diff --git a/api/pom.xml b/api/pom.xml index db802b650..d4d16e816 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -4,7 +4,7 @@ 4.0.0 akarin-api - 1.13.2-R0.1-SNAPSHOT + 1.14.4-R0.1-SNAPSHOT jar diff --git a/pom.xml b/pom.xml index 38e7be573..8ed7e81ea 100644 --- a/pom.xml +++ b/pom.xml @@ -3,16 +3,16 @@ 4.0.0 akarin jar - 1.13.2-R0.1-SNAPSHOT + 1.14.4-R0.1-SNAPSHOT Akarin https://github.com/Akarin-project/Akarin UTF-8 - 1.13.2-R0.1-SNAPSHOT - 1.13.2 - 1_13_R2 + 1.14.4-R0.1-SNAPSHOT + 1.14.4 + 1_14_R1 git-Bukkit- yyyyMMdd-HHmm @@ -31,7 +31,7 @@ com.destroystokyo.paper - akarin-api + paper-api ${api.version} compile @@ -91,7 +91,7 @@ org.xerial sqlite-jdbc - 3.25.2 + 3.28.0 runtime diff --git a/scripts/build.sh b/scripts/build.sh index 1504fd8b6..0589d03fd 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -50,8 +50,8 @@ echo "[Akarin] Ready to build" minecraftversion=$(cat "$paperworkdir/BuildData/info.json" | grep minecraftVersion | cut -d '"' -f 4) rawjar="$paperbasedir/Paper-Server/target/akarin-$minecraftversion.jar" \cp -rf "$rawjar" "$basedir/akarin-$minecraftversion.jar" - rawapi="$paperbasedir/Paper-API/target/akarin-api-1.13.2-R0.1-SNAPSHOT.jar" - \cp -rf "$rawapi" "$basedir/akarin-api-1.13.2-R0.1-SNAPSHOT.jar" + rawapi="$paperbasedir/Paper-API/target/akarin-api-1.14.4-R0.1-SNAPSHOT.jar" + \cp -rf "$rawapi" "$basedir/akarin-api-1.14.4-R0.1-SNAPSHOT.jar" echo "" echo "[Akarin] Build successful" diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java index 987727a94..c6818bc86 100644 --- a/src/main/java/co/aikar/timings/MinecraftTimings.java +++ b/src/main/java/co/aikar/timings/MinecraftTimings.java @@ -1,17 +1,18 @@ package co.aikar.timings; -import com.github.benmanes.caffeine.cache.Cache; import com.google.common.collect.MapMaker; import net.minecraft.server.*; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitTask; -import org.checkerframework.checker.nullness.qual.NonNull; + import org.bukkit.craftbukkit.scheduler.CraftTask; import java.util.Map; +// TODO: Re-implement missing timers public final class MinecraftTimings { + public static final Timing serverOversleep = Timings.ofSafe("Server Oversleep"); public static final Timing playerListTimer = Timings.ofSafe("Player List"); public static final Timing commandFunctionsTimer = Timings.ofSafe("Command Functions"); public static final Timing connectionTimer = Timings.ofSafe("Connection Handler"); @@ -32,6 +33,7 @@ public final class MinecraftTimings { public static final Timing structureGenerationTimer = Timings.ofSafe("Structure Generation"); public static final Timing processQueueTimer = Timings.ofSafe("processQueue"); + public static final Timing processTasksTimer = Timings.ofSafe("processTasks"); public static final Timing playerCommandTimer = Timings.ofSafe("playerCommand"); @@ -40,7 +42,7 @@ public final class MinecraftTimings { public static final Timing antiXrayUpdateTimer = Timings.ofSafe("anti-xray - update"); public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate"); - private static final Cache, String> taskNameCache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder().weakKeys().build(); // Akarin - caffeine + private static final Map, String> taskNameCache = new MapMaker().weakKeys().makeMap(); private MinecraftTimings() {} @@ -65,7 +67,7 @@ public final class MinecraftTimings { plugin = TimingsManager.getPluginByClassloader(taskClass); } - final String taskname = taskNameCache.get(taskClass, clazz -> // Akarin - caffeine + final String taskname = taskNameCache.computeIfAbsent(taskClass, clazz -> clazz.isAnonymousClass() || clazz.isLocalClass() ? clazz.getName() : clazz.getCanonicalName()); diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java index eff9dcf54..ddec62fbf 100644 --- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java +++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java @@ -6,6 +6,7 @@ import net.minecraft.server.WorldServer; /** * Set of timers per world, to track world specific timings. */ +// TODO: Re-implement missing timers public class WorldTimingsHandler { public final Timing mobSpawn; public final Timing doChunkUnload; @@ -35,12 +36,19 @@ public class WorldTimingsHandler { public final Timing tracker2; public final Timing doTick; public final Timing tickEntities; + public final Timing chunks; + public final Timing newEntities; + public final Timing raids; + public final Timing chunkProviderTick; + public final Timing broadcastChunkUpdates; + public final Timing countNaturalMobs; public final Timing syncChunkLoadTimer; public final Timing syncChunkLoadDataTimer; public final Timing syncChunkLoadStructuresTimer; public final Timing syncChunkLoadPostTimer; public final Timing syncChunkLoadPopulateTimer; + public final Timing chunkAwait; public final Timing chunkLoadLevelTimer; public final Timing chunkGeneration; public final Timing chunkIOStage1; @@ -50,7 +58,23 @@ public class WorldTimingsHandler { public final Timing worldSaveLevel; public final Timing chunkSaveData; - public final Timing lightingQueueTimer; + + public final Timing miscMobSpawning; + public final Timing chunkRangeCheckBig; + public final Timing chunkRangeCheckSmall; + + public final Timing poiUnload; + public final Timing chunkUnload; + public final Timing poiSaveDataSerialization; + public final Timing chunkSave; + public final Timing chunkSaveOverwriteCheck; + public final Timing chunkSaveDataSerialization; + public final Timing chunkSaveIOWait; + public final Timing chunkUnloadPrepareSave; + public final Timing chunkUnloadPOISerialization; + public final Timing chunkUnloadDataSave; + + public final Timing playerMobDistanceMapUpdate; public WorldTimingsHandler(World server) { String name = server.worldData.getName() +" - "; @@ -85,6 +109,7 @@ public class WorldTimingsHandler { syncChunkLoadStructuresTimer = Timings.ofSafe(name + "chunkLoad - recreateStructures"); syncChunkLoadPostTimer = Timings.ofSafe(name + "chunkLoad - Post"); syncChunkLoadPopulateTimer = Timings.ofSafe(name + "chunkLoad - Populate"); + chunkAwait = Timings.ofSafe(name + "chunkAwait"); chunkLoadLevelTimer = Timings.ofSafe(name + "chunkLoad - Load Level"); chunkGeneration = Timings.ofSafe(name + "chunkGeneration"); chunkIOStage1 = Timings.ofSafe(name + "ChunkIO Stage 1 - DiskIO"); @@ -99,7 +124,30 @@ public class WorldTimingsHandler { doTick = Timings.ofSafe(name + "doTick"); tickEntities = Timings.ofSafe(name + "tickEntities"); - lightingQueueTimer = Timings.ofSafe(name + "Lighting Queue"); + chunks = Timings.ofSafe(name + "Chunks"); + newEntities = Timings.ofSafe(name + "New entity registration"); + raids = Timings.ofSafe(name + "Raids"); + chunkProviderTick = Timings.ofSafe(name + "Chunk provider tick"); + broadcastChunkUpdates = Timings.ofSafe(name + "Broadcast chunk updates"); + countNaturalMobs = Timings.ofSafe(name + "Count natural mobs"); + + + miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc"); + chunkRangeCheckBig = Timings.ofSafe(name + "Chunk Tick Range - Big"); + chunkRangeCheckSmall = Timings.ofSafe(name + "Chunk Tick Range - Small"); + + poiUnload = Timings.ofSafe(name + "Chunk unload - POI"); + chunkUnload = Timings.ofSafe(name + "Chunk unload - Chunk"); + poiSaveDataSerialization = Timings.ofSafe(name + "Chunk save - POI Data serialization"); + chunkSave = Timings.ofSafe(name + "Chunk save - Chunk"); + chunkSaveOverwriteCheck = Timings.ofSafe(name + "Chunk save - Chunk Overwrite Check"); + chunkSaveDataSerialization = Timings.ofSafe(name + "Chunk save - Chunk Data serialization"); + chunkSaveIOWait = Timings.ofSafe(name + "Chunk save - Chunk IO Wait"); + chunkUnloadPrepareSave = Timings.ofSafe(name + "Chunk unload - Async Save Prepare"); + chunkUnloadPOISerialization = Timings.ofSafe(name + "Chunk unload - POI Data Serialization"); + chunkUnloadDataSave = Timings.ofSafe(name + "Chunk unload - Data Serialization"); + + playerMobDistanceMapUpdate = Timings.ofSafe(name + "Per Player Mob Spawning - Distance Map Update"); } public static Timing getTickList(WorldServer worldserver, String timingsType) { diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java index cc0c74aaa..e257d6b36 100644 --- a/src/main/java/com/destroystokyo/paper/Metrics.java +++ b/src/main/java/com/destroystokyo/paper/Metrics.java @@ -31,7 +31,7 @@ public class Metrics { public static final int B_STATS_VERSION = 1; // The url to which the data is sent - private static final String URL = "https://bStats.org/submitData/bukkit"; // Akarin + private static final String URL = "https://bStats.org/submitData/server-implementation"; // Should failed requests be logged? private static boolean logFailedRequests = false; @@ -103,7 +103,6 @@ public class Metrics { JSONObject data = new JSONObject(); data.put("pluginName", name); // Append the name of the server software - data.put("pluginVersion", Metrics.class.getPackage().getImplementationVersion() != null ? Metrics.class.getPackage().getImplementationVersion() : "unknown"); // Akarin JSONArray customCharts = new JSONArray(); for (CustomChart customChart : charts) { // Add the data of the custom charts @@ -124,24 +123,13 @@ public class Metrics { * @return The server specific data. */ private JSONObject getServerData() { - // Akarin start - Minecraft specific data - int playerAmount = Bukkit.getOnlinePlayers().size(); - int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; - String bukkitVersion = org.bukkit.Bukkit.getVersion(); - bukkitVersion = bukkitVersion.substring(bukkitVersion.indexOf("MC: ") + 4, bukkitVersion.length() - 1); - - JSONObject data = new JSONObject(); - data.put("playerAmount", playerAmount); - data.put("onlineMode", onlineMode); - data.put("bukkitVersion", bukkitVersion); - // Akarin end // OS specific data String osName = System.getProperty("os.name"); String osArch = System.getProperty("os.arch"); String osVersion = System.getProperty("os.version"); int coreCount = Runtime.getRuntime().availableProcessors(); - //JSONObject data = new JSONObject(); // Akarin + JSONObject data = new JSONObject(); data.put("serverUUID", serverUUID); @@ -590,10 +578,8 @@ public class Metrics { boolean logFailedRequests = config.getBoolean("logFailedRequests", false); // Only start Metrics, if it's enabled in the config if (config.getBoolean("enabled", true)) { - // Akarin start - Metrics metrics = new Metrics("Torch", serverUUID, logFailedRequests, Bukkit.getLogger()); + Metrics metrics = new Metrics("Paper", serverUUID, logFailedRequests, Bukkit.getLogger()); - /* metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> { String minecraftVersion = Bukkit.getVersion(); minecraftVersion = minecraftVersion.substring(minecraftVersion.indexOf("MC: ") + 4, minecraftVersion.length() - 1); @@ -634,8 +620,6 @@ public class Metrics { return map; })); - */ - // Akarin end } } diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java index 8e1bda4de..132397b3f 100644 --- a/src/main/java/com/destroystokyo/paper/PaperCommand.java +++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java @@ -1,9 +1,13 @@ package com.destroystokyo.paper; +import com.destroystokyo.paper.io.SyncLoadFinder; import com.google.common.base.Functions; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.gson.JsonObject; +import com.google.gson.internal.Streams; +import com.google.gson.stream.JsonWriter; import net.minecraft.server.*; import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -18,6 +22,9 @@ import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Player; import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.io.StringWriter; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; @@ -28,14 +35,14 @@ public class PaperCommand extends Command { public PaperCommand(String name) { super(name); this.description = "Paper related commands"; - this.usageMessage = "/paper [heap | entity | reload | version]"; + this.usageMessage = "/paper [heap | entity | reload | version | debug | chunkinfo]"; this.setPermission("bukkit.command.paper"); } @Override public List tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException { if (args.length <= 1) - return getListMatchingLast(args, "heap", "entity", "reload", "version"); + return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "chunkinfo"); switch (args[0].toLowerCase(Locale.ENGLISH)) { @@ -45,6 +52,21 @@ public class PaperCommand extends Command { if (args.length == 3) return getListMatchingLast(args, EntityTypes.getEntityNameList().stream().map(MinecraftKey::toString).sorted().toArray(String[]::new)); break; + case "debug": + if (args.length == 2) { + return getListMatchingLast(args, "help", "chunks"); + } + break; + case "chunkinfo": + List worldNames = new ArrayList<>(); + worldNames.add("*"); + for (org.bukkit.World world : Bukkit.getWorlds()) { + worldNames.add(world.getName()); + } + if (args.length == 2) { + return getListMatchingLast(args, worldNames); + } + break; } return Collections.emptyList(); } @@ -109,6 +131,15 @@ public class PaperCommand extends Command { case "reload": doReload(sender); break; + case "debug": + doDebug(sender, args); + break; + case "chunkinfo": + doChunkInfo(sender, args); + break; + case "syncloadinfo": + this.doSyncLoadInfo(sender, args); + break; case "ver": case "version": Command ver = org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version"); @@ -125,6 +156,130 @@ public class PaperCommand extends Command { return true; } + private void doSyncLoadInfo(CommandSender sender, String[] args) { + if (!SyncLoadFinder.ENABLED) { + sender.sendMessage(ChatColor.RED + "This command requires the server startup flag '-Dpaper.debug-sync-loads=true' to be set."); + return; + } + File file = new File(new File(new File("."), "debug"), + "sync-load-info" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt"); + file.getParentFile().mkdirs(); + sender.sendMessage(ChatColor.GREEN + "Writing sync load info to " + file.toString()); + + + try { + final JsonObject data = SyncLoadFinder.serialize(); + + StringWriter stringWriter = new StringWriter(); + JsonWriter jsonWriter = new JsonWriter(stringWriter); + jsonWriter.setIndent(" "); + jsonWriter.setLenient(false); + Streams.write(data, jsonWriter); + + String fileData = stringWriter.toString(); + + try ( + PrintStream out = new PrintStream(new FileOutputStream(file), false, "UTF-8") + ) { + out.print(fileData); + } + sender.sendMessage(ChatColor.GREEN + "Successfully written sync load information!"); + } catch (Throwable thr) { + sender.sendMessage(ChatColor.RED + "Failed to write sync load information"); + thr.printStackTrace(); + } + } + + private void doChunkInfo(CommandSender sender, String[] args) { + List worlds; + if (args.length < 2 || args[1].equals("*")) { + worlds = Bukkit.getWorlds(); + } else { + worlds = new ArrayList<>(args.length - 1); + for (int i = 1; i < args.length; ++i) { + org.bukkit.World world = Bukkit.getWorld(args[i]); + if (world == null) { + sender.sendMessage(ChatColor.RED + "World '" + args[i] + "' is invalid"); + return; + } + worlds.add(world); + } + } + + for (org.bukkit.World bukkitWorld : worlds) { + WorldServer world = ((CraftWorld)bukkitWorld).getHandle(); + + int total = 0; + int inactive = 0; + int border = 0; + int ticking = 0; + int entityTicking = 0; + + for (PlayerChunk chunk : world.getChunkProvider().playerChunkMap.updatingChunks.values()) { + if (chunk.getFullChunkIfCached() == null) { + continue; + } + + ++total; + + PlayerChunk.State state = PlayerChunk.getChunkState(chunk.getTicketLevel()); + + switch (state) { + case INACCESSIBLE: + ++inactive; + continue; + case BORDER: + ++border; + continue; + case TICKING: + ++ticking; + continue; + case ENTITY_TICKING: + ++entityTicking; + continue; + } + } + + sender.sendMessage(ChatColor.BLUE + "Chunks in " + ChatColor.GREEN + bukkitWorld.getName() + ChatColor.DARK_AQUA + ":"); + sender.sendMessage(ChatColor.BLUE + "Total: " + ChatColor.DARK_AQUA + total + ChatColor.BLUE + " Inactive: " + ChatColor.DARK_AQUA + + inactive + ChatColor.BLUE + " Border: " + ChatColor.DARK_AQUA + border + ChatColor.BLUE + " Ticking: " + + ChatColor.DARK_AQUA + ticking + ChatColor.BLUE + " Entity: " + ChatColor.DARK_AQUA + entityTicking); + } + } + + private void doDebug(CommandSender sender, String[] args) { + if (args.length < 2) { + sender.sendMessage(ChatColor.RED + "Use /paper debug [chunks] help for more information on a specific command"); + return; + } + + String debugType = args[1].toLowerCase(Locale.ENGLISH); + switch (debugType) { + case "chunks": + if (args.length >= 3 && args[2].toLowerCase(Locale.ENGLISH).equals("help")) { + sender.sendMessage(ChatColor.RED + "Use /paper debug chunks to dump loaded chunk information to a file"); + break; + } + File file = new File(new File(new File("."), "debug"), + "chunks-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt"); + sender.sendMessage(ChatColor.GREEN + "Writing chunk information dump to " + file.toString()); + try { + MCUtil.dumpChunks(file); + sender.sendMessage(ChatColor.GREEN + "Successfully written chunk information!"); + } catch (Throwable thr) { + MinecraftServer.LOGGER.warn("Failed to dump chunk information to file " + file.toString(), thr); + sender.sendMessage(ChatColor.RED + "Failed to dump chunk information, see console"); + } + + break; + case "help": + // fall through to default + default: + sender.sendMessage(ChatColor.RED + "Use /paper debug [chunks] help for more information on a specific command"); + return; + } + } + /* * Ported from MinecraftForge - author: LexManos - License: LGPLv2.1 */ @@ -173,8 +328,11 @@ public class PaperCommand extends Command { } WorldServer world = ((CraftWorld) Bukkit.getWorld(worldName)).getHandle(); - List entities = world.entityList; + Collection entities = world.entitiesById.values(); entities.forEach(e -> { + if (!e.isChunkLoaded()) { + return; + } MinecraftKey key = e.getMinecraftKey(); if (e.shouldBeRemoved) return; // Paper @@ -216,11 +374,14 @@ public class PaperCommand extends Command { } private void dumpHeap(CommandSender sender) { - File file = new File(new File(new File("."), "dumps"), - "heap-dump-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + "-server.hprof"); - Command.broadcastCommandMessage(sender, ChatColor.YELLOW + "Writing JVM heap data to " + file); - if (CraftServer.dumpHeap(file)) { - Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Heap dump complete"); + java.nio.file.Path dir = java.nio.file.Paths.get("./dumps"); + String name = "heap-dump-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()); + + Command.broadcastCommandMessage(sender, ChatColor.YELLOW + "Writing JVM heap data..."); + + java.nio.file.Path file = CraftServer.dumpHeap(dir, name); + if (file != null) { + Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Heap dump saved to " + file); } else { Command.broadcastCommandMessage(sender, ChatColor.RED + "Failed to write heap dump, see sever log for details"); } diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java index 9f240c35d..93c0c422d 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -1,5 +1,6 @@ package com.destroystokyo.paper; +import com.destroystokyo.paper.io.chunk.ChunkTaskManager; import com.google.common.base.Strings; import com.google.common.base.Throwables; @@ -71,8 +72,8 @@ public class PaperConfig { commands = new HashMap(); commands.put("paper", new PaperCommand("paper")); - version = getInt("config-version", 18); - set("config-version", 18); + version = getInt("config-version", 20); + set("config-version", 20); readConfig(PaperConfig.class, null); } @@ -199,13 +200,7 @@ public class PaperConfig { return config.getString(path, config.getString(path)); } - public static int maxTickMsLostLightQueue; - private static void lightQueue() { - int badSetting = config.getInt("queue-light-updates-max-loss", 10); - config.set("queue-light-updates-max-loss", null); - maxTickMsLostLightQueue = getInt("settings.queue-light-updates-max-loss", badSetting); - } - + public static String timingsServerName; private static void timings() { boolean timings = getBoolean("timings.enabled", true); boolean verboseTimings = getBoolean("timings.verbose", true); @@ -213,6 +208,7 @@ public class PaperConfig { TimingsManager.hiddenConfigs = getList("timings.hidden-config-entries", Lists.newArrayList("database", "settings.bungeecord-addresses")); int timingHistoryInterval = getInt("timings.history-interval", 300); int timingHistoryLength = getInt("timings.history-length", 3600); + timingsServerName = getString("timings.server-name", "Unknown Server"); Timings.setVerboseTimingsEnabled(verboseTimings); @@ -223,13 +219,8 @@ public class PaperConfig { log("Timings: " + timings + " - Verbose: " + verboseTimings + " - Interval: " + timeSummary(Timings.getHistoryInterval() / 20) + - " - Length: " + timeSummary(Timings.getHistoryLength() / 20)); - } - - public static boolean enableFileIOThreadSleep; - private static void enableFileIOThreadSleep() { - enableFileIOThreadSleep = getBoolean("settings.sleep-between-chunk-saves", false); - if (enableFileIOThreadSleep) Bukkit.getLogger().info("Enabled sleeping between chunk saves, beware of memory issues"); + " - Length: " + timeSummary(Timings.getHistoryLength() / 20) + + " - Server Name: " + timingsServerName); } public static boolean loadPermsBeforePlugins = true; @@ -239,7 +230,7 @@ public class PaperConfig { public static int regionFileCacheSize = 256; private static void regionFileCacheSize() { - regionFileCacheSize = getInt("settings.region-file-cache-size", 256); + regionFileCacheSize = Math.max(getInt("settings.region-file-cache-size", 256), 4); } public static boolean enablePlayerCollisions = true; @@ -277,17 +268,6 @@ public class PaperConfig { flyingKickVehicleMessage = getString("messages.kick.flying-vehicle", flyingKickVehicleMessage); } - public static int playerAutoSaveRate = -1; - public static int maxPlayerAutoSavePerTick = 10; - private static void playerAutoSaveRate() { - playerAutoSaveRate = getInt("settings.player-auto-save-rate", -1); - maxPlayerAutoSavePerTick = getInt("settings.max-player-auto-save-per-tick", -1); - if (maxPlayerAutoSavePerTick == -1) { // -1 Automatic / "Recommended" - // 10 should be safe for everyone unless your mass spamming player auto save - maxPlayerAutoSavePerTick = (playerAutoSaveRate == -1 || playerAutoSaveRate > 100) ? 10 : 20; - } - } - public static boolean suggestPlayersWhenNullTabCompletions = true; private static void suggestPlayersWhenNull() { suggestPlayersWhenNullTabCompletions = getBoolean("settings.suggest-player-names-when-null-tab-completions", suggestPlayersWhenNullTabCompletions); @@ -389,59 +369,6 @@ public class PaperConfig { } } - public static boolean asyncChunks = false; - public static boolean asyncChunkGeneration = true; - public static boolean asyncChunkGenThreadPerWorld = true; - public static int asyncChunkLoadThreads = -1; - private static void asyncChunks() { - if (version < 15) { - boolean enabled = config.getBoolean("settings.async-chunks", true); - ConfigurationSection section = config.createSection("settings.async-chunks"); - section.set("enable", enabled); - section.set("load-threads", -1); - section.set("generation", true); - section.set("thread-per-world-generation", true); - } - - asyncChunks = getBoolean("settings.async-chunks.enable", true); - asyncChunkGeneration = getBoolean("settings.async-chunks.generation", true); - asyncChunkGenThreadPerWorld = getBoolean("settings.async-chunks.thread-per-world-generation", true); - asyncChunkLoadThreads = getInt("settings.async-chunks.load-threads", -1); - if (asyncChunkLoadThreads <= 0) { - asyncChunkLoadThreads = (int) Math.min(Integer.getInteger("paper.maxChunkThreads", 8), Runtime.getRuntime().availableProcessors() * 1.5); - } - - // Let Shared Host set some limits - String sharedHostEnvGen = System.getenv("PAPER_ASYNC_CHUNKS_SHARED_HOST_GEN"); - String sharedHostEnvLoad = System.getenv("PAPER_ASYNC_CHUNKS_SHARED_HOST_LOAD"); - if ("1".equals(sharedHostEnvGen)) { - log("Async Chunks - Generation: Your host has requested to use a single thread world generation"); - asyncChunkGenThreadPerWorld = false; - } else if ("2".equals(sharedHostEnvGen)) { - log("Async Chunks - Generation: Your host has disabled async world generation - You will experience lag from world generation"); - asyncChunkGeneration = false; - } - - if (sharedHostEnvLoad != null) { - try { - asyncChunkLoadThreads = Math.max(1, Math.min(asyncChunkLoadThreads, Integer.parseInt(sharedHostEnvLoad))); - } catch (NumberFormatException ignored) {} - } - - if (!asyncChunks) { - log("Async Chunks: Disabled - Chunks will be managed synchronosuly, and will cause tremendous lag."); - } else { - log("Async Chunks: Enabled - Chunks will be loaded much faster, without lag."); - if (!asyncChunkGeneration) { - log("Async Chunks - Generation: Disabled - Chunks will be generated synchronosuly, and will cause tremendous lag."); - } else if (asyncChunkGenThreadPerWorld) { - log("Async Chunks - Generation: Enabled - Chunks will be generated much faster, without lag."); - } else { - log("Async Chunks - Generation: Enabled (Single Thread) - Chunks will be generated much faster, without lag."); - } - } - } - public static boolean velocitySupport; public static boolean velocityOnlineMode; public static byte[] velocitySecretKey; @@ -462,4 +389,64 @@ public class PaperConfig { maxBookPageSize = getInt("settings.book-size.page-max", maxBookPageSize); maxBookTotalSizeMultiplier = getDouble("settings.book-size.total-multiplier", maxBookTotalSizeMultiplier); } + + public static boolean asyncChunks = false; + //public static boolean asyncChunkGeneration = true; // Leave out for now until we can control this + //public static boolean asyncChunkGenThreadPerWorld = true; // Leave out for now until we can control this + public static int asyncChunkLoadThreads = -1; + private static void asyncChunks() { + if (version < 15) { + boolean enabled = config.getBoolean("settings.async-chunks", true); + ConfigurationSection section = config.createSection("settings.async-chunks"); + section.set("enable", enabled); + section.set("load-threads", -1); + section.set("generation", true); + section.set("thread-per-world-generation", true); + } + + // TODO load threads now control async chunk save for unloading chunks, look into renaming this? + + asyncChunks = getBoolean("settings.async-chunks.enable", true); + //asyncChunkGeneration = getBoolean("settings.async-chunks.generation", true); // Leave out for now until we can control this + //asyncChunkGenThreadPerWorld = getBoolean("settings.async-chunks.thread-per-world-generation", true); // Leave out for now until we can control this + asyncChunkLoadThreads = getInt("settings.async-chunks.load-threads", -1); + if (asyncChunkLoadThreads <= 0) { + asyncChunkLoadThreads = (int) Math.min(Integer.getInteger("paper.maxChunkThreads", 8), Math.max(1, Runtime.getRuntime().availableProcessors() - 1)); + } + + // Let Shared Host set some limits + String sharedHostEnvGen = System.getenv("PAPER_ASYNC_CHUNKS_SHARED_HOST_GEN"); + String sharedHostEnvLoad = System.getenv("PAPER_ASYNC_CHUNKS_SHARED_HOST_LOAD"); + /* Ignore temporarily - we cannot control the gen threads (for now) + if ("1".equals(sharedHostEnvGen)) { + log("Async Chunks - Generation: Your host has requested to use a single thread world generation"); + asyncChunkGenThreadPerWorld = false; + } else if ("2".equals(sharedHostEnvGen)) { + log("Async Chunks - Generation: Your host has disabled async world generation - You will experience lag from world generation"); + asyncChunkGeneration = false; + } + */ + + if (sharedHostEnvLoad != null) { + try { + asyncChunkLoadThreads = Math.max(1, Math.min(asyncChunkLoadThreads, Integer.parseInt(sharedHostEnvLoad))); + } catch (NumberFormatException ignored) {} + } + + if (!asyncChunks) { + log("Async Chunks: Disabled - Chunks will be managed synchronosuly, and will cause tremendous lag."); + } else { + ChunkTaskManager.initGlobalLoadThreads(asyncChunkLoadThreads); + log("Async Chunks: Enabled - Chunks will be loaded much faster, without lag."); + /* Ignore temporarily - we cannot control the gen threads (for now) + if (!asyncChunkGeneration) { + log("Async Chunks - Generation: Disabled - Chunks will be generated synchronosuly, and will cause tremendous lag."); + } else if (asyncChunkGenThreadPerWorld) { + log("Async Chunks - Generation: Enabled - Chunks will be generated much faster, without lag."); + } else { + log("Async Chunks - Generation: Enabled (Single Thread) - Chunks will be generated much faster, without lag."); + } + */ + } + } } diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java new file mode 100644 index 000000000..513cddb9b --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java @@ -0,0 +1,133 @@ +package com.destroystokyo.paper; + +import com.destroystokyo.paper.util.VersionFetcher; +import com.google.common.base.Charsets; +import com.google.common.io.Resources; +import com.google.gson.*; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; + +public class PaperVersionFetcher implements VersionFetcher { + private static final java.util.regex.Pattern VER_PATTERN = java.util.regex.Pattern.compile("^([0-9\\.]*)\\-.*R"); // R is an anchor, will always give '-R' at end + private static final String GITHUB_BRANCH_NAME = "ver/1.14"; + private static @Nullable String mcVer; + + @Override + public long getCacheTime() { + return 720000; + } + + @Nonnull + @Override + public String getVersionMessage(@Nonnull String serverVersion) { + String[] parts = serverVersion.substring("git-Paper-".length()).split("[-\\s]"); + String updateMessage = getUpdateStatusMessage("PaperMC/Paper", GITHUB_BRANCH_NAME, parts[0]); + String history = getHistory(); + + return history != null ? history + "\n" + updateMessage : updateMessage; + } + + private static @Nullable String getMinecraftVersion() { + if (mcVer == null) { + java.util.regex.Matcher matcher = VER_PATTERN.matcher(org.bukkit.Bukkit.getBukkitVersion()); + if (matcher.find()) { + String result = matcher.group(); + mcVer = result.substring(0, result.length() - 2); // strip 'R' anchor and trailing '-' + } else { + org.bukkit.Bukkit.getLogger().warning("Unable to match version to pattern! Report to PaperMC!"); + org.bukkit.Bukkit.getLogger().warning("Pattern: " + VER_PATTERN.toString()); + org.bukkit.Bukkit.getLogger().warning("Version: " + org.bukkit.Bukkit.getBukkitVersion()); + } + } + + return mcVer; + } + + private static String getUpdateStatusMessage(@Nonnull String repo, @Nonnull String branch, @Nonnull String versionInfo) { + int distance; + try { + int jenkinsBuild = Integer.parseInt(versionInfo); + distance = fetchDistanceFromSiteApi(jenkinsBuild, getMinecraftVersion()); + } catch (NumberFormatException ignored) { + versionInfo = versionInfo.replace("\"", ""); + distance = fetchDistanceFromGitHub(repo, branch, versionInfo); + } + + switch (distance) { + case -1: + return "Error obtaining version information"; + case 0: + return "You are running the latest version"; + case -2: + return "Unknown version"; + default: + return "You are " + distance + " version(s) behind"; + } + } + + private static int fetchDistanceFromSiteApi(int jenkinsBuild, @Nullable String siteApiVersion) { + if (siteApiVersion == null) { return -1; } + try { + try (BufferedReader reader = Resources.asCharSource( + new URL("https://papermc.io/api/v1/paper/" + siteApiVersion + "/latest"), + Charsets.UTF_8 + ).openBufferedStream()) { + JsonObject json = new Gson().fromJson(reader, JsonObject.class); + int latest = json.get("build").getAsInt(); + return latest - jenkinsBuild; + } catch (JsonSyntaxException ex) { + ex.printStackTrace(); + return -1; + } + } catch (IOException e) { + e.printStackTrace(); + return -1; + } + } + + // Contributed by Techcable in GH-65 + private static int fetchDistanceFromGitHub(@Nonnull String repo, @Nonnull String branch, @Nonnull String hash) { + try { + HttpURLConnection connection = (HttpURLConnection) new URL("https://api.github.com/repos/" + repo + "/compare/" + branch + "..." + hash).openConnection(); + connection.connect(); + if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) return -2; // Unknown commit + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8))) { + JsonObject obj = new Gson().fromJson(reader, JsonObject.class); + String status = obj.get("status").getAsString(); + switch (status) { + case "identical": + return 0; + case "behind": + return obj.get("behind_by").getAsInt(); + default: + return -1; + } + } catch (JsonSyntaxException | NumberFormatException e) { + e.printStackTrace(); + return -1; + } + } catch (IOException e) { + e.printStackTrace(); + return -1; + } + } + + @Nullable + private String getHistory() { + final VersionHistoryManager.VersionData data = VersionHistoryManager.INSTANCE.getVersionData(); + if (data == null) { + return null; + } + + final String oldVersion = data.getOldVersion(); + if (oldVersion == null) { + return null; + } + + return "Previous version: " + oldVersion; + } +} diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java index bfd690ecc..3e5571f7d 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java @@ -1,12 +1,17 @@ package com.destroystokyo.paper; import java.util.Arrays; +import java.util.EnumMap; +import java.util.HashMap; import java.util.List; +import java.util.Map; import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray.ChunkEdgeMode; import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray.EngineMode; import net.minecraft.server.MinecraftServer; import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.spigotmc.SpigotWorldConfig; @@ -78,10 +83,15 @@ public class PaperWorldConfig { } - public double babyZombieMovementSpeed; - private void babyZombieMovementSpeed() { - babyZombieMovementSpeed = getDouble("baby-zombie-movement-speed", 0.5D); // Player moves at 0.1F, for reference - log("Baby zombies will move at the speed of " + babyZombieMovementSpeed); + public double babyZombieMovementModifier; + private void babyZombieMovementModifier() { + babyZombieMovementModifier = getDouble("baby-zombie-movement-modifier", 0.5D); + if (PaperConfig.version < 20) { + babyZombieMovementModifier = getDouble("baby-zombie-movement-speed", 0.5D); + set("baby-zombie-movement-modifier", babyZombieMovementModifier); + } + + log("Baby zombies will move at the speed of " + babyZombieMovementModifier); } public int fishingMinTicks; @@ -144,14 +154,6 @@ public class PaperWorldConfig { } } - public boolean queueLightUpdates; - private void queueLightUpdates() { - queueLightUpdates = getBoolean("queue-light-updates", false); - log("Lighting Queue enabled: " + queueLightUpdates); - log("Warning: This feature may help reduce TPS loss from light, but comes at the cost of buggy light data"); - log("We are working to improve this feature."); - } - public boolean disableEndCredits; private void disableEndCredits() { disableEndCredits = getBoolean("game-mechanics.disable-end-credits", false); @@ -269,11 +271,6 @@ public class PaperWorldConfig { } } - public boolean firePhysicsEventForRedstone = false; - private void firePhysicsEventForRedstone() { - firePhysicsEventForRedstone = getBoolean("fire-physics-event-for-redstone", firePhysicsEventForRedstone); - } - public int fixedInhabitedTime; private void fixedInhabitedTime() { if (PaperConfig.version < 16) { @@ -290,12 +287,6 @@ public class PaperWorldConfig { log("Grass Spread Tick Rate: " + grassUpdateRate); } - public short keepLoadedRange; - private void keepLoadedRange() { - keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 8)) * 16); - log( "Keep Spawn Loaded Range: " + (keepLoadedRange/16)); - } - public boolean useVanillaScoreboardColoring; private void useVanillaScoreboardColoring() { useVanillaScoreboardColoring = getBoolean("use-vanilla-world-scoreboard-name-coloring", false); @@ -343,40 +334,6 @@ public class PaperWorldConfig { log("Prevent TNT from moving in water: " + preventTntFromMovingInWater); } - public long delayChunkUnloadsBy; - private void delayChunkUnloadsBy() { - delayChunkUnloadsBy = PaperConfig.getSeconds(getString("delay-chunk-unloads-by", "10s")); - if (delayChunkUnloadsBy > 0) { - log("Delaying chunk unloads by " + delayChunkUnloadsBy + " seconds"); - delayChunkUnloadsBy *= 1000; - } - } - - public boolean skipEntityTickingInChunksScheduledForUnload = true; - private void skipEntityTickingInChunksScheduledForUnload() { - skipEntityTickingInChunksScheduledForUnload = getBoolean("skip-entity-ticking-in-chunks-scheduled-for-unload", skipEntityTickingInChunksScheduledForUnload); - } - - public int autoSavePeriod = -1; - private void autoSavePeriod() { - autoSavePeriod = getInt("auto-save-interval", -1); - if (autoSavePeriod > 0) { - log("Auto Save Interval: " +autoSavePeriod + " (" + (autoSavePeriod / 20) + "s)"); - } else if (autoSavePeriod < 0) { - autoSavePeriod = MinecraftServer.getServer().autosavePeriod; - } - } - - public int maxAutoSaveChunksPerTick = 24; - private void maxAutoSaveChunksPerTick() { - maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24); - } - - public int queueSizeAutoSaveThreshold = 50; - private void queueSizeAutoSaveThreshold() { - queueSizeAutoSaveThreshold = getInt("save-queue-limit-for-auto-save", 50); - } - public boolean removeCorruptTEs = false; private void removeCorruptTEs() { removeCorruptTEs = getBoolean("remove-corrupt-tile-entities", false); @@ -429,26 +386,6 @@ public class PaperWorldConfig { log("Experience Merge Max Value: " + expMergeMaxValue); } - public int maxChunkSendsPerTick = 81; - private void maxChunkSendsPerTick() { - maxChunkSendsPerTick = getInt("max-chunk-sends-per-tick", maxChunkSendsPerTick); - if (maxChunkSendsPerTick <= 0) { - maxChunkSendsPerTick = 81; - } - log("Max Chunk Sends Per Tick: " + maxChunkSendsPerTick); - } - - public int maxChunkGensPerTick = 10; - private void maxChunkGensPerTick() { - maxChunkGensPerTick = getInt("max-chunk-gens-per-tick", maxChunkGensPerTick); - if (maxChunkGensPerTick <= 0) { - maxChunkGensPerTick = Integer.MAX_VALUE; - log("Max Chunk Gens Per Tick: Unlimited (NOT RECOMMENDED)"); - } else { - log("Max Chunk Gens Per Tick: " + maxChunkGensPerTick); - } - } - public double squidMaxSpawnHeight; private void squidMaxSpawnHeight() { squidMaxSpawnHeight = getDouble("squid-spawn-height.maximum", 0.0D); @@ -474,14 +411,6 @@ public class PaperWorldConfig { log("Disable Unloaded Chunk Enderpearl Exploit: " + (disableEnderpearlExploit ? "enabled" : "disabled")); } - public boolean villagesLoadChunks = false; - private void villagesLoadChunks() { - villagesLoadChunks = getBoolean("game-mechanics.villages-load-chunks", false); - if (villagesLoadChunks) { - log("Villages can load chunks - Warning this can cause intense TPS loss. Strongly consider disabling this."); - } - } - public int shieldBlockingDelay = 5; private void shieldBlockingDelay() { shieldBlockingDelay = getInt("game-mechanics.shield-blocking-delay", 5); @@ -509,6 +438,27 @@ public class PaperWorldConfig { log("Water over lava flow speed: " + waterOverLavaFlowSpeed); } + public boolean armorStandTick = true; + private void armorStandTick() { + this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick); + log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default"); + } + + public boolean preventMovingIntoUnloadedChunks = false; + private void preventMovingIntoUnloadedChunks() { + preventMovingIntoUnloadedChunks = getBoolean("prevent-moving-into-unloaded-chunks", false); + } + + public boolean useEigencraftRedstone = false; + private void useEigencraftRedstone() { + useEigencraftRedstone = this.getBoolean("use-faster-eigencraft-redstone", false); + if (useEigencraftRedstone) { + log("Using Eigencraft redstone algorithm by theosib."); + } else { + log("Using vanilla redstone algorithm."); + } + } + public enum DuplicateUUIDMode { SAFE_REGEN, DELETE, NOTHING, WARN } @@ -548,10 +498,35 @@ public class PaperWorldConfig { } } - public boolean armorStandTick = true; - private void armorStandTick() { - this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick); - log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default"); + public short keepLoadedRange; + private void keepLoadedRange() { + keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16); + log( "Keep Spawn Loaded Range: " + (keepLoadedRange/16)); + } + + public int autoSavePeriod = -1; + private void autoSavePeriod() { + autoSavePeriod = getInt("auto-save-interval", -1); + if (autoSavePeriod > 0) { + log("Auto Save Interval: " +autoSavePeriod + " (" + (autoSavePeriod / 20) + "s)"); + } else if (autoSavePeriod < 0) { + autoSavePeriod = net.minecraft.server.MinecraftServer.getServer().autosavePeriod; + } + } + + public int maxAutoSaveChunksPerTick = 24; + private void maxAutoSaveChunksPerTick() { + maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24); + } + + public boolean countAllMobsForSpawning = false; + private void countAllMobsForSpawning() { + countAllMobsForSpawning = getBoolean("count-all-mobs-for-spawning", false); + if (countAllMobsForSpawning) { + log("Counting all mobs for spawning. Mob farms may reduce natural spawns elsewhere in world."); + } else { + log("Using improved mob spawn limits (Only Natural Spawns impact spawn limits for more natural spawns)"); + } } public boolean antiXray; @@ -579,33 +554,85 @@ public class PaperWorldConfig { maxChunkSectionIndex = getInt("anti-xray.max-chunk-section-index", 3); maxChunkSectionIndex = maxChunkSectionIndex > 15 ? 15 : maxChunkSectionIndex; updateRadius = getInt("anti-xray.update-radius", 2); - hiddenBlocks = getList("anti-xray.hidden-blocks", Arrays.asList("gold_ore", "iron_ore", "coal_ore", "lapis_ore", "mossy_cobblestone", "obsidian", "chest", "diamond_ore", "redstone_ore", "lit_redstone_ore", "clay", "emerald_ore", "ender_chest")); - replacementBlocks = getList("anti-xray.replacement-blocks", Arrays.asList("stone", "planks")); + hiddenBlocks = getList("anti-xray.hidden-blocks", Arrays.asList("gold_ore", "iron_ore", "coal_ore", "lapis_ore", "mossy_cobblestone", "obsidian", "chest", "diamond_ore", "redstone_ore", "clay", "emerald_ore", "ender_chest")); + replacementBlocks = getList("anti-xray.replacement-blocks", Arrays.asList("stone", "oak_planks")); + if (PaperConfig.version < 19) { + hiddenBlocks.remove("lit_redstone_ore"); + int index = replacementBlocks.indexOf("planks"); + if (index != -1) { + replacementBlocks.set(index, "oak_planks"); + } + set("anti-xray.hidden-blocks", hiddenBlocks); + set("anti-xray.replacement-blocks", replacementBlocks); + } log("Anti-Xray: " + (antiXray ? "enabled" : "disabled") + " / Engine Mode: " + engineMode.getDescription() + " / Chunk Edge Mode: " + chunkEdgeMode.getDescription() + " / Up to " + ((maxChunkSectionIndex + 1) * 16) + " blocks / Update Radius: " + updateRadius); } - public boolean preventMovingIntoUnloadedChunks = false; - private void preventMovingIntoUnloadedChunks() { - preventMovingIntoUnloadedChunks = getBoolean("prevent-moving-into-unloaded-chunks", false); + public boolean disableRelativeProjectileVelocity; + private void disableRelativeProjectileVelocity() { + disableRelativeProjectileVelocity = getBoolean("game-mechanics.disable-relative-projectile-velocity", false); } - public boolean useEigencraftRedstone = false; - private void useEigencraftRedstone() { - useEigencraftRedstone = this.getBoolean("use-faster-eigencraft-redstone", false); - if (useEigencraftRedstone) { - log("Using Eigencraft redstone algorithm by theosib."); - } else { - log("Using vanilla redstone algorithm."); + public boolean fixZeroTickInstantGrowFarms = true; + private void fixZeroTickInstantGrowFarms() { + fixZeroTickInstantGrowFarms = getBoolean("fix-zero-tick-instant-grow-farms", fixZeroTickInstantGrowFarms); + } + + public boolean altItemDespawnRateEnabled; + public Map altItemDespawnRateMap; + private void altItemDespawnRate() { + String path = "alt-item-despawn-rate"; + + altItemDespawnRateEnabled = getBoolean(path + ".enabled", false); + + Map altItemDespawnRateMapDefault = new EnumMap<>(Material.class); + altItemDespawnRateMapDefault.put(Material.COBBLESTONE, 300); + for (Material key : altItemDespawnRateMapDefault.keySet()) { + config.addDefault("world-settings.default." + path + ".items." + key, altItemDespawnRateMapDefault.get(key)); + } + + Map rawMap = new HashMap<>(); + try { + ConfigurationSection mapSection = config.getConfigurationSection("world-settings." + worldName + "." + path + ".items"); + if (mapSection == null) { + mapSection = config.getConfigurationSection("world-settings.default." + path + ".items"); + } + for (String key : mapSection.getKeys(false)) { + int val = mapSection.getInt(key); + rawMap.put(key, val); + } + } + catch (Exception e) { + logError("alt-item-despawn-rate was malformatted"); + altItemDespawnRateEnabled = false; + } + + altItemDespawnRateMap = new EnumMap<>(Material.class); + if (!altItemDespawnRateEnabled) { + return; + } + + for(String key : rawMap.keySet()) { + try { + altItemDespawnRateMap.put(Material.valueOf(key), rawMap.get(key)); + } catch (Exception e) { + logError("Could not add item " + key + " to altItemDespawnRateMap: " + e.getMessage()); + } + } + if(altItemDespawnRateEnabled) { + for(Material key : altItemDespawnRateMap.keySet()) { + log("Alternative item despawn rate of " + key + ": " + altItemDespawnRateMap.get(key)); + } } } - public boolean countAllMobsForSpawning = false; - private void countAllMobsForSpawning() { - countAllMobsForSpawning = getBoolean("count-all-mobs-for-spawning", false); - if (countAllMobsForSpawning) { - log("Counting all mobs for spawning. Mob farms may reduce natural spawns elsewhere in world."); - } else { - log("Using improved mob spawn limits (Only Natural Spawns impact spawn limits for more natural spawns)"); - } + public boolean perPlayerMobSpawns = false; + private void perPlayerMobSpawns() { + perPlayerMobSpawns = getBoolean("per-player-mob-spawns", false); + } + + public boolean generateFlatBedrock; + private void generatorSettings() { + generateFlatBedrock = getBoolean("generator-settings.flat-bedrock", false); } } diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java b/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java deleted file mode 100644 index a5a63f800..000000000 --- a/src/main/java/com/destroystokyo/paper/PaperWorldEntityList.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.destroystokyo.paper; - -import net.minecraft.server.Entity; -import net.minecraft.server.EntityInsentient; -import net.minecraft.server.EnumCreatureType; -import net.minecraft.server.IAnimal; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.World; -import net.minecraft.server.WorldServer; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; - -import java.util.ArrayList; -import java.util.Collection; - -public class PaperWorldEntityList extends ArrayList { - - private final WorldServer world; - private final int[] entityCounts = new int[EnumCreatureType.values().length]; - - - public PaperWorldEntityList(World world) { - this.world = (WorldServer) world; - } - - @Override - public boolean addAll(Collection c) { - for (Entity e : c) { - updateEntityCount(e, 1); - } - - return super.addAll(c); - } - - @Override - public boolean removeAll(Collection c) { - for (Object e : c) { - if (e instanceof Entity && ((Entity) e).getWorld() == world) { - updateEntityCount((Entity) e, -1); - } - } - - return super.removeAll(c); - } - - @Override - public boolean add(Entity e) { - updateEntityCount(e, 1); - - return super.add(e); - } - - @Override - public Entity remove(int index) { - guard(); - Entity entity = super.remove(index); - if (entity != null) updateEntityCount(entity, -1); - return entity; - } - - @Override - public boolean remove(Object o) { - guard(); - if (super.remove(o)) { - updateEntityCount((Entity) o, -1); - return true; - } - return false; - } - - private void guard() { - if (world.guardEntityList) { - throw new java.util.ConcurrentModificationException(); - } - } - - public int getCreatureCount(EnumCreatureType type) { - return entityCounts[type.ordinal()]; - } - - private void updateEntityCount(EnumCreatureType type, int amt) { - int count = entityCounts[type.ordinal()]; - - count += amt; - - if (count < 0) { - MinecraftServer.LOGGER.error("Paper - Entity count cache has gone negative"); - count = 0; - } - - entityCounts[type.ordinal()] = count; - } - - public void updateEntityCount(Entity entity, int amt) { - // Only count natural spawns so that mob - if (!(entity instanceof IAnimal) || ( - !world.paperConfig.countAllMobsForSpawning && - entity.spawnReason != SpawnReason.NATURAL && - entity.spawnReason != SpawnReason.CHUNK_GEN - )) return; - - if (entity instanceof EntityInsentient) { - EntityInsentient entityinsentient = (EntityInsentient) entity; - if (amt > 0 && entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) { - return; - } - } - if (amt < 0) { - if (!entity.hasBeenCounted) { - return; - } - // Only remove once, we remove from if the entity list is guarded, but may be called later - entity.hasBeenCounted = false; - } else { - if (entity.hasBeenCounted) { - return; - } - entity.hasBeenCounted = true; - } - - for (EnumCreatureType type : EnumCreatureType.values()) { - if (type.matches(entity)) { - updateEntityCount(type, amt); - break; - } - } - } -} diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldMap.java b/src/main/java/com/destroystokyo/paper/PaperWorldMap.java index 449f620a3..6bb2f98b4 100644 --- a/src/main/java/com/destroystokyo/paper/PaperWorldMap.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldMap.java @@ -12,11 +12,10 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; public class PaperWorldMap extends HashMap { - private final List worlds = new CopyOnWriteArrayList<>(); // Akarin - private final List worldsIterable = new CopyOnWriteArrayList() { // Akarin + private final List worlds = new ArrayList<>(); + private final List worldsIterable = new ArrayList() { @Override public Iterator iterator() { Iterator iterator = super.iterator(); @@ -36,7 +35,7 @@ public class PaperWorldMap extends HashMap { @Override public void remove() { - worlds.set(last.dimension.getDimensionID()+1, null); + worlds.set(last.worldProvider.getDimensionManager().getDimensionID() + 1, null); } }; } @@ -116,7 +115,7 @@ public class PaperWorldMap extends HashMap { @Override public boolean containsValue(Object value) { - return value instanceof WorldServer && get(((WorldServer) value).dimension) != null; + return value instanceof WorldServer && get(((WorldServer) value).worldProvider.getDimensionManager()) != null; } @Nonnull @@ -135,7 +134,7 @@ public class PaperWorldMap extends HashMap { @Override public DimensionManager next() { - return iterator.next().dimension; + return iterator.next().worldProvider.getDimensionManager(); } @Override @@ -173,7 +172,7 @@ public class PaperWorldMap extends HashMap { @Override public Entry next() { WorldServer entry = iterator.next(); - return new SimpleEntry<>(entry.dimension, entry); + return new SimpleEntry<>(entry.worldProvider.getDimensionManager(), entry); } @Override diff --git a/src/main/java/com/destroystokyo/paper/VersionHistoryManager.java b/src/main/java/com/destroystokyo/paper/VersionHistoryManager.java new file mode 100644 index 000000000..aac3f66cb --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/VersionHistoryManager.java @@ -0,0 +1,145 @@ +package com.destroystokyo.paper; + +import com.google.common.base.MoreObjects; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.Bukkit; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public enum VersionHistoryManager { + INSTANCE; + + private final Gson gson = new Gson(); + + private final Logger logger = Bukkit.getLogger(); + + private VersionData currentData = null; + + VersionHistoryManager() { + final Path path = Paths.get("version_history.json"); + + if (Files.exists(path)) { + // Basic file santiy checks + if (!Files.isRegularFile(path)) { + if (Files.isDirectory(path)) { + logger.severe(path + " is a directory, cannot be used for version history"); + } else { + logger.severe(path + " is not a regular file, cannot be used for version history"); + } + // We can't continue + return; + } + + try (final BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { + currentData = gson.fromJson(reader, VersionData.class); + } catch (final IOException e) { + logger.log(Level.SEVERE, "Failed to read version history file '" + path + "'", e); + return; + } catch (final JsonSyntaxException e) { + logger.log(Level.SEVERE, "Invalid json syntax for file '" + path + "'", e); + return; + } + + final String version = Bukkit.getVersion(); + if (version == null) { + logger.severe("Failed to retrieve current version"); + return; + } + + if (!version.equals(currentData.getCurrentVersion())) { + // The version appears to have changed + currentData.setOldVersion(currentData.getCurrentVersion()); + currentData.setCurrentVersion(version); + writeFile(path); + } + } else { + // File doesn't exist, start fresh + currentData = new VersionData(); + // oldVersion is null + currentData.setCurrentVersion(Bukkit.getVersion()); + writeFile(path); + } + } + + private void writeFile(@Nonnull final Path path) { + try (final BufferedWriter writer = Files.newBufferedWriter( + path, + StandardCharsets.UTF_8, + StandardOpenOption.WRITE, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING + )) { + gson.toJson(currentData, writer); + } catch (final IOException e) { + logger.log(Level.SEVERE, "Failed to write to version history file", e); + } + } + + @Nullable + public VersionData getVersionData() { + return currentData; + } + + public static class VersionData { + private String oldVersion; + + private String currentVersion; + + @Nullable + public String getOldVersion() { + return oldVersion; + } + + public void setOldVersion(@Nullable String oldVersion) { + this.oldVersion = oldVersion; + } + + @Nullable + public String getCurrentVersion() { + return currentVersion; + } + + public void setCurrentVersion(@Nullable String currentVersion) { + this.currentVersion = currentVersion; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("oldVersion", oldVersion) + .add("currentVersion", currentVersion) + .toString(); + } + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final VersionData versionData = (VersionData) o; + return Objects.equals(oldVersion, versionData.oldVersion) && + Objects.equals(currentVersion, versionData.currentVersion); + } + + @Override + public int hashCode() { + return Objects.hash(oldVersion, currentVersion); + } + } +} diff --git a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockController.java b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockController.java index 1ba8477bf..f7e376ce6 100644 --- a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockController.java +++ b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockController.java @@ -19,7 +19,7 @@ public class ChunkPacketBlockController { } - public IBlockData[] getPredefinedBlockData(IWorldReader world, IChunkAccess chunk, ChunkSection chunkSection, boolean skyLight, boolean initializeBlocks) { + public IBlockData[] getPredefinedBlockData(IWorldReader world, IChunkAccess chunk, ChunkSection chunkSection, boolean initializeBlocks) { return null; } @@ -27,11 +27,12 @@ public class ChunkPacketBlockController { return true; } - public ChunkPacketInfo getChunkPacketInfo(PacketPlayOutMapChunk packetPlayOutMapChunk, Chunk chunk, int chunkSectionSelector) { + public ChunkPacketInfo getChunkPacketInfo(PacketPlayOutMapChunk packetPlayOutMapChunk, Chunk chunk, + int chunkSectionSelector, boolean forceLoad) { return null; } - public void modifyBlocks(PacketPlayOutMapChunk packetPlayOutMapChunk, ChunkPacketInfo chunkPacketInfo) { + public void modifyBlocks(PacketPlayOutMapChunk packetPlayOutMapChunk, ChunkPacketInfo chunkPacketInfo, boolean loadChunks, Integer ticketHold) { packetPlayOutMapChunk.setReady(true); } diff --git a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java index e3da35b6b..1edcecd2e 100644 --- a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java +++ b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java @@ -1,33 +1,21 @@ package com.destroystokyo.paper.antixray; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; -import net.minecraft.server.IRegistry; -import net.minecraft.server.MinecraftKey; +import com.destroystokyo.paper.io.PrioritizedTaskQueue; +import net.minecraft.server.*; +import org.bukkit.Bukkit; import org.bukkit.World.Environment; import com.destroystokyo.paper.PaperWorldConfig; -import net.minecraft.server.Block; -import net.minecraft.server.BlockPosition; -import net.minecraft.server.Blocks; -import net.minecraft.server.Chunk; -import net.minecraft.server.ChunkSection; -import net.minecraft.server.DataPalette; -import net.minecraft.server.EnumDirection; -import net.minecraft.server.GeneratorAccess; -import net.minecraft.server.IBlockData; -import net.minecraft.server.IChunkAccess; -import net.minecraft.server.IWorldReader; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.PacketPlayOutMapChunk; -import net.minecraft.server.PlayerInteractManager; -import net.minecraft.server.World; -import net.minecraft.server.WorldServer; - public class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockController { private static ExecutorService executorServiceInstance = null; @@ -63,7 +51,10 @@ public class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockControll executorService = null; } + List toObfuscate; + if (engineMode == EngineMode.HIDE) { + toObfuscate = paperWorldConfig.hiddenBlocks; predefinedBlockData = null; predefinedBlockDataStone = new IBlockData[] {Blocks.STONE.getBlockData()}; predefinedBlockDataNetherrack = new IBlockData[] {Blocks.NETHERRACK.getBlockData()}; @@ -73,17 +64,19 @@ public class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockControll predefinedBlockDataBitsNetherrackGlobal = new int[] {ChunkSection.GLOBAL_PALETTE.getOrCreateIdFor(Blocks.NETHERRACK.getBlockData())}; predefinedBlockDataBitsEndStoneGlobal = new int[] {ChunkSection.GLOBAL_PALETTE.getOrCreateIdFor(Blocks.END_STONE.getBlockData())}; } else { + toObfuscate = new ArrayList<>(paperWorldConfig.replacementBlocks); Set predefinedBlockDataSet = new HashSet(); for (String id : paperWorldConfig.hiddenBlocks) { - Block block = IRegistry.BLOCK.get(new MinecraftKey(id)); + Block block = IRegistry.BLOCK.getOptional(new MinecraftKey(id)).orElse(null); if (block != null && !block.isTileEntity()) { + toObfuscate.add(id); predefinedBlockDataSet.add(block.getBlockData()); } } - predefinedBlockData = predefinedBlockDataSet.size() == 0 ? new IBlockData[] {Blocks.DIAMOND_ORE.getBlockData()} : predefinedBlockDataSet.toArray(new IBlockData[predefinedBlockDataSet.size()]); + predefinedBlockData = predefinedBlockDataSet.size() == 0 ? new IBlockData[] {Blocks.DIAMOND_ORE.getBlockData()} : predefinedBlockDataSet.toArray(new IBlockData[0]); predefinedBlockDataStone = null; predefinedBlockDataNetherrack = null; predefinedBlockDataEndStone = null; @@ -98,19 +91,24 @@ public class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockControll predefinedBlockDataBitsEndStoneGlobal = null; } - for (String id : (engineMode == EngineMode.HIDE) ? paperWorldConfig.hiddenBlocks : paperWorldConfig.replacementBlocks) { - Block block = IRegistry.BLOCK.get(new MinecraftKey(id)); + for (String id : toObfuscate) { + Block block = IRegistry.BLOCK.getOptional(new MinecraftKey(id)).orElse(null); if (block != null) { obfuscateGlobal[ChunkSection.GLOBAL_PALETTE.getOrCreateIdFor(block.getBlockData())] = true; } } + ChunkEmpty emptyChunk = new ChunkEmpty(null, new ChunkCoordIntPair(0, 0)); + BlockPosition zeroPos = new BlockPosition(0, 0, 0); + for (int i = 0; i < solidGlobal.length; i++) { IBlockData blockData = ChunkSection.GLOBAL_PALETTE.getObject(i); if (blockData != null) { - solidGlobal[i] = blockData.getBlock().isOccluding(blockData) && blockData.getBlock() != Blocks.SPAWNER && blockData.getBlock() != Blocks.BARRIER; + solidGlobal[i] = blockData.getBlock().isOccluding(blockData, emptyChunk, zeroPos) + && blockData.getBlock() != Blocks.SPAWNER && blockData.getBlock() != Blocks.BARRIER && blockData.getBlock() != Blocks.SHULKER_BOX; + // shulker box checks TE. } } @@ -126,7 +124,7 @@ public class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockControll } @Override - public IBlockData[] getPredefinedBlockData(IWorldReader world, IChunkAccess chunk, ChunkSection chunkSection, boolean skyLight, boolean initializeBlocks) { + public IBlockData[] getPredefinedBlockData(IWorldReader world, IChunkAccess chunk, ChunkSection chunkSection, boolean initializeBlocks) { //Return the block data which should be added to the data palettes so that they can be used for the obfuscation if (chunkSection.getYPosition() >> 4 <= maxChunkSectionIndex) { switch (engineMode) { @@ -151,28 +149,103 @@ public class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockControll return null; } + private final AtomicInteger xrayRequests = new AtomicInteger(); + + // Paper start - async chunk api + private Integer nextTicketHold() { + return Integer.valueOf(this.xrayRequests.getAndIncrement()); + } + // Paper end + + private Integer addXrayTickets(final int x, final int z, final ChunkProviderServer chunkProvider) { + final Integer hold = Integer.valueOf(this.xrayRequests.getAndIncrement()); + + // Add at ticket level 33, which is just enough to keep chunks loaded + chunkProvider.addTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x, z), 0, hold); + chunkProvider.addTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x - 1, z), 0, hold); + chunkProvider.addTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x + 1, z), 0, hold); + chunkProvider.addTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x, z - 1), 0, hold); + chunkProvider.addTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x, z + 1), 0, hold); + + return hold; + } + + private void removeXrayTickets(final int x, final int z, final ChunkProviderServer chunkProvider, final Integer hold) { + // Remove at ticket level 33 (same one we added as), which is just enough to keep chunks loaded + chunkProvider.removeTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x, z), 0, hold); + chunkProvider.removeTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x - 1, z), 0, hold); + chunkProvider.removeTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x + 1, z), 0, hold); + chunkProvider.removeTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x, z - 1), 0, hold); + chunkProvider.removeTicket(TicketType.ANTIXRAY, new ChunkCoordIntPair(x, z + 1), 0, hold); + } + + private void loadNeighbours(Chunk chunk) { + int locX = chunk.getPos().x; + int locZ = chunk.getPos().z; + chunk.world.getChunkAt(locX - 1, locZ); + chunk.world.getChunkAt(locX + 1, locZ); + chunk.world.getChunkAt(locX, locZ - 1); + chunk.world.getChunkAt(locX, locZ + 1); + } + + // Paper start - async chunk api + private void loadNeighbourAsync(ChunkProviderServer chunkProvider, WorldServer world, int chunkX, int chunkZ, int[] counter, java.util.function.Consumer onNeighourLoad, Runnable onAllNeighboursLoad) { + chunkProvider.getChunkAtAsynchronously(chunkX, chunkZ, true, (Chunk neighbour) -> { + onNeighourLoad.accept(neighbour); + if (++counter[0] == 4) { + onAllNeighboursLoad.run(); + } + }); + world.asyncChunkTaskManager.raisePriority(chunkX, chunkZ, PrioritizedTaskQueue.HIGHER_PRIORITY); + } + + private void loadNeighboursAsync(Chunk chunk, java.util.function.Consumer onNeighourLoad, Runnable onAllNeighboursLoad) { + int[] loaded = new int[1]; + + int locX = chunk.getPos().x; + int locZ = chunk.getPos().z; + WorldServer world = ((WorldServer)chunk.world); + + onNeighourLoad.accept(chunk); + + ChunkProviderServer chunkProvider = world.getChunkProvider(); + + this.loadNeighbourAsync(chunkProvider, world, locX - 1, locZ, loaded, onNeighourLoad, onAllNeighboursLoad); + this.loadNeighbourAsync(chunkProvider, world, locX + 1, locZ, loaded, onNeighourLoad, onAllNeighboursLoad); + this.loadNeighbourAsync(chunkProvider, world, locX, locZ - 1, loaded, onNeighourLoad, onAllNeighboursLoad); + this.loadNeighbourAsync(chunkProvider, world, locX, locZ + 1, loaded, onNeighourLoad, onAllNeighboursLoad); + } + // Paper end + @Override public boolean onChunkPacketCreate(Chunk chunk, int chunkSectionSelector, boolean force) { + int locX = chunk.getPos().x; + int locZ = chunk.getPos().z; + WorldServer world = (WorldServer)chunk.world; + ChunkProviderServer chunkProvider = world.getChunkProvider(); + //Load nearby chunks if necessary - if (force) { + if (force || chunkEdgeMode == ChunkEdgeMode.LOAD) { // TODO temporary // if forced, load NOW; - chunk.world.getChunkAt(chunk.locX - 1, chunk.locZ); - chunk.world.getChunkAt(chunk.locX + 1, chunk.locZ); - chunk.world.getChunkAt(chunk.locX, chunk.locZ - 1); - chunk.world.getChunkAt(chunk.locX, chunk.locZ + 1); - } else if (chunkEdgeMode == ChunkEdgeMode.WAIT && !force) { - if (chunk.world.getChunkIfLoaded(chunk.locX - 1, chunk.locZ) == null || chunk.world.getChunkIfLoaded(chunk.locX + 1, chunk.locZ) == null || chunk.world.getChunkIfLoaded(chunk.locX, chunk.locZ - 1) == null || chunk.world.getChunkIfLoaded(chunk.locX, chunk.locZ + 1) == null) { + this.loadNeighbours(chunk); + } else if (chunkEdgeMode == ChunkEdgeMode.WAIT) { + if (chunkProvider.getChunkAtIfCachedImmediately(locX - 1, locZ) == null || + chunkProvider.getChunkAtIfCachedImmediately(locX + 1, locZ) == null || + chunkProvider.getChunkAtIfCachedImmediately(locX, locZ - 1) == null || + chunkProvider.getChunkAtIfCachedImmediately(locX, locZ + 1) == null) { //Don't create the chunk packet now, wait until nearby chunks are loaded and create it later return false; } - } else if (chunkEdgeMode == ChunkEdgeMode.LOAD) { + } else if (false && chunkEdgeMode == ChunkEdgeMode.LOAD) { + // TODO Note: These should be asynchronous loads; however we have no such thing in 1.14. boolean missingChunk = false; //noinspection ConstantConditions + /* missingChunk |= ((WorldServer)chunk.world).getChunkProvider().getChunkAt(chunk.locX - 1, chunk.locZ, true, true, c -> {}) == null; missingChunk |= ((WorldServer)chunk.world).getChunkProvider().getChunkAt(chunk.locX + 1, chunk.locZ, true, true, c -> {}) == null; missingChunk |= ((WorldServer)chunk.world).getChunkProvider().getChunkAt(chunk.locX, chunk.locZ - 1, true, true, c -> {}) == null; missingChunk |= ((WorldServer)chunk.world).getChunkProvider().getChunkAt(chunk.locX, chunk.locZ + 1, true, true, c -> {}) == null; - + */ if (missingChunk) { return false; } @@ -183,15 +256,61 @@ public class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockControll } @Override - public ChunkPacketInfoAntiXray getChunkPacketInfo(PacketPlayOutMapChunk packetPlayOutMapChunk, Chunk chunk, int chunkSectionSelector) { - //Return a new instance to collect data and objects in the right state while creating the chunk packet for thread safe access later + public ChunkPacketInfoAntiXray getChunkPacketInfo(PacketPlayOutMapChunk packetPlayOutMapChunk, Chunk chunk, + int chunkSectionSelector, boolean forceLoad) { + // Return a new instance to collect data and objects in the right state while creating the chunk packet for thread safe access later + // Note: As of 1.14 this has to be moved later due to the chunk system. + ChunkPacketInfoAntiXray chunkPacketInfoAntiXray = new ChunkPacketInfoAntiXray(packetPlayOutMapChunk, chunk, chunkSectionSelector, this); - chunkPacketInfoAntiXray.setNearbyChunks(chunk.world.getChunkIfLoaded(chunk.locX - 1, chunk.locZ), chunk.world.getChunkIfLoaded(chunk.locX + 1, chunk.locZ), chunk.world.getChunkIfLoaded(chunk.locX, chunk.locZ - 1), chunk.world.getChunkIfLoaded(chunk.locX, chunk.locZ + 1)); return chunkPacketInfoAntiXray; } @Override - public void modifyBlocks(PacketPlayOutMapChunk packetPlayOutMapChunk, ChunkPacketInfo chunkPacketInfo) { + public void modifyBlocks(PacketPlayOutMapChunk packetPlayOutMapChunk, ChunkPacketInfo chunkPacketInfo, boolean loadChunks, Integer hold) { + if (!Bukkit.isPrimaryThread()) { + // plugins? + final Integer finalHold = hold; + MinecraftServer.getServer().scheduleOnMain(() -> { + this.modifyBlocks(packetPlayOutMapChunk, chunkPacketInfo, loadChunks, finalHold); + }); + return; + } + Chunk chunk = chunkPacketInfo.getChunk(); + int locX = chunk.getPos().x; + int locZ = chunk.getPos().z; + WorldServer world = (WorldServer)chunk.world; + + Chunk[] chunks = new Chunk[] { + (Chunk)world.getChunkIfLoadedImmediately(locX - 1, locZ), + (Chunk)world.getChunkIfLoadedImmediately(locX + 1, locZ), + (Chunk)world.getChunkIfLoadedImmediately(locX, locZ - 1), + (Chunk)world.getChunkIfLoadedImmediately(locX, locZ + 1) + }; + + if (loadChunks) { + // Note: This ugly hack is to get us out of the general chunk load/unload queue to prevent deadlock + + if (chunks[0] == null || chunks[1] == null || chunks[2] == null || chunks[3] == null) { + // we need to load + // Paper start - async chunk api + Integer ticketHold = this.nextTicketHold(); + this.loadNeighboursAsync(chunk, (Chunk neighbour) -> { // when a neighbour is loaded + ((WorldServer)neighbour.world).getChunkProvider().addTicket(TicketType.ANTIXRAY, neighbour.getPos(), 0, ticketHold); + }, + () -> { // once neighbours get loaded + this.modifyBlocks(packetPlayOutMapChunk, chunkPacketInfo, false, ticketHold); + }); + // Paper end + return; + } + + hold = this.addXrayTickets(locX, locZ, world.getChunkProvider()); + // fall through to normal behavior, our chunks are now loaded & have a ticket + } + + ((ChunkPacketInfoAntiXray)chunkPacketInfo).setNearbyChunks(chunks); + ((ChunkPacketInfoAntiXray)chunkPacketInfo).ticketHold = hold; + if (asynchronous) { executorService.submit((ChunkPacketInfoAntiXray) chunkPacketInfo); } else { @@ -212,108 +331,126 @@ public class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockControll private final ChunkSection[] nearbyChunkSections = new ChunkSection[4]; public void obfuscate(ChunkPacketInfoAntiXray chunkPacketInfoAntiXray) { - boolean[] solidTemp = null; - boolean[] obfuscateTemp = null; - dataBitsReader.setDataBits(chunkPacketInfoAntiXray.getData()); - dataBitsWriter.setDataBits(chunkPacketInfoAntiXray.getData()); - int counter = 0; + try { + boolean[] solidTemp = null; + boolean[] obfuscateTemp = null; + dataBitsReader.setDataBits(chunkPacketInfoAntiXray.getData()); + dataBitsWriter.setDataBits(chunkPacketInfoAntiXray.getData()); + int counter = 0; - for (int chunkSectionIndex = 0; chunkSectionIndex <= maxChunkSectionIndex; chunkSectionIndex++) { - if (chunkPacketInfoAntiXray.isWritten(chunkSectionIndex) && chunkPacketInfoAntiXray.getPredefinedObjects(chunkSectionIndex) != null) { - int[] predefinedBlockDataBitsTemp; + for (int chunkSectionIndex = 0; chunkSectionIndex <= maxChunkSectionIndex; chunkSectionIndex++) { + if (chunkPacketInfoAntiXray.isWritten(chunkSectionIndex) && chunkPacketInfoAntiXray.getPredefinedObjects(chunkSectionIndex) != null) { + int[] predefinedBlockDataBitsTemp; - if (chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex) == ChunkSection.GLOBAL_PALETTE) { - predefinedBlockDataBitsTemp = engineMode == EngineMode.HIDE ? chunkPacketInfoAntiXray.getChunk().world.getWorld().getEnvironment() == Environment.NETHER ? predefinedBlockDataBitsNetherrackGlobal : chunkPacketInfoAntiXray.getChunk().world.getWorld().getEnvironment() == Environment.THE_END ? predefinedBlockDataBitsEndStoneGlobal : predefinedBlockDataBitsStoneGlobal : predefinedBlockDataBitsGlobal; - } else { - predefinedBlockDataBitsTemp = predefinedBlockDataBits == null ? predefinedBlockDataBits = engineMode == EngineMode.HIDE ? new int[1] : new int[predefinedBlockData.length] : predefinedBlockDataBits; + if (chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex) == ChunkSection.GLOBAL_PALETTE) { + predefinedBlockDataBitsTemp = engineMode == EngineMode.HIDE ? chunkPacketInfoAntiXray.getChunk().world.getWorld().getEnvironment() == Environment.NETHER ? predefinedBlockDataBitsNetherrackGlobal : chunkPacketInfoAntiXray.getChunk().world.getWorld().getEnvironment() == Environment.THE_END ? predefinedBlockDataBitsEndStoneGlobal : predefinedBlockDataBitsStoneGlobal : predefinedBlockDataBitsGlobal; + } else { + predefinedBlockDataBitsTemp = predefinedBlockDataBits == null ? predefinedBlockDataBits = engineMode == EngineMode.HIDE ? new int[1] : new int[predefinedBlockData.length] : predefinedBlockDataBits; - for (int i = 0; i < predefinedBlockDataBitsTemp.length; i++) { - predefinedBlockDataBitsTemp[i] = chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex).getOrCreateIdFor(chunkPacketInfoAntiXray.getPredefinedObjects(chunkSectionIndex)[i]); - } - } - - dataBitsWriter.setIndex(chunkPacketInfoAntiXray.getOrCreateIdForIndex(chunkSectionIndex)); - - //Check if the chunk section below was not obfuscated - if (chunkSectionIndex == 0 || !chunkPacketInfoAntiXray.isWritten(chunkSectionIndex - 1) || chunkPacketInfoAntiXray.getPredefinedObjects(chunkSectionIndex - 1) == null) { - //If so, initialize some stuff - dataBitsReader.setBitsPerObject(chunkPacketInfoAntiXray.getBitsPerObject(chunkSectionIndex)); - dataBitsReader.setIndex(chunkPacketInfoAntiXray.getOrCreateIdForIndex(chunkSectionIndex)); - solidTemp = readDataPalette(chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex), solid, solidGlobal); - obfuscateTemp = readDataPalette(chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex), obfuscate, obfuscateGlobal); - //Read the blocks of the upper layer of the chunk section below if it exists - ChunkSection belowChunkSection = null; - boolean skipFirstLayer = chunkSectionIndex == 0 || (belowChunkSection = chunkPacketInfoAntiXray.getChunk().getSections()[chunkSectionIndex - 1]) == Chunk.EMPTY_CHUNK_SECTION; - - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - current[z][x] = true; - next[z][x] = skipFirstLayer || !solidGlobal[ChunkSection.GLOBAL_PALETTE.getOrCreateIdFor(belowChunkSection.getType(x, 15, z))]; + for (int i = 0; i < predefinedBlockDataBitsTemp.length; i++) { + predefinedBlockDataBitsTemp[i] = chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex).getOrCreateIdFor(chunkPacketInfoAntiXray.getPredefinedObjects(chunkSectionIndex)[i]); } } - //Abuse the obfuscateLayer method to read the blocks of the first layer of the current chunk section - dataBitsWriter.setBitsPerObject(0); - obfuscateLayer(-1, dataBitsReader, dataBitsWriter, solidTemp, obfuscateTemp, predefinedBlockDataBitsTemp, current, next, nextNext, emptyNearbyChunkSections, counter); - } + dataBitsWriter.setIndex(chunkPacketInfoAntiXray.getOrCreateIdForIndex(chunkSectionIndex)); - dataBitsWriter.setBitsPerObject(chunkPacketInfoAntiXray.getBitsPerObject(chunkSectionIndex)); - nearbyChunkSections[0] = chunkPacketInfoAntiXray.getNearbyChunks()[0] == null ? Chunk.EMPTY_CHUNK_SECTION : chunkPacketInfoAntiXray.getNearbyChunks()[0].getSections()[chunkSectionIndex]; - nearbyChunkSections[1] = chunkPacketInfoAntiXray.getNearbyChunks()[1] == null ? Chunk.EMPTY_CHUNK_SECTION : chunkPacketInfoAntiXray.getNearbyChunks()[1].getSections()[chunkSectionIndex]; - nearbyChunkSections[2] = chunkPacketInfoAntiXray.getNearbyChunks()[2] == null ? Chunk.EMPTY_CHUNK_SECTION : chunkPacketInfoAntiXray.getNearbyChunks()[2].getSections()[chunkSectionIndex]; - nearbyChunkSections[3] = chunkPacketInfoAntiXray.getNearbyChunks()[3] == null ? Chunk.EMPTY_CHUNK_SECTION : chunkPacketInfoAntiXray.getNearbyChunks()[3].getSections()[chunkSectionIndex]; + //Check if the chunk section below was not obfuscated + if (chunkSectionIndex == 0 || !chunkPacketInfoAntiXray.isWritten(chunkSectionIndex - 1) || chunkPacketInfoAntiXray.getPredefinedObjects(chunkSectionIndex - 1) == null) { + //If so, initialize some stuff + dataBitsReader.setBitsPerObject(chunkPacketInfoAntiXray.getBitsPerObject(chunkSectionIndex)); + dataBitsReader.setIndex(chunkPacketInfoAntiXray.getOrCreateIdForIndex(chunkSectionIndex)); + solidTemp = readDataPalette(chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex), solid, solidGlobal); + obfuscateTemp = readDataPalette(chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex), obfuscate, obfuscateGlobal); + //Read the blocks of the upper layer of the chunk section below if it exists + ChunkSection belowChunkSection = null; + boolean skipFirstLayer = chunkSectionIndex == 0 || (belowChunkSection = chunkPacketInfoAntiXray.getChunk().getSections()[chunkSectionIndex - 1]) == Chunk.EMPTY_CHUNK_SECTION; - //Obfuscate all layers of the current chunk section except the upper one - for (int y = 0; y < 15; y++) { - boolean[][] temp = current; - current = next; - next = nextNext; - nextNext = temp; - counter = obfuscateLayer(y, dataBitsReader, dataBitsWriter, solidTemp, obfuscateTemp, predefinedBlockDataBitsTemp, current, next, nextNext, nearbyChunkSections, counter); - } + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + current[z][x] = true; + next[z][x] = skipFirstLayer || !solidGlobal[ChunkSection.GLOBAL_PALETTE.getOrCreateIdFor(belowChunkSection.getType(x, 15, z))]; + } + } - //Check if the chunk section above doesn't need obfuscation - if (chunkSectionIndex == maxChunkSectionIndex || !chunkPacketInfoAntiXray.isWritten(chunkSectionIndex + 1) || chunkPacketInfoAntiXray.getPredefinedObjects(chunkSectionIndex + 1) == null) { - //If so, obfuscate the upper layer of the current chunk section by reading blocks of the first layer from the chunk section above if it exists - ChunkSection aboveChunkSection; + //Abuse the obfuscateLayer method to read the blocks of the first layer of the current chunk section + dataBitsWriter.setBitsPerObject(0); + obfuscateLayer(-1, dataBitsReader, dataBitsWriter, solidTemp, obfuscateTemp, predefinedBlockDataBitsTemp, current, next, nextNext, emptyNearbyChunkSections, counter); + } - if (chunkSectionIndex != 15 && (aboveChunkSection = chunkPacketInfoAntiXray.getChunk().getSections()[chunkSectionIndex + 1]) != Chunk.EMPTY_CHUNK_SECTION) { + dataBitsWriter.setBitsPerObject(chunkPacketInfoAntiXray.getBitsPerObject(chunkSectionIndex)); + nearbyChunkSections[0] = chunkPacketInfoAntiXray.getNearbyChunks()[0] == null ? Chunk.EMPTY_CHUNK_SECTION : chunkPacketInfoAntiXray.getNearbyChunks()[0].getSections()[chunkSectionIndex]; + nearbyChunkSections[1] = chunkPacketInfoAntiXray.getNearbyChunks()[1] == null ? Chunk.EMPTY_CHUNK_SECTION : chunkPacketInfoAntiXray.getNearbyChunks()[1].getSections()[chunkSectionIndex]; + nearbyChunkSections[2] = chunkPacketInfoAntiXray.getNearbyChunks()[2] == null ? Chunk.EMPTY_CHUNK_SECTION : chunkPacketInfoAntiXray.getNearbyChunks()[2].getSections()[chunkSectionIndex]; + nearbyChunkSections[3] = chunkPacketInfoAntiXray.getNearbyChunks()[3] == null ? Chunk.EMPTY_CHUNK_SECTION : chunkPacketInfoAntiXray.getNearbyChunks()[3].getSections()[chunkSectionIndex]; + + //Obfuscate all layers of the current chunk section except the upper one + for (int y = 0; y < 15; y++) { boolean[][] temp = current; current = next; next = nextNext; nextNext = temp; + counter = obfuscateLayer(y, dataBitsReader, dataBitsWriter, solidTemp, obfuscateTemp, predefinedBlockDataBitsTemp, current, next, nextNext, nearbyChunkSections, counter); + } - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - if (!solidGlobal[ChunkSection.GLOBAL_PALETTE.getOrCreateIdFor(aboveChunkSection.getType(x, 0, z))]) { - current[z][x] = true; + //Check if the chunk section above doesn't need obfuscation + if (chunkSectionIndex == maxChunkSectionIndex || !chunkPacketInfoAntiXray.isWritten(chunkSectionIndex + 1) || chunkPacketInfoAntiXray.getPredefinedObjects(chunkSectionIndex + 1) == null) { + //If so, obfuscate the upper layer of the current chunk section by reading blocks of the first layer from the chunk section above if it exists + ChunkSection aboveChunkSection; + + if (chunkSectionIndex != 15 && (aboveChunkSection = chunkPacketInfoAntiXray.getChunk().getSections()[chunkSectionIndex + 1]) != Chunk.EMPTY_CHUNK_SECTION) { + boolean[][] temp = current; + current = next; + next = nextNext; + nextNext = temp; + + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + if (!solidGlobal[ChunkSection.GLOBAL_PALETTE.getOrCreateIdFor(aboveChunkSection.getType(x, 0, z))]) { + current[z][x] = true; + } } } + + //There is nothing to read anymore + dataBitsReader.setBitsPerObject(0); + solid[0] = true; + counter = obfuscateLayer(15, dataBitsReader, dataBitsWriter, solid, obfuscateTemp, predefinedBlockDataBitsTemp, current, next, nextNext, nearbyChunkSections, counter); } - - //There is nothing to read anymore - dataBitsReader.setBitsPerObject(0); - solid[0] = true; - counter = obfuscateLayer(15, dataBitsReader, dataBitsWriter, solid, obfuscateTemp, predefinedBlockDataBitsTemp, current, next, nextNext, nearbyChunkSections, counter); + } else { + //If not, initialize the reader and other stuff for the chunk section above to obfuscate the upper layer of the current chunk section + dataBitsReader.setBitsPerObject(chunkPacketInfoAntiXray.getBitsPerObject(chunkSectionIndex + 1)); + dataBitsReader.setIndex(chunkPacketInfoAntiXray.getOrCreateIdForIndex(chunkSectionIndex + 1)); + solidTemp = readDataPalette(chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex + 1), solid, solidGlobal); + obfuscateTemp = readDataPalette(chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex + 1), obfuscate, obfuscateGlobal); + boolean[][] temp = current; + current = next; + next = nextNext; + nextNext = temp; + counter = obfuscateLayer(15, dataBitsReader, dataBitsWriter, solidTemp, obfuscateTemp, predefinedBlockDataBitsTemp, current, next, nextNext, nearbyChunkSections, counter); } - } else { - //If not, initialize the reader and other stuff for the chunk section above to obfuscate the upper layer of the current chunk section - dataBitsReader.setBitsPerObject(chunkPacketInfoAntiXray.getBitsPerObject(chunkSectionIndex + 1)); - dataBitsReader.setIndex(chunkPacketInfoAntiXray.getOrCreateIdForIndex(chunkSectionIndex + 1)); - solidTemp = readDataPalette(chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex + 1), solid, solidGlobal); - obfuscateTemp = readDataPalette(chunkPacketInfoAntiXray.getDataPalette(chunkSectionIndex + 1), obfuscate, obfuscateGlobal); - boolean[][] temp = current; - current = next; - next = nextNext; - nextNext = temp; - counter = obfuscateLayer(15, dataBitsReader, dataBitsWriter, solidTemp, obfuscateTemp, predefinedBlockDataBitsTemp, current, next, nextNext, nearbyChunkSections, counter); - } - dataBitsWriter.finish(); + dataBitsWriter.finish(); + } + } + + chunkPacketInfoAntiXray.getPacketPlayOutMapChunk().setReady(true); + + } finally { + if (chunkPacketInfoAntiXray.ticketHold != null) { + Runnable runnable = () -> { + Chunk chunk = chunkPacketInfoAntiXray.getChunk(); + ChunkCoordIntPair chunkPos = chunk.getPos(); + + ChunkPacketBlockControllerAntiXray.this.removeXrayTickets(chunkPos.x, chunkPos.z, (ChunkProviderServer) chunk.world.getChunkProvider(), + chunkPacketInfoAntiXray.ticketHold); + }; + if (MinecraftServer.getServer().isMainThread()) { + runnable.run(); + } else { + MinecraftServer.getServer().scheduleOnMain(runnable); + } } } - - chunkPacketInfoAntiXray.getPacketPlayOutMapChunk().setReady(true); } private int obfuscateLayer(int y, DataBitsReader dataBitsReader, DataBitsWriter dataBitsWriter, boolean[] solid, boolean[] obfuscate, int[] predefinedBlockDataBits, boolean[][] current, boolean[][] next, boolean[][] nextNext, ChunkSection[] nearbyChunkSections, int counter) { @@ -613,7 +750,8 @@ public class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockControll IBlockData blockData = world.getTypeIfLoaded(blockPosition); if (blockData != null && obfuscateGlobal[ChunkSection.GLOBAL_PALETTE.getOrCreateIdFor(blockData)]) { - world.notify(blockPosition, blockData, blockData, 3); + //world.notify(blockPosition, blockData, blockData, 3); + ((WorldServer)world).getChunkProvider().flagDirty(blockPosition); // We only need to re-send to client } } diff --git a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketInfoAntiXray.java b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketInfoAntiXray.java index e255a45fa..067dfb2f1 100644 --- a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketInfoAntiXray.java +++ b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketInfoAntiXray.java @@ -8,8 +8,10 @@ public class ChunkPacketInfoAntiXray extends ChunkPacketInfo impleme private Chunk[] nearbyChunks; private final ChunkPacketBlockControllerAntiXray chunkPacketBlockControllerAntiXray; + public Integer ticketHold; - public ChunkPacketInfoAntiXray(PacketPlayOutMapChunk packetPlayOutMapChunk, Chunk chunk, int chunkSectionSelector, ChunkPacketBlockControllerAntiXray chunkPacketBlockControllerAntiXray) { + public ChunkPacketInfoAntiXray(PacketPlayOutMapChunk packetPlayOutMapChunk, Chunk chunk, int chunkSectionSelector, + ChunkPacketBlockControllerAntiXray chunkPacketBlockControllerAntiXray) { super(packetPlayOutMapChunk, chunk, chunkSectionSelector); this.chunkPacketBlockControllerAntiXray = chunkPacketBlockControllerAntiXray; } diff --git a/src/main/java/com/destroystokyo/paper/block/CraftBlockSoundGroup.java b/src/main/java/com/destroystokyo/paper/block/CraftBlockSoundGroup.java new file mode 100644 index 000000000..99f99330d --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/block/CraftBlockSoundGroup.java @@ -0,0 +1,38 @@ +package com.destroystokyo.paper.block; + +import net.minecraft.server.SoundEffectType; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.CraftSound; + +public class CraftBlockSoundGroup implements BlockSoundGroup { + private final SoundEffectType soundEffectType; + + public CraftBlockSoundGroup(SoundEffectType soundEffectType) { + this.soundEffectType = soundEffectType; + } + + @Override + public Sound getBreakSound() { + return CraftSound.getSoundByEffect(soundEffectType.getBreakSound()); + } + + @Override + public Sound getStepSound() { + return CraftSound.getSoundByEffect(soundEffectType.getStepSound()); + } + + @Override + public Sound getPlaceSound() { + return CraftSound.getSoundByEffect(soundEffectType.getPlaceSound()); + } + + @Override + public Sound getHitSound() { + return CraftSound.getSoundByEffect(soundEffectType.getHitSound()); + } + + @Override + public Sound getFallSound() { + return CraftSound.getSoundByEffect(soundEffectType.getFallSound()); + } +} diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java index 688b4715e..cd6e25923 100644 --- a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java +++ b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java @@ -34,7 +34,7 @@ public final class PaperConsole extends SimpleTerminalConsole { @Override protected void shutdown() { - this.server.safeShutdown(); + this.server.safeShutdown(false); } } diff --git a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java index ed3d86ddd..f68a07cb9 100644 --- a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java +++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java @@ -83,11 +83,9 @@ public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinde @Override public List getPoints() { - int pathCount = path.getPathCount(); List points = new ArrayList<>(); - PathPoint[] pathPoints = path.getPoints(); - for (int i = 0; i < pathCount; i++) { - points.add(toLoc(pathPoints[i])); + for (PathPoint point : path.getPoints()) { + points.add(toLoc(point)); } return points; } @@ -103,7 +101,7 @@ public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinde if (!path.hasNext()) { return null; } - return toLoc(path.getPoints()[path.getNextIndex()]); + return toLoc(path.getPoints().get(path.getNextIndex())); } } diff --git a/src/main/java/com/destroystokyo/paper/io/IOUtil.java b/src/main/java/com/destroystokyo/paper/io/IOUtil.java new file mode 100644 index 000000000..5af0ac3d9 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/IOUtil.java @@ -0,0 +1,62 @@ +package com.destroystokyo.paper.io; + +import org.bukkit.Bukkit; + +public final class IOUtil { + + /* Copied from concrete or concurrentutil */ + + public static long getCoordinateKey(final int x, final int z) { + return ((long)z << 32) | (x & 0xFFFFFFFFL); + } + + public static int getCoordinateX(final long key) { + return (int)key; + } + + public static int getCoordinateZ(final long key) { + return (int)(key >>> 32); + } + + public static int getRegionCoordinate(final int chunkCoordinate) { + return chunkCoordinate >> 5; + } + + public static int getChunkInRegion(final int chunkCoordinate) { + return chunkCoordinate & 31; + } + + public static String genericToString(final Object object) { + return object == null ? "null" : object.getClass().getName() + ":" + object.toString(); + } + + public static T notNull(final T obj) { + if (obj == null) { + throw new NullPointerException(); + } + return obj; + } + + public static T notNull(final T obj, final String msgIfNull) { + if (obj == null) { + throw new NullPointerException(msgIfNull); + } + return obj; + } + + public static void arrayBounds(final int off, final int len, final int arrayLength, final String msgPrefix) { + if (off < 0 || len < 0 || (arrayLength - off) < len) { + throw new ArrayIndexOutOfBoundsException(msgPrefix + ": off: " + off + ", len: " + len + ", array length: " + arrayLength); + } + } + + public static int getPriorityForCurrentThread() { + return Bukkit.isPrimaryThread() ? PrioritizedTaskQueue.HIGHEST_PRIORITY : PrioritizedTaskQueue.NORMAL_PRIORITY; + } + + @SuppressWarnings("unchecked") + public static void rethrow(final Throwable throwable) throws T { + throw (T)throwable; + } + +} diff --git a/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java new file mode 100644 index 000000000..4f10a8311 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java @@ -0,0 +1,661 @@ +package com.destroystokyo.paper.io; + +import net.minecraft.server.ChunkCoordIntPair; +import net.minecraft.server.ExceptionWorldConflict; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.RegionFile; +import net.minecraft.server.WorldServer; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * Prioritized singleton thread responsible for all chunk IO that occurs in a minecraft server. + * + *

+ * Singleton access: {@link Holder#INSTANCE} + *

+ * + *

+ * All functions provided are MT-Safe, however certain ordering constraints are (but not enforced): + *

  • + * Chunk saves may not occur for unloaded chunks. + *
  • + *
  • + * Tasks must be scheduled on the main thread. + *
  • + *

    + * + * @see Holder#INSTANCE + * @see #scheduleSave(WorldServer, int, int, NBTTagCompound, NBTTagCompound, int) + * @see #loadChunkDataAsync(WorldServer, int, int, int, Consumer, boolean, boolean, boolean) + */ +public final class PaperFileIOThread extends QueueExecutorThread { + + public static final Logger LOGGER = MinecraftServer.LOGGER; + public static final NBTTagCompound FAILURE_VALUE = new NBTTagCompound(); + + public static final class Holder { + + public static final PaperFileIOThread INSTANCE = new PaperFileIOThread(); + + static { + INSTANCE.start(); + } + } + + private final AtomicLong writeCounter = new AtomicLong(); + + private PaperFileIOThread() { + super(new PrioritizedTaskQueue<>(), (int)(1.0e6)); // 1.0ms spinwait time + this.setName("Paper RegionFile IO Thread"); + this.setPriority(Thread.NORM_PRIORITY - 1); // we keep priority close to normal because threads can wait on us + this.setUncaughtExceptionHandler((final Thread unused, final Throwable thr) -> { + LOGGER.fatal("Uncaught exception thrown from IO thread, report this!", thr); + }); + } + + /* run() is implemented by superclass */ + + /* + * + * IO thread will perform reads before writes + * + * How reads/writes are scheduled: + * + * If read in progress while scheduling write, ignore read and schedule write + * If read in progress while scheduling read (no write in progress), chain the read task + * + * + * If write in progress while scheduling read, use the pending write data and ret immediately + * If write in progress while scheduling write (ignore read in progress), overwrite the write in progress data + * + * This allows the reads and writes to act as if they occur synchronously to the thread scheduling them, however + * it fails to properly propagate write failures. When writes fail the data is kept so future reads will actually + * read the failed write data. This should hopefully act as a way to prevent data loss for spurious fails for writing data. + * + */ + + /** + * Attempts to bump the priority of all IO tasks for the given chunk coordinates. This has no effect if no tasks are queued. + * @param world Chunk's world + * @param chunkX Chunk's x coordinate + * @param chunkZ Chunk's z coordinate + * @param priority Priority level to try to bump to + */ + public void bumpPriority(final WorldServer world, final int chunkX, final int chunkZ, final int priority) { + if (!PrioritizedTaskQueue.validPriority(priority)) { + throw new IllegalArgumentException("Invalid priority: " + priority); + } + + final Long key = Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ)); + + final ChunkDataTask poiTask = world.poiDataController.tasks.get(key); + final ChunkDataTask chunkTask = world.chunkDataController.tasks.get(key); + + if (poiTask != null) { + poiTask.raisePriority(priority); + } + if (chunkTask != null) { + chunkTask.raisePriority(priority); + } + } + + // Hack start + /** + * if {@code waitForRead} is true, then this task will wait on an available read task, else it will wait on an available + * write task + * if {@code poiTask} is true, then this task will wait on a poi task, else it will wait on chunk data task + * @deprecated API is garbage and will only work for main thread queueing of tasks (which is vanilla), plugins messing + * around asynchronously will give unexpected results + * @return whether the task succeeded, or {@code null} if there is no task + */ + @Deprecated + public Boolean waitForIOToComplete(final WorldServer world, final int chunkX, final int chunkZ, final boolean waitForRead, + final boolean poiTask) { + final ChunkDataTask task; + + final Long key = IOUtil.getCoordinateKey(chunkX, chunkZ); + if (poiTask) { + task = world.poiDataController.tasks.get(key); + } else { + task = world.chunkDataController.tasks.get(key); + } + + if (task == null) { + return null; + } + + if (waitForRead) { + ChunkDataController.InProgressRead read = task.inProgressRead; + if (read == null) { + return null; + } + return Boolean.valueOf(read.readFuture.join() != PaperFileIOThread.FAILURE_VALUE); + } + + // wait for write + ChunkDataController.InProgressWrite write = task.inProgressWrite; + if (write == null) { + return null; + } + return Boolean.valueOf(write.wrote.join() != PaperFileIOThread.FAILURE_VALUE); + } + // Hack end + + public NBTTagCompound getPendingWrite(final WorldServer world, final int chunkX, final int chunkZ, final boolean poiData) { + final ChunkDataController taskController = poiData ? world.poiDataController : world.chunkDataController; + + final ChunkDataTask dataTask = taskController.tasks.get(Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ))); + + if (dataTask == null) { + return null; + } + + final ChunkDataController.InProgressWrite write = dataTask.inProgressWrite; + + if (write == null) { + return null; + } + + return write.data; + } + + /** + * Sets the priority of all IO tasks for the given chunk coordinates. This has no effect if no tasks are queued. + * @param world Chunk's world + * @param chunkX Chunk's x coordinate + * @param chunkZ Chunk's z coordinate + * @param priority Priority level to set to + */ + public void setPriority(final WorldServer world, final int chunkX, final int chunkZ, final int priority) { + if (!PrioritizedTaskQueue.validPriority(priority)) { + throw new IllegalArgumentException("Invalid priority: " + priority); + } + + final Long key = Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ)); + + final ChunkDataTask poiTask = world.poiDataController.tasks.get(key); + final ChunkDataTask chunkTask = world.chunkDataController.tasks.get(key); + + if (poiTask != null) { + poiTask.updatePriority(priority); + } + if (chunkTask != null) { + chunkTask.updatePriority(priority); + } + } + + /** + * Schedules the chunk data to be written asynchronously. + *

    + * Impl notes: + *

    + *
  • + * This function presumes a chunk load for the coordinates is not called during this function (anytime after is OK). This means + * saves must be scheduled before a chunk is unloaded. + *
  • + *
  • + * Writes may be called concurrently, although only the "later" write will go through. + *
  • + * @param world Chunk's world + * @param chunkX Chunk's x coordinate + * @param chunkZ Chunk's z coordinate + * @param poiData Chunk point of interest data. If {@code null}, then no poi data is saved. + * @param chunkData Chunk data. If {@code null}, then no chunk data is saved. + * @param priority Priority level for this task. See {@link PrioritizedTaskQueue} + * @throws IllegalArgumentException If both {@code poiData} and {@code chunkData} are {@code null}. + * @throws IllegalStateException If the file io thread has shutdown. + */ + public void scheduleSave(final WorldServer world, final int chunkX, final int chunkZ, + final NBTTagCompound poiData, final NBTTagCompound chunkData, + final int priority) throws IllegalArgumentException { + if (!PrioritizedTaskQueue.validPriority(priority)) { + throw new IllegalArgumentException("Invalid priority: " + priority); + } + + final long writeCounter = this.writeCounter.getAndIncrement(); + + if (poiData != null) { + this.scheduleWrite(world.poiDataController, world, chunkX, chunkZ, poiData, priority, writeCounter); + } + if (chunkData != null) { + this.scheduleWrite(world.chunkDataController, world, chunkX, chunkZ, chunkData, priority, writeCounter); + } + } + + private void scheduleWrite(final ChunkDataController dataController, final WorldServer world, + final int chunkX, final int chunkZ, final NBTTagCompound data, final int priority, final long writeCounter) { + dataController.tasks.compute(Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ)), (final Long keyInMap, final ChunkDataTask taskRunning) -> { + if (taskRunning == null) { + // no task is scheduled + + // create task + final ChunkDataTask newTask = new ChunkDataTask(priority, world, chunkX, chunkZ, dataController); + newTask.inProgressWrite = new ChunkDataController.InProgressWrite(); + newTask.inProgressWrite.writeCounter = writeCounter; + newTask.inProgressWrite.data = data; + + PaperFileIOThread.this.queueTask(newTask); // schedule + return newTask; + } + + taskRunning.raisePriority(priority); + + if (taskRunning.inProgressWrite == null) { + taskRunning.inProgressWrite = new ChunkDataController.InProgressWrite(); + } + + boolean reschedule = taskRunning.inProgressWrite.writeCounter == -1L; + + // synchronize for readers + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (taskRunning) { + taskRunning.inProgressWrite.data = data; + taskRunning.inProgressWrite.writeCounter = writeCounter; + } + + if (reschedule) { + // We need to reschedule this task since the previous one is not currently scheduled since it failed + taskRunning.reschedule(priority); + } + + return taskRunning; + }); + } + + /** + * Same as {@link #loadChunkDataAsync(WorldServer, int, int, int, Consumer, boolean, boolean, boolean)}, except this function returns + * a {@link CompletableFuture} which is potentially completed ASYNCHRONOUSLY ON THE FILE IO THREAD when the load task + * has completed. + *

    + * Note that if the chunk fails to load the returned future is completed with {@code null}. + *

    + */ + public CompletableFuture loadChunkDataAsyncFuture(final WorldServer world, final int chunkX, final int chunkZ, + final int priority, final boolean readPoiData, final boolean readChunkData, + final boolean intendingToBlock) { + final CompletableFuture future = new CompletableFuture<>(); + this.loadChunkDataAsync(world, chunkX, chunkZ, priority, future::complete, readPoiData, readChunkData, intendingToBlock); + return future; + } + + /** + * Schedules a load to be executed asynchronously. + *

    + * Impl notes: + *

    + *
  • + * If a chunk fails to load, the {@code onComplete} parameter is completed with {@code null}. + *
  • + *
  • + * It is possible for the {@code onComplete} parameter to be given {@link ChunkData} containing data + * this call did not request. + *
  • + *
  • + * The {@code onComplete} parameter may be completed during the execution of this function synchronously or it may + * be completed asynchronously on this file io thread. Interacting with the file IO thread in the completion of + * data is undefined behaviour, and can cause deadlock. + *
  • + * @param world Chunk's world + * @param chunkX Chunk's x coordinate + * @param chunkZ Chunk's z coordinate + * @param priority Priority level for this task. See {@link PrioritizedTaskQueue} + * @param onComplete Consumer to execute once this task has completed + * @param readPoiData Whether to read point of interest data. If {@code false}, the {@code NBTTagCompound} will be {@code null}. + * @param readChunkData Whether to read chunk data. If {@code false}, the {@code NBTTagCompound} will be {@code null}. + * @return The {@link PrioritizedTaskQueue.PrioritizedTask} associated with this task. Note that this task does not support + * cancellation. + */ + public void loadChunkDataAsync(final WorldServer world, final int chunkX, final int chunkZ, + final int priority, final Consumer onComplete, + final boolean readPoiData, final boolean readChunkData, + final boolean intendingToBlock) { + if (!PrioritizedTaskQueue.validPriority(priority)) { + throw new IllegalArgumentException("Invalid priority: " + priority); + } + + if (!(readPoiData | readChunkData)) { + throw new IllegalArgumentException("Must read chunk data or poi data"); + } + + final ChunkData complete = new ChunkData(); + final boolean[] requireCompletion = new boolean[] { readPoiData, readChunkData }; + + if (readPoiData) { + this.scheduleRead(world.poiDataController, world, chunkX, chunkZ, (final NBTTagCompound poiData) -> { + complete.poiData = poiData; + + final boolean finished; + + // avoid a race condition where the file io thread completes and we complete synchronously + // Note: Synchronization can be elided if both of the accesses are volatile + synchronized (requireCompletion) { + requireCompletion[0] = false; // 0 -> poi data + finished = !requireCompletion[1]; // 1 -> chunk data + } + + if (finished) { + onComplete.accept(complete); + } + }, priority, intendingToBlock); + } + + if (readChunkData) { + this.scheduleRead(world.chunkDataController, world, chunkX, chunkZ, (final NBTTagCompound chunkData) -> { + complete.chunkData = chunkData; + + final boolean finished; + + // avoid a race condition where the file io thread completes and we complete synchronously + // Note: Synchronization can be elided if both of the accesses are volatile + synchronized (requireCompletion) { + requireCompletion[1] = false; // 1 -> chunk data + finished = !requireCompletion[0]; // 0 -> poi data + } + + if (finished) { + onComplete.accept(complete); + } + }, priority, intendingToBlock); + } + + } + + // Note: the onComplete may be called asynchronously or synchronously here. + private void scheduleRead(final ChunkDataController dataController, final WorldServer world, + final int chunkX, final int chunkZ, final Consumer onComplete, final int priority, + final boolean intendingToBlock) { + + Function tryLoadFunction = (final RegionFile file) -> { + if (file == null) { + return Boolean.TRUE; + } + return Boolean.valueOf(file.chunkExists(new ChunkCoordIntPair(chunkX, chunkZ))); + }; + + dataController.tasks.compute(Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ)), (final Long keyInMap, final ChunkDataTask running) -> { + if (running == null) { + // not scheduled + + final Boolean shouldSchedule = intendingToBlock ? dataController.computeForRegionFile(chunkX, chunkZ, tryLoadFunction) : + dataController.computeForRegionFileIfLoaded(chunkX, chunkZ, tryLoadFunction); + + if (shouldSchedule == Boolean.FALSE) { + // not on disk + onComplete.accept(null); + return null; + } + + // set up task + final ChunkDataTask newTask = new ChunkDataTask(priority, world, chunkX, chunkZ, dataController); + newTask.inProgressRead = new ChunkDataController.InProgressRead(); + newTask.inProgressRead.readFuture.thenAccept(onComplete); + + PaperFileIOThread.this.queueTask(newTask); // schedule task + return newTask; + } + + running.raisePriority(priority); + + if (running.inProgressWrite == null) { + // chain to the read future + running.inProgressRead.readFuture.thenAccept(onComplete); + return running; + } + + // at this stage we have to use the in progress write's data to avoid an order issue + // we don't synchronize since all writes to data occur in the compute() call + onComplete.accept(running.inProgressWrite.data); + return running; + }); + } + + /** + * Same as {@link #loadChunkDataAsync(WorldServer, int, int, int, Consumer, boolean, boolean, boolean)}, except this function returns + * the {@link ChunkData} associated with the specified chunk when the task is complete. + * @return The chunk data, or {@code null} if the chunk failed to load. + */ + public ChunkData loadChunkData(final WorldServer world, final int chunkX, final int chunkZ, final int priority, + final boolean readPoiData, final boolean readChunkData) { + return this.loadChunkDataAsyncFuture(world, chunkX, chunkZ, priority, readPoiData, readChunkData, true).join(); + } + + /** + * Schedules the given task at the specified priority to be executed on the IO thread. + *

    + * Internal api. Do not use. + *

    + */ + public void runTask(final int priority, final Runnable runnable) { + this.queueTask(new GeneralTask(priority, runnable)); + } + + static final class GeneralTask extends PrioritizedTaskQueue.PrioritizedTask implements Runnable { + + private final Runnable run; + + public GeneralTask(final int priority, final Runnable run) { + super(priority); + this.run = IOUtil.notNull(run, "Task may not be null"); + } + + @Override + public void run() { + try { + this.run.run(); + } catch (final Throwable throwable) { + if (throwable instanceof ThreadDeath) { + throw (ThreadDeath)throwable; + } + LOGGER.fatal("Failed to execute general task on IO thread " + IOUtil.genericToString(this.run), throwable); + } + } + } + + public static final class ChunkData { + + public NBTTagCompound poiData; + public NBTTagCompound chunkData; + + public ChunkData() {} + + public ChunkData(final NBTTagCompound poiData, final NBTTagCompound chunkData) { + this.poiData = poiData; + this.chunkData = chunkData; + } + } + + public static abstract class ChunkDataController { + + // ConcurrentHashMap synchronizes per chain, so reduce the chance of task's hashes colliding. + public final ConcurrentHashMap tasks = new ConcurrentHashMap<>(64, 0.5f); + + public abstract void writeData(final int x, final int z, final NBTTagCompound compound) throws IOException; + public abstract NBTTagCompound readData(final int x, final int z) throws IOException; + + public abstract T computeForRegionFile(final int chunkX, final int chunkZ, final Function function); + public abstract T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function function); + + public static final class InProgressWrite { + public long writeCounter; + public NBTTagCompound data; + + // Hack start + @Deprecated + public CompletableFuture wrote = new CompletableFuture<>(); + // Hack end + } + + public static final class InProgressRead { + public final CompletableFuture readFuture = new CompletableFuture<>(); + } + } + + public static final class ChunkDataTask extends PrioritizedTaskQueue.PrioritizedTask implements Runnable { + + public ChunkDataController.InProgressWrite inProgressWrite; + public ChunkDataController.InProgressRead inProgressRead; + + private final WorldServer world; + private final int x; + private final int z; + private final ChunkDataController taskController; + + public ChunkDataTask(final int priority, final WorldServer world, final int x, final int z, final ChunkDataController taskController) { + super(priority); + this.world = world; + this.x = x; + this.z = z; + this.taskController = taskController; + } + + @Override + public String toString() { + return "Task for world: '" + this.world.getWorld().getName() + "' at " + this.x + "," + this.z + + " poi: " + (this.taskController == this.world.poiDataController) + ", hash: " + this.hashCode(); + } + + /* + * + * IO thread will perform reads before writes + * + * How reads/writes are scheduled: + * + * If read in progress while scheduling write, ignore read and schedule write + * If read in progress while scheduling read (no write in progress), chain the read task + * + * + * If write in progress while scheduling read, use the pending write data and ret immediately + * If write in progress while scheduling write (ignore read in progress), overwrite the write in progress data + * + * This allows the reads and writes to act as if they occur synchronously to the thread scheduling them, however + * it fails to properly propagate write failures + * + */ + + void reschedule(final int priority) { + // priority is checked before this stage // TODO what + this.queue.lazySet(null); + this.inProgressWrite.wrote = new CompletableFuture<>(); // Hack + this.priority.lazySet(priority); + PaperFileIOThread.Holder.INSTANCE.queueTask(this); + } + + @Override + public void run() { + ChunkDataController.InProgressRead read = this.inProgressRead; + if (read != null) { + NBTTagCompound compound = PaperFileIOThread.FAILURE_VALUE; + try { + compound = this.taskController.readData(this.x, this.z); + } catch (final Throwable thr) { + if (thr instanceof ThreadDeath) { + throw (ThreadDeath)thr; + } + LOGGER.fatal("Failed to read chunk data for task: " + this.toString(), thr); + // fall through to complete with null data + } + read.readFuture.complete(compound); + } + + final Long chunkKey = Long.valueOf(IOUtil.getCoordinateKey(this.x, this.z)); + + ChunkDataController.InProgressWrite write = this.inProgressWrite; + + if (write == null) { + // IntelliJ warns this is invalid, however it does not consider that writes to the task map & the inProgress field can occur concurrently. + ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final Long keyInMap, final ChunkDataTask valueInMap) -> { + if (valueInMap == null) { + throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); + } + if (valueInMap != ChunkDataTask.this) { + throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); + } + return valueInMap.inProgressWrite == null ? null : valueInMap; + }); + + if (inMap == null) { + return; // set the task value to null, indicating we're done + } + + // not null, which means there was a concurrent write + write = this.inProgressWrite; + } + + // check if another process is writing + try { + this.world.checkSession(); + } catch (final ExceptionWorldConflict ex) { + LOGGER.fatal("Couldn't save chunk; already in use by another instance of Minecraft?", ex); + // we don't need to set the write counter to -1 as we know at this stage there's no point in re-scheduling + // writes since they'll fail anyways. + write.wrote.complete(PaperFileIOThread.FAILURE_VALUE); // Hack - However we need to fail the write + return; + } + + for (;;) { + final long writeCounter; + final NBTTagCompound data; + + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (write) { + writeCounter = write.writeCounter; + data = write.data; + } + + boolean failedWrite = false; + + try { + this.taskController.writeData(this.x, this.z, data); + } catch (final Throwable thr) { + if (thr instanceof ThreadDeath) { + throw (ThreadDeath)thr; + } + LOGGER.fatal("Failed to write chunk data for task: " + this.toString(), thr); + failedWrite = true; + } + + boolean finalFailWrite = failedWrite; + + ChunkDataTask inMap = this.taskController.tasks.compute(chunkKey, (final Long keyInMap, final ChunkDataTask valueInMap) -> { + if (valueInMap == null) { + ChunkDataTask.this.inProgressWrite.wrote.complete(PaperFileIOThread.FAILURE_VALUE); // Hack + throw new IllegalStateException("Write completed concurrently, expected this task: " + ChunkDataTask.this.toString() + ", report this!"); + } + if (valueInMap != ChunkDataTask.this) { + ChunkDataTask.this.inProgressWrite.wrote.complete(PaperFileIOThread.FAILURE_VALUE); // Hack + throw new IllegalStateException("Chunk task mismatch, expected this task: " + ChunkDataTask.this.toString() + ", got: " + valueInMap.toString() + ", report this!"); + } + if (valueInMap.inProgressWrite.writeCounter == writeCounter) { + if (finalFailWrite) { + valueInMap.inProgressWrite.writeCounter = -1L; + valueInMap.inProgressWrite.wrote.complete(PaperFileIOThread.FAILURE_VALUE); + } else { + valueInMap.inProgressWrite.wrote.complete(data); + } + + return null; + } + return valueInMap; + // Hack end + }); + + if (inMap == null) { + // write counter matched, so we wrote the most up-to-date pending data, we're done here + // or we failed to write and successfully set the write counter to -1 + return; // we're done here + } + + // fetch & write new data + continue; + } + } + } +} diff --git a/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java b/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java new file mode 100644 index 000000000..78bd238f4 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java @@ -0,0 +1,276 @@ +package com.destroystokyo.paper.io; + +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +public class PrioritizedTaskQueue { + + // lower numbers are a higher priority (except < 0) + // higher priorities are always executed before lower priorities + + /** + * Priority value indicating the task has completed or is being completed. + */ + public static final int COMPLETING_PRIORITY = -1; + + /** + * Highest priority, should only be used for main thread tasks or tasks that are blocking the main thread. + */ + public static final int HIGHEST_PRIORITY = 0; + + /** + * Should be only used in an IO task so that chunk loads do not wait on other IO tasks. + * This only exists because IO tasks are scheduled before chunk load tasks to decrease IO waiting times. + */ + public static final int HIGHER_PRIORITY = 1; + + /** + * Should be used for scheduling chunk loads/generation that would increase response times to users. + */ + public static final int HIGH_PRIORITY = 2; + + /** + * Default priority. + */ + public static final int NORMAL_PRIORITY = 3; + + /** + * Use for tasks not at all critical and can potentially be delayed. + */ + public static final int LOW_PRIORITY = 4; + + /** + * Use for tasks that should "eventually" execute. + */ + public static final int LOWEST_PRIORITY = 5; + + private static final int TOTAL_PRIORITIES = 6; + + final ConcurrentLinkedQueue[] queues = (ConcurrentLinkedQueue[])new ConcurrentLinkedQueue[TOTAL_PRIORITIES]; + + private final AtomicBoolean shutdown = new AtomicBoolean(); + + { + for (int i = 0; i < TOTAL_PRIORITIES; ++i) { + this.queues[i] = new ConcurrentLinkedQueue<>(); + } + } + + /** + * Returns whether the specified priority is valid + */ + public static boolean validPriority(final int priority) { + return priority >= 0 && priority < TOTAL_PRIORITIES; + } + + /** + * Queues a task. + * @throws IllegalStateException If the task has already been queued. Use {@link PrioritizedTask#raisePriority(int)} to + * raise a task's priority. + * This can also be thrown if the queue has shutdown. + */ + public void add(final T task) throws IllegalStateException { + task.onQueue(this); + this.queues[task.getPriority()].add(task); + if (this.shutdown.get()) { + // note: we're not actually sure at this point if our task will go through + throw new IllegalStateException("Queue has shutdown, refusing to execute task " + IOUtil.genericToString(task)); + } + } + + /** + * Polls the highest priority task currently available. {@code null} if none. + */ + public T poll() { + T task; + for (int i = 0; i < TOTAL_PRIORITIES; ++i) { + final ConcurrentLinkedQueue queue = this.queues[i]; + + while ((task = queue.poll()) != null) { + final int prevPriority = task.tryComplete(i); + if (prevPriority != COMPLETING_PRIORITY && prevPriority <= i) { + // if the prev priority was greater-than or equal to our current priority + return task; + } + } + } + + return null; + } + + /** + * Returns whether this queue may have tasks queued. + *

    + * This operation is not atomic, but is MT-Safe. + *

    + * @return {@code true} if tasks may be queued, {@code false} otherwise + */ + public boolean hasTasks() { + for (int i = 0; i < TOTAL_PRIORITIES; ++i) { + final ConcurrentLinkedQueue queue = this.queues[i]; + + if (queue.peek() != null) { + return true; + } + } + return false; + } + + /** + * Prevent further additions to this queue. Attempts to add after this call has completed (potentially during) will + * result in {@link IllegalStateException} being thrown. + *

    + * This operation is atomic with respect to other shutdown calls + *

    + *

    + * After this call has completed, regardless of return value, this queue will be shutdown. + *

    + * @return {@code true} if the queue was shutdown, {@code false} if it has shut down already + */ + public boolean shutdown() { + return this.shutdown.getAndSet(false); + } + + public abstract static class PrioritizedTask { + + protected final AtomicReference queue = new AtomicReference<>(); + + protected final AtomicInteger priority; + + protected PrioritizedTask() { + this(PrioritizedTaskQueue.NORMAL_PRIORITY); + } + + protected PrioritizedTask(final int priority) { + if (!PrioritizedTaskQueue.validPriority(priority)) { + throw new IllegalArgumentException("Invalid priority " + priority); + } + this.priority = new AtomicInteger(priority); + } + + /** + * Returns the current priority. Note that {@link PrioritizedTaskQueue#COMPLETING_PRIORITY} will be returned + * if this task is completing or has completed. + */ + public final int getPriority() { + return this.priority.get(); + } + + /** + * Returns whether this task is scheduled to execute, or has been already executed. + */ + public boolean isScheduled() { + return this.queue.get() != null; + } + + final int tryComplete(final int minPriority) { + for (int curr = this.getPriorityVolatile();;) { + if (curr == COMPLETING_PRIORITY) { + return COMPLETING_PRIORITY; + } + if (curr > minPriority) { + // curr is lower priority + return curr; + } + + if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, COMPLETING_PRIORITY))) { + return curr; + } + continue; + } + } + + /** + * Forces this task to be completed. + * @return {@code true} if the task was cancelled, {@code false} if the task has already completed or is being completed. + */ + public boolean cancel() { + return this.exchangePriorityVolatile(PrioritizedTaskQueue.COMPLETING_PRIORITY) != PrioritizedTaskQueue.COMPLETING_PRIORITY; + } + + /** + * Attempts to raise the priority to the priority level specified. + * @param priority Priority specified + * @return {@code true} if successful, {@code false} otherwise. + */ + public boolean raisePriority(final int priority) { + if (!PrioritizedTaskQueue.validPriority(priority)) { + throw new IllegalArgumentException("Invalid priority"); + } + + for (int curr = this.getPriorityVolatile();;) { + if (curr == COMPLETING_PRIORITY) { + return false; + } + if (priority >= curr) { + return true; + } + + if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority))) { + PrioritizedTaskQueue queue = this.queue.get(); + if (queue != null) { + //noinspection unchecked + queue.queues[priority].add(this); // silently fail on shutdown + } + return true; + } + continue; + } + } + + /** + * Attempts to set this task's priority level to the level specified. + * @param priority Specified priority level. + * @return {@code true} if successful, {@code false} if this task is completing or has completed. + */ + public boolean updatePriority(final int priority) { + if (!PrioritizedTaskQueue.validPriority(priority)) { + throw new IllegalArgumentException("Invalid priority"); + } + + for (int curr = this.getPriorityVolatile();;) { + if (curr == COMPLETING_PRIORITY) { + return false; + } + if (curr == priority) { + return true; + } + + if (curr == (curr = this.compareAndExchangePriorityVolatile(curr, priority))) { + PrioritizedTaskQueue queue = this.queue.get(); + if (queue != null) { + //noinspection unchecked + queue.queues[priority].add(this); // silently fail on shutdown + } + return true; + } + continue; + } + } + + void onQueue(final PrioritizedTaskQueue queue) { + if (this.queue.getAndSet(queue) != null) { + throw new IllegalStateException("Already queued!"); + } + } + + /* priority */ + + protected final int getPriorityVolatile() { + return this.priority.get(); + } + + protected final int compareAndExchangePriorityVolatile(final int expect, final int update) { + if (this.priority.compareAndSet(expect, update)) { + return expect; + } + return this.priority.get(); + } + + protected final int exchangePriorityVolatile(final int value) { + return this.priority.getAndSet(value); + } + } +} diff --git a/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java new file mode 100644 index 000000000..ee906b594 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java @@ -0,0 +1,241 @@ +package com.destroystokyo.paper.io; + +import net.minecraft.server.MinecraftServer; +import org.apache.logging.log4j.Logger; + +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.LockSupport; + +public class QueueExecutorThread extends Thread { + + private static final Logger LOGGER = MinecraftServer.LOGGER; + + protected final PrioritizedTaskQueue queue; + protected final long spinWaitTime; + + protected volatile boolean closed; + + protected final AtomicBoolean parked = new AtomicBoolean(); + + protected volatile ConcurrentLinkedQueue flushQueue = new ConcurrentLinkedQueue<>(); + protected volatile long flushCycles; + + public QueueExecutorThread(final PrioritizedTaskQueue queue) { + this(queue, (int)(1.e6)); // 1.0ms + } + + public QueueExecutorThread(final PrioritizedTaskQueue queue, final long spinWaitTime) { // in ms + this.queue = queue; + this.spinWaitTime = spinWaitTime; + } + + @Override + public void run() { + final long spinWaitTime = this.spinWaitTime; + main_loop: + for (;;) { + this.pollTasks(true); + + // spinwait + + final long start = System.nanoTime(); + + for (;;) { + // If we are interrpted for any reason, park() will always return immediately. Clear so that we don't needlessly use cpu in such an event. + Thread.interrupted(); + LockSupport.parkNanos("Spinwaiting on tasks", 1000L); // 1us + + if (this.pollTasks(true)) { + // restart loop, found tasks + continue main_loop; + } + + if (this.handleClose()) { + return; // we're done + } + + if ((System.nanoTime() - start) >= spinWaitTime) { + break; + } + } + + if (this.handleClose()) { + return; + } + + this.parked.set(true); + + // We need to parse here to avoid a race condition where a thread queues a task before we set parked to true + // (i.e it will not notify us) + if (this.pollTasks(true)) { + this.parked.set(false); + continue; + } + + if (this.handleClose()) { + return; + } + + // we don't need to check parked before sleeping, but we do need to check parked in a do-while loop + // LockSupport.park() can fail for any reason + do { + Thread.interrupted(); + LockSupport.park("Waiting on tasks"); + } while (this.parked.get()); + } + } + + protected boolean handleClose() { + if (this.closed) { + this.pollTasks(true); // this ensures we've emptied the queue + this.handleFlushThreads(true); + return true; + } + return false; + } + + protected boolean pollTasks(boolean flushTasks) { + Runnable task; + boolean ret = false; + + while ((task = this.queue.poll()) != null) { + ret = true; + try { + task.run(); + } catch (final Throwable throwable) { + if (throwable instanceof ThreadDeath) { + throw (ThreadDeath)throwable; + } + LOGGER.fatal("Exception thrown from prioritized runnable task in thread '" + this.getName() + "': " + IOUtil.genericToString(task), throwable); + } + } + + if (flushTasks) { + this.handleFlushThreads(false); + } + + return ret; + } + + protected void handleFlushThreads(final boolean shutdown) { + Thread parking; + ConcurrentLinkedQueue flushQueue = this.flushQueue; + do { + ++flushCycles; // may be plain read opaque write + while ((parking = flushQueue.poll()) != null) { + LockSupport.unpark(parking); + } + } while (this.pollTasks(false)); + + if (shutdown) { + this.flushQueue = null; + + // defend against a race condition where a flush thread double-checks right before we set to null + while ((parking = flushQueue.poll()) != null) { + LockSupport.unpark(parking); + } + } + } + + /** + * Notify's this thread that a task has been added to its queue + * @return {@code true} if this thread was waiting for tasks, {@code false} if it is executing tasks + */ + public boolean notifyTasks() { + if (this.parked.get() && this.parked.getAndSet(false)) { + LockSupport.unpark(this); + return true; + } + return false; + } + + protected void queueTask(final T task) { + this.queue.add(task); + this.notifyTasks(); + } + + /** + * Waits until this thread's queue is empty. + * + * @throws IllegalStateException If the current thread is {@code this} thread. + */ + public void flush() { + final Thread currentThread = Thread.currentThread(); + + if (currentThread == this) { + // avoid deadlock + throw new IllegalStateException("Cannot flush the queue executor thread while on the queue executor thread"); + } + + // order is important + + int successes = 0; + long lastCycle = -1L; + + do { + final ConcurrentLinkedQueue flushQueue = this.flushQueue; + if (flushQueue == null) { + return; + } + + flushQueue.add(currentThread); + + // double check flush queue + if (this.flushQueue == null) { + return; + } + + final long currentCycle = this.flushCycles; // may be opaque read + + if (currentCycle == lastCycle) { + Thread.yield(); + continue; + } + + // force response + this.parked.set(false); + LockSupport.unpark(this); + + LockSupport.park("flushing queue executor thread"); + + // returns whether there are tasks queued, does not return whether there are tasks executing + // this is why we cycle twice twice through flush (we know a pollTask call is made after a flush cycle) + // we really only need to guarantee that the tasks this thread has queued has gone through, and can leave + // tasks queued concurrently that are unsychronized with this thread as undefined behavior + if (this.queue.hasTasks()) { + successes = 0; + } else { + ++successes; + } + + } while (successes != 2); + + } + + /** + * Closes this queue executor's queue and optionally waits for it to empty. + *

    + * If wait is {@code true}, then the queue will be empty by the time this call completes. + *

    + *

    + * This function is MT-Safe. + *

    + * @param wait If this call is to wait until the queue is empty + * @param killQueue Whether to shutdown this thread's queue + * @return whether this thread shut down the queue + */ + public boolean close(final boolean wait, final boolean killQueue) { + boolean ret = !killQueue ? false : this.queue.shutdown(); + this.closed = true; + + // force thread to respond to the shutdown + this.parked.set(false); + LockSupport.unpark(this); + + if (wait) { + this.flush(); + } + return ret; + } +} diff --git a/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java new file mode 100644 index 000000000..59aec1032 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java @@ -0,0 +1,172 @@ +package com.destroystokyo.paper.io; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.mojang.datafixers.util.Pair; +import it.unimi.dsi.fastutil.longs.Long2IntMap; +import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.minecraft.server.World; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +public class SyncLoadFinder { + + public static final boolean ENABLED = Boolean.getBoolean("paper.debug-sync-loads"); + + private static final WeakHashMap> SYNC_LOADS = new WeakHashMap<>(); + + private static final class SyncLoadInformation { + + public int times; + + public final Long2IntOpenHashMap coordinateTimes = new Long2IntOpenHashMap(); + } + + public static void logSyncLoad(final World world, final int chunkX, final int chunkZ) { + if (!ENABLED) { + return; + } + + final ThrowableWithEquals stacktrace = new ThrowableWithEquals(Thread.currentThread().getStackTrace()); + + SYNC_LOADS.compute(world, (final World keyInMap, Object2ObjectOpenHashMap map) -> { + if (map == null) { + map = new Object2ObjectOpenHashMap<>(); + } + + map.compute(stacktrace, (ThrowableWithEquals keyInMap0, SyncLoadInformation valueInMap) -> { + if (valueInMap == null) { + valueInMap = new SyncLoadInformation(); + } + + ++valueInMap.times; + + valueInMap.coordinateTimes.compute(IOUtil.getCoordinateKey(chunkX, chunkZ), (Long keyInMap1, Integer valueInMap1) -> { + return valueInMap1 == null ? Integer.valueOf(1) : Integer.valueOf(valueInMap1.intValue() + 1); + }); + + return valueInMap; + }); + + return map; + }); + } + + public static JsonObject serialize() { + final JsonObject ret = new JsonObject(); + + final JsonArray worldsData = new JsonArray(); + + for (final Map.Entry> entry : SYNC_LOADS.entrySet()) { + final World world = entry.getKey(); + + final JsonObject worldData = new JsonObject(); + + worldData.addProperty("name", world.getWorld().getName()); + + final List> data = new ArrayList<>(); + + entry.getValue().forEach((ThrowableWithEquals stacktrace, SyncLoadInformation times) -> { + data.add(new Pair<>(stacktrace, times)); + }); + + data.sort((Pair pair1, Pair pair2) -> { + return Integer.compare(pair2.getSecond().times, pair1.getSecond().times); // reverse order + }); + + final JsonArray stacktraces = new JsonArray(); + + for (Pair pair : data) { + final JsonObject stacktrace = new JsonObject(); + + stacktrace.addProperty("times", pair.getSecond().times); + + final JsonArray traces = new JsonArray(); + + for (StackTraceElement element : pair.getFirst().stacktrace) { + traces.add(String.valueOf(element)); + } + + stacktrace.add("stacktrace", traces); + + final JsonArray coordinates = new JsonArray(); + + for (Long2IntMap.Entry coordinate : pair.getSecond().coordinateTimes.long2IntEntrySet()) { + final long key = coordinate.getLongKey(); + final int times = coordinate.getIntValue(); + coordinates.add("(" + IOUtil.getCoordinateX(key) + "," + IOUtil.getCoordinateZ(key) + "): " + times); + } + + stacktrace.add("coordinates", coordinates); + + stacktraces.add(stacktrace); + } + + + worldData.add("stacktraces", stacktraces); + worldsData.add(worldData); + } + + ret.add("worlds", worldsData); + + return ret; + } + + static final class ThrowableWithEquals { + + private final StackTraceElement[] stacktrace; + private final int hash; + + public ThrowableWithEquals(final StackTraceElement[] stacktrace) { + this.stacktrace = stacktrace; + this.hash = ThrowableWithEquals.hash(stacktrace); + } + + public static int hash(final StackTraceElement[] stacktrace) { + int hash = 0; + + for (int i = 0; i < stacktrace.length; ++i) { + hash *= 31; + hash += stacktrace[i].hashCode(); + } + + return hash; + } + + @Override + public int hashCode() { + return this.hash; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null || obj.getClass() != this.getClass()) { + return false; + } + + final ThrowableWithEquals other = (ThrowableWithEquals)obj; + final StackTraceElement[] otherStackTrace = other.stacktrace; + + if (this.stacktrace.length != otherStackTrace.length) { + return false; + } + + if (this == obj) { + return true; + } + + for (int i = 0; i < this.stacktrace.length; ++i) { + if (!this.stacktrace[i].equals(otherStackTrace[i])) { + return false; + } + } + + return true; + } + } +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java new file mode 100644 index 000000000..305da4786 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java @@ -0,0 +1,149 @@ +package com.destroystokyo.paper.io.chunk; + +import co.aikar.timings.Timing; +import com.destroystokyo.paper.io.PaperFileIOThread; +import com.destroystokyo.paper.io.IOUtil; +import net.minecraft.server.ChunkCoordIntPair; +import net.minecraft.server.ChunkRegionLoader; +import net.minecraft.server.PlayerChunkMap; +import net.minecraft.server.WorldServer; + +import java.util.ArrayDeque; +import java.util.function.Consumer; + +public final class ChunkLoadTask extends ChunkTask { + + public boolean cancelled; + + Consumer onComplete; + public PaperFileIOThread.ChunkData chunkData; + + private boolean hasCompleted; + + public ChunkLoadTask(final WorldServer world, final int chunkX, final int chunkZ, final int priority, + final ChunkTaskManager taskManager, + final Consumer onComplete) { + super(world, chunkX, chunkZ, priority, taskManager); + this.onComplete = onComplete; + } + + private static final ArrayDeque EMPTY_QUEUE = new ArrayDeque<>(); + + private static ChunkRegionLoader.InProgressChunkHolder createEmptyHolder() { + return new ChunkRegionLoader.InProgressChunkHolder(null, EMPTY_QUEUE); + } + + @Override + public void run() { + try { + this.executeTask(); + } catch (final Throwable ex) { + PaperFileIOThread.LOGGER.error("Failed to execute chunk load task: " + this.toString(), ex); + if (!this.hasCompleted) { + this.complete(ChunkLoadTask.createEmptyHolder()); + } + } + } + + private boolean checkCancelled() { + if (this.cancelled) { + // IntelliJ does not understand writes may occur to cancelled concurrently. + return this.taskManager.chunkLoadTasks.compute(Long.valueOf(IOUtil.getCoordinateKey(this.chunkX, this.chunkZ)), (final Long keyInMap, final ChunkLoadTask valueInMap) -> { + if (valueInMap != ChunkLoadTask.this) { + throw new IllegalStateException("Expected this task to be scheduled, but another was! Other: " + valueInMap + ", current: " + ChunkLoadTask.this); + } + + if (valueInMap.cancelled) { + return null; + } + return valueInMap; + }) == null; + } + return false; + } + + public void executeTask() { + if (this.checkCancelled()) { + return; + } + + // either executed synchronously or asynchronously + final PaperFileIOThread.ChunkData chunkData = this.chunkData; + + if (chunkData.poiData == PaperFileIOThread.FAILURE_VALUE || chunkData.chunkData == PaperFileIOThread.FAILURE_VALUE) { + PaperFileIOThread.LOGGER.error("Could not load chunk for task: " + this.toString() + ", file IO thread has dumped the relevant exception above"); + this.complete(ChunkLoadTask.createEmptyHolder()); + return; + } + + if (chunkData.chunkData == null) { + // not on disk + this.complete(ChunkLoadTask.createEmptyHolder()); + return; + } + + final ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(this.chunkX, this.chunkZ); + + final PlayerChunkMap chunkManager = this.world.getChunkProvider().playerChunkMap; + + try (Timing ignored = this.world.timings.chunkIOStage1.startTimingIfSync()) { + final ChunkRegionLoader.InProgressChunkHolder chunkHolder; + + // apply fixes + + try { + if (chunkData.poiData != null) { + chunkData.poiData = chunkData.poiData.clone(); // clone data for safety, file IO thread does not clone + } + chunkData.chunkData = chunkManager.getChunkData(this.world.getWorldProvider().getDimensionManager(), + chunkManager.getWorldPersistentDataSupplier(), chunkData.chunkData.clone(), chunkPos, this.world); // clone data for safety, file IO thread does not clone + } catch (final Throwable ex) { + PaperFileIOThread.LOGGER.error("Could not apply datafixers for chunk task: " + this.toString(), ex); + this.complete(ChunkLoadTask.createEmptyHolder()); + } + + if (this.checkCancelled()) { + return; + } + + try { + this.world.getChunkProvider().playerChunkMap.updateChunkStatusOnDisk(chunkPos, chunkData.chunkData); + } catch (final Throwable ex) { + PaperFileIOThread.LOGGER.warn("Failed to update chunk status cache for task: " + this.toString(), ex); + // non-fatal, continue + } + + try { + chunkHolder = ChunkRegionLoader.loadChunk(this.world, + chunkManager.definedStructureManager, chunkManager.getVillagePlace(), chunkPos, + chunkData.chunkData, true); + } catch (final Throwable ex) { + PaperFileIOThread.LOGGER.error("Could not de-serialize chunk data for task: " + this.toString(), ex); + this.complete(ChunkLoadTask.createEmptyHolder()); + return; + } + + this.complete(chunkHolder); + } + } + + private void complete(final ChunkRegionLoader.InProgressChunkHolder holder) { + this.hasCompleted = true; + holder.poiData = this.chunkData == null ? null : this.chunkData.poiData; + + this.taskManager.chunkLoadTasks.compute(Long.valueOf(IOUtil.getCoordinateKey(this.chunkX, this.chunkZ)), (final Long keyInMap, final ChunkLoadTask valueInMap) -> { + if (valueInMap != ChunkLoadTask.this) { + throw new IllegalStateException("Expected this task to be scheduled, but another was! Other: " + valueInMap + ", current: " + ChunkLoadTask.this); + } + if (valueInMap.cancelled) { + return null; + } + try { + ChunkLoadTask.this.onComplete.accept(holder); + } catch (final Throwable thr) { + PaperFileIOThread.LOGGER.error("Failed to complete chunk data for task: " + this.toString(), thr); + } + return null; + }); + } +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkSaveTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkSaveTask.java new file mode 100644 index 000000000..60312b85f --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkSaveTask.java @@ -0,0 +1,112 @@ +package com.destroystokyo.paper.io.chunk; + +import co.aikar.timings.Timing; +import com.destroystokyo.paper.io.PaperFileIOThread; +import com.destroystokyo.paper.io.IOUtil; +import com.destroystokyo.paper.io.PrioritizedTaskQueue; +import net.minecraft.server.ChunkRegionLoader; +import net.minecraft.server.IAsyncTaskHandler; +import net.minecraft.server.IChunkAccess; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.WorldServer; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; + +public final class ChunkSaveTask extends ChunkTask { + + public final ChunkRegionLoader.AsyncSaveData asyncSaveData; + public final IChunkAccess chunk; + public final CompletableFuture onComplete = new CompletableFuture<>(); + + private final AtomicInteger attemptedPriority; + + public ChunkSaveTask(final WorldServer world, final int chunkX, final int chunkZ, final int priority, + final ChunkTaskManager taskManager, final ChunkRegionLoader.AsyncSaveData asyncSaveData, + final IChunkAccess chunk) { + super(world, chunkX, chunkZ, priority, taskManager); + this.chunk = chunk; + this.asyncSaveData = asyncSaveData; + this.attemptedPriority = new AtomicInteger(priority); + } + + @Override + public void run() { + // can be executed asynchronously or synchronously + final NBTTagCompound compound; + + try (Timing ignored = this.world.timings.chunkUnloadDataSave.startTimingIfSync()) { + compound = ChunkRegionLoader.saveChunk(this.world, this.chunk, this.asyncSaveData); + } catch (final Throwable ex) { + // has a plugin modified something it should not have and made us CME? + PaperFileIOThread.LOGGER.error("Failed to serialize unloading chunk data for task: " + this.toString() + ", falling back to a synchronous execution", ex); + + // Note: We add to the server thread queue here since this is what the server will drain tasks from + // when waiting for chunks + ChunkTaskManager.queueChunkWaitTask(() -> { + try (Timing ignored = this.world.timings.chunkUnloadDataSave.startTiming()) { + NBTTagCompound data = PaperFileIOThread.FAILURE_VALUE; + + try { + data = ChunkRegionLoader.saveChunk(this.world, this.chunk, this.asyncSaveData); + PaperFileIOThread.LOGGER.info("Successfully serialized chunk data for task: " + this.toString() + " synchronously"); + } catch (final Throwable ex1) { + PaperFileIOThread.LOGGER.fatal("Failed to synchronously serialize unloading chunk data for task: " + this.toString() + "! Chunk data will be lost", ex1); + } + + ChunkSaveTask.this.complete(data); + } + }); + + return; // the main thread will now complete the data + } + + this.complete(compound); + } + + @Override + public boolean raisePriority(final int priority) { + if (!PrioritizedTaskQueue.validPriority(priority)) { + throw new IllegalStateException("Invalid priority: " + priority); + } + + // we know priority is valid here + for (int curr = this.attemptedPriority.get();;) { + if (curr <= priority) { + break; // curr is higher/same priority + } + if (this.attemptedPriority.compareAndSet(curr, priority)) { + break; + } + curr = this.attemptedPriority.get(); + } + + return super.raisePriority(priority); + } + + @Override + public boolean updatePriority(final int priority) { + if (!PrioritizedTaskQueue.validPriority(priority)) { + throw new IllegalStateException("Invalid priority: " + priority); + } + this.attemptedPriority.set(priority); + return super.updatePriority(priority); + } + + private void complete(final NBTTagCompound compound) { + try { + this.onComplete.complete(compound); + } catch (final Throwable thr) { + PaperFileIOThread.LOGGER.error("Failed to complete chunk data for task: " + this.toString(), thr); + } + if (compound != PaperFileIOThread.FAILURE_VALUE) { + PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, this.chunkX, this.chunkZ, null, compound, this.attemptedPriority.get()); + } + this.taskManager.chunkSaveTasks.compute(Long.valueOf(IOUtil.getCoordinateKey(this.chunkX, this.chunkZ)), (final Long keyInMap, final ChunkSaveTask valueInMap) -> { + if (valueInMap != ChunkSaveTask.this) { + throw new IllegalStateException("Expected this task to be scheduled, but another was! Other: " + valueInMap + ", this: " + ChunkSaveTask.this); + } + return null; + }); + } +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTask.java new file mode 100644 index 000000000..1dfa8abfd --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTask.java @@ -0,0 +1,40 @@ +package com.destroystokyo.paper.io.chunk; + +import com.destroystokyo.paper.io.PaperFileIOThread; +import com.destroystokyo.paper.io.PrioritizedTaskQueue; +import net.minecraft.server.WorldServer; + +abstract class ChunkTask extends PrioritizedTaskQueue.PrioritizedTask implements Runnable { + + public final WorldServer world; + public final int chunkX; + public final int chunkZ; + public final ChunkTaskManager taskManager; + + public ChunkTask(final WorldServer world, final int chunkX, final int chunkZ, final int priority, + final ChunkTaskManager taskManager) { + super(priority); + this.world = world; + this.chunkX = chunkX; + this.chunkZ = chunkZ; + this.taskManager = taskManager; + } + + @Override + public String toString() { + return "Chunk task: class:" + this.getClass().getName() + ", for world '" + this.world.getWorld().getName() + + "', (" + this.chunkX + "," + this.chunkZ + "), hashcode:" + this.hashCode() + ", priority: " + this.getPriority(); + } + + @Override + public boolean raisePriority(final int priority) { + PaperFileIOThread.Holder.INSTANCE.bumpPriority(this.world, this.chunkX, this.chunkZ, priority); + return super.raisePriority(priority); + } + + @Override + public boolean updatePriority(final int priority) { + PaperFileIOThread.Holder.INSTANCE.setPriority(this.world, this.chunkX, this.chunkZ, priority); + return super.updatePriority(priority); + } +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java new file mode 100644 index 000000000..59d73bfad --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java @@ -0,0 +1,453 @@ +package com.destroystokyo.paper.io.chunk; + +import com.destroystokyo.paper.io.PaperFileIOThread; +import com.destroystokyo.paper.io.IOUtil; +import com.destroystokyo.paper.io.PrioritizedTaskQueue; +import com.destroystokyo.paper.io.QueueExecutorThread; +import net.minecraft.server.ChunkRegionLoader; +import net.minecraft.server.IAsyncTaskHandler; +import net.minecraft.server.IChunkAccess; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.WorldServer; +import org.apache.logging.log4j.Level; +import org.bukkit.Bukkit; +import org.spigotmc.AsyncCatcher; + +import java.util.ArrayDeque; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.function.Consumer; + +public final class ChunkTaskManager { + + private final QueueExecutorThread[] workers; + private final WorldServer world; + + private final PrioritizedTaskQueue queue; + private final boolean perWorldQueue; + + final ConcurrentHashMap chunkLoadTasks = new ConcurrentHashMap<>(64, 0.5f); + final ConcurrentHashMap chunkSaveTasks = new ConcurrentHashMap<>(64, 0.5f); + + private final PrioritizedTaskQueue chunkTasks = new PrioritizedTaskQueue<>(); // used if async chunks are disabled in config + + protected static QueueExecutorThread[] globalWorkers; + protected static PrioritizedTaskQueue globalQueue; + + protected static final ConcurrentLinkedQueue CHUNK_WAIT_QUEUE = new ConcurrentLinkedQueue<>(); + + public static final ArrayDeque WAITING_CHUNKS = new ArrayDeque<>(); // stack + + private static final class ChunkInfo { + + public final int chunkX; + public final int chunkZ; + public final WorldServer world; + + public ChunkInfo(final int chunkX, final int chunkZ, final WorldServer world) { + this.chunkX = chunkX; + this.chunkZ = chunkZ; + this.world = world; + } + + @Override + public String toString() { + return "[( " + this.chunkX + "," + this.chunkZ + ") in '" + this.world.getWorld().getName() + "']"; + } + } + + public static void pushChunkWait(final WorldServer world, final int chunkX, final int chunkZ) { + synchronized (WAITING_CHUNKS) { + WAITING_CHUNKS.push(new ChunkInfo(chunkX, chunkZ, world)); + } + } + + public static void popChunkWait() { + synchronized (WAITING_CHUNKS) { + WAITING_CHUNKS.pop(); + } + } + + public static String getChunkWaitInfo() { + synchronized (WAITING_CHUNKS) { + return WAITING_CHUNKS.toString(); + } + } + + public static void dumpAllChunkLoadInfo() { + synchronized (WAITING_CHUNKS) { + if (WAITING_CHUNKS.isEmpty()) { + return; + } + + PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk wait task info below: "); + + for (final ChunkInfo chunkInfo : WAITING_CHUNKS) { + final long key = IOUtil.getCoordinateKey(chunkInfo.chunkX, chunkInfo.chunkZ); + final ChunkLoadTask loadTask = chunkInfo.world.asyncChunkTaskManager.chunkLoadTasks.get(key); + final ChunkSaveTask saveTask = chunkInfo.world.asyncChunkTaskManager.chunkSaveTasks.get(key); + + PaperFileIOThread.LOGGER.log(Level.ERROR, chunkInfo.chunkX + "," + chunkInfo.chunkZ + " in '" + chunkInfo.world.getWorld().getName() + ":"); + PaperFileIOThread.LOGGER.log(Level.ERROR, "Load Task - " + (loadTask == null ? "none" : loadTask.toString())); + PaperFileIOThread.LOGGER.log(Level.ERROR, "Save Task - " + (saveTask == null ? "none" : saveTask.toString())); + // log current status of chunk to indicate whether we're waiting on generation or loading + net.minecraft.server.PlayerChunk chunkHolder = chunkInfo.world.getChunkProvider().playerChunkMap.getVisibleChunk(key); + + if (chunkHolder == null) { + PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Holder - null"); + } else { + IChunkAccess chunk = chunkHolder.getAvailableChunkNow(); + PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Holder - non-null"); + PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getChunkStatus().toString())); + } + + } + } + } + + public static void initGlobalLoadThreads(int threads) { + if (threads <= 0 || globalWorkers != null) { + return; + } + + globalWorkers = new QueueExecutorThread[threads]; + globalQueue = new PrioritizedTaskQueue<>(); + + for (int i = 0; i < threads; ++i) { + globalWorkers[i] = new QueueExecutorThread<>(globalQueue, (long)0.10e6); //0.1ms + globalWorkers[i].setName("Paper Async Chunk Task Thread #" + i); + globalWorkers[i].setPriority(Thread.NORM_PRIORITY - 1); + globalWorkers[i].setUncaughtExceptionHandler((final Thread thread, final Throwable throwable) -> { + PaperFileIOThread.LOGGER.fatal("Thread '" + thread.getName() + "' threw an uncaught exception!", throwable); + }); + + globalWorkers[i].start(); + } + } + + /** + * Creates this chunk task manager to operate off the specified number of threads. If the specified number of threads is + * less-than or equal to 0, then this chunk task manager will operate off of the world's chunk task queue. + * @param world Specified world. + * @param threads Specified number of threads. + * @see net.minecraft.server.ChunkProviderServer#serverThreadQueue + */ + public ChunkTaskManager(final WorldServer world, final int threads) { + this.world = world; + this.workers = threads <= 0 ? null : new QueueExecutorThread[threads]; + this.queue = new PrioritizedTaskQueue<>(); + this.perWorldQueue = true; + + for (int i = 0; i < threads; ++i) { + this.workers[i] = new QueueExecutorThread<>(this.queue, (long)0.10e6); //0.1ms + this.workers[i].setName("Async chunk loader thread #" + i + " for world: " + world.getWorldData().getName()); + this.workers[i].setPriority(Thread.NORM_PRIORITY - 1); + this.workers[i].setUncaughtExceptionHandler((final Thread thread, final Throwable throwable) -> { + PaperFileIOThread.LOGGER.fatal("Thread '" + thread.getName() + "' threw an uncaught exception!", throwable); + }); + + this.workers[i].start(); + } + } + + /** + * Creates the chunk task manager to work from the global workers. When {@link #close(boolean)} is invoked, + * the global queue is not shutdown. If the global workers is configured to be disabled or use 0 threads, then + * this chunk task manager will operate off of the world's chunk task queue. + * @param world The world that this task manager is responsible for + * @see net.minecraft.server.ChunkProviderServer#serverThreadQueue + */ + public ChunkTaskManager(final WorldServer world) { + this.world = world; + this.workers = globalWorkers; + this.queue = globalQueue; + this.perWorldQueue = false; + } + + public boolean pollNextChunkTask() { + final ChunkTask task = this.chunkTasks.poll(); + + if (task != null) { + task.run(); + return true; + } + return false; + } + + /** + * Polls and runs the next available chunk wait queue task. This is to be used when the server is waiting on a chunk queue. + * (per-world can cause issues if all the worker threads are blocked waiting for a response from the main thread) + */ + public static boolean pollChunkWaitQueue() { + final Runnable run = CHUNK_WAIT_QUEUE.poll(); + if (run != null) { + run.run(); + return true; + } + return false; + } + + /** + * Queues a chunk wait task. Note that this will execute out of order with respect to tasks scheduled on a world's + * chunk task queue, since this is the global chunk wait queue. + */ + public static void queueChunkWaitTask(final Runnable runnable) { + CHUNK_WAIT_QUEUE.add(runnable); + } + + private static void drainChunkWaitQueue() { + Runnable run; + while ((run = CHUNK_WAIT_QUEUE.poll()) != null) { + run.run(); + } + } + + /** + * The exact same as {@link #scheduleChunkLoad(int, int, int, Consumer, boolean)}, except that the chunk data is provided as + * the {@code data} parameter. + */ + public ChunkLoadTask scheduleChunkLoad(final int chunkX, final int chunkZ, final int priority, + final Consumer onComplete, + final boolean intendingToBlock, final CompletableFuture dataFuture) { + final WorldServer world = this.world; + + return this.chunkLoadTasks.compute(Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ)), (final Long keyInMap, final ChunkLoadTask valueInMap) -> { + if (valueInMap != null) { + if (!valueInMap.cancelled) { + throw new IllegalStateException("Double scheduling chunk load for task: " + valueInMap.toString()); + } + valueInMap.cancelled = false; + valueInMap.onComplete = onComplete; + return valueInMap; + } + + final ChunkLoadTask ret = new ChunkLoadTask(world, chunkX, chunkZ, priority, ChunkTaskManager.this, onComplete); + + dataFuture.thenAccept((final NBTTagCompound data) -> { + final boolean failed = data == PaperFileIOThread.FAILURE_VALUE; + PaperFileIOThread.Holder.INSTANCE.loadChunkDataAsync(world, chunkX, chunkZ, priority, (final PaperFileIOThread.ChunkData chunkData) -> { + ret.chunkData = chunkData; + if (!failed) { + chunkData.chunkData = data; + } + ChunkTaskManager.this.internalSchedule(ret); // only schedule to the worker threads here + }, true, failed, intendingToBlock); // read data off disk if the future fails + }); + + return ret; + }); + } + + public void cancelChunkLoad(final int chunkX, final int chunkZ) { + this.chunkLoadTasks.compute(IOUtil.getCoordinateKey(chunkX, chunkZ), (final Long keyInMap, final ChunkLoadTask valueInMap) -> { + if (valueInMap == null) { + return null; + } + + if (valueInMap.cancelled) { + PaperFileIOThread.LOGGER.warn("Task " + valueInMap.toString() + " is already cancelled!"); + } + valueInMap.cancelled = true; + if (valueInMap.cancel()) { + return null; + } + + return valueInMap; + }); + } + + /** + * Schedules an asynchronous chunk load for the specified coordinates. The onComplete parameter may be invoked asynchronously + * on a worker thread or on the world's chunk executor queue. As such the code that is executed for the parameter should be + * carefully chosen. + * @param chunkX Chunk's x coordinate + * @param chunkZ Chunk's z coordinate + * @param priority Priority for this task + * @param onComplete The consumer to invoke with the {@link net.minecraft.server.ChunkRegionLoader.InProgressChunkHolder} object once this task is complete + * @param intendingToBlock Whether the caller is intending to block on this task completing (this is a performance tune, and has no adverse side-effects) + * @return The {@link ChunkLoadTask} associated with + */ + public ChunkLoadTask scheduleChunkLoad(final int chunkX, final int chunkZ, final int priority, + final Consumer onComplete, + final boolean intendingToBlock) { + final WorldServer world = this.world; + + return this.chunkLoadTasks.compute(Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ)), (final Long keyInMap, final ChunkLoadTask valueInMap) -> { + if (valueInMap != null) { + if (!valueInMap.cancelled) { + throw new IllegalStateException("Double scheduling chunk load for task: " + valueInMap.toString()); + } + valueInMap.cancelled = false; + valueInMap.onComplete = onComplete; + return valueInMap; + } + + final ChunkLoadTask ret = new ChunkLoadTask(world, chunkX, chunkZ, priority, ChunkTaskManager.this, onComplete); + + PaperFileIOThread.Holder.INSTANCE.loadChunkDataAsync(world, chunkX, chunkZ, priority, (final PaperFileIOThread.ChunkData chunkData) -> { + ret.chunkData = chunkData; + ChunkTaskManager.this.internalSchedule(ret); // only schedule to the worker threads here + }, true, true, intendingToBlock); + + return ret; + }); + } + + /** + * Schedules an async save for the specified chunk. The chunk, at the beginning of this call, must be completely unloaded + * from the world. + * @param chunkX Chunk's x coordinate + * @param chunkZ Chunk's z coordinate + * @param priority Priority for this task + * @param asyncSaveData Async save data. See {@link ChunkRegionLoader#getAsyncSaveData(WorldServer, IChunkAccess)} + * @param chunk Chunk to save + * @return The {@link ChunkSaveTask} associated with the save task. + */ + public ChunkSaveTask scheduleChunkSave(final int chunkX, final int chunkZ, final int priority, + final ChunkRegionLoader.AsyncSaveData asyncSaveData, + final IChunkAccess chunk) { + AsyncCatcher.catchOp("chunk save schedule"); + + final WorldServer world = this.world; + + return this.chunkSaveTasks.compute(Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ)), (final Long keyInMap, final ChunkSaveTask valueInMap) -> { + if (valueInMap != null) { + throw new IllegalStateException("Double scheduling chunk save for task: " + valueInMap.toString()); + } + + final ChunkSaveTask ret = new ChunkSaveTask(world, chunkX, chunkZ, priority, ChunkTaskManager.this, asyncSaveData, chunk); + + ChunkTaskManager.this.internalSchedule(ret); + + return ret; + }); + } + + /** + * Returns a completable future which will be completed with the un-copied chunk data for an in progress async save. + * Returns {@code null} if no save is in progress. + * @param chunkX Chunk's x coordinate + * @param chunkZ Chunk's z coordinate + */ + public CompletableFuture getChunkSaveFuture(final int chunkX, final int chunkZ) { + final ChunkSaveTask chunkSaveTask = this.chunkSaveTasks.get(Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ))); + if (chunkSaveTask == null) { + return null; + } + return chunkSaveTask.onComplete; + } + + /** + * Returns the chunk object being used to serialize data async for an unloaded chunk. Note that modifying this chunk + * is not safe to do as another thread is handling its save. The chunk is also not loaded into the world. + * @param chunkX Chunk's x coordinate + * @param chunkZ Chunk's z coordinate + * @return Chunk object for an in-progress async save, or {@code null} if no save is in progress + */ + public IChunkAccess getChunkInSaveProgress(final int chunkX, final int chunkZ) { + final ChunkSaveTask chunkSaveTask = this.chunkSaveTasks.get(Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ))); + if (chunkSaveTask == null) { + return null; + } + return chunkSaveTask.chunk; + } + + public void flush() { + // flush here since we schedule tasks on the IO thread that can schedule tasks here + drainChunkWaitQueue(); + PaperFileIOThread.Holder.INSTANCE.flush(); + drainChunkWaitQueue(); + + if (this.workers == null) { + if (Bukkit.isPrimaryThread()) { + ((IAsyncTaskHandler)this.world.getChunkProvider().serverThreadQueue).executeAll(); + } else { + CompletableFuture wait = new CompletableFuture<>(); + MinecraftServer.getServer().scheduleOnMain(() -> { + ((IAsyncTaskHandler)this.world.getChunkProvider().serverThreadQueue).executeAll(); + }); + wait.join(); + } + } else { + for (final QueueExecutorThread worker : this.workers) { + worker.flush(); + } + } + + // flush again since tasks we execute async saves + drainChunkWaitQueue(); + PaperFileIOThread.Holder.INSTANCE.flush(); + } + + public void close(final boolean wait) { + // flush here since we schedule tasks on the IO thread that can schedule tasks to this task manager + // we do this regardless of the wait param since after we invoke close no tasks can be queued + PaperFileIOThread.Holder.INSTANCE.flush(); + + if (this.workers == null) { + if (wait) { + this.flush(); + } + return; + } + + if (this.workers != globalWorkers) { + for (final QueueExecutorThread worker : this.workers) { + worker.close(false, this.perWorldQueue); + } + } + + if (wait) { + this.flush(); + } + } + + public void raisePriority(final int chunkX, final int chunkZ, final int priority) { + final Long chunkKey = Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ)); + + ChunkSaveTask chunkSaveTask = this.chunkSaveTasks.get(chunkKey); + if (chunkSaveTask != null) { + final boolean raised = chunkSaveTask.raisePriority(priority); + if (chunkSaveTask.isScheduled() && raised) { + // only notify if we're in queue to be executed + this.internalScheduleNotify(); + } + } + + ChunkLoadTask chunkLoadTask = this.chunkLoadTasks.get(chunkKey); + if (chunkLoadTask != null) { + final boolean raised = chunkLoadTask.raisePriority(priority); + if (chunkLoadTask.isScheduled() && raised) { + // only notify if we're in queue to be executed + this.internalScheduleNotify(); + } + } + } + + protected void internalSchedule(final ChunkTask task) { + if (this.workers == null) { + this.chunkTasks.add(task); + return; + } + + // It's important we order the task to be executed before notifying. Avoid a race condition where the worker thread + // wakes up and goes to sleep before we actually schedule (or it's just about to sleep) + this.queue.add(task); + this.internalScheduleNotify(); + } + + protected void internalScheduleNotify() { + if (this.workers == null) { + return; + } + for (final QueueExecutorThread worker : this.workers) { + if (worker.notifyTasks()) { + // break here since we only want to wake up one worker for scheduling one task + break; + } + } + } + +} diff --git a/src/main/java/com/destroystokyo/paper/log/LogFullPolicy.java b/src/main/java/com/destroystokyo/paper/log/LogFullPolicy.java new file mode 100644 index 000000000..db652a1f7 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/log/LogFullPolicy.java @@ -0,0 +1,17 @@ +package com.destroystokyo.paper.log; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.async.AsyncQueueFullPolicy; +import org.apache.logging.log4j.core.async.EventRoute; + +public final class LogFullPolicy implements AsyncQueueFullPolicy { + + /* + * Prevents log calls being logged out of order when the log queue is full. + */ + + @Override + public EventRoute getRoute(final long backgroundThreadId, final Level level) { + return EventRoute.ENQUEUE; + } +} diff --git a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java index a7dbe11cb..b151a13c1 100644 --- a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java +++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java @@ -1,18 +1,17 @@ package com.destroystokyo.paper.profile; import com.destroystokyo.paper.PaperConfig; +import com.google.common.base.Charsets; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.PropertyMap; - -import net.minecraft.server.AkarinUserCache; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.UserCache; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.spigotmc.SpigotConfig; import javax.annotation.Nonnull; import javax.annotation.Nullable; - import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; @@ -144,9 +143,7 @@ public class CraftPlayerProfile implements PlayerProfile { } MinecraftServer server = MinecraftServer.getServer(); String name = profile.getName(); - // Akarin start - AkarinUserCache userCache = server.getModernUserCache(); - /* + UserCache userCache = server.getUserCache(); if (profile.getId() == null) { final GameProfile profile; boolean isOnlineMode = server.getOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode); @@ -168,24 +165,7 @@ public class CraftPlayerProfile implements PlayerProfile { this.profile = profile; } } - */ - - if (profile.getId() == null) { - if (lookupName) { - profile = userCache.acquire(name); - } else { - GameProfile peeked = userCache.peek(name); - - if (peeked != null) - profile = peeked; - } - } - - if (profile.getName() == null) - profile = userCache.acquire(name); - - return profile.isComplete(); - // Akarin end + return this.profile.isComplete(); } public boolean complete(boolean textures) { diff --git a/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java new file mode 100644 index 000000000..9ebd7ecb7 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java @@ -0,0 +1,253 @@ +package com.destroystokyo.paper.util; + +import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; +import net.minecraft.server.ChunkCoordIntPair; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.SectionPosition; +import org.spigotmc.AsyncCatcher; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** @author Spottedleaf */ +public final class PlayerMobDistanceMap { + + private static final PooledHashSets.PooledObjectLinkedOpenHashSet EMPTY_SET = new PooledHashSets.PooledObjectLinkedOpenHashSet<>(); + + private final Map players = new HashMap<>(); + // we use linked for better iteration. + private final Long2ObjectOpenHashMap> playerMap = new Long2ObjectOpenHashMap<>(32, 0.5f); + private int viewDistance; + + private final PooledHashSets pooledHashSets = new PooledHashSets<>(); + + public PooledHashSets.PooledObjectLinkedOpenHashSet getPlayersInRange(final ChunkCoordIntPair chunkPos) { + return this.getPlayersInRange(chunkPos.x, chunkPos.z); + } + + public PooledHashSets.PooledObjectLinkedOpenHashSet getPlayersInRange(final int chunkX, final int chunkZ) { + return this.playerMap.getOrDefault(ChunkCoordIntPair.pair(chunkX, chunkZ), EMPTY_SET); + } + + public void update(final List currentPlayers, final int newViewDistance) { + AsyncCatcher.catchOp("Distance map update"); + final ObjectLinkedOpenHashSet gone = new ObjectLinkedOpenHashSet<>(this.players.keySet()); + + final int oldViewDistance = this.viewDistance; + this.viewDistance = newViewDistance; + + for (final EntityPlayer player : currentPlayers) { + if (player.isSpectator() || !player.affectsSpawning) { + continue; // will be left in 'gone' (or not added at all) + } + + gone.remove(player); + + final SectionPosition newPosition = player.getPlayerMapSection(); + final SectionPosition oldPosition = this.players.put(player, newPosition); + + if (oldPosition == null) { + this.addNewPlayer(player, newPosition, newViewDistance); + } else { + this.updatePlayer(player, oldPosition, newPosition, oldViewDistance, newViewDistance); + } + //this.validatePlayer(player, newViewDistance); // debug only + } + + for (final EntityPlayer player : gone) { + final SectionPosition oldPosition = this.players.remove(player); + if (oldPosition != null) { + this.removePlayer(player, oldPosition, oldViewDistance); + } + } + } + + // expensive op, only for debug + private void validatePlayer(final EntityPlayer player, final int viewDistance) { + int entiesGot = 0; + int expectedEntries = (2 * viewDistance + 1); + expectedEntries *= expectedEntries; + + final SectionPosition currPosition = player.getPlayerMapSection(); + + final int centerX = currPosition.getX(); + final int centerZ = currPosition.getZ(); + + for (final Long2ObjectLinkedOpenHashMap.Entry> entry : this.playerMap.long2ObjectEntrySet()) { + final long key = entry.getLongKey(); + final PooledHashSets.PooledObjectLinkedOpenHashSet map = entry.getValue(); + + if (map.referenceCount == 0) { + throw new IllegalStateException("Invalid map"); + } + + if (map.set.contains(player)) { + ++entiesGot; + + final int chunkX = ChunkCoordIntPair.getX(key); + final int chunkZ = ChunkCoordIntPair.getZ(key); + + final int dist = Math.max(Math.abs(chunkX - centerX), Math.abs(chunkZ - centerZ)); + + if (dist > viewDistance) { + throw new IllegalStateException("Expected view distance " + viewDistance + ", got " + dist); + } + } + } + + if (entiesGot != expectedEntries) { + throw new IllegalStateException("Expected " + expectedEntries + ", got " + entiesGot); + } + } + + private void addPlayerTo(final EntityPlayer player, final int chunkX, final int chunkZ) { + this.playerMap.compute(ChunkCoordIntPair.pair(chunkX, chunkZ), (final Long key, final PooledHashSets.PooledObjectLinkedOpenHashSet players) -> { + if (players == null) { + return player.cachedSingleMobDistanceMap; + } else { + return PlayerMobDistanceMap.this.pooledHashSets.findMapWith(players, player); + } + }); + } + + private void removePlayerFrom(final EntityPlayer player, final int chunkX, final int chunkZ) { + this.playerMap.compute(ChunkCoordIntPair.pair(chunkX, chunkZ), (final Long keyInMap, final PooledHashSets.PooledObjectLinkedOpenHashSet players) -> { + return PlayerMobDistanceMap.this.pooledHashSets.findMapWithout(players, player); // rets null instead of an empty map + }); + } + + private void updatePlayer(final EntityPlayer player, final SectionPosition oldPosition, final SectionPosition newPosition, final int oldViewDistance, final int newViewDistance) { + final int toX = newPosition.getX(); + final int toZ = newPosition.getZ(); + final int fromX = oldPosition.getX(); + final int fromZ = oldPosition.getZ(); + + final int dx = toX - fromX; + final int dz = toZ - fromZ; + + final int totalX = Math.abs(fromX - toX); + final int totalZ = Math.abs(fromZ - toZ); + + if (Math.max(totalX, totalZ) > (2 * oldViewDistance)) { + // teleported? + this.removePlayer(player, oldPosition, oldViewDistance); + this.addNewPlayer(player, newPosition, newViewDistance); + return; + } + + // x axis is width + // z axis is height + // right refers to the x axis of where we moved + // top refers to the z axis of where we moved + + if (oldViewDistance == newViewDistance) { + // same view distance + + // used for relative positioning + final int up = 1 | (dz >> (Integer.SIZE - 1)); // 1 if dz >= 0, -1 otherwise + final int right = 1 | (dx >> (Integer.SIZE - 1)); // 1 if dx >= 0, -1 otherwise + + // The area excluded by overlapping the two view distance squares creates four rectangles: + // Two on the left, and two on the right. The ones on the left we consider the "removed" section + // and on the right the "added" section. + // https://i.imgur.com/MrnOBgI.png is a reference image. Note that the outside border is not actually + // exclusive to the regions they surround. + + // 4 points of the rectangle + int maxX; // exclusive + int minX; // inclusive + int maxZ; // exclusive + int minZ; // inclusive + + if (dx != 0) { + // handle right addition + + maxX = toX + (oldViewDistance * right) + right; // exclusive + minX = fromX + (oldViewDistance * right) + right; // inclusive + maxZ = fromZ + (oldViewDistance * up) + up; // exclusive + minZ = toZ - (oldViewDistance * up); // inclusive + + for (int currX = minX; currX != maxX; currX += right) { + for (int currZ = minZ; currZ != maxZ; currZ += up) { + this.addPlayerTo(player, currX, currZ); + } + } + } + + if (dz != 0) { + // handle up addition + + maxX = toX + (oldViewDistance * right) + right; // exclusive + minX = toX - (oldViewDistance * right); // inclusive + maxZ = toZ + (oldViewDistance * up) + up; // exclusive + minZ = fromZ + (oldViewDistance * up) + up; // inclusive + + for (int currX = minX; currX != maxX; currX += right) { + for (int currZ = minZ; currZ != maxZ; currZ += up) { + this.addPlayerTo(player, currX, currZ); + } + } + } + + if (dx != 0) { + // handle left removal + + maxX = toX - (oldViewDistance * right); // exclusive + minX = fromX - (oldViewDistance * right); // inclusive + maxZ = fromZ + (oldViewDistance * up) + up; // exclusive + minZ = toZ - (oldViewDistance * up); // inclusive + + for (int currX = minX; currX != maxX; currX += right) { + for (int currZ = minZ; currZ != maxZ; currZ += up) { + this.removePlayerFrom(player, currX, currZ); + } + } + } + + if (dz != 0) { + // handle down removal + + maxX = fromX + (oldViewDistance * right) + right; // exclusive + minX = fromX - (oldViewDistance * right); // inclusive + maxZ = toZ - (oldViewDistance * up); // exclusive + minZ = fromZ - (oldViewDistance * up); // inclusive + + for (int currX = minX; currX != maxX; currX += right) { + for (int currZ = minZ; currZ != maxZ; currZ += up) { + this.removePlayerFrom(player, currX, currZ); + } + } + } + } else { + // different view distance + // for now :) + this.removePlayer(player, oldPosition, oldViewDistance); + this.addNewPlayer(player, newPosition, newViewDistance); + } + } + + private void removePlayer(final EntityPlayer player, final SectionPosition position, final int viewDistance) { + final int x = position.getX(); + final int z = position.getZ(); + + for (int xoff = -viewDistance; xoff <= viewDistance; ++xoff) { + for (int zoff = -viewDistance; zoff <= viewDistance; ++zoff) { + this.removePlayerFrom(player, x + xoff, z + zoff); + } + } + } + + private void addNewPlayer(final EntityPlayer player, final SectionPosition position, final int viewDistance) { + final int x = position.getX(); + final int z = position.getZ(); + + for (int xoff = -viewDistance; xoff <= viewDistance; ++xoff) { + for (int zoff = -viewDistance; zoff <= viewDistance; ++zoff) { + this.addPlayerTo(player, x + xoff, z + zoff); + } + } + } +} diff --git a/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java b/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java new file mode 100644 index 000000000..4f13d3ff8 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/PooledHashSets.java @@ -0,0 +1,241 @@ +package com.destroystokyo.paper.util; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; +import java.lang.ref.WeakReference; +import java.util.Iterator; + +/** @author Spottedleaf */ +public class PooledHashSets { + + // we really want to avoid that equals() check as much as possible... + protected final Object2ObjectOpenHashMap, PooledObjectLinkedOpenHashSet> mapPool = new Object2ObjectOpenHashMap<>(64, 0.25f); + + protected void decrementReferenceCount(final PooledObjectLinkedOpenHashSet current) { + if (current.referenceCount == 0) { + throw new IllegalStateException("Cannot decrement reference count for " + current); + } + if (current.referenceCount == -1 || --current.referenceCount > 0) { + return; + } + + this.mapPool.remove(current); + return; + } + + public PooledObjectLinkedOpenHashSet findMapWith(final PooledObjectLinkedOpenHashSet current, final E object) { + final PooledObjectLinkedOpenHashSet cached = current.getAddCache(object); + + if (cached != null) { + if (cached.referenceCount != -1) { + ++cached.referenceCount; + } + + decrementReferenceCount(current); + + return cached; + } + + if (!current.add(object)) { + return current; + } + + // we use get/put since we use a different key on put + PooledObjectLinkedOpenHashSet ret = this.mapPool.get(current); + + if (ret == null) { + ret = new PooledObjectLinkedOpenHashSet<>(current); + current.remove(object); + this.mapPool.put(ret, ret); + ret.referenceCount = 1; + } else { + if (ret.referenceCount != -1) { + ++ret.referenceCount; + } + current.remove(object); + } + + current.updateAddCache(object, ret); + + decrementReferenceCount(current); + return ret; + } + + // rets null if current.size() == 1 + public PooledObjectLinkedOpenHashSet findMapWithout(final PooledObjectLinkedOpenHashSet current, final E object) { + if (current.set.size() == 1) { + decrementReferenceCount(current); + return null; + } + + final PooledObjectLinkedOpenHashSet cached = current.getRemoveCache(object); + + if (cached != null) { + if (cached.referenceCount != -1) { + ++cached.referenceCount; + } + + decrementReferenceCount(current); + + return cached; + } + + if (!current.remove(object)) { + return current; + } + + // we use get/put since we use a different key on put + PooledObjectLinkedOpenHashSet ret = this.mapPool.get(current); + + if (ret == null) { + ret = new PooledObjectLinkedOpenHashSet<>(current); + current.add(object); + this.mapPool.put(ret, ret); + ret.referenceCount = 1; + } else { + if (ret.referenceCount != -1) { + ++ret.referenceCount; + } + current.add(object); + } + + current.updateRemoveCache(object, ret); + + decrementReferenceCount(current); + return ret; + } + + public static final class PooledObjectLinkedOpenHashSet implements Iterable { + + private static final WeakReference NULL_REFERENCE = new WeakReference(null); + + final ObjectLinkedOpenHashSet set; + int referenceCount; // -1 if special + int hash; // optimize hashcode + + // add cache + WeakReference lastAddObject = NULL_REFERENCE; + WeakReference> lastAddMap = NULL_REFERENCE; + + // remove cache + WeakReference lastRemoveObject = NULL_REFERENCE; + WeakReference> lastRemoveMap = NULL_REFERENCE; + + public PooledObjectLinkedOpenHashSet() { + this.set = new ObjectLinkedOpenHashSet<>(2, 0.6f); + } + + public PooledObjectLinkedOpenHashSet(final E single) { + this(); + this.referenceCount = -1; + this.add(single); + } + + public PooledObjectLinkedOpenHashSet(final PooledObjectLinkedOpenHashSet other) { + this.set = other.set.clone(); + this.hash = other.hash; + } + + // from https://github.com/Spottedleaf/ConcurrentUtil/blob/master/src/main/java/ca/spottedleaf/concurrentutil/util/IntegerUtil.java + // generated by https://github.com/skeeto/hash-prospector + static int hash0(int x) { + x *= 0x36935555; + x ^= x >>> 16; + return x; + } + + public PooledObjectLinkedOpenHashSet getAddCache(final E element) { + final E currentAdd = this.lastAddObject.get(); + + if (currentAdd == null || !(currentAdd == element || currentAdd.equals(element))) { + return null; + } + + final PooledObjectLinkedOpenHashSet map = this.lastAddMap.get(); + if (map == null || map.referenceCount == 0) { + // we need to ret null if ref count is zero as calling code will assume the map is in use + return null; + } + + return map; + } + + public PooledObjectLinkedOpenHashSet getRemoveCache(final E element) { + final E currentRemove = this.lastRemoveObject.get(); + + if (currentRemove == null || !(currentRemove == element || currentRemove.equals(element))) { + return null; + } + + final PooledObjectLinkedOpenHashSet map = this.lastRemoveMap.get(); + if (map == null || map.referenceCount == 0) { + // we need to ret null if ref count is zero as calling code will assume the map is in use + return null; + } + + return map; + } + + public void updateAddCache(final E element, final PooledObjectLinkedOpenHashSet map) { + this.lastAddObject = new WeakReference<>(element); + this.lastAddMap = new WeakReference<>(map); + } + + public void updateRemoveCache(final E element, final PooledObjectLinkedOpenHashSet map) { + this.lastRemoveObject = new WeakReference<>(element); + this.lastRemoveMap = new WeakReference<>(map); + } + + boolean add(final E element) { + boolean added = this.set.add(element); + + if (added) { + this.hash += hash0(element.hashCode()); + } + + return added; + } + + boolean remove(Object element) { + boolean removed = this.set.remove(element); + + if (removed) { + this.hash -= hash0(element.hashCode()); + } + + return removed; + } + + @Override + public Iterator iterator() { + return this.set.iterator(); + } + + @Override + public int hashCode() { + return this.hash; + } + + @Override + public boolean equals(final Object other) { + if (!(other instanceof PooledObjectLinkedOpenHashSet)) { + return false; + } + if (this.referenceCount == 0) { + return other == this; + } else { + if (other == this) { + // Unfortunately we are never equal to our own instance while in use! + return false; + } + return this.hash == ((PooledObjectLinkedOpenHashSet)other).hash && this.set.equals(((PooledObjectLinkedOpenHashSet)other).set); + } + } + + @Override + public String toString() { + return "PooledHashSet: size: " + this.set.size() + ", reference count: " + this.referenceCount + ", hash: " + + this.hashCode() + ", identity: " + System.identityHashCode(this) + " map: " + this.set.toString(); + } + } +} diff --git a/src/main/java/com/destroystokyo/paper/util/PriorityQueuedExecutor.java b/src/main/java/com/destroystokyo/paper/util/PriorityQueuedExecutor.java deleted file mode 100644 index 8f18c2869..000000000 --- a/src/main/java/com/destroystokyo/paper/util/PriorityQueuedExecutor.java +++ /dev/null @@ -1,347 +0,0 @@ -package com.destroystokyo.paper.util; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.AbstractExecutorService; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Supplier; - -/** - * Implements an Executor Service that allows specifying Task Priority - * and bumping of task priority. - * - * This is a non blocking executor with 3 priority levels. - * - * URGENT: Rarely used, something that is critical to take action now. - * HIGH: Something with more importance than the base tasks - * - * @author Daniel Ennis <aikar@aikar.co> - */ -@SuppressWarnings({"WeakerAccess", "UnusedReturnValue", "unused"}) -public class PriorityQueuedExecutor extends AbstractExecutorService { - - private final ConcurrentLinkedQueue urgent = new ConcurrentLinkedQueue<>(); - private final ConcurrentLinkedQueue high = new ConcurrentLinkedQueue<>(); - private final ConcurrentLinkedQueue normal = new ConcurrentLinkedQueue<>(); - private final List threads = new ArrayList<>(); - private final RejectionHandler handler; - - private volatile boolean shuttingDown = false; - private volatile boolean shuttingDownNow = false; - - public PriorityQueuedExecutor(String name) { - this(name, Math.max(1, Runtime.getRuntime().availableProcessors() - 1)); - } - - public PriorityQueuedExecutor(String name, int threads) { - this(name, threads, Thread.NORM_PRIORITY, null); - } - - public PriorityQueuedExecutor(String name, int threads, int threadPriority) { - this(name, threads, threadPriority, null); - } - - public PriorityQueuedExecutor(String name, int threads, RejectionHandler handler) { - this(name, threads, Thread.NORM_PRIORITY, handler); - } - - public PriorityQueuedExecutor(String name, int threads, int threadPriority, RejectionHandler handler) { - for (int i = 0; i < threads; i++) { - ExecutorThread thread = new ExecutorThread(this::processQueues); - thread.setDaemon(true); - thread.setName(threads == 1 ? name : name + "-" + (i + 1)); - thread.setPriority(threadPriority); - thread.start(); - this.threads.add(thread); - } - if (handler == null) { - handler = ABORT_POLICY; - } - this.handler = handler; - } - - /** - * If the Current thread belongs to a PriorityQueuedExecutor, return that Executro - * @return The executor that controls this thread - */ - public static PriorityQueuedExecutor getExecutor() { - if (!(Thread.currentThread() instanceof ExecutorThread)) { - return null; - } - return ((ExecutorThread) Thread.currentThread()).getExecutor(); - } - - public void shutdown() { - shuttingDown = true; - synchronized (this) { - this.notifyAll(); - } - } - - @Nonnull - @Override - public List shutdownNow() { - shuttingDown = true; - shuttingDownNow = true; - List tasks = new ArrayList<>(high.size() + normal.size()); - Runnable run; - while ((run = getTask()) != null) { - tasks.add(run); - } - - return tasks; - } - - @Override - public boolean isShutdown() { - return shuttingDown; - } - - @Override - public boolean isTerminated() { - if (!shuttingDown) { - return false; - } - return high.isEmpty() && normal.isEmpty(); - } - - @Override - public boolean awaitTermination(long timeout, @Nonnull TimeUnit unit) { - synchronized (this) { - this.notifyAll(); - } - final long wait = unit.toNanos(timeout); - final long max = System.nanoTime() + wait; - for (;!threads.isEmpty() && System.nanoTime() < max;) { - threads.removeIf(thread -> !thread.isAlive()); - } - return isTerminated(); - } - - - public PendingTask createPendingTask(Runnable task) { - return createPendingTask(task, Priority.NORMAL); - } - public PendingTask createPendingTask(Runnable task, Priority priority) { - return createPendingTask(() -> { - task.run(); - return null; - }, priority); - } - - public PendingTask createPendingTask(Supplier task) { - return createPendingTask(task, Priority.NORMAL); - } - - public PendingTask createPendingTask(Supplier task, Priority priority) { - return new PendingTask<>(task, priority); - } - - public PendingTask submitTask(Runnable run) { - return createPendingTask(run).submit(); - } - - public PendingTask submitTask(Runnable run, Priority priority) { - return createPendingTask(run, priority).submit(); - } - - public PendingTask submitTask(Supplier run) { - return createPendingTask(run).submit(); - } - - public PendingTask submitTask(Supplier run, Priority priority) { - PendingTask task = createPendingTask(run, priority); - return task.submit(); - } - - @Override - public void execute(@Nonnull Runnable command) { - submitTask(command); - } - - public boolean isCurrentThread() { - final Thread thread = Thread.currentThread(); - if (!(thread instanceof ExecutorThread)) { - return false; - } - return ((ExecutorThread) thread).getExecutor() == this; - } - - public Runnable getUrgentTask() { - return urgent.poll(); - } - - public Runnable getTask() { - Runnable run = urgent.poll(); - if (run != null) { - return run; - } - run = high.poll(); - if (run != null) { - return run; - } - return normal.poll(); - } - - private void processQueues() { - Runnable run = null; - while (true) { - if (run != null) { - run.run(); - } - if (shuttingDownNow) { - return; - } - if ((run = getTask()) != null) { - continue; - } - synchronized (PriorityQueuedExecutor.this) { - if ((run = getTask()) != null) { - continue; - } - - if (shuttingDown || shuttingDownNow) { - return; - } - try { - PriorityQueuedExecutor.this.wait(); - } catch (InterruptedException ignored) { - } - } - } - } - - public boolean processUrgentTasks() { - Runnable run; - boolean hadTask = false; - while ((run = getUrgentTask()) != null) { - run.run(); - hadTask = true; - } - return hadTask; - } - - public enum Priority { - NORMAL, HIGH, URGENT - } - - public class ExecutorThread extends Thread { - public ExecutorThread(Runnable runnable) { - super(runnable); - } - - public PriorityQueuedExecutor getExecutor() { - return PriorityQueuedExecutor.this; - } - } - - public class PendingTask implements Runnable { - - private final AtomicBoolean hasRan = new AtomicBoolean(); - private final AtomicInteger submitted = new AtomicInteger(-1); - private final AtomicInteger priority; - private final Supplier run; - private final CompletableFuture future = new CompletableFuture<>(); - private volatile PriorityQueuedExecutor executor; - - public PendingTask(Supplier run) { - this(run, Priority.NORMAL); - } - - public PendingTask(Supplier run, Priority priority) { - this.priority = new AtomicInteger(priority.ordinal()); - this.run = run; - } - - public boolean cancel() { - return hasRan.compareAndSet(false, true); - } - - @Override - public void run() { - if (!hasRan.compareAndSet(false, true)) { - return; - } - - try { - future.complete(run.get()); - } catch (Throwable e) { - future.completeExceptionally(e); - } - } - - public void bumpPriority() { - bumpPriority(Priority.HIGH); - } - - public void bumpPriority(Priority newPriority) { - for (;;) { - int current = this.priority.get(); - int ordinal = newPriority.ordinal(); - if (current >= ordinal || priority.compareAndSet(current, ordinal)) { - break; - } - } - - - if (this.submitted.get() == -1 || this.hasRan.get()) { - return; - } - - // Only resubmit if it hasnt ran yet and has been submitted - submit(); - } - - public CompletableFuture onDone() { - return future; - } - - public PendingTask submit() { - if (shuttingDown) { - handler.onRejection(this, PriorityQueuedExecutor.this); - return this; - } - for (;;) { - final int submitted = this.submitted.get(); - final int priority = this.priority.get(); - if (submitted == priority) { - return this; - } - if (this.submitted.compareAndSet(submitted, priority)) { - if (priority == Priority.URGENT.ordinal()) { - urgent.add(this); - } else if (priority == Priority.HIGH.ordinal()) { - high.add(this); - } else { - normal.add(this); - } - - break; - } - } - - synchronized (PriorityQueuedExecutor.this) { - // Wake up a thread to take this work - PriorityQueuedExecutor.this.notify(); - } - return this; - } - } - public interface RejectionHandler { - void onRejection(Runnable run, PriorityQueuedExecutor executor); - } - - public static final RejectionHandler ABORT_POLICY = (run, executor) -> { - throw new RejectedExecutionException("Executor has been shutdown"); - }; - public static final RejectionHandler CALLER_RUNS_POLICY = (run, executor) -> { - run.run(); - }; - -} diff --git a/src/main/java/com/destroystokyo/paper/util/RedstoneWireTurbo.java b/src/main/java/com/destroystokyo/paper/util/RedstoneWireTurbo.java index 4b3d62ab8..cf5661f1c 100644 --- a/src/main/java/com/destroystokyo/paper/util/RedstoneWireTurbo.java +++ b/src/main/java/com/destroystokyo/paper/util/RedstoneWireTurbo.java @@ -13,6 +13,8 @@ import net.minecraft.server.Block; import net.minecraft.server.BlockPosition; import net.minecraft.server.BlockRedstoneWire; import net.minecraft.server.IBlockData; +import net.minecraft.server.Items; +import net.minecraft.server.ItemStack; import net.minecraft.server.World; /** @@ -320,7 +322,7 @@ public class RedstoneWireTurbo { // be replicated here. if (!wire.canPlace(null, worldIn, pos)) { // Pop off the redstone dust - oldState.dropNaturally(worldIn, pos, 0); + Block.a(worldIn, pos, new ItemStack(Items.REDSTONE)); // TODO worldIn.setAir(pos); // Mark this position as not being redstone wire @@ -843,7 +845,7 @@ public class RedstoneWireTurbo { // position directly above the node being calculated is always // at index 1. UpdateNode center_up = upd.neighbor_nodes[1]; - boolean center_up_is_cube = center_up.currentState.isOccluding(); + boolean center_up_is_cube = center_up.currentState.isOccluding(worldIn, center_up.self); // TODO for (int m = 0; m < 4; m++) { // Get the neighbor array index of each of the four cardinal @@ -857,7 +859,7 @@ public class RedstoneWireTurbo { // Also check the positions above and below the cardinal // neighbors - boolean neighbor_is_cube = neighbor.currentState.isOccluding(); + boolean neighbor_is_cube = neighbor.currentState.isOccluding(worldIn, neighbor.self); // TODO if (!neighbor_is_cube) { UpdateNode neighbor_down = upd.neighbor_nodes[rs_neighbors_dn[m]]; l = getMaxCurrentStrength(neighbor_down, l); @@ -881,7 +883,7 @@ public class RedstoneWireTurbo { // egg82's amendment // Adding Bukkit's BlockRedstoneEvent - er.. event. if (i != j) { - BlockRedstoneEvent event = new BlockRedstoneEvent(worldIn.getWorld().getBlockAt(upd.self), i, j); // Akarin + BlockRedstoneEvent event = new BlockRedstoneEvent(worldIn.getWorld().getBlockAt(upd.self.getX(), upd.self.getY(), upd.self.getZ()), i, j); worldIn.getServer().getPluginManager().callEvent(event); j = event.getNewCurrent(); } diff --git a/src/main/java/com/destroystokyo/paper/util/ReentrantLockWithGetOwner.java b/src/main/java/com/destroystokyo/paper/util/ReentrantLockWithGetOwner.java new file mode 100644 index 000000000..a3b174618 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/ReentrantLockWithGetOwner.java @@ -0,0 +1,11 @@ +package com.destroystokyo.paper.util; + +import java.util.concurrent.locks.ReentrantLock; + +public class ReentrantLockWithGetOwner extends ReentrantLock { + + @Override + public Thread getOwner() { + return super.getOwner(); + } +} diff --git a/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java b/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java index 370c8716d..23f1447cf 100644 --- a/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java +++ b/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java @@ -18,10 +18,7 @@ import java.util.Set; public class YggdrasilGameProfileRepository implements GameProfileRepository { private static final Logger LOGGER = LogManager.getLogger(); - // Akarin Start - //private static final String BASE_URL = "https://api.mojang.com/"; - private static final String BASE_URL = io.akarin.server.core.AkarinGlobalConfig.yggdrasilServerURL; //Akarin - // Akarin End + private static final String BASE_URL = "https://api.mojang.com/"; private static final String SEARCH_PAGE_URL = BASE_URL + "profiles/"; private static final int ENTRIES_PER_PAGE = 2; private static final int MAX_FAIL_COUNT = 3; diff --git a/src/main/java/io/akarin/server/api/structure/CraftVillage.java b/src/main/java/io/akarin/server/api/structure/CraftVillage.java deleted file mode 100644 index 121e77e28..000000000 --- a/src/main/java/io/akarin/server/api/structure/CraftVillage.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.akarin.server.api.structure; - -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class CraftVillage implements Village { - private final net.minecraft.server.Village village; - - public Village getHandle() { - return (Village) village; - } - - @Override - public String toString() { - return "CraftVillage"; - } -} diff --git a/src/main/java/io/akarin/server/core/AkarinAsyncExecutor.java b/src/main/java/io/akarin/server/core/AkarinAsyncExecutor.java deleted file mode 100644 index 386919e27..000000000 --- a/src/main/java/io/akarin/server/core/AkarinAsyncExecutor.java +++ /dev/null @@ -1,61 +0,0 @@ -package io.akarin.server.core; - -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import com.google.common.util.concurrent.ThreadFactoryBuilder; - -import co.aikar.timings.ThreadAssertion; - -public class AkarinAsyncExecutor { - private static final ExecutorService singleExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Akarin Single Async Executor Thread - %1$d").build()); - private static final ExecutorService asyncExecutor = Executors.newFixedThreadPool(getNThreads(), new ThreadFactoryBuilder().setNameFormat("Akarin Async Executor Thread - %1$d").build()); - - private static int getNThreads() { - int processors = Runtime.getRuntime().availableProcessors() / 2; - if (processors < 2) - return 2; - if (processors > 8) - return 8; - return processors; - } - - /** - * Posts a task to be executed asynchronously in a single thread - * @param run - */ - public static void scheduleSingleAsyncTask(Runnable run) { - ThreadAssertion.close(); - singleExecutor.execute(run); - } - - /** - * Posts a task to be executed asynchronously - * @param run - */ - public static void scheduleAsyncTask(Runnable run) { - ThreadAssertion.close(); - asyncExecutor.execute(run); - } - - /** - * Posts a task to be executed asynchronously in a single thread - * @param run - * @return - */ - public static Future scheduleSingleAsyncTask(Callable run) { - ThreadAssertion.close(); - return singleExecutor.submit(run); - } - - /** - * Posts a task to be executed asynchronously - * @param run - */ - public static Future scheduleAsyncTask(Callable run) { - ThreadAssertion.close(); - return asyncExecutor.submit(run); - } -} \ No newline at end of file diff --git a/src/main/java/io/akarin/server/core/AkarinAsyncScheduler.java b/src/main/java/io/akarin/server/core/AkarinAsyncScheduler.java deleted file mode 100644 index 253eb85e3..000000000 --- a/src/main/java/io/akarin/server/core/AkarinAsyncScheduler.java +++ /dev/null @@ -1,129 +0,0 @@ -package io.akarin.server.core; - -import java.util.List; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; - -import net.minecraft.server.EntityHuman; -import net.minecraft.server.EntityPlayer; -import net.minecraft.server.EnumDifficulty; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.NetworkManager; -import net.minecraft.server.PacketPlayOutPlayerInfo; -import net.minecraft.server.PacketPlayOutUpdateTime; -import net.minecraft.server.WorldServer; - -public class AkarinAsyncScheduler extends Thread { - private final static Logger LOGGER = LogManager.getLogger("Akarin"); - private final static int STD_TICK_TIME = 50; - - public static AkarinAsyncScheduler initalise() { - return Singleton.instance; - } - - private static class Singleton { - private static final AkarinAsyncScheduler instance; - - static { - instance = new AkarinAsyncScheduler(); - instance.setName("Akarin Async Scheduler Thread"); - instance.setDaemon(true); - instance.setPriority(MIN_PRIORITY); - instance.start(); - LOGGER.info("Async executor started"); - } - } - - private int playerListTick; - - @Override - public void run() { - MinecraftServer server = MinecraftServer.getServer(); - - while (server.isRunning()) { - long currentLoop = System.currentTimeMillis(); - - // Send pending chunk packets - List networkManagers = server.getServerConnection().getNetworkManagers(); - if (!networkManagers.isEmpty()) { - synchronized (networkManagers) { - for (NetworkManager player : networkManagers) - player.sendPacketQueue(); - } - } - - for (WorldServer world : server.getWorlds()) { - // Send time updates to everyone, it will get the right time from the world the player is in. - boolean doDaylight = world.getGameRules().getBoolean("doDaylightCycle"); - long dayTime = world.getDayTime(); - long worldTime = world.getTime(); - final PacketPlayOutUpdateTime worldPacket = new PacketPlayOutUpdateTime(worldTime, dayTime, doDaylight); - for (EntityHuman entityhuman : world.players) { - if (!(entityhuman instanceof EntityPlayer) || (server.currentTick() + entityhuman.getId()) % 20 != 0) { - continue; - } - EntityPlayer entityplayer = (EntityPlayer) entityhuman; - long playerTime = entityplayer.getPlayerTime(); - PacketPlayOutUpdateTime packet = (playerTime == dayTime) ? worldPacket : - new PacketPlayOutUpdateTime(worldTime, playerTime, doDaylight); - entityplayer.playerConnection.sendPacket(packet); // Add support for per player time - } - - // Hardcore difficulty lock - if (world.getWorldData().isHardcore() && world.getDifficulty() != EnumDifficulty.HARD) { - world.getWorldData().setDifficulty(EnumDifficulty.HARD); - } - - // Sleeping time management - if (world.everyoneDeeplySleeping()) { - if (world.getGameRules().getBoolean("doDaylightCycle")) { - long i = world.worldData.getDayTime() + 24000L; - - world.worldData.setDayTime(i - i % 24000L); - } - - if (world.getGameRules().getBoolean("doWeatherCycle")) { - world.clearWeather(); - } - } - - // Random light updates - world.randomLightUpdates(); - } - - // Send player latency update packets - if (++playerListTick > 600) { - List players = server.getPlayerList().players; - for (EntityPlayer target : players) { - target.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_LATENCY, Iterables.filter(players, new Predicate() { - @Override - public boolean apply(EntityPlayer input) { - return target.getBukkitEntity().canSee(input.getBukkitEntity()); - } - }))); - } - playerListTick = 0; - } - - // Save players data - int playerSaveInterval = com.destroystokyo.paper.PaperConfig.playerAutoSaveRate; - if (playerSaveInterval < 0) { - playerSaveInterval = server.autosavePeriod; - } - if (playerSaveInterval > 0) { - server.getPlayerList().savePlayers(playerSaveInterval); - } - - try { - long sleepFixed = STD_TICK_TIME - (System.currentTimeMillis() - currentLoop); - if (sleepFixed > 0) Thread.sleep(sleepFixed); - } catch (InterruptedException interrupted) { - continue; - } - } - } -} \ No newline at end of file diff --git a/src/main/java/io/akarin/server/core/AkarinCreatureSpanwner.java b/src/main/java/io/akarin/server/core/AkarinCreatureSpanwner.java deleted file mode 100644 index c2acc5554..000000000 --- a/src/main/java/io/akarin/server/core/AkarinCreatureSpanwner.java +++ /dev/null @@ -1,275 +0,0 @@ -package io.akarin.server.core; - -import java.util.EnumMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.ThreadLocalRandom; - -import javax.annotation.Nullable; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; - -import com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent; -import com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent; -import com.destroystokyo.paper.exception.ServerInternalException; -import com.google.common.collect.Maps; -import com.koloboke.collect.set.hash.HashObjSets; - -import io.akarin.server.misc.ChunkCoordOrdinalInt3Tuple; -import net.minecraft.server.BiomeBase; -import net.minecraft.server.BlockPosition; -import net.minecraft.server.ChunkCoordIntPair; -import net.minecraft.server.EntityHuman; -import net.minecraft.server.EntityInsentient; -import net.minecraft.server.EntityPositionTypes; -import net.minecraft.server.EntityTypes; -import net.minecraft.server.EnumCreatureType; -import net.minecraft.server.GroupDataEntity; -import net.minecraft.server.MCUtil; -import net.minecraft.server.MathHelper; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.SpawnerCreature; -import net.minecraft.server.WorldServer; - -/* - * Reference on spawning mechanics by Colin Godsey - * https://github.com/yesdog/Paper/blob/0de3dd84b7e6688feb42af4fe6b4f323ce7e3013/Spigot-Server-Patches/0433-alternate-mob-spawning-mechanic.patch - */ -public class AkarinCreatureSpanwner { - private static final Map rangeChunks = Maps.newConcurrentMap(); - - public static void increment(ChunkCoordIntPair chunk, EnumCreatureType type) { - int[] values = rangeChunks.get(chunk); - if (values == null) { - values = new int[EnumCreatureType.values().length];; - values[type.ordinal()]++; - rangeChunks.put(chunk, values); - } else { - values[type.ordinal()]++; - } - } - - public static void decrement(ChunkCoordIntPair chunk, EnumCreatureType type) { - int[] values = rangeChunks.get(chunk); - if (values == null) { - values = new int[EnumCreatureType.values().length];; - int count = values[type.ordinal()]; - values[type.ordinal()] = count > 1 ? --count : 0; - rangeChunks.put(chunk, values); - } else { - int count = values[type.ordinal()]; - values[type.ordinal()] = count > 1 ? --count : 0; - } - } - - private static int getSpawnRange(WorldServer world, EntityHuman player) { - byte mobSpawnRange = world.spigotConfig.mobSpawnRange; - - mobSpawnRange = (mobSpawnRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : mobSpawnRange; - mobSpawnRange = (mobSpawnRange > 8) ? 8 : mobSpawnRange; - - if (PlayerNaturallySpawnCreaturesEvent.getHandlerList().getRegisteredListeners().length != 0) { - PlayerNaturallySpawnCreaturesEvent event = new PlayerNaturallySpawnCreaturesEvent((Player) player.getBukkitEntity(), mobSpawnRange); - // prevent concurrent handling, at least - synchronized (PlayerNaturallySpawnCreaturesEvent.class) { - Bukkit.getPluginManager().callEvent(event); - } - - return event.isCancelled() ? 0 : event.getSpawnRadius(); - } - - return mobSpawnRange; - } - - private static int getCreatureLimit(WorldServer world, EnumCreatureType type) { - switch (type) { - case MONSTER: - return world.getWorld().getMonsterSpawnLimit(); - case CREATURE: - return world.getWorld().getAnimalSpawnLimit(); - case WATER_CREATURE: - return world.getWorld().getWaterAnimalSpawnLimit(); - case AMBIENT: - return world.getWorld().getAmbientSpawnLimit(); - } - return type.spawnLimit(); - } - - @Nullable - private static EntityInsentient createMob(WorldServer world, EnumCreatureType type, BlockPosition pos, BiomeBase.BiomeMeta biomeMeta) { - if (!world.isBiomeMetaValidAt(type, biomeMeta, pos)) return null; - - EntityTypes entityType = biomeMeta.entityType(); - org.bukkit.entity.EntityType bType = EntityTypes.clsToTypeMap.get(entityType.entityClass()); - if (bType != null) { - PreCreatureSpawnEvent event = new PreCreatureSpawnEvent( - MCUtil.toLocation(world, pos), - bType, SpawnReason.NATURAL - ); - - if (!event.callEvent() || event.shouldAbortSpawn()) - return null; - } - - EntityInsentient entity = null; - - try { - entity = entityType.create(world); - } catch (Exception exception) { - MinecraftServer.LOGGER.warn("Failed to create mob", exception); - ServerInternalException.reportInternalException(exception); - } - - return entity; - } - - private static void spawnMob0(WorldServer world, Set chunks, EnumCreatureType type, int amount) { - if (chunks.isEmpty()) return; - - Random rand = ThreadLocalRandom.current(); - final int maxPackIterations = 10; // X attempts per pack, 1 pack per chunk - Iterator iterator = chunks.iterator(); - BlockPosition worldSpawn = world.getSpawn(); - - int spawned = 0; - - while (spawned < amount && iterator.hasNext()) { - ChunkCoordIntPair chunkCoord = iterator.next(); - int packSize = rand.nextInt(4) + 1; - BlockPosition packCenter = SpawnerCreature.getRandomPosition(world, chunkCoord.x, chunkCoord.z); - - if (world.getType(packCenter).isOccluding()) continue; - - int x = packCenter.getX(); - int y = packCenter.getY(); - int z = packCenter.getZ(); - BlockPosition.MutableBlockPosition blockPointer = new BlockPosition.MutableBlockPosition(); - BiomeBase.BiomeMeta biomeMeta = null; - GroupDataEntity group = null; - EntityPositionTypes.Surface surfaceType = null; - int iter = 0; - int packSpawned = 0; - - while (packSpawned < packSize && iter < maxPackIterations) { - iter++; - - // random walk - x += rand.nextInt(12) - 6; - y += rand.nextInt(2) - 1; - z += rand.nextInt(12) - 6; - blockPointer.setValues(x, y, z); - - if (worldSpawn.distanceSquared(x + 0.5, y, z + 0.5) < (24 * 24)) continue; - - if (biomeMeta == null) { - biomeMeta = world.getBiomeMetaAt(type, blockPointer); - - if (biomeMeta == null) break; - - int packRange = 1 + biomeMeta.getMaxPackSize() - biomeMeta.getMinPackSize(); - packSize = biomeMeta.getMinPackSize() + rand.nextInt(packRange); - surfaceType = EntityPositionTypes.a(biomeMeta.entityType()); - } - - EntityInsentient entity = createMob(world, type, blockPointer, biomeMeta); - - if (entity == null) continue; - - entity.setPositionRotation(x + 0.5, y, z + 0.5, rand.nextFloat() * 360.0F, 0.0F); - - if (entity.canSpawnHere() && surfaceType != null - && SpawnerCreature.isValidSpawnSurface(surfaceType, world, blockPointer, biomeMeta.entityType()) - && entity.isNotColliding(world) && !world.isPlayerNearby(x + 0.5, y, z + 0.5, 24)) { - group = entity.prepare(world.getDamageScaler(new BlockPosition(entity)), group, null); - - if (entity.isNotColliding(world) && world.addEntity(entity, SpawnReason.NATURAL)) - packSpawned++; - - if (packSpawned >= entity.maxPackSize()) break; - if ((packSpawned + spawned) >= amount) break; - } else { - entity.die(); - } - } - - spawned += packSpawned; - } - } - - public static void spawnMobs(WorldServer world, boolean spawnMonsters, boolean spawnPassives, boolean spawnRare) { - if(!spawnMonsters && !spawnPassives) return; - - AkarinAsyncExecutor.scheduleAsyncTask(() -> { - Random rand = ThreadLocalRandom.current(); - int hashOrdinal = rand.nextInt(); - - //Set rangeChunks = HashObjSets.newUpdatableSet(); - Map> creatureChunks = new EnumMap<>(EnumCreatureType.class); - int[] typeNumSpawn = new int[EnumCreatureType.values().length]; - - for (EnumCreatureType type : EnumCreatureType.values()) { - if (type.passive() && !spawnPassives) continue; - if (!type.passive() && !spawnMonsters) continue; - if (type.rare() && !spawnRare) continue; - if (getCreatureLimit(world, type) <= 0) continue; - - creatureChunks.put(type, HashObjSets.newUpdatableSet()); - } - - if (creatureChunks.isEmpty()) return; - - for (EntityHuman player : world.players) { - if (!player.affectsSpawning || player.isSpectator()) continue; - - int spawnRange = getSpawnRange(world, player); - if (spawnRange <= 0) continue; - - int playerChunkX = MathHelper.floor(player.locX / 16.0); - int playerChunkZ = MathHelper.floor(player.locZ / 16.0); - - rangeChunks.clear(); - - for (int dX = -spawnRange; dX <= spawnRange; ++dX) { - for (int dZ = -spawnRange; dZ <= spawnRange; ++dZ) { - ChunkCoordIntPair chunkCoord = new ChunkCoordOrdinalInt3Tuple(dX + playerChunkX, dZ + playerChunkZ, hashOrdinal); - - if (!world.getWorldBorder().isInBounds(chunkCoord)) continue; - - ChunkCoordIntPair pair = new ChunkCoordIntPair(chunkCoord.x, chunkCoord.z); - int[] cached = rangeChunks.get(pair); - if (cached == null) - rangeChunks.put(pair, new int[EnumCreatureType.values().length]); - else - for (int i = 0; i < cached.length; i++) - cached[i] = 0; - } - } - - for (EnumCreatureType type : creatureChunks.keySet()) { - int limit = getCreatureLimit(world, type); - int creatureTotal = 0; - - for (int[] chunk : rangeChunks.values()) - creatureTotal += chunk[type.ordinal()]; - - // if our local count is above the limit, dont qualify our chunks - if (creatureTotal >= limit) continue; - - // expect number is rather meaningless, just a ceil - int expect = limit - creatureTotal; - typeNumSpawn[type.ordinal()] = Math.max(typeNumSpawn[type.ordinal()], expect); - } - } - - for (EnumCreatureType type : creatureChunks.keySet()) { - Set chunks = creatureChunks.get(type); - - if (!chunks.isEmpty()) - MinecraftServer.getServer().ensuresMainThread(() -> spawnMob0(world, chunks, type, typeNumSpawn[type.ordinal()])); - } - }); - } -} \ No newline at end of file diff --git a/src/main/java/io/akarin/server/core/AkarinWorldAccessor.java b/src/main/java/io/akarin/server/core/AkarinWorldAccessor.java deleted file mode 100644 index a0350329a..000000000 --- a/src/main/java/io/akarin/server/core/AkarinWorldAccessor.java +++ /dev/null @@ -1,146 +0,0 @@ -package io.akarin.server.core; - -import java.util.List; - -import javax.annotation.Nullable; - -import com.google.common.collect.Lists; - -import net.minecraft.server.BlockPosition; -import net.minecraft.server.Entity; -import net.minecraft.server.EntityHuman; -import net.minecraft.server.IBlockAccess; -import net.minecraft.server.IBlockData; -import net.minecraft.server.IWorldAccess; -import net.minecraft.server.NavigationListener; -import net.minecraft.server.ParticleParam; -import net.minecraft.server.SoundCategory; -import net.minecraft.server.SoundEffect; -import net.minecraft.server.WorldManager; - -public class AkarinWorldAccessor implements IWorldAccess { - private @Nullable WorldManager worldManager; - private final NavigationListener navigationListener; - private IWorldAccess[] customAccessors = new IWorldAccess[0]; - private boolean hasCustomAccessor; - - public AkarinWorldAccessor(WorldManager worldManager, NavigationListener navigationListener) { - this.worldManager = worldManager; - this.navigationListener = navigationListener; - } - - public AkarinWorldAccessor(NavigationListener navigationListener) { - this.navigationListener = navigationListener; - } - - public void add(IWorldAccess worldAccessor) { - if (worldManager == null && worldAccessor instanceof WorldManager) { - worldManager = (WorldManager) worldAccessor; - return; - } - List accessors = Lists.newArrayList(customAccessors); - accessors.add(worldAccessor); - customAccessors = accessors.toArray(new IWorldAccess[accessors.size()]); - hasCustomAccessor = true; - } - - @Override - public void a(Entity arg0) { - worldManager.a(arg0); - navigationListener.a(arg0); - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0); - } - - @Override - public void a(int arg0, BlockPosition arg1, int arg2) { - worldManager.a(arg0, arg1, arg2); - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0, arg1, arg2); - } - - @Override - public void a(EntityHuman arg0, int arg1, BlockPosition arg2, int arg3) { - worldManager.a(arg0, arg1, arg2, arg3); - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0, arg1, arg2, arg3); - } - - @Override - public void a(IBlockAccess arg0, BlockPosition arg1, IBlockData arg2, IBlockData arg3, int arg4) { - worldManager.a(arg0, arg1, arg2, arg3, arg4); - navigationListener.a(arg0, arg1, arg2, arg3, arg4); - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0, arg1, arg2, arg3, arg4); - } - - @Override - public void a(EntityHuman arg0, SoundEffect arg1, SoundCategory arg2, double arg3, double arg4, double arg5, float arg6, float arg7) { - worldManager.a(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - @Override - public void b(Entity arg0) { - worldManager.b(arg0); - navigationListener.b(arg0); - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.b(arg0); - } - - @Override - public void b(int arg0, BlockPosition arg1, int arg2) { - worldManager.b(arg0, arg1, arg2); - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.b(arg0, arg1, arg2); - } - - // unused - @Override - @Deprecated - public void a(BlockPosition arg0) { - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0); - } - - @Override - @Deprecated - public void a(SoundEffect arg0, BlockPosition arg1) { - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0, arg1); - } - - @Override - @Deprecated - public void a(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5) { - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0, arg1, arg2, arg3, arg4, arg5); - } - - @Override - @Deprecated - public void a(ParticleParam arg0, boolean arg1, double arg2, double arg3, double arg4, double arg5, double arg6, double arg7) { - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - } - - @Override - @Deprecated - public void a(ParticleParam arg0, boolean arg1, boolean arg2, double arg3, double arg4, double arg5, double arg6, double arg7, double arg8) { - if (hasCustomAccessor) - for (IWorldAccess accessor : customAccessors) - accessor.a(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - } -} \ No newline at end of file diff --git a/src/main/java/io/akarin/server/core/PacketType.java b/src/main/java/io/akarin/server/core/PacketType.java deleted file mode 100644 index 49dfacf08..000000000 --- a/src/main/java/io/akarin/server/core/PacketType.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.akarin.server.core; - -public enum PacketType { - PLAY_OUT_MAP_CHUNK, - PLAY_OUT_SPAWN_POSITION, - PLAY_OUT_CHAT, - - UNKNOWN; -} \ No newline at end of file diff --git a/src/main/java/io/akarin/server/misc/ChunkCoordOrdinalInt3Tuple.java b/src/main/java/io/akarin/server/misc/ChunkCoordOrdinalInt3Tuple.java deleted file mode 100644 index de10f5bcf..000000000 --- a/src/main/java/io/akarin/server/misc/ChunkCoordOrdinalInt3Tuple.java +++ /dev/null @@ -1,47 +0,0 @@ -package io.akarin.server.misc; - -import net.minecraft.server.ChunkCoordIntPair; - -import com.google.common.hash.Hashing; -import com.google.common.hash.HashFunction; - -/* - * Reference on spawning mechanics by Colin Godsey - * https://github.com/yesdog/Paper/blob/0de3dd84b7e6688feb42af4fe6b4f323ce7e3013/Spigot-Server-Patches/0433-alternate-mob-spawning-mechanic.patch - */ -public class ChunkCoordOrdinalInt3Tuple extends ChunkCoordIntPair { - public static final HashFunction hashFunc = Hashing.murmur3_32("akarin".hashCode()); - - public final int ordinal; - public final int cachedHashCode; - - public ChunkCoordOrdinalInt3Tuple(int x, int z, int ord) { - super(x, z); - - this.ordinal = ord; - - cachedHashCode = hashFunc.newHasher() - .putInt(ordinal) - .putInt(x) - .putInt(z) - .hash().asInt(); - } - - @Override - public int hashCode() { - return cachedHashCode; - } - - @Override - public boolean equals(Object object) { - if (this == object) { - return true; - } else if (!(object instanceof ChunkCoordOrdinalInt3Tuple)) { - return false; - } else { - ChunkCoordOrdinalInt3Tuple pair = (ChunkCoordOrdinalInt3Tuple) object; - - return this.x == pair.x && this.z == pair.z && this.ordinal == pair.ordinal; - } - } -} \ No newline at end of file diff --git a/src/main/java/io/akarin/server/misc/CopyOnWriteHashMap.java b/src/main/java/io/akarin/server/misc/CopyOnWriteHashMap.java deleted file mode 100644 index ca9c60ea7..000000000 --- a/src/main/java/io/akarin/server/misc/CopyOnWriteHashMap.java +++ /dev/null @@ -1,184 +0,0 @@ -package io.akarin.server.misc; - -import java.io.Serializable; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; - -/** - * A thread-safe version of {@link Map} in which all operations that change the - * Map are implemented by making a new copy of the underlying Map. - *

    - * While the creation of a new Map can be expensive, this class is designed for - * cases in which the primary function is to read data from the Map, not to - * modify the Map. Therefore the operations that do not cause a change to this - * class happen quickly and concurrently. - * - * @author Kuzma Deretuke - */ -public class CopyOnWriteHashMap implements Map, Serializable, Cloneable { - private static final long serialVersionUID = 5481095911554321115L; - private AtomicReference> internalMap = new AtomicReference>(); - - /** - * Creates a new instance of CopyOnWriteHashMap. - */ - public CopyOnWriteHashMap() { - internalMap.set(new HashMap()); - } - - /** - * Creates a new instance of CopyOnWriteHashMap with the specified initial size. - * - * @param initialCapacity The initial size of the Map. - */ - public CopyOnWriteHashMap(int initialCapacity) { - internalMap.set(new HashMap(initialCapacity)); - } - - /** - * Creates a new instance of CopyOnWriteHashMap in which the initial data, - * being held by this map, is contained in the supplied map. - * - * @param data A Map containing the initial contents to be placed into this class. - */ - public CopyOnWriteHashMap(Map data) { - internalMap.set(new HashMap(data)); - } - - @Override - public V put(K key, V value) { - Map oldMap; - Map newMap; - V val; - do { - oldMap = internalMap.get(); - newMap = new HashMap(oldMap); - val = newMap.put(key, value); - } - while (!internalMap.compareAndSet(oldMap, newMap)); - return val; - } - - @Override - public V remove(Object key) { - Map oldMap; - Map newMap; - V val; - do { - oldMap = internalMap.get(); - newMap = new HashMap(oldMap); - val = newMap.remove(key); - } - while (!internalMap.compareAndSet(oldMap, newMap)); - return val; - } - - @Override - public void putAll(Map newData) { - Map oldMap; - Map newMap; - do { - oldMap = internalMap.get(); - newMap = new HashMap(oldMap); - newMap.putAll(newData); - } - while (!internalMap.compareAndSet(oldMap, newMap)); - } - - @Override - public void clear() { - internalMap.set(new HashMap()); - } - - // - // Below are methods that do not modify the internal map - // - - @Override - public int size() { - return internalMap.get().size(); - } - - @Override - public boolean isEmpty() { - return internalMap.get().isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - return internalMap.get().containsKey(key); - } - - @Override - public boolean containsValue(Object value) { - return internalMap.get().containsValue(value); - } - - @Override - public V get(Object key) { - return internalMap.get().get(key); - } - - @Override - public Set keySet() { - return internalMap.get().keySet(); - } - - @Override - public Collection values() { - return internalMap.get().values(); - } - - @Override - public Set> entrySet() { - return internalMap.get().entrySet(); - } - - @Override - public int hashCode() { - return internalMap.get().hashCode(); - } - - @Override - public boolean equals(Object o) { - return internalMap.get().equals(o); - } - - @Override - public String toString() { - Map map = internalMap.get(); - Iterator> i = map.entrySet().iterator(); - if (!i.hasNext()) - return "{}"; - - StringBuilder sb = new StringBuilder(); - sb.append('{'); - for (; ; ) { - Entry e = i.next(); - K key = e.getKey(); - V value = e.getValue(); - sb.append(key == this ? "(this Map)" : (key == map ? "(internal Map)" : key)); - sb.append('='); - sb.append(value == this ? "(this Map)" : (value == map ? "(internal Map)" : value)); - if (!i.hasNext()) - return sb.append('}').toString(); - sb.append(',').append(' '); - } - } - - @Override - public Object clone() { - try { - CopyOnWriteHashMap clone = (CopyOnWriteHashMap) super.clone(); - clone.internalMap = new AtomicReference>(new HashMap(internalMap.get())); - return clone; - } - catch (CloneNotSupportedException e) { - throw new InternalError(); - } - } -} \ No newline at end of file diff --git a/src/main/java/net/minecraft/server/Advancement.java b/src/main/java/net/minecraft/server/Advancement.java index b88d0207e..3ef2f4d2a 100644 --- a/src/main/java/net/minecraft/server/Advancement.java +++ b/src/main/java/net/minecraft/server/Advancement.java @@ -158,6 +158,10 @@ public class Advancement { return this; } + public Advancement.SerializedAdvancement a(ItemStack itemstack, IChatBaseComponent ichatbasecomponent, IChatBaseComponent ichatbasecomponent1, @Nullable MinecraftKey minecraftkey, AdvancementFrameType advancementframetype, boolean flag, boolean flag1, boolean flag2) { + return this.a(new AdvancementDisplay(itemstack, ichatbasecomponent, ichatbasecomponent1, minecraftkey, advancementframetype, flag, flag1, flag2)); + } + public Advancement.SerializedAdvancement a(IMaterial imaterial, IChatBaseComponent ichatbasecomponent, IChatBaseComponent ichatbasecomponent1, @Nullable MinecraftKey minecraftkey, AdvancementFrameType advancementframetype, boolean flag, boolean flag1, boolean flag2) { return this.a(new AdvancementDisplay(new ItemStack(imaterial.getItem()), ichatbasecomponent, ichatbasecomponent1, minecraftkey, advancementframetype, flag, flag1, flag2)); } @@ -349,7 +353,7 @@ public class Advancement { String s; - for (Iterator iterator = map.keySet().iterator(); iterator.hasNext(); astring[i++] = new String[] { s}) { + for (Iterator iterator = map.keySet().iterator(); iterator.hasNext(); astring[i++] = new String[]{s}) { s = (String) iterator.next(); } } @@ -413,13 +417,13 @@ public class Advancement { } public static Advancement.SerializedAdvancement b(PacketDataSerializer packetdataserializer) { - MinecraftKey minecraftkey = packetdataserializer.readBoolean() ? packetdataserializer.l() : null; + MinecraftKey minecraftkey = packetdataserializer.readBoolean() ? packetdataserializer.o() : null; AdvancementDisplay advancementdisplay = packetdataserializer.readBoolean() ? AdvancementDisplay.b(packetdataserializer) : null; Map map = Criterion.c(packetdataserializer); - String[][] astring = new String[packetdataserializer.g()][]; + String[][] astring = new String[packetdataserializer.i()][]; for (int i = 0; i < astring.length; ++i) { - astring[i] = new String[packetdataserializer.g()]; + astring[i] = new String[packetdataserializer.i()]; for (int j = 0; j < astring[i].length; ++j) { astring[i][j] = packetdataserializer.e(32767); diff --git a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java index 8b07d6921..b7f1f39a1 100644 --- a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java +++ b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java @@ -1,6 +1,6 @@ package net.minecraft.server; -import com.google.common.collect.Collections2; +import com.google.common.base.Charsets; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -12,18 +12,14 @@ import com.google.gson.JsonParseException; import com.google.gson.internal.Streams; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; -import com.koloboke.collect.map.hash.HashObjObjMaps; -import com.mojang.datafixers.DataFixTypes; import com.mojang.datafixers.Dynamic; import com.mojang.datafixers.types.JsonOps; - -import io.akarin.server.core.AkarinAsyncExecutor; - import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStreamWriter; import java.io.StringReader; import java.nio.charset.StandardCharsets; -import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -38,7 +34,7 @@ import org.apache.logging.log4j.Logger; public class AdvancementDataPlayer { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final Gson b = (new GsonBuilder()).registerTypeAdapter(AdvancementProgress.class, new AdvancementProgress.a()).registerTypeAdapter(MinecraftKey.class, new MinecraftKey.a()).setPrettyPrinting().create(); private static final TypeToken> c = new TypeToken>() { }; @@ -87,7 +83,7 @@ public class AdvancementDataPlayer { } private void d() { - Iterator iterator = this.d.getAdvancementData().b().iterator(); + Iterator iterator = this.d.getAdvancementData().a().iterator(); while (iterator.hasNext()) { Advancement advancement = (Advancement) iterator.next(); @@ -121,7 +117,7 @@ public class AdvancementDataPlayer { } private void f() { - Iterator iterator = this.d.getAdvancementData().b().iterator(); + Iterator iterator = this.d.getAdvancementData().a().iterator(); while (iterator.hasNext()) { Advancement advancement = (Advancement) iterator.next(); @@ -144,11 +140,11 @@ public class AdvancementDataPlayer { jsonreader.setLenient(false); Dynamic dynamic = new Dynamic(JsonOps.INSTANCE, Streams.parse(jsonreader)); - if (!dynamic.get("DataVersion").flatMap(Dynamic::getNumberValue).isPresent()) { + if (!dynamic.get("DataVersion").asNumber().isPresent()) { dynamic = dynamic.set("DataVersion", dynamic.createInt(1343)); } - dynamic = this.d.az().update(DataFixTypes.ADVANCEMENTS, dynamic, dynamic.getInt("DataVersion"), 1631); + dynamic = this.d.aB().update(DataFixTypes.ADVANCEMENTS.a(), dynamic, dynamic.get("DataVersion").asInt(0), SharedConstants.a().getWorldVersion()); dynamic = dynamic.remove("DataVersion"); Map map = (Map) AdvancementDataPlayer.b.getAdapter(AdvancementDataPlayer.c).fromJsonTree((JsonElement) dynamic.getValue()); @@ -165,8 +161,8 @@ public class AdvancementDataPlayer { if (advancement == null) { // CraftBukkit start - if (((MinecraftKey) entry.getKey()).b().equals("minecraft")) { - AdvancementDataPlayer.a.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", entry.getKey(), this.e); + if (entry.getKey().getNamespace().equals("minecraft")) { + AdvancementDataPlayer.LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", entry.getKey(), this.e); } // CraftBukkit end } else { @@ -191,9 +187,9 @@ public class AdvancementDataPlayer { } } catch (JsonParseException jsonparseexception) { - AdvancementDataPlayer.a.error("Couldn't parse player advancements in {}", this.e, jsonparseexception); + AdvancementDataPlayer.LOGGER.error("Couldn't parse player advancements in {}", this.e, jsonparseexception); } catch (IOException ioexception) { - AdvancementDataPlayer.a.error("Couldn't access player advancements in {}", this.e, ioexception); + AdvancementDataPlayer.LOGGER.error("Couldn't access player advancements in {}", this.e, ioexception); } } @@ -202,33 +198,6 @@ public class AdvancementDataPlayer { this.d(); } - // Akarin start - copied from below - public Map toSerializableMap() { - Map map = HashObjObjMaps.newMutableMap(); - Iterator> iterator = this.data.entrySet().iterator(); - - while (iterator.hasNext()) { - Entry entry = iterator.next(); - AdvancementProgress advancementprogress = (AdvancementProgress) entry.getValue(); - - if (advancementprogress.b()) { - map.put(((Advancement) entry.getKey()).getName(), advancementprogress); - } - } - return map; - } - public void save(Map serializableMap) { - if (this.e.getParentFile() != null) { - this.e.getParentFile().mkdirs(); - } - - try { - Files.write(AdvancementDataPlayer.b.toJson(serializableMap), this.e, StandardCharsets.UTF_8); - } catch (IOException ioexception) { - AdvancementDataPlayer.a.error("Couldn't save player advancements to {}", this.e, ioexception); - } - } - // Akarin end public void c() { if (org.spigotmc.SpigotConfig.disableAdvancementSaving) return; Map map = Maps.newHashMap(); @@ -247,10 +216,56 @@ public class AdvancementDataPlayer { this.e.getParentFile().mkdirs(); } + JsonElement jsonelement = AdvancementDataPlayer.b.toJsonTree(map); + + jsonelement.getAsJsonObject().addProperty("DataVersion", SharedConstants.a().getWorldVersion()); + try { - Files.write(AdvancementDataPlayer.b.toJson(map), this.e, StandardCharsets.UTF_8); + FileOutputStream fileoutputstream = new FileOutputStream(this.e); + Throwable throwable = null; + + try { + OutputStreamWriter outputstreamwriter = new OutputStreamWriter(fileoutputstream, Charsets.UTF_8.newEncoder()); + Throwable throwable1 = null; + + try { + AdvancementDataPlayer.b.toJson(jsonelement, outputstreamwriter); + } catch (Throwable throwable2) { + throwable1 = throwable2; + throw throwable2; + } finally { + if (outputstreamwriter != null) { + if (throwable1 != null) { + try { + outputstreamwriter.close(); + } catch (Throwable throwable3) { + throwable1.addSuppressed(throwable3); + } + } else { + outputstreamwriter.close(); + } + } + + } + } catch (Throwable throwable4) { + throwable = throwable4; + throw throwable4; + } finally { + if (fileoutputstream != null) { + if (throwable != null) { + try { + fileoutputstream.close(); + } catch (Throwable throwable5) { + throwable.addSuppressed(throwable5); + } + } else { + fileoutputstream.close(); + } + } + + } } catch (IOException ioexception) { - AdvancementDataPlayer.a.error("Couldn't save player advancements to {}", this.e, ioexception); + AdvancementDataPlayer.LOGGER.error("Couldn't save player advancements to {}", this.e, ioexception); } } @@ -273,8 +288,8 @@ public class AdvancementDataPlayer { if (!flag1 && advancementprogress.isDone()) { this.player.world.getServer().getPluginManager().callEvent(new org.bukkit.event.player.PlayerAdvancementDoneEvent(this.player.getBukkitEntity(), advancement.bukkit)); // CraftBukkit advancement.d().a(this.player); - if (advancement.c() != null && advancement.c().i() && this.player.world.getGameRules().getBoolean("announceAdvancements")) { - this.d.getPlayerList().sendMessage(new ChatMessage("chat.type.advancement." + advancement.c().e().a(), new Object[] { this.player.getScoreboardDisplayName(), advancement.j()})); + if (advancement.c() != null && advancement.c().i() && this.player.world.getGameRules().getBoolean(GameRules.ANNOUNCE_ADVANCEMENTS)) { + this.d.getPlayerList().sendMessage(new ChatMessage("chat.type.advancement." + advancement.c().e().a(), new Object[]{this.player.getScoreboardDisplayName(), advancement.j()})); } } } diff --git a/src/main/java/net/minecraft/server/AdvancementDataWorld.java b/src/main/java/net/minecraft/server/AdvancementDataWorld.java index 9f9e5484d..54f6331ec 100644 --- a/src/main/java/net/minecraft/server/AdvancementDataWorld.java +++ b/src/main/java/net/minecraft/server/AdvancementDataWorld.java @@ -7,105 +7,51 @@ import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; -import java.io.IOException; import java.lang.reflect.Type; -import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.Iterator; import java.util.Map; import javax.annotation.Nullable; -import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -public class AdvancementDataWorld implements IResourcePackListener { +public class AdvancementDataWorld extends ResourceDataJson { - private static final Logger c = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public static final Gson DESERIALIZER = (new GsonBuilder()).registerTypeHierarchyAdapter(Advancement.SerializedAdvancement.class, (com.google.gson.JsonDeserializer) (jsonelement, type, jsondeserializationcontext) -> { JsonObject jsonobject = ChatDeserializer.m(jsonelement, "advancement"); return Advancement.SerializedAdvancement.a(jsonobject, jsondeserializationcontext); }).registerTypeAdapter(AdvancementRewards.class, new AdvancementRewards.b()).registerTypeHierarchyAdapter(IChatBaseComponent.class, new IChatBaseComponent.ChatSerializer()).registerTypeHierarchyAdapter(ChatModifier.class, new ChatModifier.ChatModifierSerializer()).registerTypeAdapterFactory(new ChatTypeAdapterFactory()).create(); - public static final Advancements REGISTRY = new Advancements(); - public static final int a = "advancements/".length(); - public static final int b = ".json".length(); - private boolean f; + public Advancements REGISTRY = new Advancements(); - public AdvancementDataWorld() {} + public AdvancementDataWorld() { + super(AdvancementDataWorld.DESERIALIZER, "advancements"); + } - private Map b(IResourceManager iresourcemanager) { - Map map = Maps.newHashMap(); - Iterator iterator = iresourcemanager.a("advancements", (s) -> { - return s.endsWith(".json"); - }).iterator(); + protected void a(Map map, IResourceManager iresourcemanager, GameProfilerFiller gameprofilerfiller) { + Map map1 = Maps.newHashMap(); - while (iterator.hasNext()) { - MinecraftKey minecraftkey = (MinecraftKey) iterator.next(); - String s = minecraftkey.getKey(); - MinecraftKey minecraftkey1 = new MinecraftKey(minecraftkey.b(), s.substring(AdvancementDataWorld.a, s.length() - AdvancementDataWorld.b)); + map.forEach((minecraftkey, jsonobject) -> { + // Spigot start + if (org.spigotmc.SpigotConfig.disabledAdvancements != null && (org.spigotmc.SpigotConfig.disabledAdvancements.contains("*") || org.spigotmc.SpigotConfig.disabledAdvancements.contains(minecraftkey.toString()))) { + return; + } + // Spigot end try { - IResource iresource = iresourcemanager.a(minecraftkey); - Throwable throwable = null; - // Spigot start - if (org.spigotmc.SpigotConfig.disabledAdvancements != null && (org.spigotmc.SpigotConfig.disabledAdvancements.contains("*") || org.spigotmc.SpigotConfig.disabledAdvancements.contains(minecraftkey.toString()))) { - continue; - } - // Spigot end + Advancement.SerializedAdvancement advancement_serializedadvancement = (Advancement.SerializedAdvancement) AdvancementDataWorld.DESERIALIZER.fromJson(jsonobject, Advancement.SerializedAdvancement.class); - try { - Advancement.SerializedAdvancement advancement_serializedadvancement = (Advancement.SerializedAdvancement) ChatDeserializer.a(AdvancementDataWorld.DESERIALIZER, IOUtils.toString(iresource.b(), StandardCharsets.UTF_8), Advancement.SerializedAdvancement.class); - - if (advancement_serializedadvancement == null) { - AdvancementDataWorld.c.error("Couldn't load custom advancement {} from {} as it's empty or null", minecraftkey1, minecraftkey); - } else { - map.put(minecraftkey1, advancement_serializedadvancement); - } - } catch (Throwable throwable1) { - throwable = throwable1; - throw throwable1; - } finally { - if (iresource != null) { - if (throwable != null) { - try { - iresource.close(); - } catch (Throwable throwable2) { - throwable.addSuppressed(throwable2); - } - } else { - iresource.close(); - } - } - - } + map1.put(minecraftkey, advancement_serializedadvancement); } catch (IllegalArgumentException | JsonParseException jsonparseexception) { - AdvancementDataWorld.c.error("Parsing error loading custom advancement {}: {}", minecraftkey1, jsonparseexception.getMessage()); - this.f = true; - } catch (IOException ioexception) { - AdvancementDataWorld.c.error("Couldn't read custom advancement {} from {}", minecraftkey1, minecraftkey, ioexception); - this.f = true; + AdvancementDataWorld.LOGGER.error("Parsing error loading custom advancement {}: {}", minecraftkey, jsonparseexception.getMessage()); } - } - return map; - } + }); + Advancements advancements = new Advancements(); - @Nullable - public Advancement a(MinecraftKey minecraftkey) { - return AdvancementDataWorld.REGISTRY.a(minecraftkey); - } - - public Collection b() { - return AdvancementDataWorld.REGISTRY.c(); - } - - public void a(IResourceManager iresourcemanager) { - this.f = false; - AdvancementDataWorld.REGISTRY.a(); - Map map = this.b(iresourcemanager); - - AdvancementDataWorld.REGISTRY.a(map); - Iterator iterator = AdvancementDataWorld.REGISTRY.b().iterator(); + advancements.a((Map) map1); + Iterator iterator = advancements.b().iterator(); while (iterator.hasNext()) { Advancement advancement = (Advancement) iterator.next(); @@ -115,5 +61,15 @@ public class AdvancementDataWorld implements IResourcePackListener { } } + this.REGISTRY = advancements; + } + + @Nullable + public Advancement a(MinecraftKey minecraftkey) { + return this.REGISTRY.a(minecraftkey); + } + + public Collection a() { + return this.REGISTRY.c(); } } diff --git a/src/main/java/net/minecraft/server/Advancements.java b/src/main/java/net/minecraft/server/Advancements.java index 5d32caff3..bc043ad4f 100644 --- a/src/main/java/net/minecraft/server/Advancements.java +++ b/src/main/java/net/minecraft/server/Advancements.java @@ -15,7 +15,7 @@ import org.apache.logging.log4j.Logger; public class Advancements { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public final Map advancements = Maps.newHashMap(); private final Set c = Sets.newLinkedHashSet(); private final Set d = Sets.newLinkedHashSet(); @@ -67,22 +67,12 @@ public class Advancements { } entry = (Entry) iterator.next(); - Advancements.a.error("Couldn't load advancement {}: {}", entry.getKey(), entry.getValue()); + Advancements.LOGGER.error("Couldn't load advancement {}: {}", entry.getKey(), entry.getValue()); } } } - // Advancements.a.info("Loaded {} advancements", this.advancements.size()); // CraftBukkit - moved to AdvancementDataWorld#reload - } - - public void a() { - this.advancements.clear(); - this.c.clear(); - this.d.clear(); - if (this.e != null) { - this.e.a(); - } - + // Advancements.LOGGER.info("Loaded {} advancements", this.advancements.size()); // CraftBukkit - moved to AdvancementDataWorld#reload } public Iterable b() { @@ -103,7 +93,5 @@ public class Advancements { void a(Advancement advancement); void c(Advancement advancement); - - void a(); } } diff --git a/src/main/java/net/minecraft/server/AkarinUserCache.java b/src/main/java/net/minecraft/server/AkarinUserCache.java deleted file mode 100644 index 53008f775..000000000 --- a/src/main/java/net/minecraft/server/AkarinUserCache.java +++ /dev/null @@ -1,262 +0,0 @@ -package net.minecraft.server; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.spigotmc.SpigotConfig; - -import com.destroystokyo.paper.PaperConfig; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; -import com.google.common.base.Charsets; -import com.google.common.collect.Lists; -import com.google.common.io.Files; -import com.google.gson.Gson; -import com.google.gson.JsonParseException; -import com.google.gson.JsonSyntaxException; -import com.mojang.authlib.Agent; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.GameProfileRepository; -import com.mojang.authlib.ProfileLookupCallback; -import io.akarin.server.core.AkarinAsyncExecutor; -import io.akarin.server.core.AkarinGlobalConfig; -import net.minecraft.server.UserCache.UserCacheEntry; - -public class AkarinUserCache { - private final static Logger LOGGER = LogManager.getLogger("Akarin"); - public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); - - // To reduce date creation - private final static long RECREATE_DATE_INTERVAL = TimeUnit.MILLISECONDS.convert(10, TimeUnit.MINUTES); - private static long lastWarpExpireDate; - private static Date lastExpireDate; - - /** - * All user caches - * String username -> UserCacheEntry cacheEntry (profile and expire date) - */ - private final Cache profiles = Caffeine.newBuilder().maximumSize(SpigotConfig.userCacheCap).build(); - - private final GameProfileRepository profileHandler; - protected final Gson gson; - private final File userCacheFile; - - protected static boolean isOnlineMode() { - return UserCache.isOnlineMode() || (SpigotConfig.bungee && PaperConfig.bungeeOnlineMode); - } - - private static Date createExpireDate(boolean force) { - long now = System.currentTimeMillis(); - if (force || (now - lastWarpExpireDate) > RECREATE_DATE_INTERVAL) { - lastWarpExpireDate = now; - Calendar calendar = Calendar.getInstance(); - - calendar.add(Calendar.SECOND, AkarinGlobalConfig.userCacheExpireDays); - return lastExpireDate = calendar.getTime(); - } - - return lastExpireDate; - } - - private static boolean isExpired(UserCacheEntry entry) { - return System.currentTimeMillis() >= entry.getExpireDate().getTime(); - } - - private static UserCacheEntry refreshExpireDate(UserCacheEntry entry) { - return new UserCacheEntry(entry.getProfile(), createExpireDate(true)); - } - - private static GameProfile lookup(GameProfileRepository profileRepo, String username, @Nonnull Consumer cachedCallbackHandler, boolean async) { - GameProfile[] gameProfile = new GameProfile[1]; - ProfileLookupCallback handler = new ProfileLookupCallback() { - @Override - public void onProfileLookupSucceeded(GameProfile gameprofile) { - cachedCallbackHandler.accept(gameprofile); - gameProfile[0] = gameprofile; - } - - @Override - public void onProfileLookupFailed(GameProfile gameprofile, Exception ex) { - LOGGER.warn("Failed to lookup profile for player {}, applying offline UUID.", gameprofile.getName()); - GameProfile offline = createOfflineProfile(username); - cachedCallbackHandler.accept(offline); - gameProfile[0] = offline; - } - }; - - Runnable find = () -> profileRepo.findProfilesByNames(new String[]{username}, Agent.MINECRAFT, handler); - if (async) { - AkarinAsyncExecutor.scheduleAsyncTask(find); - } else { - find.run(); - } - return gameProfile[0]; - } - - private static GameProfile createOfflineProfile(String username) { - String usernameOffline = username.toLowerCase(Locale.ROOT); - GameProfile offlineProfile = new GameProfile(EntityHuman.getOfflineUUID(usernameOffline), username); - return offlineProfile; - } - - public AkarinUserCache(GameProfileRepository repo, File file, Gson gson) { - lastExpireDate = createExpireDate(true); - - this.profileHandler = repo; - this.userCacheFile = file; - this.gson = gson; - - this.load(); - } - - private GameProfile lookupAndCache(String username, @Nullable Consumer callback, boolean async) { - return lookupAndCache(username, callback, createExpireDate(false), async); - } - - private GameProfile lookupAndCache(String username, @Nullable Consumer callback, Date expireDate, boolean async) { - Consumer cachedCallbackHandler = profile -> { - profiles.put(username, new UserCacheEntry(profile, expireDate)); - if (async) - callback.accept(profile); - - if (!org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) - save(); - }; - - GameProfileRepository repository = MinecraftServer.getServer().getUserCache().gameProfileRepository(); - return lookup(repository != null ? repository : profileHandler, username, cachedCallbackHandler, async); - } - - public GameProfile acquire(String username) { - return acquire(username, null, false); - } - - public GameProfile acquire(String username, @Nonnull Consumer callback) { - return acquire(username, callback, true); - } - - public GameProfile acquire(String username, @Nullable Consumer callback, boolean async) { - if (StringUtils.isBlank(username)) - throw new UnsupportedOperationException("Blank username"); - - if (!isOnlineMode()) - return createOfflineProfile(username); - - UserCacheEntry entry = profiles.getIfPresent(username); - - if (entry != null) { - if (isExpired(entry)) { - profiles.invalidate(username); - } else { - if (async) - callback.accept(entry.getProfile()); - - return entry.getProfile(); - } - } - return lookupAndCache(username, callback, async); - } - - @Nullable - public GameProfile peek(String username) { - if (!isOnlineMode()) - return createOfflineProfile(username); - - UserCacheEntry entry = profiles.getIfPresent(username); - return entry == null ? null : entry.getProfile(); - } - - protected void offer(GameProfile profile) { - if (isOnlineMode()) - offer(profile, createExpireDate(false)); - } - - private void offer(GameProfile profile, Date date) { - String username = profile.getName(); - UserCacheEntry entry = profiles.getIfPresent(username); - // Refresh expire date or create new entry - entry = entry != null ? refreshExpireDate(entry) : new UserCacheEntry(profile, date); - - profiles.put(username, entry); - } - - private void offer(UserCacheEntry entry) { - if (!isExpired(entry)) - profiles.put(entry.getProfile().getName(), entry); - } - - protected void load() { - if (!isOnlineMode()) - return; - - BufferedReader reader = null; - try { - profiles.invalidateAll(); - - reader = Files.newReader(userCacheFile, Charsets.UTF_8); - List entries; - synchronized (this.userCacheFile) { - entries = this.gson.fromJson(reader, UserCache.PARAMETERIZED_TYPE); - } - - if (entries != null && !entries.isEmpty()) - Lists.reverse(entries).forEach(this::offer); - } catch (FileNotFoundException e) { - ; - } catch (JsonSyntaxException e) { - LOGGER.warn("Usercache.json is corrupted or has bad formatting. Deleting it to prevent further issues."); - this.userCacheFile.delete(); - } catch (JsonParseException e) { - ; - } finally { - IOUtils.closeQuietly(reader); - } - } - - protected void save() { - if (!isOnlineMode()) - return; - - Runnable save = () -> { - String jsonString = this.gson.toJson(this.entries()); - BufferedWriter writer = null; - - try { - writer = Files.newWriter(this.userCacheFile, Charsets.UTF_8); - synchronized (this.userCacheFile) { - writer.write(jsonString); - } - } catch (FileNotFoundException e) { - ; - } catch (IOException io) { - ; - } finally { - IOUtils.closeQuietly(writer); - } - }; - - AkarinAsyncExecutor.scheduleSingleAsyncTask(save); - } - - private List entries() { - return isOnlineMode() ? Lists.newArrayList(profiles.asMap().values()) : Collections.emptyList(); - } -} \ No newline at end of file diff --git a/src/main/java/net/minecraft/server/ArgumentBlock.java b/src/main/java/net/minecraft/server/ArgumentBlock.java index f52936581..97d85f845 100644 --- a/src/main/java/net/minecraft/server/ArgumentBlock.java +++ b/src/main/java/net/minecraft/server/ArgumentBlock.java @@ -23,19 +23,19 @@ public class ArgumentBlock { public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("argument.block.tag.disallowed", new Object[0])); public static final DynamicCommandExceptionType b = new DynamicCommandExceptionType((object) -> { - return new ChatMessage("argument.block.id.invalid", new Object[] { object}); + return new ChatMessage("argument.block.id.invalid", new Object[]{object}); }); public static final Dynamic2CommandExceptionType c = new Dynamic2CommandExceptionType((object, object1) -> { - return new ChatMessage("argument.block.property.unknown", new Object[] { object, object1}); + return new ChatMessage("argument.block.property.unknown", new Object[]{object, object1}); }); public static final Dynamic2CommandExceptionType d = new Dynamic2CommandExceptionType((object, object1) -> { - return new ChatMessage("argument.block.property.duplicate", new Object[] { object1, object}); + return new ChatMessage("argument.block.property.duplicate", new Object[]{object1, object}); }); public static final Dynamic3CommandExceptionType e = new Dynamic3CommandExceptionType((object, object1, object2) -> { - return new ChatMessage("argument.block.property.invalid", new Object[] { object, object2, object1}); + return new ChatMessage("argument.block.property.invalid", new Object[]{object, object2, object1}); }); public static final Dynamic2CommandExceptionType f = new Dynamic2CommandExceptionType((object, object1) -> { - return new ChatMessage("argument.block.property.novalue", new Object[] { object, object1}); + return new ChatMessage("argument.block.property.novalue", new Object[]{object, object1}); }); public static final SimpleCommandExceptionType g = new SimpleCommandExceptionType(new ChatMessage("argument.block.property.unclosed", new Object[0])); private static final Function> h = SuggestionsBuilder::buildFuture; @@ -216,7 +216,7 @@ public class ArgumentBlock { } private static > SuggestionsBuilder a(SuggestionsBuilder suggestionsbuilder, IBlockState iblockstate) { - Iterator iterator = iblockstate.d().iterator(); + Iterator iterator = iblockstate.getValues().iterator(); while (iterator.hasNext()) { T t0 = (T) iterator.next(); // CraftBukkit - decompile error @@ -335,15 +335,13 @@ public class ArgumentBlock { int i = this.i.getCursor(); this.m = MinecraftKey.a(this.i); - if (IRegistry.BLOCK.c(this.m)) { - Block block = (Block) IRegistry.BLOCK.getOrDefault(this.m); - - this.n = block.getStates(); - this.o = block.getBlockData(); - } else { + Block block = (Block) IRegistry.BLOCK.getOptional(this.m).orElseThrow(() -> { this.i.setCursor(i); - throw ArgumentBlock.b.createWithContext(this.i, this.m.toString()); - } + return ArgumentBlock.b.createWithContext(this.i, this.m.toString()); + }); + + this.n = block.getStates(); + this.o = block.getBlockData(); } public void f() throws CommandSyntaxException { @@ -498,7 +496,7 @@ public class ArgumentBlock { } } - public static String a(IBlockData iblockdata, @Nullable NBTTagCompound nbttagcompound) { + public static String a(IBlockData iblockdata) { StringBuilder stringbuilder = new StringBuilder(IRegistry.BLOCK.getKey(iblockdata.getBlock()).toString()); if (!iblockdata.a().isEmpty()) { @@ -518,10 +516,6 @@ public class ArgumentBlock { stringbuilder.append(']'); } - if (nbttagcompound != null) { - stringbuilder.append(nbttagcompound); - } - return stringbuilder.toString(); } diff --git a/src/main/java/net/minecraft/server/ArgumentEntity.java b/src/main/java/net/minecraft/server/ArgumentEntity.java index 5164b79b0..39a6a9ac0 100644 --- a/src/main/java/net/minecraft/server/ArgumentEntity.java +++ b/src/main/java/net/minecraft/server/ArgumentEntity.java @@ -39,7 +39,7 @@ public class ArgumentEntity implements ArgumentType { return ((EntitySelector) commandcontext.getArgument(s, EntitySelector.class)).a((CommandListenerWrapper) commandcontext.getSource()); } - public static ArgumentEntity b() { + public static ArgumentEntity multipleEntities() { return new ArgumentEntity(false, false); } @@ -54,7 +54,7 @@ public class ArgumentEntity implements ArgumentType { } public static Collection c(CommandContext commandcontext, String s) throws CommandSyntaxException { - return ((EntitySelector) commandcontext.getArgument(s, EntitySelector.class)).b((CommandListenerWrapper) commandcontext.getSource()); + return ((EntitySelector) commandcontext.getArgument(s, EntitySelector.class)).getEntities((CommandListenerWrapper) commandcontext.getSource()); } public static Collection d(CommandContext commandcontext, String s) throws CommandSyntaxException { @@ -92,7 +92,7 @@ public class ArgumentEntity implements ArgumentType { // CraftBukkit end boolean flag = false; ArgumentParserSelector argumentparserselector = new ArgumentParserSelector(stringreader); - EntitySelector entityselector = argumentparserselector.s(overridePermissions); // CraftBukkit + EntitySelector entityselector = argumentparserselector.parse(overridePermissions); // CraftBukkit if (entityselector.a() > 1 && this.h) { if (this.i) { @@ -119,7 +119,7 @@ public class ArgumentEntity implements ArgumentType { ArgumentParserSelector argumentparserselector = new ArgumentParserSelector(stringreader, icompletionprovider.hasPermission(2)); try { - argumentparserselector.s(); + argumentparserselector.parse(); } catch (CommandSyntaxException commandsyntaxexception) { ; } @@ -157,6 +157,7 @@ public class ArgumentEntity implements ArgumentType { packetdataserializer.writeByte(b0); } + @Override public ArgumentEntity b(PacketDataSerializer packetdataserializer) { byte b0 = packetdataserializer.readByte(); diff --git a/src/main/java/net/minecraft/server/ArgumentParserSelector.java b/src/main/java/net/minecraft/server/ArgumentParserSelector.java index 988f77f1e..75db3678a 100644 --- a/src/main/java/net/minecraft/server/ArgumentParserSelector.java +++ b/src/main/java/net/minecraft/server/ArgumentParserSelector.java @@ -23,24 +23,24 @@ public class ArgumentParserSelector { public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("argument.entity.invalid", new Object[0])); public static final DynamicCommandExceptionType b = new DynamicCommandExceptionType((object) -> { - return new ChatMessage("argument.entity.selector.unknown", new Object[] { object}); + return new ChatMessage("argument.entity.selector.unknown", new Object[]{object}); }); public static final SimpleCommandExceptionType c = new SimpleCommandExceptionType(new ChatMessage("argument.entity.selector.not_allowed", new Object[0])); public static final SimpleCommandExceptionType d = new SimpleCommandExceptionType(new ChatMessage("argument.entity.selector.missing", new Object[0])); public static final SimpleCommandExceptionType e = new SimpleCommandExceptionType(new ChatMessage("argument.entity.options.unterminated", new Object[0])); public static final DynamicCommandExceptionType f = new DynamicCommandExceptionType((object) -> { - return new ChatMessage("argument.entity.options.valueless", new Object[] { object}); + return new ChatMessage("argument.entity.options.valueless", new Object[]{object}); }); public static final BiConsumer> g = (vec3d, list) -> { }; public static final BiConsumer> h = (vec3d, list) -> { list.sort((entity, entity1) -> { - return Doubles.compare(entity.a(vec3d), entity1.a(vec3d)); + return Doubles.compare(entity.c(vec3d), entity1.c(vec3d)); }); }; public static final BiConsumer> i = (vec3d, list) -> { list.sort((entity, entity1) -> { - return Doubles.compare(entity1.a(vec3d), entity.a(vec3d)); + return Doubles.compare(entity1.c(vec3d), entity.c(vec3d)); }); }; public static final BiConsumer> j = (vec3d, list) -> { @@ -87,11 +87,12 @@ public class ArgumentParserSelector { private boolean M; private boolean N; private boolean O; - private Class P; + @Nullable + private EntityTypes P; private boolean Q; private boolean R; private boolean S; - private boolean T; + private boolean checkPermissions; public ArgumentParserSelector(StringReader stringreader) { this(stringreader, true); @@ -138,7 +139,7 @@ public class ArgumentParserSelector { }; } - return new EntitySelector(this.n, this.o, this.p, this.A, this.q, function, axisalignedbb, this.B, this.C, this.D, this.F, this.P == null ? Entity.class : this.P, this.T); + return new EntitySelector(this.n, this.o, this.p, this.A, this.q, function, axisalignedbb, this.B, this.C, this.D, this.F, this.P, this.checkPermissions); } private AxisAlignedBB a(double d0, double d1, double d2) { @@ -188,8 +189,8 @@ public class ArgumentParserSelector { } // CraftBukkit start - protected void b(boolean overridePermissions) throws CommandSyntaxException { - this.T = !overridePermissions; + protected void parseSelector(boolean overridePermissions) throws CommandSyntaxException { + this.checkPermissions = !overridePermissions; // CraftBukkit end this.G = this::d; if (!this.l.canRead()) { @@ -202,17 +203,17 @@ public class ArgumentParserSelector { this.n = 1; this.o = false; this.B = ArgumentParserSelector.h; - this.a(EntityPlayer.class); + this.a(EntityTypes.PLAYER); } else if (c0 == 'a') { this.n = Integer.MAX_VALUE; this.o = false; this.B = ArgumentParserSelector.g; - this.a(EntityPlayer.class); + this.a(EntityTypes.PLAYER); } else if (c0 == 'r') { this.n = 1; this.o = false; this.B = ArgumentParserSelector.j; - this.a(EntityPlayer.class); + this.a(EntityTypes.PLAYER); } else if (c0 == 's') { this.n = 1; this.o = true; @@ -322,7 +323,18 @@ public class ArgumentParserSelector { } } - public StringReader f() { + public boolean f() { + this.l.skipWhitespace(); + if (this.l.canRead() && this.l.peek() == '#') { + this.l.skip(); + this.l.skipWhitespace(); + return true; + } else { + return false; + } + } + + public StringReader g() { return this.l; } @@ -330,11 +342,11 @@ public class ArgumentParserSelector { this.A = this.A.and(predicate); } - public void g() { + public void h() { this.p = true; } - public CriterionConditionValue.FloatRange h() { + public CriterionConditionValue.FloatRange i() { return this.q; } @@ -342,7 +354,7 @@ public class ArgumentParserSelector { this.q = criterionconditionvalue_floatrange; } - public CriterionConditionValue.IntegerRange i() { + public CriterionConditionValue.IntegerRange j() { return this.r; } @@ -350,7 +362,7 @@ public class ArgumentParserSelector { this.r = criterionconditionvalue_integerrange; } - public CriterionConditionRange j() { + public CriterionConditionRange k() { return this.y; } @@ -358,7 +370,7 @@ public class ArgumentParserSelector { this.y = criterionconditionrange; } - public CriterionConditionRange k() { + public CriterionConditionRange l() { return this.z; } @@ -367,17 +379,17 @@ public class ArgumentParserSelector { } @Nullable - public Double l() { + public Double m() { return this.s; } @Nullable - public Double m() { + public Double n() { return this.t; } @Nullable - public Double n() { + public Double o() { return this.u; } @@ -406,17 +418,17 @@ public class ArgumentParserSelector { } @Nullable - public Double o() { + public Double p() { return this.v; } @Nullable - public Double p() { + public Double q() { return this.w; } @Nullable - public Double q() { + public Double r() { return this.x; } @@ -432,12 +444,12 @@ public class ArgumentParserSelector { this.B = biconsumer; } - public EntitySelector s() throws CommandSyntaxException { + public EntitySelector parse() throws CommandSyntaxException { // CraftBukkit start - return s(false); + return parse(false); } - public EntitySelector s(boolean overridePermissions) throws CommandSyntaxException { + public EntitySelector parse(boolean overridePermissions) throws CommandSyntaxException { // CraftBukkit end this.E = this.l.getCursor(); this.G = this::b; @@ -447,7 +459,7 @@ public class ArgumentParserSelector { } this.l.skip(); - this.b(overridePermissions); // CraftBukkit + this.parseSelector(overridePermissions); // CraftBukkit } else { this.c(); } @@ -510,7 +522,7 @@ public class ArgumentParserSelector { return suggestionsbuilder.buildFuture(); } - public boolean t() { + public boolean u() { return this.C; } @@ -522,7 +534,7 @@ public class ArgumentParserSelector { return (CompletableFuture) this.G.apply(suggestionsbuilder.createOffset(this.l.getCursor()), consumer); } - public boolean u() { + public boolean v() { return this.H; } @@ -530,7 +542,7 @@ public class ArgumentParserSelector { this.H = flag; } - public boolean v() { + public boolean w() { return this.I; } @@ -538,7 +550,7 @@ public class ArgumentParserSelector { this.I = flag; } - public boolean w() { + public boolean x() { return this.J; } @@ -546,7 +558,7 @@ public class ArgumentParserSelector { this.J = flag; } - public boolean x() { + public boolean y() { return this.K; } @@ -554,7 +566,7 @@ public class ArgumentParserSelector { this.K = flag; } - public boolean y() { + public boolean z() { return this.L; } @@ -562,7 +574,7 @@ public class ArgumentParserSelector { this.L = flag; } - public boolean z() { + public boolean A() { return this.M; } @@ -570,7 +582,7 @@ public class ArgumentParserSelector { this.M = flag; } - public boolean A() { + public boolean B() { return this.N; } @@ -582,11 +594,11 @@ public class ArgumentParserSelector { this.O = flag; } - public void a(Class oclass) { - this.P = oclass; + public void a(EntityTypes entitytypes) { + this.P = entitytypes; } - public void C() { + public void D() { this.Q = true; } diff --git a/src/main/java/net/minecraft/server/ArgumentProfile.java b/src/main/java/net/minecraft/server/ArgumentProfile.java deleted file mode 100644 index 02231684f..000000000 --- a/src/main/java/net/minecraft/server/ArgumentProfile.java +++ /dev/null @@ -1,123 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import com.mojang.brigadier.suggestion.Suggestions; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -public class ArgumentProfile implements ArgumentType { - - private static final Collection b = Arrays.asList("Player", "0123", "dd12be42-52a9-4a91-a8a1-11c01849e498", "@e"); - public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("argument.player.unknown", new Object[0])); - - public ArgumentProfile() {} - - public static Collection a(CommandContext commandcontext, String s) throws CommandSyntaxException { - return ((ArgumentProfile.a) commandcontext.getArgument(s, ArgumentProfile.a.class)).getNames((CommandListenerWrapper) commandcontext.getSource()); - } - - public static ArgumentProfile a() { - return new ArgumentProfile(); - } - - public ArgumentProfile.a parse(StringReader stringreader) throws CommandSyntaxException { - if (stringreader.canRead() && stringreader.peek() == '@') { - ArgumentParserSelector argumentparserselector = new ArgumentParserSelector(stringreader); - EntitySelector entityselector = argumentparserselector.s(); - - if (entityselector.b()) { - throw ArgumentEntity.c.create(); - } else { - return new ArgumentProfile.b(entityselector); - } - } else { - int i = stringreader.getCursor(); - - while (stringreader.canRead() && stringreader.peek() != ' ') { - stringreader.skip(); - } - - String s = stringreader.getString().substring(i, stringreader.getCursor()); - - return (commandlistenerwrapper) -> { - GameProfile gameprofile = commandlistenerwrapper.getServer().getModernUserCache().acquire(s); // Akarin - - if (gameprofile == null) { - throw ArgumentProfile.a.create(); - } else { - return Collections.singleton(gameprofile); - } - }; - } - } - - public CompletableFuture listSuggestions(CommandContext commandcontext, SuggestionsBuilder suggestionsbuilder) { - if (commandcontext.getSource() instanceof ICompletionProvider) { - StringReader stringreader = new StringReader(suggestionsbuilder.getInput()); - - stringreader.setCursor(suggestionsbuilder.getStart()); - ArgumentParserSelector argumentparserselector = new ArgumentParserSelector(stringreader); - - try { - argumentparserselector.s(); - } catch (CommandSyntaxException commandsyntaxexception) { - ; - } - - return argumentparserselector.a(suggestionsbuilder, (suggestionsbuilder1) -> { - ICompletionProvider.b((Iterable) ((ICompletionProvider) commandcontext.getSource()).l(), suggestionsbuilder1); - }); - } else { - return Suggestions.empty(); - } - } - - public Collection getExamples() { - return ArgumentProfile.b; - } - - public static class b implements ArgumentProfile.a { - - private final EntitySelector a; - - public b(EntitySelector entityselector) { - this.a = entityselector; - } - - public Collection getNames(CommandListenerWrapper commandlistenerwrapper) throws CommandSyntaxException { - List list = this.a.d(commandlistenerwrapper); - - if (list.isEmpty()) { - throw ArgumentEntity.e.create(); - } else { - List list1 = Lists.newArrayList(); - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - - list1.add(entityplayer.getProfile()); - } - - return list1; - } - } - } - - @FunctionalInterface - public interface a { - - Collection getNames(CommandListenerWrapper commandlistenerwrapper) throws CommandSyntaxException; - } -} diff --git a/src/main/java/net/minecraft/server/AttributeInstance.java b/src/main/java/net/minecraft/server/AttributeInstance.java deleted file mode 100644 index c53bc8230..000000000 --- a/src/main/java/net/minecraft/server/AttributeInstance.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.minecraft.server; - -import java.util.Collection; -import java.util.UUID; -import javax.annotation.Nullable; - -public interface AttributeInstance { - - IAttribute getAttribute(); - - double b(); - - void setValue(double d0); - - Collection a(int i); - - Collection c(); - - boolean a(AttributeModifier attributemodifier); - - @Nullable - AttributeModifier a(UUID uuid); - - default void addModifier(AttributeModifier modifier) { b(modifier); } // Paper - OBFHELPER - void b(AttributeModifier attributemodifier); - - default void removeModifier(AttributeModifier modifier) { c(modifier); } // Paper - OBFHELPER - void c(AttributeModifier attributemodifier); - - void b(UUID uuid); - - double getValue(); -} diff --git a/src/main/java/net/minecraft/server/AttributeRanged.java b/src/main/java/net/minecraft/server/AttributeRanged.java index 02dea695c..0cbd75f14 100644 --- a/src/main/java/net/minecraft/server/AttributeRanged.java +++ b/src/main/java/net/minecraft/server/AttributeRanged.java @@ -30,6 +30,7 @@ public class AttributeRanged extends AttributeBase { return this.c; } + @Override public double a(double d0) { if (d0 != d0) return getDefault(); // CraftBukkit diff --git a/src/main/java/net/minecraft/server/AxisAlignedBB.java b/src/main/java/net/minecraft/server/AxisAlignedBB.java index dad1ff737..c950139c0 100644 --- a/src/main/java/net/minecraft/server/AxisAlignedBB.java +++ b/src/main/java/net/minecraft/server/AxisAlignedBB.java @@ -1,6 +1,7 @@ package net.minecraft.server; import java.util.Iterator; +import java.util.Optional; import javax.annotation.Nullable; public class AxisAlignedBB { @@ -29,6 +30,14 @@ public class AxisAlignedBB { this((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), (double) blockposition1.getX(), (double) blockposition1.getY(), (double) blockposition1.getZ()); } + public AxisAlignedBB(Vec3D vec3d, Vec3D vec3d1) { + this(vec3d.x, vec3d.y, vec3d.z, vec3d1.x, vec3d1.y, vec3d1.z); + } + + public static AxisAlignedBB a(StructureBoundingBox structureboundingbox) { + return new AxisAlignedBB((double) structureboundingbox.a, (double) structureboundingbox.b, (double) structureboundingbox.c, (double) (structureboundingbox.d + 1), (double) (structureboundingbox.e + 1), (double) (structureboundingbox.f + 1)); + } + public double a(EnumDirection.EnumAxis enumdirection_enumaxis) { return enumdirection_enumaxis.a(this.minX, this.minY, this.minZ); } @@ -95,7 +104,11 @@ public class AxisAlignedBB { return new AxisAlignedBB(d3, d4, d5, d6, d7, d8); } - public AxisAlignedBB expand(double x, double y, double z) { return b(x, y, z); } // Paper - OBFHELPER + public AxisAlignedBB a(Vec3D vec3d) { + return this.b(vec3d.x, vec3d.y, vec3d.z); + } + + public final AxisAlignedBB expand(double x, double y, double z) { return b(x, y, z); } // Paper - OBFHELPER public AxisAlignedBB b(double d0, double d1, double d2) { double d3 = this.minX; double d4 = this.minY; @@ -176,7 +189,7 @@ public class AxisAlignedBB { return new AxisAlignedBB(this.minX + (double) blockposition.getX(), this.minY + (double) blockposition.getY(), this.minZ + (double) blockposition.getZ(), this.maxX + (double) blockposition.getX(), this.maxY + (double) blockposition.getY(), this.maxZ + (double) blockposition.getZ()); } - public AxisAlignedBB a(Vec3D vec3d) { + public AxisAlignedBB b(Vec3D vec3d) { return this.d(vec3d.x, vec3d.y, vec3d.z); } @@ -188,8 +201,8 @@ public class AxisAlignedBB { return this.minX < d3 && this.maxX > d0 && this.minY < d4 && this.maxY > d1 && this.minZ < d5 && this.maxZ > d2; } - public boolean contains(Vec3D vec3d) { return b(vec3d); } // Paper - OBFHELPER - public boolean b(Vec3D vec3d) { + public final boolean contains(Vec3D vec3d) { return c(vec3d); } // Paper - OBFHELPER + public boolean c(Vec3D vec3d) { return this.e(vec3d.x, vec3d.y, vec3d.z); } @@ -198,48 +211,49 @@ public class AxisAlignedBB { } public double a() { - double d0 = this.maxX - this.minX; - double d1 = this.maxY - this.minY; - double d2 = this.maxZ - this.minZ; + double d0 = this.b(); + double d1 = this.c(); + double d2 = this.d(); return (d0 + d1 + d2) / 3.0D; } - public AxisAlignedBB f(double d0, double d1, double d2) { - return this.grow(-d0, -d1, -d2); + public double b() { + return this.maxX - this.minX; + } + + public double c() { + return this.maxY - this.minY; + } + + public double d() { + return this.maxZ - this.minZ; } public AxisAlignedBB shrink(double d0) { return this.g(-d0); } - public MovingObjectPosition calculateIntercept(Vec3D vec3d, Vec3D vec3d1) { return b(vec3d, vec3d1); } // Paper - OBFHELPER - @Nullable - public MovingObjectPosition b(Vec3D vec3d, Vec3D vec3d1) { - return this.a(vec3d, vec3d1, (BlockPosition) null); - } - - @Nullable - public MovingObjectPosition a(Vec3D vec3d, Vec3D vec3d1, @Nullable BlockPosition blockposition) { - double[] adouble = new double[] { 1.0D}; - EnumDirection enumdirection = null; + public final Optional calculateIntercept(Vec3D vec3d, Vec3D vec3d1) { return b(vec3d, vec3d1); } // Paper - OBFHELPER + public Optional b(Vec3D vec3d, Vec3D vec3d1) { + double[] adouble = new double[]{1.0D}; double d0 = vec3d1.x - vec3d.x; double d1 = vec3d1.y - vec3d.y; double d2 = vec3d1.z - vec3d.z; + EnumDirection enumdirection = a(this, vec3d, adouble, (EnumDirection) null, d0, d1, d2); - enumdirection = a(blockposition == null ? this : this.a(blockposition), vec3d, adouble, enumdirection, d0, d1, d2); if (enumdirection == null) { - return null; + return Optional.empty(); } else { double d3 = adouble[0]; - return new MovingObjectPosition(vec3d.add(d3 * d0, d3 * d1, d3 * d2), enumdirection, blockposition == null ? BlockPosition.ZERO : blockposition); + return Optional.of(vec3d.add(d3 * d0, d3 * d1, d3 * d2)); } } @Nullable - public static MovingObjectPosition a(Iterable iterable, Vec3D vec3d, Vec3D vec3d1, BlockPosition blockposition) { - double[] adouble = new double[] { 1.0D}; + public static MovingObjectPositionBlock a(Iterable iterable, Vec3D vec3d, Vec3D vec3d1, BlockPosition blockposition) { + double[] adouble = new double[]{1.0D}; EnumDirection enumdirection = null; double d0 = vec3d1.x - vec3d.x; double d1 = vec3d1.y - vec3d.y; @@ -256,7 +270,7 @@ public class AxisAlignedBB { } else { double d3 = adouble[0]; - return new MovingObjectPosition(vec3d.add(d3 * d0, d3 * d1, d3 * d2), enumdirection, blockposition); + return new MovingObjectPositionBlock(vec3d.add(d3 * d0, d3 * d1, d3 * d2), enumdirection, blockposition, false); } } @@ -298,6 +312,10 @@ public class AxisAlignedBB { } public String toString() { - return "box[" + this.minX + ", " + this.minY + ", " + this.minZ + " -> " + this.maxX + ", " + this.maxY + ", " + this.maxZ + "]"; + return "box[" + this.minX + ", " + this.minY + ", " + this.minZ + "] -> [" + this.maxX + ", " + this.maxY + ", " + this.maxZ + "]"; + } + + public Vec3D f() { + return new Vec3D(MathHelper.d(0.5D, this.minX, this.maxX), MathHelper.d(0.5D, this.minY, this.maxY), MathHelper.d(0.5D, this.minZ, this.maxZ)); } } diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/main/java/net/minecraft/server/BaseBlockPosition.java index cc17a414f..e96428bb2 100644 --- a/src/main/java/net/minecraft/server/BaseBlockPosition.java +++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java @@ -67,36 +67,37 @@ public class BaseBlockPosition implements Comparable { return new BaseBlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX()); } - public double h(int i, int j, int k) { - double d0 = (double) (this.getX() - i); - double d1 = (double) (this.getY() - j); - double d2 = (double) (this.getZ() - k); + public boolean a(BaseBlockPosition baseblockposition, double d0) { + return this.distanceSquared((double) baseblockposition.x, (double) baseblockposition.y, (double) baseblockposition.z, false) < d0 * d0; // Paper + } - return Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + public boolean a(IPosition iposition, double d0) { + return this.distanceSquared(iposition.getX(), iposition.getY(), iposition.getZ(), true) < d0 * d0; } public double m(BaseBlockPosition baseblockposition) { - return this.h(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); + return this.distanceSquared((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ(), true); } - public double distanceSquared(double d0, double d1, double d2) { - double d3 = (double) this.getX() - d0; - double d4 = (double) this.getY() - d1; - double d5 = (double) this.getZ() - d2; - - return d3 * d3 + d4 * d4 + d5 * d5; + public double a(IPosition iposition, boolean flag) { + return this.distanceSquared(iposition.getX(), iposition.getY(), iposition.getZ(), flag); } - public double g(double d0, double d1, double d2) { - double d3 = (double) this.getX() + 0.5D - d0; - double d4 = (double) this.getY() + 0.5D - d1; - double d5 = (double) this.getZ() + 0.5D - d2; + public double distanceSquared(double d0, double d1, double d2, boolean flag) { + double d3 = flag ? 0.5D : 0.0D; + double d4 = (double) this.getX() + d3 - d0; + double d5 = (double) this.getY() + d3 - d1; + double d6 = (double) this.getZ() + d3 - d2; - return d3 * d3 + d4 * d4 + d5 * d5; + return d4 * d4 + d5 * d5 + d6 * d6; } - public double n(BaseBlockPosition baseblockposition) { - return this.distanceSquared((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ()); + public int n(BaseBlockPosition baseblockposition) { + float f = (float) Math.abs(baseblockposition.getX() - this.x); // Paper + float f1 = (float) Math.abs(baseblockposition.getY() - this.y); // Paper + float f2 = (float) Math.abs(baseblockposition.getZ() - this.z); // Paper + + return (int) (f + f1 + f2); } public String toString() { diff --git a/src/main/java/net/minecraft/server/BehaviorCareer.java b/src/main/java/net/minecraft/server/BehaviorCareer.java new file mode 100644 index 000000000..525501608 --- /dev/null +++ b/src/main/java/net/minecraft/server/BehaviorCareer.java @@ -0,0 +1,40 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableMap; +// CraftBukkit start +import org.bukkit.craftbukkit.entity.CraftVillager; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.VillagerCareerChangeEvent; +// CraftBukkit end + +public class BehaviorCareer extends Behavior { + + public BehaviorCareer() { + super(ImmutableMap.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT)); + } + + protected boolean a(WorldServer worldserver, EntityVillager entityvillager) { + return entityvillager.getVillagerData().getProfession() == VillagerProfession.NONE; + } + + protected void a(WorldServer worldserver, EntityVillager entityvillager, long i) { + GlobalPos globalpos = (GlobalPos) entityvillager.getBehaviorController().getMemory(MemoryModuleType.JOB_SITE).get(); + MinecraftServer minecraftserver = worldserver.getMinecraftServer(); + + minecraftserver.getWorldServer(globalpos.getDimensionManager()).B().c(globalpos.getBlockPosition()).ifPresent((villageplacetype) -> { + IRegistry.VILLAGER_PROFESSION.d().filter((villagerprofession) -> { + return villagerprofession.b() == villageplacetype; + }).findFirst().ifPresent((villagerprofession) -> { + // CraftBukkit start - Fire VillagerCareerChangeEvent where Villager gets employed + VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(entityvillager, CraftVillager.nmsToBukkitProfession(villagerprofession), VillagerCareerChangeEvent.ChangeReason.EMPLOYED); + if (event.isCancelled()) { + return; + } + + entityvillager.setVillagerData(entityvillager.getVillagerData().withProfession(CraftVillager.bukkitToNmsProfession(event.getProfession()))); + // CraftBukkit end + entityvillager.a(worldserver); + }); + }); + } +} diff --git a/src/main/java/net/minecraft/server/BehaviorFarm.java b/src/main/java/net/minecraft/server/BehaviorFarm.java new file mode 100644 index 000000000..0b7fa5084 --- /dev/null +++ b/src/main/java/net/minecraft/server/BehaviorFarm.java @@ -0,0 +1,169 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import java.util.List; +import javax.annotation.Nullable; + +public class BehaviorFarm extends Behavior { + + @Nullable + private BlockPosition a; + private boolean b; + private boolean c; + private long d; + private int e; + private final List f = Lists.newArrayList(); + + public BehaviorFarm() { + super(ImmutableMap.of(MemoryModuleType.LOOK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.SECONDARY_JOB_SITE, MemoryStatus.VALUE_PRESENT)); + } + + protected boolean a(WorldServer worldserver, EntityVillager entityvillager) { + if (!worldserver.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { + return false; + } else if (entityvillager.getVillagerData().getProfession() != VillagerProfession.FARMER) { + return false; + } else { + this.b = entityvillager.er(); + this.c = false; + InventorySubcontainer inventorysubcontainer = entityvillager.getInventory(); + int i = inventorysubcontainer.getSize(); + + for (int j = 0; j < i; ++j) { + ItemStack itemstack = inventorysubcontainer.getItem(j); + + if (itemstack.isEmpty()) { + this.c = true; + break; + } + + if (itemstack.getItem() == Items.WHEAT_SEEDS || itemstack.getItem() == Items.BEETROOT_SEEDS) { + this.c = true; + break; + } + } + + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(entityvillager.locX, entityvillager.locY, entityvillager.locZ); + + this.f.clear(); + + for (int k = -1; k <= 1; ++k) { + for (int l = -1; l <= 1; ++l) { + for (int i1 = -1; i1 <= 1; ++i1) { + blockposition_mutableblockposition.c(entityvillager.locX + (double) k, entityvillager.locY + (double) l, entityvillager.locZ + (double) i1); + if (this.a((BlockPosition) blockposition_mutableblockposition, worldserver)) { + this.f.add(new BlockPosition(blockposition_mutableblockposition)); + } + } + } + } + + this.a = this.a(worldserver); + return (this.b || this.c) && this.a != null; + } + } + + @Nullable + private BlockPosition a(WorldServer worldserver) { + return this.f.isEmpty() ? null : (BlockPosition) this.f.get(worldserver.getRandom().nextInt(this.f.size())); + } + + private boolean a(BlockPosition blockposition, WorldServer worldserver) { + IBlockData iblockdata = worldserver.getType(blockposition); + Block block = iblockdata.getBlock(); + Block block1 = worldserver.getType(blockposition.down()).getBlock(); + + return block instanceof BlockCrops && ((BlockCrops) block).isRipe(iblockdata) && this.c || iblockdata.isAir() && block1 instanceof BlockSoil && this.b; + } + + protected void a(WorldServer worldserver, EntityVillager entityvillager, long i) { + if (i > this.d && this.a != null) { + entityvillager.getBehaviorController().setMemory(MemoryModuleType.LOOK_TARGET, (new BehaviorTarget(this.a))); // CraftBukkit - decompile error + entityvillager.getBehaviorController().setMemory(MemoryModuleType.WALK_TARGET, (new MemoryTarget(new BehaviorTarget(this.a), 0.5F, 1))); // CraftBukkit - decompile error + } + + } + + protected void f(WorldServer worldserver, EntityVillager entityvillager, long i) { + entityvillager.getBehaviorController().removeMemory(MemoryModuleType.LOOK_TARGET); + entityvillager.getBehaviorController().removeMemory(MemoryModuleType.WALK_TARGET); + this.e = 0; + this.d = i + 40L; + } + + protected void d(WorldServer worldserver, EntityVillager entityvillager, long i) { + if (this.a != null && i > this.d) { + IBlockData iblockdata = worldserver.getType(this.a); + Block block = iblockdata.getBlock(); + Block block1 = worldserver.getType(this.a.down()).getBlock(); + + if (block instanceof BlockCrops && ((BlockCrops) block).isRipe(iblockdata) && this.c) { + // CraftBukkit start + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityvillager, this.a, Blocks.AIR.getBlockData()).isCancelled()) { + worldserver.b(this.a, true); + } + // CraftBukkit end + } + + if (iblockdata.isAir() && block1 instanceof BlockSoil && this.b) { + InventorySubcontainer inventorysubcontainer = entityvillager.getInventory(); + + for (int j = 0; j < inventorysubcontainer.getSize(); ++j) { + ItemStack itemstack = inventorysubcontainer.getItem(j); + boolean flag = false; + + if (!itemstack.isEmpty()) { + // CraftBukkit start + Block planted = null; + if (itemstack.getItem() == Items.WHEAT_SEEDS) { + planted = Blocks.WHEAT; + flag = true; + } else if (itemstack.getItem() == Items.POTATO) { + planted = Blocks.POTATOES; + flag = true; + } else if (itemstack.getItem() == Items.CARROT) { + planted = Blocks.CARROTS; + flag = true; + } else if (itemstack.getItem() == Items.BEETROOT_SEEDS) { + planted = Blocks.BEETROOTS; + flag = true; + } + + if (planted != null && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityvillager, this.a, planted.getBlockData()).isCancelled()) { + worldserver.setTypeAndData(this.a, planted.getBlockData(), 3); + } else { + flag = false; + } + // CraftBukkit end + } + + if (flag) { + worldserver.playSound((EntityHuman) null, (double) this.a.getX(), (double) this.a.getY(), (double) this.a.getZ(), SoundEffects.ITEM_CROP_PLANT, SoundCategory.BLOCKS, 1.0F, 1.0F); + itemstack.subtract(1); + if (itemstack.isEmpty()) { + inventorysubcontainer.setItem(j, ItemStack.a); + } + break; + } + } + } + + if (block instanceof BlockCrops && !((BlockCrops) block).isRipe(iblockdata)) { + this.f.remove(this.a); + this.a = this.a(worldserver); + if (this.a != null) { + this.d = i + 20L; + entityvillager.getBehaviorController().setMemory(MemoryModuleType.WALK_TARGET, (new MemoryTarget(new BehaviorTarget(this.a), 0.5F, 1))); // CraftBukkit - decompile error + entityvillager.getBehaviorController().setMemory(MemoryModuleType.LOOK_TARGET, (new BehaviorTarget(this.a))); // CraftBukkit - decompile error + } + } + } + + ++this.e; + } + + protected boolean g(WorldServer worldserver, EntityVillager entityvillager, long i) { + return this.e < 200; + } +} diff --git a/src/main/java/net/minecraft/server/BehaviorInteractDoor.java b/src/main/java/net/minecraft/server/BehaviorInteractDoor.java new file mode 100644 index 000000000..01d9c2d92 --- /dev/null +++ b/src/main/java/net/minecraft/server/BehaviorInteractDoor.java @@ -0,0 +1,101 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class BehaviorInteractDoor extends Behavior { + + public BehaviorInteractDoor() { + super(ImmutableMap.of(MemoryModuleType.PATH, MemoryStatus.VALUE_PRESENT, MemoryModuleType.INTERACTABLE_DOORS, MemoryStatus.VALUE_PRESENT, MemoryModuleType.OPENED_DOORS, MemoryStatus.REGISTERED)); + } + + @Override + protected void a(WorldServer worldserver, EntityLiving entityliving, long i) { + BehaviorController behaviorcontroller = entityliving.getBehaviorController(); + PathEntity pathentity = (PathEntity) behaviorcontroller.getMemory(MemoryModuleType.PATH).get(); + List list = (List) behaviorcontroller.getMemory(MemoryModuleType.INTERACTABLE_DOORS).get(); + List list1 = (List) pathentity.d().stream().map((pathpoint) -> { + return new BlockPosition(pathpoint.a, pathpoint.b, pathpoint.c); + }).collect(Collectors.toList()); + Set set = this.a(worldserver, list, list1); + int j = pathentity.f() - 1; + + this.a(worldserver, list1, set, j, entityliving, behaviorcontroller); + } + + private Set a(WorldServer worldserver, List list, List list1) { + Stream stream = list.stream().filter((globalpos) -> { + return globalpos.getDimensionManager() == worldserver.getWorldProvider().getDimensionManager(); + }).map(GlobalPos::getBlockPosition); + + list1.getClass(); + return (Set) stream.filter(list1::contains).collect(Collectors.toSet()); + } + + private void a(WorldServer worldserver, List list, Set set, int i, EntityLiving entityliving, BehaviorController behaviorcontroller) { + set.forEach((blockposition) -> { + int j = list.indexOf(blockposition); + IBlockData iblockdata = worldserver.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (TagsBlock.WOODEN_DOORS.isTagged(block) && block instanceof BlockDoor) { + boolean flag = j >= i; + + // CraftBukkit start - entities opening doors + org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entityliving.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(entityliving.world, blockposition)); + entityliving.world.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + // CaftBukkit end + ((BlockDoor) block).setDoor(worldserver, blockposition, flag); + GlobalPos globalpos = GlobalPos.create(worldserver.getWorldProvider().getDimensionManager(), blockposition); + + if (!behaviorcontroller.getMemory(MemoryModuleType.OPENED_DOORS).isPresent() && flag) { + behaviorcontroller.setMemory(MemoryModuleType.OPENED_DOORS, Sets.newHashSet(new GlobalPos[]{globalpos})); // CraftBukkit - decompile error + } else { + behaviorcontroller.getMemory(MemoryModuleType.OPENED_DOORS).ifPresent((set1) -> { + if (flag) { + set1.add(globalpos); + } else { + set1.remove(globalpos); + } + + }); + } + } + + }); + a(worldserver, list, i, entityliving, behaviorcontroller); + } + + public static void a(WorldServer worldserver, List list, int i, EntityLiving entityliving, BehaviorController behaviorcontroller) { + behaviorcontroller.getMemory(MemoryModuleType.OPENED_DOORS).ifPresent((set) -> { + Iterator iterator = set.iterator(); + + while (iterator.hasNext()) { + GlobalPos globalpos = (GlobalPos) iterator.next(); + BlockPosition blockposition = globalpos.getBlockPosition(); + int j = list.indexOf(blockposition); + + if (worldserver.getWorldProvider().getDimensionManager() != globalpos.getDimensionManager()) { + iterator.remove(); + } else { + IBlockData iblockdata = worldserver.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (TagsBlock.WOODEN_DOORS.isTagged(block) && block instanceof BlockDoor && j < i && blockposition.a((IPosition) entityliving.getPositionVector(), 4.0D)) { + ((BlockDoor) block).setDoor(worldserver, blockposition, false); + iterator.remove(); + } + } + } + + }); + } +} diff --git a/src/main/java/net/minecraft/server/BehaviorMakeLove.java b/src/main/java/net/minecraft/server/BehaviorMakeLove.java new file mode 100644 index 000000000..f958c46f3 --- /dev/null +++ b/src/main/java/net/minecraft/server/BehaviorMakeLove.java @@ -0,0 +1,126 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableMap; +import java.util.Optional; + +public class BehaviorMakeLove extends Behavior { + + private long a; + + public BehaviorMakeLove() { + super(ImmutableMap.of(MemoryModuleType.BREED_TARGET, MemoryStatus.VALUE_PRESENT, MemoryModuleType.VISIBLE_MOBS, MemoryStatus.VALUE_PRESENT), 350, 350); + } + + protected boolean a(WorldServer worldserver, EntityVillager entityvillager) { + return this.b(entityvillager); + } + + protected boolean g(WorldServer worldserver, EntityVillager entityvillager, long i) { + return i <= this.a && this.b(entityvillager); + } + + protected void a(WorldServer worldserver, EntityVillager entityvillager, long i) { + EntityVillager entityvillager1 = this.a(entityvillager); + + BehaviorUtil.a((EntityLiving) entityvillager, (EntityLiving) entityvillager1); + worldserver.broadcastEntityEffect(entityvillager1, (byte) 18); + worldserver.broadcastEntityEffect(entityvillager, (byte) 18); + int j = 275 + entityvillager.getRandom().nextInt(50); + + this.a = i + (long) j; + } + + protected void d(WorldServer worldserver, EntityVillager entityvillager, long i) { + EntityVillager entityvillager1 = this.a(entityvillager); + + if (entityvillager.h((Entity) entityvillager1) <= 5.0D) { + BehaviorUtil.a((EntityLiving) entityvillager, (EntityLiving) entityvillager1); + if (i >= this.a) { + entityvillager.eo(); + entityvillager1.eo(); + this.a(worldserver, entityvillager, entityvillager1); + } else if (entityvillager.getRandom().nextInt(35) == 0) { + worldserver.broadcastEntityEffect(entityvillager1, (byte) 12); + worldserver.broadcastEntityEffect(entityvillager, (byte) 12); + } + + } + } + + private void a(WorldServer worldserver, EntityVillager entityvillager, EntityVillager entityvillager1) { + Optional optional = this.b(worldserver, entityvillager); + + if (!optional.isPresent()) { + worldserver.broadcastEntityEffect(entityvillager1, (byte) 13); + worldserver.broadcastEntityEffect(entityvillager, (byte) 13); + } else { + Optional optional1 = this.a(entityvillager, entityvillager1); + + if (optional1.isPresent()) { + this.a(worldserver, (EntityVillager) optional1.get(), (BlockPosition) optional.get()); + } else { + worldserver.B().b((BlockPosition) optional.get()); + } + } + + } + + protected void f(WorldServer worldserver, EntityVillager entityvillager, long i) { + entityvillager.getBehaviorController().removeMemory(MemoryModuleType.BREED_TARGET); + } + + private EntityVillager a(EntityVillager entityvillager) { + return (EntityVillager) entityvillager.getBehaviorController().getMemory(MemoryModuleType.BREED_TARGET).get(); + } + + private boolean b(EntityVillager entityvillager) { + BehaviorController behaviorcontroller = entityvillager.getBehaviorController(); + + if (!behaviorcontroller.getMemory(MemoryModuleType.BREED_TARGET).isPresent()) { + return false; + } else { + EntityVillager entityvillager1 = this.a(entityvillager); + + return BehaviorUtil.a(behaviorcontroller, MemoryModuleType.BREED_TARGET, EntityTypes.VILLAGER) && entityvillager.canBreed() && entityvillager1.canBreed(); + } + } + + private Optional b(WorldServer worldserver, EntityVillager entityvillager) { + return worldserver.B().a(VillagePlaceType.q.c(), (blockposition) -> { + return this.a(entityvillager, blockposition); + }, new BlockPosition(entityvillager), 48); + } + + private boolean a(EntityVillager entityvillager, BlockPosition blockposition) { + PathEntity pathentity = entityvillager.getNavigation().a(blockposition, VillagePlaceType.q.d()); + + return pathentity != null && pathentity.h(); + } + + private Optional a(EntityVillager entityvillager, EntityVillager entityvillager1) { + EntityVillager entityvillager2 = entityvillager.createChild(entityvillager1); + // CraftBukkit start - call EntityBreedEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityvillager2, entityvillager, entityvillager1, null, null, 0).isCancelled()) { + return Optional.empty(); + } + // CraftBukkit end + + if (entityvillager2 == null) { + return Optional.empty(); + } else { + entityvillager.setAgeRaw(6000); + entityvillager1.setAgeRaw(6000); + entityvillager2.setAgeRaw(-24000); + entityvillager2.setPositionRotation(entityvillager.locX, entityvillager.locY, entityvillager.locZ, 0.0F, 0.0F); + entityvillager.world.addEntity(entityvillager2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + entityvillager.world.broadcastEntityEffect(entityvillager2, (byte) 12); + return Optional.of(entityvillager2); + } + } + + private void a(WorldServer worldserver, EntityVillager entityvillager, BlockPosition blockposition) { + GlobalPos globalpos = GlobalPos.create(worldserver.getWorldProvider().getDimensionManager(), blockposition); + + entityvillager.getBehaviorController().setMemory(MemoryModuleType.HOME, globalpos); // CraftBukkit - decompile error + } +} diff --git a/src/main/java/net/minecraft/server/BehaviorProfession.java b/src/main/java/net/minecraft/server/BehaviorProfession.java new file mode 100644 index 000000000..7f2d6b864 --- /dev/null +++ b/src/main/java/net/minecraft/server/BehaviorProfession.java @@ -0,0 +1,33 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableMap; +// CraftBukkit start +import org.bukkit.craftbukkit.entity.CraftVillager; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.VillagerCareerChangeEvent; +// CraftBukkit end + +public class BehaviorProfession extends Behavior { + + public BehaviorProfession() { + super(ImmutableMap.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_ABSENT)); + } + + protected boolean a(WorldServer worldserver, EntityVillager entityvillager) { + VillagerData villagerdata = entityvillager.getVillagerData(); + + return villagerdata.getProfession() != VillagerProfession.NONE && villagerdata.getProfession() != VillagerProfession.NITWIT && entityvillager.getExperience() == 0 && villagerdata.getLevel() <= 1; + } + + protected void a(WorldServer worldserver, EntityVillager entityvillager, long i) { + // CraftBukkit start + VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(entityvillager, CraftVillager.nmsToBukkitProfession(VillagerProfession.NONE), VillagerCareerChangeEvent.ChangeReason.EMPLOYED); + if (event.isCancelled()) { + return; + } + + entityvillager.setVillagerData(entityvillager.getVillagerData().withProfession(CraftVillager.bukkitToNmsProfession(event.getProfession()))); + // CraftBukkit end + entityvillager.a(worldserver); + } +} diff --git a/src/main/java/net/minecraft/server/BehaviorUtil.java b/src/main/java/net/minecraft/server/BehaviorUtil.java new file mode 100644 index 000000000..306844c67 --- /dev/null +++ b/src/main/java/net/minecraft/server/BehaviorUtil.java @@ -0,0 +1,77 @@ +package net.minecraft.server; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Stream; + +public class BehaviorUtil { + + public static void a(EntityLiving entityliving, EntityLiving entityliving1) { + b(entityliving, entityliving1); + d(entityliving, entityliving1); + } + + public static boolean a(BehaviorController behaviorcontroller, EntityLiving entityliving) { + return behaviorcontroller.getMemory(MemoryModuleType.VISIBLE_MOBS).filter((list) -> { + return list.contains(entityliving); + }).isPresent(); + } + + public static boolean a(BehaviorController behaviorcontroller, MemoryModuleType memorymoduletype, EntityTypes entitytypes) { + return behaviorcontroller.getMemory(memorymoduletype).filter((entityliving) -> { + return entityliving.getEntityType() == entitytypes; + }).filter(EntityLiving::isAlive).filter((entityliving) -> { + return a(behaviorcontroller, entityliving); + }).isPresent(); + } + + public static void b(EntityLiving entityliving, EntityLiving entityliving1) { + c(entityliving, entityliving1); + c(entityliving1, entityliving); + } + + public static void c(EntityLiving entityliving, EntityLiving entityliving1) { + entityliving.getBehaviorController().setMemory(MemoryModuleType.LOOK_TARGET, (new BehaviorPositionEntity(entityliving1))); // CraftBukkit - decompile error + } + + public static void d(EntityLiving entityliving, EntityLiving entityliving1) { + boolean flag = true; + + a(entityliving, entityliving1, 2); + a(entityliving1, entityliving, 2); + } + + public static void a(EntityLiving entityliving, EntityLiving entityliving1, int i) { + float f = (float) entityliving.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue(); + BehaviorPositionEntity behaviorpositionentity = new BehaviorPositionEntity(entityliving1); + MemoryTarget memorytarget = new MemoryTarget(behaviorpositionentity, f, i); + + entityliving.getBehaviorController().setMemory(MemoryModuleType.LOOK_TARGET, behaviorpositionentity); // CraftBukkit - decompile error + entityliving.getBehaviorController().setMemory(MemoryModuleType.WALK_TARGET, memorytarget); // CraftBukkit - decompile error + } + + public static void a(EntityLiving entityliving, ItemStack itemstack, EntityLiving entityliving1) { + if (itemstack.isEmpty()) return; // CraftBukkit - SPIGOT-4940: no empty loot + double d0 = entityliving.locY - 0.30000001192092896D + (double) entityliving.getHeadHeight(); + EntityItem entityitem = new EntityItem(entityliving.world, entityliving.locX, d0, entityliving.locZ, itemstack); + BlockPosition blockposition = new BlockPosition(entityliving1); + BlockPosition blockposition1 = new BlockPosition(entityliving); + float f = 0.3F; + Vec3D vec3d = new Vec3D(blockposition.b(blockposition1)); + + vec3d = vec3d.d().a(0.30000001192092896D); + entityitem.setMot(vec3d); + entityitem.defaultPickupDelay(); + entityliving.world.addEntity(entityitem); + } + + public static SectionPosition a(WorldServer worldserver, SectionPosition sectionposition, int i) { + int j = worldserver.b(sectionposition); + Stream stream = SectionPosition.a(sectionposition, i).filter((sectionposition1) -> { // CraftBukkit - decompile error + return worldserver.b(sectionposition1) < j; + }); + + worldserver.getClass(); + return (SectionPosition) stream.min(Comparator.comparingInt(worldserver::b)).orElse(sectionposition); + } +} diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java index 8d80e748d..a86ece834 100644 --- a/src/main/java/net/minecraft/server/BiomeBase.java +++ b/src/main/java/net/minecraft/server/BiomeBase.java @@ -3,154 +3,81 @@ package net.minecraft.server; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import java.util.Collections; +import it.unimi.dsi.fastutil.longs.Long2FloatLinkedOpenHashMap; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.stream.Collectors; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public abstract class BiomeBase { - public static final Logger a = LogManager.getLogger(); - public static final WorldGenCarverAbstract b = new WorldGenCaves(); - public static final WorldGenCarverAbstract c = new WorldGenCavesHell(); - public static final WorldGenCarverAbstract d = new WorldGenCanyon(); - public static final WorldGenCarverAbstract e = new WorldGenCanyonOcean(); - public static final WorldGenCarverAbstract f = new WorldGenCavesOcean(); - public static final WorldGenDecorator g = new WorldGenDecoratorHeight(); - public static final WorldGenDecorator h = new WorldGenDecoratorSkyVisible(); - public static final WorldGenDecorator i = new WorldGenDecoratorHeight32(); - public static final WorldGenDecorator j = new WorldGenDecoratorHeightDouble(); - public static final WorldGenDecorator k = new WorldGenDecoratorHeight64(); - public static final WorldGenDecorator l = new WorldGenDecoratorNoiseHeight32(); - public static final WorldGenDecorator m = new WorldGenDecoratorNoiseHeightDouble(); - public static final WorldGenDecorator n = new WorldGenDecoratorEmpty(); - public static final WorldGenDecorator o = new WorldGenDecoratorChance(); - public static final WorldGenDecorator p = new WorldGenDecoratorChanceHeight(); - public static final WorldGenDecorator q = new WorldGenDecoratorChancePass(); - public static final WorldGenDecorator r = new WorldGenDecoratorSkyVisibleBiased(); - public static final WorldGenDecorator s = new WorldGenDecoratorHeightExtraChance(); - public static final WorldGenDecorator t = new WorldGenDecoratorNetherHeight(); - public static final WorldGenDecorator u = new WorldGenDecoratorHeightBiased(); - public static final WorldGenDecorator v = new WorldGenDecoratorHeightBiased2(); - public static final WorldGenDecorator w = new WorldGenDecoratorNetherRandomCount(); - public static final WorldGenDecorator x = new WorldGenDecoratorNetherChance(); - public static final WorldGenDecorator y = new WorldGenFeatureChanceDecorator(); - public static final WorldGenDecorator z = new WorldGenFeatureChanceDecoratorHeight(); - public static final WorldGenDecorator A = new WorldGenDecoratorHeightAverage(); - public static final WorldGenDecorator B = new WorldGenDecoratorSolidTop(); - public static final WorldGenDecorator C = new WorldGenDecoratorSolidTopHeight(); - public static final WorldGenDecorator D = new WorldGenDecoratorSolidTopNoise(); - public static final WorldGenDecorator E = new WorldGenDecoratorCarveMask(); - public static final WorldGenDecorator F = new WorldGenDecoratorForestRock(); - public static final WorldGenDecorator G = new WorldGenDecoratorNetherFire(); - public static final WorldGenDecorator H = new WorldGenDecoratorNetherMagma(); - public static final WorldGenDecorator I = new WorldGenDecoratorEmerald(); - public static final WorldGenDecorator J = new WorldGenDecoratorLakeLava(); - public static final WorldGenDecorator K = new WorldGenDecoratorLakeWater(); - public static final WorldGenDecorator L = new WorldGenDecoratorDungeon(); - public static final WorldGenDecorator M = new WorldGenDecoratorRoofedTree(); - public static final WorldGenDecorator N = new WorldGenDecoratorIceburg(); - public static final WorldGenDecorator O = new WorldGenDecoratorNetherGlowstone(); - public static final WorldGenDecorator P = new WorldGenDecoratorSpike(); - public static final WorldGenDecorator Q = new WorldGenDecoratorEndIsland(); - public static final WorldGenDecorator R = new WorldGenDecoratorChorusPlant(); - public static final WorldGenDecorator S = new WorldGenDecoratorEndGateway(); - protected static final IBlockData T = Blocks.AIR.getBlockData(); - protected static final IBlockData U = Blocks.DIRT.getBlockData(); - protected static final IBlockData V = Blocks.GRASS_BLOCK.getBlockData(); - protected static final IBlockData W = Blocks.PODZOL.getBlockData(); - protected static final IBlockData X = Blocks.GRAVEL.getBlockData(); - protected static final IBlockData Y = Blocks.STONE.getBlockData(); - protected static final IBlockData Z = Blocks.COARSE_DIRT.getBlockData(); - protected static final IBlockData aa = Blocks.SAND.getBlockData(); - protected static final IBlockData ab = Blocks.RED_SAND.getBlockData(); - protected static final IBlockData ac = Blocks.WHITE_TERRACOTTA.getBlockData(); - protected static final IBlockData ad = Blocks.MYCELIUM.getBlockData(); - protected static final IBlockData ae = Blocks.NETHERRACK.getBlockData(); - protected static final IBlockData af = Blocks.END_STONE.getBlockData(); - public static final WorldGenSurfaceConfigurationBase ag = new WorldGenSurfaceConfigurationBase(BiomeBase.T, BiomeBase.T, BiomeBase.T); - public static final WorldGenSurfaceConfigurationBase ah = new WorldGenSurfaceConfigurationBase(BiomeBase.U, BiomeBase.U, BiomeBase.X); - public static final WorldGenSurfaceConfigurationBase ai = new WorldGenSurfaceConfigurationBase(BiomeBase.V, BiomeBase.U, BiomeBase.X); - public static final WorldGenSurfaceConfigurationBase aj = new WorldGenSurfaceConfigurationBase(BiomeBase.Y, BiomeBase.Y, BiomeBase.X); - public static final WorldGenSurfaceConfigurationBase ak = new WorldGenSurfaceConfigurationBase(BiomeBase.X, BiomeBase.X, BiomeBase.X); - public static final WorldGenSurfaceConfigurationBase al = new WorldGenSurfaceConfigurationBase(BiomeBase.Z, BiomeBase.U, BiomeBase.X); - public static final WorldGenSurfaceConfigurationBase am = new WorldGenSurfaceConfigurationBase(BiomeBase.W, BiomeBase.U, BiomeBase.X); - public static final WorldGenSurfaceConfigurationBase an = new WorldGenSurfaceConfigurationBase(BiomeBase.aa, BiomeBase.aa, BiomeBase.aa); - public static final WorldGenSurfaceConfigurationBase ao = new WorldGenSurfaceConfigurationBase(BiomeBase.V, BiomeBase.U, BiomeBase.aa); - public static final WorldGenSurfaceConfigurationBase ap = new WorldGenSurfaceConfigurationBase(BiomeBase.aa, BiomeBase.aa, BiomeBase.X); - public static final WorldGenSurfaceConfigurationBase aq = new WorldGenSurfaceConfigurationBase(BiomeBase.ab, BiomeBase.ac, BiomeBase.X); - public static final WorldGenSurfaceConfigurationBase ar = new WorldGenSurfaceConfigurationBase(BiomeBase.ad, BiomeBase.U, BiomeBase.X); - public static final WorldGenSurfaceConfigurationBase as = new WorldGenSurfaceConfigurationBase(BiomeBase.ae, BiomeBase.ae, BiomeBase.ae); - public static final WorldGenSurfaceConfigurationBase at = new WorldGenSurfaceConfigurationBase(BiomeBase.af, BiomeBase.af, BiomeBase.af); - public static final WorldGenSurface au = new WorldGenSurfaceDefaultBlock(); - public static final WorldGenSurface av = new WorldGenSurfaceExtremeHills(); - public static final WorldGenSurface aw = new WorldGenSurfaceSavannaMutated(); - public static final WorldGenSurface ax = new WorldGenSurfaceExtremeHillMutated(); - public static final WorldGenSurface ay = new WorldGenSurfaceTaigaMega(); - public static final WorldGenSurface az = new WorldGenSurfaceSwamp(); - public static final WorldGenSurface aA = new WorldGenSurfaceMesa(); - public static final WorldGenSurface aB = new WorldGenSurfaceMesaForest(); - public static final WorldGenSurface aC = new WorldGenSurfaceMesaBryce(); - public static final WorldGenSurface aD = new WorldGenSurfaceFrozenOcean(); - public static final WorldGenSurface aE = new WorldGenSurfaceNether(); - public static final WorldGenSurface aF = new WorldGenSurfaceEmpty(); - public static final Set aG = Sets.newHashSet(); - public static final RegistryBlockID aH = new RegistryBlockID<>(); - protected static final NoiseGenerator3 aI = new NoiseGenerator3(new Random(1234L), 1); - public static final NoiseGenerator3 aJ = new NoiseGenerator3(new Random(2345L), 1); + public static final Logger LOGGER = LogManager.getLogger(); + public static final Set b = Sets.newHashSet(); + public static final RegistryBlockID c = new RegistryBlockID<>(); + protected static final NoiseGenerator3 d = new NoiseGenerator3(new Random(1234L), 1); + public static final NoiseGenerator3 e = new NoiseGenerator3(new Random(2345L), 1); @Nullable - protected String aK; - protected final float aL; - protected final float aM; - protected final float aN; - protected final float aO; - protected final int aP; - protected final int aQ; + protected String f; + protected final float g; + protected final float h; + protected final float i; + protected final float j; + protected final int k; + protected final int l; @Nullable - protected final String aR; - protected final WorldGenSurfaceComposite aS; - protected final BiomeBase.Geography aT; - protected final BiomeBase.Precipitation aU; - protected final Map>> aV = Maps.newHashMap(); - protected final Map>> aW = Maps.newHashMap(); - protected final List> aX = Lists.newArrayList(); - protected final Map, WorldGenFeatureConfiguration> aY = Maps.newHashMap(); - private final java.util.EnumMap> aZ = Maps.newEnumMap(EnumCreatureType.class); // Paper + protected final String m; + protected final WorldGenSurfaceComposite n; + protected final BiomeBase.Geography o; + protected final BiomeBase.Precipitation p; + protected final Map>> q = Maps.newHashMap(); + protected final Map>> r = Maps.newHashMap(); + protected final List> s = Lists.newArrayList(); + protected final Map, WorldGenFeatureConfiguration> t = Maps.newHashMap(); + private final java.util.EnumMap> u = Maps.newEnumMap(EnumCreatureType.class); // Paper + private final ThreadLocal v = ThreadLocal.withInitial(() -> { + return (Long2FloatLinkedOpenHashMap) SystemUtils.a(() -> { + Long2FloatLinkedOpenHashMap long2floatlinkedopenhashmap = new Long2FloatLinkedOpenHashMap(1024, 0.25F) { + protected void rehash(int i) {} + }; + + long2floatlinkedopenhashmap.defaultReturnValue(Float.NaN); + return long2floatlinkedopenhashmap; + }); + }); @Nullable public static BiomeBase a(BiomeBase biomebase) { - return (BiomeBase) BiomeBase.aH.fromId(IRegistry.BIOME.a(biomebase)); // Paper - decompile fix + return (BiomeBase) BiomeBase.c.fromId(IRegistry.BIOME.a(biomebase)); // Paper - decompile fix } - public static WorldGenCarverWrapper a(WorldGenCarver worldgencarver, C c0) { - return new WorldGenCarverWrapper<>(worldgencarver, c0); + public static WorldGenCarverWrapper a(WorldGenCarverAbstract worldgencarverabstract, C c0) { + return new WorldGenCarverWrapper<>(worldgencarverabstract, c0); } - public static WorldGenFeatureComposite a(WorldGenerator worldgenerator, F f0, WorldGenDecorator worldgendecorator, D d0) { - return new WorldGenFeatureComposite<>(worldgenerator, f0, worldgendecorator, d0); - } + public static WorldGenFeatureConfigured a(WorldGenerator worldgenerator, F f0, WorldGenDecorator worldgendecorator, D d0) { + WorldGenerator worldgenerator1 = worldgenerator instanceof WorldGenFlowers ? WorldGenerator.DECORATED_FLOWER : WorldGenerator.DECORATED; - public static WorldGenFeatureCompositeFlower a(WorldGenFlowers worldgenflowers, WorldGenDecorator worldgendecorator, D d0) { - return new WorldGenFeatureCompositeFlower<>(worldgenflowers, worldgendecorator, d0); + return new WorldGenFeatureConfigured<>(worldgenerator1, new WorldGenFeatureCompositeConfiguration(worldgenerator, f0, worldgendecorator, d0)); } protected BiomeBase(BiomeBase.a biomebase_a) { if (biomebase_a.a != null && biomebase_a.b != null && biomebase_a.c != null && biomebase_a.d != null && biomebase_a.e != null && biomebase_a.f != null && biomebase_a.g != null && biomebase_a.h != null && biomebase_a.i != null) { - this.aS = biomebase_a.a; - this.aU = biomebase_a.b; - this.aT = biomebase_a.c; - this.aL = biomebase_a.d; - this.aM = biomebase_a.e; - this.aN = biomebase_a.f; - this.aO = biomebase_a.g; - this.aP = biomebase_a.h; - this.aQ = biomebase_a.i; - this.aR = biomebase_a.j; + this.n = biomebase_a.a; + this.p = biomebase_a.b; + this.o = biomebase_a.c; + this.g = biomebase_a.d; + this.h = biomebase_a.e; + this.i = biomebase_a.f; + this.j = biomebase_a.g; + this.k = biomebase_a.h; + this.l = biomebase_a.i; + this.m = biomebase_a.j; WorldGenStage.Decoration[] aworldgenstage_decoration = WorldGenStage.Decoration.values(); int i = aworldgenstage_decoration.length; @@ -159,7 +86,7 @@ public abstract class BiomeBase { for (j = 0; j < i; ++j) { WorldGenStage.Decoration worldgenstage_decoration = aworldgenstage_decoration[j]; - this.aW.put(worldgenstage_decoration, Lists.newArrayList()); + this.r.put(worldgenstage_decoration, Lists.newArrayList()); } EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values(); @@ -169,7 +96,7 @@ public abstract class BiomeBase { for (j = 0; j < i; ++j) { EnumCreatureType enumcreaturetype = aenumcreaturetype[j]; - this.aZ.put(enumcreaturetype, new MobList()); // Paper + this.u.put(enumcreaturetype, new MobList()); // Paper } } else { @@ -177,48 +104,33 @@ public abstract class BiomeBase { } } - protected void a() { - this.a(WorldGenStage.Decoration.UNDERGROUND_STRUCTURES, a(WorldGenerator.f, new WorldGenMineshaftConfiguration(0.004000000189989805D, WorldGenMineshaft.Type.NORMAL), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, a(WorldGenerator.e, new WorldGenFeatureVillageConfiguration(0, WorldGenVillagePieces.Material.OAK), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.UNDERGROUND_STRUCTURES, a(WorldGenerator.m, new WorldGenFeatureStrongholdConfiguration(), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, a(WorldGenerator.l, new WorldGenFeatureSwampHutConfiguration(), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, a(WorldGenerator.i, new WorldGenFeatureDesertPyramidConfiguration(), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, a(WorldGenerator.h, new WorldGenFeatureJunglePyramidConfiguration(), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, a(WorldGenerator.j, new WorldGenFeatureIglooConfiguration(), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, a(WorldGenerator.k, new WorldGenFeatureShipwreckConfiguration(false), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, a(WorldGenerator.n, new WorldGenMonumentConfiguration(), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, a(WorldGenerator.g, new WorldGenMansionConfiguration(), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.SURFACE_STRUCTURES, a(WorldGenerator.o, new WorldGenFeatureOceanRuinConfiguration(WorldGenFeatureOceanRuin.Temperature.COLD, 0.3F, 0.9F), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - this.a(WorldGenStage.Decoration.UNDERGROUND_STRUCTURES, a(WorldGenerator.r, new WorldGenBuriedTreasureConfiguration(0.01F), BiomeBase.n, WorldGenFeatureDecoratorConfiguration.e)); - } - - public boolean b() { - return this.aR != null; + public boolean a() { + return this.m != null; } protected void a(EnumCreatureType enumcreaturetype, BiomeBase.BiomeMeta biomebase_biomemeta) { - ((List) this.aZ.get(enumcreaturetype)).add(biomebase_biomemeta); + ((List) this.u.get(enumcreaturetype)).add(biomebase_biomemeta); } public List getMobs(EnumCreatureType enumcreaturetype) { - return (List) this.aZ.get(enumcreaturetype); + return (List) this.u.get(enumcreaturetype); } - public BiomeBase.Precipitation c() { - return this.aU; + public BiomeBase.Precipitation b() { + return this.p; } - public boolean d() { + public boolean c() { return this.getHumidity() > 0.85F; } - public float e() { + public float d() { return 0.1F; } - public float getAdjustedTemperature(BlockPosition blockposition) { + protected float c(BlockPosition blockposition) { if (blockposition.getY() > 64) { - float f = (float) (BiomeBase.aI.a((double) ((float) blockposition.getX() / 8.0F), (double) ((float) blockposition.getZ() / 8.0F)) * 4.0D); + float f = (float) (BiomeBase.d.a((double) ((float) blockposition.getX() / 8.0F), (double) ((float) blockposition.getZ() / 8.0F)) * 4.0D); return this.getTemperature() - (f + (float) blockposition.getY() - 64.0F) * 0.05F / 30.0F; } else { @@ -226,6 +138,25 @@ public abstract class BiomeBase { } } + public final float getAdjustedTemperature(BlockPosition blockposition) { + long i = blockposition.asLong(); + Long2FloatLinkedOpenHashMap long2floatlinkedopenhashmap = (Long2FloatLinkedOpenHashMap) this.v.get(); + float f = long2floatlinkedopenhashmap.get(i); + + if (!Float.isNaN(f)) { + return f; + } else { + float f1 = this.c(blockposition); + + if (long2floatlinkedopenhashmap.size() == 1024) { + long2floatlinkedopenhashmap.removeFirstFloat(); + } + + long2floatlinkedopenhashmap.put(i, f1); + return f1; + } + } + public boolean a(IWorldReader iworldreader, BlockPosition blockposition) { return this.a(iworldreader, blockposition, true); } @@ -238,12 +169,12 @@ public abstract class BiomeBase { IBlockData iblockdata = iworldreader.getType(blockposition); Fluid fluid = iworldreader.getFluid(blockposition); - if (fluid.c() == FluidTypes.WATER && iblockdata.getBlock() instanceof BlockFluids) { + if (fluid.getType() == FluidTypes.WATER && iblockdata.getBlock() instanceof BlockFluids) { if (!flag) { return true; } - boolean flag1 = iworldreader.B(blockposition.west()) && iworldreader.B(blockposition.east()) && iworldreader.B(blockposition.north()) && iworldreader.B(blockposition.south()); + boolean flag1 = iworldreader.x(blockposition.west()) && iworldreader.x(blockposition.east()) && iworldreader.x(blockposition.north()) && iworldreader.x(blockposition.south()); if (!flag1) { return true; @@ -271,206 +202,126 @@ public abstract class BiomeBase { } } - public void a(WorldGenStage.Decoration worldgenstage_decoration, WorldGenFeatureComposite worldgenfeaturecomposite) { - if (worldgenfeaturecomposite instanceof WorldGenFeatureCompositeFlower) { - this.aX.add((WorldGenFeatureCompositeFlower) worldgenfeaturecomposite); + public void a(WorldGenStage.Decoration worldgenstage_decoration, WorldGenFeatureConfigured worldgenfeatureconfigured) { + if (worldgenfeatureconfigured.a == WorldGenerator.DECORATED_FLOWER) { + this.s.add(worldgenfeatureconfigured); } - ((List) this.aW.get(worldgenstage_decoration)).add(worldgenfeaturecomposite); + ((List) this.r.get(worldgenstage_decoration)).add(worldgenfeatureconfigured); } - public void a(WorldGenStage.Features worldgenstage_features, WorldGenCarverWrapper worldgencarverwrapper) { - ((List) this.aV.computeIfAbsent(worldgenstage_features, (worldgenstage_features1) -> { + public void a(WorldGenStage.Features worldgenstage_features, WorldGenCarverWrapper worldgencarverwrapper) { + ((List) this.q.computeIfAbsent(worldgenstage_features, (worldgenstage_features1) -> { return Lists.newArrayList(); })).add(worldgencarverwrapper); } public List> a(WorldGenStage.Features worldgenstage_features) { - return (List) this.aV.computeIfAbsent(worldgenstage_features, (worldgenstage_features1) -> { + return (List) this.q.computeIfAbsent(worldgenstage_features, (worldgenstage_features1) -> { return Lists.newArrayList(); }); } public void a(StructureGenerator structuregenerator, C c0) { - this.aY.put(structuregenerator, c0); + this.t.put(structuregenerator, c0); } public boolean a(StructureGenerator structuregenerator) { - return this.aY.containsKey(structuregenerator); + return this.t.containsKey(structuregenerator); } @Nullable - public WorldGenFeatureConfiguration b(StructureGenerator structuregenerator) { - return (WorldGenFeatureConfiguration) this.aY.get(structuregenerator); + public C b(StructureGenerator structuregenerator) { + return (C) this.t.get(structuregenerator); // Paper - decompile fix } - public List> f() { - return this.aX; + public List> e() { + return this.s; } - public List> a(WorldGenStage.Decoration worldgenstage_decoration) { - return (List) this.aW.get(worldgenstage_decoration); + public List> a(WorldGenStage.Decoration worldgenstage_decoration) { + return (List) this.r.get(worldgenstage_decoration); } - public void a(WorldGenStage.Decoration worldgenstage_decoration, ChunkGenerator chunkgenerator, GeneratorAccess generatoraccess, long i, SeededRandom seededrandom, BlockPosition blockposition) { + public void a(WorldGenStage.Decoration worldgenstage_decoration, ChunkGenerator chunkgenerator, GeneratorAccess generatoraccess, long i, SeededRandom seededrandom, BlockPosition blockposition) { int j = 0; - for (Iterator iterator = ((List) this.aW.get(worldgenstage_decoration)).iterator(); iterator.hasNext(); ++j) { - WorldGenFeatureComposite worldgenfeaturecomposite = (WorldGenFeatureComposite) iterator.next(); + for (Iterator iterator = ((List) this.r.get(worldgenstage_decoration)).iterator(); iterator.hasNext(); ++j) { + WorldGenFeatureConfigured worldgenfeatureconfigured = (WorldGenFeatureConfigured) iterator.next(); seededrandom.b(i, j, worldgenstage_decoration.ordinal()); - worldgenfeaturecomposite.a(generatoraccess, chunkgenerator, seededrandom, blockposition, WorldGenFeatureConfiguration.e); + + try { + worldgenfeatureconfigured.a(generatoraccess, chunkgenerator, seededrandom, blockposition); + } catch (Exception exception) { + CrashReport crashreport = CrashReport.a(exception, "Feature placement"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Feature").a("Id", (Object) IRegistry.FEATURE.getKey(worldgenfeatureconfigured.a)); + WorldGenerator worldgenerator = worldgenfeatureconfigured.a; + + worldgenfeatureconfigured.a.getClass(); + crashreportsystemdetails.a("Description", worldgenerator::toString); + throw new ReportedException(crashreport); + } } } public void a(Random random, IChunkAccess ichunkaccess, int i, int j, int k, double d0, IBlockData iblockdata, IBlockData iblockdata1, int l, long i1) { - this.aS.a(i1); - this.aS.a(random, ichunkaccess, this, i, j, k, d0, iblockdata, iblockdata1, l, i1, BiomeBase.ag); + this.n.a(i1); + this.n.a(random, ichunkaccess, this, i, j, k, d0, iblockdata, iblockdata1, l, i1); } - public BiomeBase.EnumTemperature g() { - return this.aT == BiomeBase.Geography.OCEAN ? BiomeBase.EnumTemperature.OCEAN : ((double) this.getTemperature() < 0.2D ? BiomeBase.EnumTemperature.COLD : ((double) this.getTemperature() < 1.0D ? BiomeBase.EnumTemperature.MEDIUM : BiomeBase.EnumTemperature.WARM)); + public BiomeBase.EnumTemperature f() { + return this.o == BiomeBase.Geography.OCEAN ? BiomeBase.EnumTemperature.OCEAN : ((double) this.getTemperature() < 0.2D ? BiomeBase.EnumTemperature.COLD : ((double) this.getTemperature() < 1.0D ? BiomeBase.EnumTemperature.MEDIUM : BiomeBase.EnumTemperature.WARM)); } - public static BiomeBase getBiome(int i, BiomeBase biomebase) { - BiomeBase biomebase1 = (BiomeBase) IRegistry.BIOME.fromId(i); - - return biomebase1 == null ? biomebase : biomebase1; - } - - public final float h() { - return this.aL; + public final float g() { + return this.g; } public final float getHumidity() { - return this.aO; + return this.j; } - public String k() { - if (this.aK == null) { - this.aK = SystemUtils.a("biome", IRegistry.BIOME.getKey(this)); + public String j() { + if (this.f == null) { + this.f = SystemUtils.a("biome", IRegistry.BIOME.getKey(this)); } - return this.aK; + return this.f; } - public final float l() { - return this.aM; + public final float k() { + return this.h; } public final float getTemperature() { - return this.aN; + return this.i; + } + + public final int m() { + return this.k; } public final int n() { - return this.aP; + return this.l; } - public final int o() { - return this.aQ; + public final BiomeBase.Geography o() { + return this.o; } - public final BiomeBase.Geography p() { - return this.aT; + public WorldGenSurfaceComposite p() { + return this.n; } - public WorldGenSurfaceComposite q() { - return this.aS; - } - - public WorldGenSurfaceConfiguration r() { - return this.aS.a(); + public WorldGenSurfaceConfiguration q() { + return this.n.a(); } @Nullable - public String s() { - return this.aR; - } - - public static void t() { - a(0, "ocean", new BiomeOcean()); - a(1, "plains", new BiomePlains()); - a(2, "desert", new BiomeDesert()); - a(3, "mountains", new BiomeBigHills()); - a(4, "forest", new BiomeForest()); - a(5, "taiga", new BiomeTaiga()); - a(6, "swamp", new BiomeSwamp()); - a(7, "river", new BiomeRiver()); - a(8, "nether", new BiomeHell()); - a(9, "the_end", new BiomeTheEnd()); - a(10, "frozen_ocean", new BiomeFrozenOcean()); - a(11, "frozen_river", new BiomeFrozenRiver()); - a(12, "snowy_tundra", new BiomeIcePlains()); - a(13, "snowy_mountains", new BiomeIceMountains()); - a(14, "mushroom_fields", new BiomeMushrooms()); - a(15, "mushroom_field_shore", new BiomeMushroomIslandShore()); - a(16, "beach", new BiomeBeach()); - a(17, "desert_hills", new BiomeDesertHills()); - a(18, "wooded_hills", new BiomeForestHills()); - a(19, "taiga_hills", new BiomeTaigaHills()); - a(20, "mountain_edge", new BiomeExtremeHillsEdge()); - a(21, "jungle", new BiomeJungle()); - a(22, "jungle_hills", new BiomeJungleHills()); - a(23, "jungle_edge", new BiomeJungleEdge()); - a(24, "deep_ocean", new BiomeDeepOcean()); - a(25, "stone_shore", new BiomeStoneBeach()); - a(26, "snowy_beach", new BiomeColdBeach()); - a(27, "birch_forest", new BiomeBirchForest()); - a(28, "birch_forest_hills", new BiomeBirchForestHills()); - a(29, "dark_forest", new BiomeRoofedForest()); - a(30, "snowy_taiga", new BiomeColdTaiga()); - a(31, "snowy_taiga_hills", new BiomeColdTaigaHills()); - a(32, "giant_tree_taiga", new BiomeMegaTaiga()); - a(33, "giant_tree_taiga_hills", new BiomeMegaTaigaHills()); - a(34, "wooded_mountains", new BiomeExtremeHillsWithTrees()); - a(35, "savanna", new BiomeSavanna()); - a(36, "savanna_plateau", new BiomeSavannaPlateau()); - a(37, "badlands", new BiomeMesa()); - a(38, "wooded_badlands_plateau", new BiomeMesaPlataeu()); - a(39, "badlands_plateau", new BiomeMesaPlataeuClear()); - a(40, "small_end_islands", new BiomeTheEndFloatingIslands()); - a(41, "end_midlands", new BiomeTheEndMediumIsland()); - a(42, "end_highlands", new BiomeTheEndHighIsland()); - a(43, "end_barrens", new BiomeTheEndBarrenIsland()); - a(44, "warm_ocean", new BiomeWarmOcean()); - a(45, "lukewarm_ocean", new BiomeLukewarmOcean()); - a(46, "cold_ocean", new BiomeColdOcean()); - a(47, "deep_warm_ocean", new BiomeWarmDeepOcean()); - a(48, "deep_lukewarm_ocean", new BiomeLukewarmDeepOcean()); - a(49, "deep_cold_ocean", new BiomeColdDeepOcean()); - a(50, "deep_frozen_ocean", new BiomeFrozenDeepOcean()); - a(127, "the_void", new BiomeVoid()); - a(129, "sunflower_plains", new BiomeSunflowerPlains()); - a(130, "desert_lakes", new BiomeDesertMutated()); - a(131, "gravelly_mountains", new BiomeExtremeHillsMutated()); - a(132, "flower_forest", new BiomeFlowerForest()); - a(133, "taiga_mountains", new BiomeTaigaMutated()); - a(134, "swamp_hills", new BiomeSwamplandMutated()); - a(140, "ice_spikes", new BiomeIcePlainsSpikes()); - a(149, "modified_jungle", new BiomeJungleMutated()); - a(151, "modified_jungle_edge", new BiomeJungleEdgeMutated()); - a(155, "tall_birch_forest", new BiomeBirchForestMutated()); - a(156, "tall_birch_hills", new BiomeBirchForestHillsMutated()); - a(157, "dark_forest_hills", new BiomeRoofedForestMutated()); - a(158, "snowy_taiga_mountains", new BiomeColdTaigaMutated()); - a(160, "giant_spruce_taiga", new BiomeMegaSpruceTaiga()); - a(161, "giant_spruce_taiga_hills", new BiomeRedwoodTaigaHillsMutated()); - a(162, "modified_gravelly_mountains", new BiomeExtremeHillsWithTreesMutated()); - a(163, "shattered_savanna", new BiomeSavannaMutated()); - a(164, "shattered_savanna_plateau", new BiomeSavannaPlateauMutated()); - a(165, "eroded_badlands", new BiomeMesaBryce()); - a(166, "modified_wooded_badlands_plateau", new BiomeMesaPlateauMutated()); - a(167, "modified_badlands_plateau", new BiomeMesaPlateauClearMutated()); - Collections.addAll(BiomeBase.aG, new BiomeBase[] { Biomes.OCEAN, Biomes.PLAINS, Biomes.DESERT, Biomes.MOUNTAINS, Biomes.FOREST, Biomes.TAIGA, Biomes.SWAMP, Biomes.RIVER, Biomes.FROZEN_RIVER, Biomes.SNOWY_TUNDRA, Biomes.SNOWY_MOUNTAINS, Biomes.MUSHROOM_FIELDS, Biomes.MUSHROOM_FIELD_SHORE, Biomes.BEACH, Biomes.DESERT_HILLS, Biomes.WOODED_HILLS, Biomes.TAIGA_HILLS, Biomes.JUNGLE, Biomes.JUNGLE_HILLS, Biomes.JUNGLE_EDGE, Biomes.DEEP_OCEAN, Biomes.STONE_SHORE, Biomes.SNOWY_BEACH, Biomes.BIRCH_FOREST, Biomes.BIRCH_FOREST_HILLS, Biomes.DARK_FOREST, Biomes.SNOWY_TAIGA, Biomes.SNOWY_TAIGA_HILLS, Biomes.GIANT_TREE_TAIGA, Biomes.GIANT_TREE_TAIGA_HILLS, Biomes.WOODED_MOUNTAINS, Biomes.SAVANNA, Biomes.SAVANNA_PLATEAU, Biomes.BADLANDS, Biomes.WOODED_BADLANDS_PLATEAU, Biomes.BADLANDS_PLATEAU}); - } - - private static void a(int i, String s, BiomeBase biomebase) { - IRegistry.BIOME.a(i, new MinecraftKey(s), biomebase); - if (biomebase.b()) { - BiomeBase.aH.a(biomebase, IRegistry.BIOME.a(IRegistry.BIOME.get(new MinecraftKey(biomebase.aR)))); - } - + public String r() { + return this.m; } // Paper start - keep track of data in a pair set to give O(1) contains calls - we have to hook removals incase plugins mess with it @@ -530,6 +381,11 @@ public abstract class BiomeBase { public a() {} + public BiomeBase.a a(WorldGenSurface worldgensurface, SC sc) { + this.a = new WorldGenSurfaceComposite<>(worldgensurface, sc); + return this; + } + public BiomeBase.a a(WorldGenSurfaceComposite worldgensurfacecomposite) { this.a = worldgensurfacecomposite; return this; @@ -587,11 +443,11 @@ public abstract class BiomeBase { public static class BiomeMeta extends WeightedRandom.WeightedRandomChoice { - public EntityTypes b; public EntityTypes entityType() { return b; } // Akarin - public int c; public int getMinPackSize() { return c; } // Akarin - OBFHELPER - public int d; public int getMaxPackSize() { return d; } // Akarin - OBFHELPER + public final EntityTypes b; + public final int c; + public final int d; - public BiomeMeta(EntityTypes entitytypes, int i, int j, int k) { + public BiomeMeta(EntityTypes entitytypes, int i, int j, int k) { super(i); this.b = entitytypes; this.c = j; @@ -605,22 +461,55 @@ public abstract class BiomeBase { public static enum Precipitation { - NONE, RAIN, SNOW; + NONE("none"), RAIN("rain"), SNOW("snow"); - private Precipitation() {} + private static final Map d = (Map) Arrays.stream(values()).collect(Collectors.toMap(BiomeBase.Precipitation::a, (biomebase_precipitation) -> { + return biomebase_precipitation; + })); + private final String e; + + private Precipitation(String s) { + this.e = s; + } + + public String a() { + return this.e; + } } public static enum Geography { - NONE, TAIGA, EXTREME_HILLS, JUNGLE, MESA, PLAINS, SAVANNA, ICY, THEEND, BEACH, FOREST, OCEAN, DESERT, RIVER, SWAMP, MUSHROOM, NETHER; + NONE("none"), TAIGA("taiga"), EXTREME_HILLS("extreme_hills"), JUNGLE("jungle"), MESA("mesa"), PLAINS("plains"), SAVANNA("savanna"), ICY("icy"), THEEND("the_end"), BEACH("beach"), FOREST("forest"), OCEAN("ocean"), DESERT("desert"), RIVER("river"), SWAMP("swamp"), MUSHROOM("mushroom"), NETHER("nether"); - private Geography() {} + private static final Map r = (Map) Arrays.stream(values()).collect(Collectors.toMap(BiomeBase.Geography::a, (biomebase_geography) -> { + return biomebase_geography; + })); + private final String s; + + private Geography(String s) { + this.s = s; + } + + public String a() { + return this.s; + } } public static enum EnumTemperature { - OCEAN, COLD, MEDIUM, WARM; + OCEAN("ocean"), COLD("cold"), MEDIUM("medium"), WARM("warm"); - private EnumTemperature() {} + private static final Map e = (Map) Arrays.stream(values()).collect(Collectors.toMap(BiomeBase.EnumTemperature::a, (biomebase_enumtemperature) -> { + return biomebase_enumtemperature; + })); + private final String f; + + private EnumTemperature(String s) { + this.f = s; + } + + public String a() { + return this.f; + } } } diff --git a/src/main/java/net/minecraft/server/BiomeCache.java b/src/main/java/net/minecraft/server/BiomeCache.java deleted file mode 100644 index 57b933456..000000000 --- a/src/main/java/net/minecraft/server/BiomeCache.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.minecraft.server; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.LoadingCache; -import java.util.concurrent.TimeUnit; - -public class BiomeCache { - - private final WorldChunkManager a; - private final com.github.benmanes.caffeine.cache.LoadingCache b; // Akarin - caffeine - - public BiomeCache(WorldChunkManager worldchunkmanager) { - // Akarin start - caffeine - this.b = com.github.benmanes.caffeine.cache.Caffeine.newBuilder().expireAfterAccess(30L, TimeUnit.SECONDS).build(new com.github.benmanes.caffeine.cache.CacheLoader() { - @Override - public BiomeCache.a load(ChunkCoordIntPair chunkcoordintpair) throws Exception { - return BiomeCache.this.new a(chunkcoordintpair.x, chunkcoordintpair.z); - } - }); - // Akarin end - this.a = worldchunkmanager; - } - - public BiomeCache.a a(int i, int j) { - i >>= 4; - j >>= 4; - return (BiomeCache.a) this.b.get(new ChunkCoordIntPair(i, j)); // Akarin - caffeine - } - - public BiomeBase a(int i, int j, BiomeBase biomebase) { - BiomeBase biomebase1 = this.a(i, j).a(i, j); - - return biomebase1 == null ? biomebase : biomebase1; - } - - public void a() {} - - public BiomeBase[] b(int i, int j) { - return this.a(i, j).b; - } - - public class a { - - private final BiomeBase[] b; - - public a(int i, int j) { - this.b = BiomeCache.this.a.a(i << 4, j << 4, 16, 16, false); - } - - public BiomeBase a(int i, int j) { - return this.b[i & 15 | (j & 15) << 4]; - } - } -} diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java index acd659d37..619237d68 100644 --- a/src/main/java/net/minecraft/server/Block.java +++ b/src/main/java/net/minecraft/server/Block.java @@ -1,28 +1,34 @@ package net.minecraft.server; -import com.google.common.collect.UnmodifiableIterator; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap; +import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Objects; import java.util.Random; import java.util.stream.Stream; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bukkit.craftbukkit.CraftWorld; -import org.bukkit.craftbukkit.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; public class Block implements IMaterial { - protected static final Logger d = LogManager.getLogger(); + protected static final Logger LOGGER = LogManager.getLogger(); public static final RegistryBlockID REGISTRY_ID = new RegistryBlockID<>(); - private static final EnumDirection[] a = new EnumDirection[] { EnumDirection.WEST, EnumDirection.EAST, EnumDirection.NORTH, EnumDirection.SOUTH, EnumDirection.DOWN, EnumDirection.UP}; - protected final int f; + private static final EnumDirection[] a = new EnumDirection[]{EnumDirection.WEST, EnumDirection.EAST, EnumDirection.NORTH, EnumDirection.SOUTH, EnumDirection.DOWN, EnumDirection.UP}; + private static final LoadingCache b = CacheBuilder.newBuilder().maximumSize(512L).weakKeys().build(new CacheLoader() { + public Boolean load(VoxelShape voxelshape) { + return !VoxelShapes.c(VoxelShapes.b(), voxelshape, OperatorBoolean.NOT_SAME); + } + }); + private static final VoxelShape c = VoxelShapes.a(VoxelShapes.b(), a(2.0D, 0.0D, 2.0D, 14.0D, 16.0D, 14.0D), OperatorBoolean.ONLY_FIRST); + private static final VoxelShape d = a(7.0D, 0.0D, 7.0D, 9.0D, 10.0D, 9.0D); + protected final int n; public final float strength; protected final float durability; - protected final boolean i; + protected final boolean q; protected final SoundEffectType stepSound; protected final Material material; // Paper start @@ -34,15 +40,20 @@ public class Block implements IMaterial { return timing; } // Paper end - protected final MaterialMapColor l; + protected final MaterialMapColor t; private final float frictionFactor; protected final BlockStateList blockStateList; private IBlockData blockData; - protected final boolean n; - private final boolean o; + public boolean randomTick = false; // Paper - fix MC-113809 + protected final boolean v; + private final boolean g; + @Nullable + private MinecraftKey h; @Nullable private String name; - private static final ThreadLocal> q = ThreadLocal.withInitial(() -> { + @Nullable + private Item j; + private static final ThreadLocal> k = ThreadLocal.withInitial(() -> { Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap = new Object2ByteLinkedOpenHashMap(200) { protected void rehash(int i) {} }; @@ -91,8 +102,8 @@ public class Block implements IMaterial { } @Deprecated - public boolean a(IBlockData iblockdata, Entity entity) { - return true; + public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EntityTypes entitytypes) { + return iblockdata.d(iblockaccess, blockposition, EnumDirection.UP) && this.n < 14; } @Deprecated @@ -101,18 +112,18 @@ public class Block implements IMaterial { } @Deprecated - public int m(IBlockData iblockdata) { - return this.f; + public int a(IBlockData iblockdata) { + return this.n; } @Deprecated - public Material n(IBlockData iblockdata) { + public Material l(IBlockData iblockdata) { return this.material; } @Deprecated - public MaterialMapColor c(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.l; + public MaterialMapColor e(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.t; } @Deprecated @@ -131,7 +142,7 @@ public class Block implements IMaterial { IBlockData iblockdata1 = generatoraccess.getType(blockposition_pooledblockposition); IBlockData iblockdata2 = iblockdata1.updateState(enumdirection.opposite(), iblockdata, generatoraccess, blockposition_pooledblockposition, blockposition); - ensuresTypeAndData(iblockdata1, iblockdata2, generatoraccess, blockposition_pooledblockposition, i, blockposition); // Akarin - fixes physics event + a(iblockdata1, iblockdata2, generatoraccess, blockposition_pooledblockposition, i); } } catch (Throwable throwable1) { throwable = throwable1; @@ -175,29 +186,10 @@ public class Block implements IMaterial { } public static void a(IBlockData iblockdata, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, int i) { - // Akarin start - ensuresTypeAndData(iblockdata, iblockdata1, generatoraccess, blockposition, i, blockposition); - } - - public static void ensuresTypeAndData(IBlockData iblockdata, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, int i, BlockPosition sourceBlockPosition) { - // Akarin end if (iblockdata1 != iblockdata) { - // Akarin start - fixes physics event - if (io.akarin.server.core.AkarinGlobalConfig.fixPhysicsEventBehaviour && ((WorldServer) generatoraccess).hasPhysicsEvent) { - CraftWorld world = ((WorldServer) generatoraccess).getWorld(); - if (world != null) { - BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition), CraftBlockData.fromData(iblockdata), world.getBlockAt(sourceBlockPosition)); // Akarin - ((WorldServer) generatoraccess).getServer().getPluginManager().callEvent(event); - - if (event.isCancelled()) { - return; - } - } - } - // Akarin end if (iblockdata1.isAir()) { if (!generatoraccess.e()) { - generatoraccess.setAir(blockposition, (i & 32) == 0); + generatoraccess.b(blockposition, (i & 32) == 0); } } else { generatoraccess.setTypeAndData(blockposition, iblockdata1, i & -33); @@ -228,64 +220,46 @@ public class Block implements IMaterial { BlockStateList.a blockstatelist_a = new BlockStateList.a<>(this); this.a(blockstatelist_a); - this.blockStateList = blockstatelist_a.a(BlockData::new); - this.v((IBlockData) this.blockStateList.getBlockData()); this.material = block_info.a; - this.l = block_info.b; - this.n = block_info.c; + this.t = block_info.b; + this.v = block_info.c; this.stepSound = block_info.d; - this.f = block_info.e; + this.n = block_info.e; this.durability = block_info.f; this.strength = block_info.g; - this.i = block_info.h; + this.q = block_info.h; this.frictionFactor = block_info.i; - this.o = block_info.j; + this.g = block_info.k; + this.h = block_info.j; + this.blockStateList = blockstatelist_a.a(IBlockData::new); + this.o((IBlockData) this.blockStateList.getBlockData()); } - protected static boolean a(Block block) { - return block instanceof BlockShulkerBox || block instanceof BlockLeaves || block.a(TagsBlock.TRAPDOORS) || block instanceof BlockStainedGlass || block == Blocks.BEACON || block == Blocks.CAULDRON || block == Blocks.GLASS || block == Blocks.GLOWSTONE || block == Blocks.ICE || block == Blocks.SEA_LANTERN || block == Blocks.CONDUIT; - } - - public static boolean b(Block block) { - return a(block) || block == Blocks.PISTON || block == Blocks.STICKY_PISTON || block == Blocks.PISTON_HEAD; + public static boolean a(Block block) { + return block instanceof BlockLeaves || block == Blocks.BARRIER || block == Blocks.CARVED_PUMPKIN || block == Blocks.JACK_O_LANTERN || block == Blocks.MELON || block == Blocks.PUMPKIN; } @Deprecated - public boolean o(IBlockData iblockdata) { - return iblockdata.getMaterial().isSolid() && iblockdata.g(); + public boolean isOccluding(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockdata.getMaterial().f() && iblockdata.o(iblockaccess, blockposition) && !iblockdata.isPowerSource(); } @Deprecated - public boolean isOccluding(IBlockData iblockdata) { - return iblockdata.getMaterial().f() && iblockdata.g() && !iblockdata.isPowerSource(); - } - - @Deprecated - public boolean q(IBlockData iblockdata) { - return this.material.isSolid() && iblockdata.g(); - } - - @Deprecated - public boolean a(IBlockData iblockdata) { - return true; - } - - @Deprecated - public boolean r(IBlockData iblockdata) { - return iblockdata.getMaterial().f() && iblockdata.g(); + public boolean c(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.material.isSolid() && iblockdata.o(iblockaccess, blockposition); } @Deprecated public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { switch (pathmode) { - case LAND: - return !a(this.f(iblockdata, iblockaccess, blockposition)); - case WATER: - return iblockaccess.getFluid(blockposition).a(TagsFluid.WATER); - case AIR: - return !a(this.f(iblockdata, iblockaccess, blockposition)); - default: - return false; + case LAND: + return !iblockdata.o(iblockaccess, blockposition); + case WATER: + return iblockaccess.getFluid(blockposition).a(TagsFluid.WATER); + case AIR: + return !iblockdata.o(iblockaccess, blockposition); + default: + return false; } } @@ -296,16 +270,16 @@ public class Block implements IMaterial { @Deprecated public boolean a(IBlockData iblockdata, BlockActionContext blockactioncontext) { - return this.material.isReplaceable() && blockactioncontext.getItemStack().getItem() != this.getItem(); + return this.material.isReplaceable() && (blockactioncontext.getItemStack().isEmpty() || blockactioncontext.getItemStack().getItem() != this.getItem()); } @Deprecated - public float d(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + public float f(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return this.strength; } public boolean isTicking(IBlockData iblockdata) { - return this.i; + return this.q; } public boolean isTileEntity() { @@ -313,40 +287,51 @@ public class Block implements IMaterial { } @Deprecated - public boolean e(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + public boolean g(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return false; } @Deprecated public boolean f(IBlockData iblockdata) { - return this.n && iblockdata.getBlock().c() == TextureType.SOLID; + return this.v && this.c() == TextureType.SOLID; } @Deprecated - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.SOLID; - } - - @Deprecated - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return VoxelShapes.b(); } @Deprecated - public VoxelShape f(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.n ? iblockdata.getShape(iblockaccess, blockposition) : VoxelShapes.a(); - } - - @Deprecated - public VoxelShape g(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return iblockdata.getShape(iblockaccess, blockposition); + public VoxelShape b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return this.v ? iblockdata.getShape(iblockaccess, blockposition) : VoxelShapes.a(); } @Deprecated public VoxelShape h(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockdata.getShape(iblockaccess, blockposition); + } + + @Deprecated + public VoxelShape i(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return VoxelShapes.a(); } + public static boolean c(IBlockAccess iblockaccess, BlockPosition blockposition) { + IBlockData iblockdata = iblockaccess.getType(blockposition); + + return !iblockdata.a(TagsBlock.LEAVES) && !VoxelShapes.c(iblockdata.getCollisionShape(iblockaccess, blockposition).a(EnumDirection.UP), Block.c, OperatorBoolean.ONLY_SECOND); + } + + public static boolean a(IWorldReader iworldreader, BlockPosition blockposition, EnumDirection enumdirection) { + IBlockData iblockdata = iworldreader.getType(blockposition); + + return !iblockdata.a(TagsBlock.LEAVES) && !VoxelShapes.c(iblockdata.getCollisionShape(iworldreader, blockposition).a(enumdirection), Block.d, OperatorBoolean.ONLY_SECOND); + } + + public static boolean d(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + return !iblockdata.a(TagsBlock.LEAVES) && a(iblockdata.getCollisionShape(iblockaccess, blockposition), enumdirection); + } + public static boolean a(VoxelShape voxelshape, EnumDirection enumdirection) { VoxelShape voxelshape1 = voxelshape.a(enumdirection); @@ -354,77 +339,70 @@ public class Block implements IMaterial { } public static boolean a(VoxelShape voxelshape) { - return !VoxelShapes.c(VoxelShapes.b(), voxelshape, OperatorBoolean.ONLY_FIRST); + return (Boolean) Block.b.getUnchecked(voxelshape); } @Deprecated - public final boolean i(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - boolean flag = iblockdata.p(); - VoxelShape voxelshape = flag ? iblockdata.i(iblockaccess, blockposition) : VoxelShapes.a(); - - return a(voxelshape); + public final boolean j(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockdata.o() ? a(iblockdata.j(iblockaccess, blockposition)) : false; } - public boolean a_(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return !a(iblockdata.getShape(iblockaccess, blockposition)) && iblockdata.s().e(); + public boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return !a(iblockdata.getShape(iblockaccess, blockposition)) && iblockdata.p().isEmpty(); } @Deprecated - public int j(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return iblockdata.f(iblockaccess, blockposition) ? iblockaccess.K() : (iblockdata.a(iblockaccess, blockposition) ? 0 : 1); + public int k(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockdata.g(iblockaccess, blockposition) ? iblockaccess.H() : (iblockdata.a(iblockaccess, blockposition) ? 0 : 1); } @Deprecated - public final boolean k(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return !iblockdata.f(iblockaccess, blockposition) && iblockdata.b(iblockaccess, blockposition) == iblockaccess.K(); - } - - public boolean isCollidable(IBlockData iblockdata) { - return this.j(); - } - - public boolean j() { - return true; + public boolean n(IBlockData iblockdata) { + return false; } @Deprecated - public void b(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { - this.a(iblockdata, world, blockposition, random); + public void c(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + this.tick(iblockdata, world, blockposition, random); } @Deprecated - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) {} + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) {} public void postBreak(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata) {} @Deprecated - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) {} + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { + PacketDebug.a(world, blockposition); + } public int a(IWorldReader iworldreader) { return 10; } + @Nullable @Deprecated - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { - //org.spigotmc.AsyncCatcher.catchOp( "block onPlace"); // Spigot // Akarin + public ITileInventory getInventory(IBlockData iblockdata, World world, BlockPosition blockposition) { + return null; + } + + @Deprecated + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { + org.spigotmc.AsyncCatcher.catchOp("block onPlace"); // Spigot } @Deprecated public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { - //org.spigotmc.AsyncCatcher.catchOp( "block remove"); // Spigot // Akarin - } + org.spigotmc.AsyncCatcher.catchOp("block remove"); // Spigot + if (this.isTileEntity() && iblockdata.getBlock() != iblockdata1.getBlock()) { + world.removeTileEntity(blockposition); + } - public int a(IBlockData iblockdata, Random random) { - return 1; - } - - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return this; } @Deprecated public float getDamage(IBlockData iblockdata, EntityHuman entityhuman, IBlockAccess iblockaccess, BlockPosition blockposition) { - float f = iblockdata.e(iblockaccess, blockposition); + float f = iblockdata.f(iblockaccess, blockposition); if (f == -1.0F) { return 0.0F; @@ -436,33 +414,95 @@ public class Block implements IMaterial { } @Deprecated - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - if (!world.isClientSide) { - int j = this.getDropCount(iblockdata, i, world, blockposition, world.random); + public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) {} - for (int k = 0; k < j; ++k) { - // CraftBukkit - <= to < to allow for plugins to completely disable block drops from explosions - if (f >= 1.0F || world.random.nextFloat() < f) { - Item item = this.getDropType(iblockdata, world, blockposition, i).getItem(); + public MinecraftKey i() { + if (this.h == null) { + MinecraftKey minecraftkey = IRegistry.BLOCK.getKey(this); - if (item != Items.AIR) { - a(world, blockposition, new ItemStack(item)); - } - } - } + this.h = new MinecraftKey(minecraftkey.getNamespace(), "blocks/" + minecraftkey.getKey()); + } + return this.h; + } + + @Deprecated + public List a(IBlockData iblockdata, LootTableInfo.Builder loottableinfo_builder) { + MinecraftKey minecraftkey = this.i(); + + if (minecraftkey == LootTables.a) { + return Collections.emptyList(); + } else { + LootTableInfo loottableinfo = loottableinfo_builder.set(LootContextParameters.BLOCK_STATE, iblockdata).build(LootContextParameterSets.BLOCK); + WorldServer worldserver = loottableinfo.d(); + LootTable loottable = worldserver.getMinecraftServer().getLootTableRegistry().getLootTable(minecraftkey); + + return loottable.populateLoot(loottableinfo); } } + public static List a(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, @Nullable TileEntity tileentity) { + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder(worldserver)).a(worldserver.random).set(LootContextParameters.POSITION, blockposition).set(LootContextParameters.TOOL, ItemStack.a).setOptional(LootContextParameters.BLOCK_ENTITY, tileentity); + + return iblockdata.a(loottableinfo_builder); + } + + public static List getDrops(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, @Nullable TileEntity tileentity, Entity entity, ItemStack itemstack) { + // CraftBukkit - make entity optional + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder(worldserver)).a(worldserver.random).set(LootContextParameters.POSITION, blockposition).set(LootContextParameters.TOOL, itemstack).setOptional(LootContextParameters.THIS_ENTITY, entity).setOptional(LootContextParameters.BLOCK_ENTITY, tileentity); + + return iblockdata.a(loottableinfo_builder); + } + + public static void b(IBlockData iblockdata, LootTableInfo.Builder loottableinfo_builder) { + WorldServer worldserver = loottableinfo_builder.a(); + BlockPosition blockposition = (BlockPosition) loottableinfo_builder.a(LootContextParameters.POSITION); + + iblockdata.a(loottableinfo_builder).forEach((itemstack) -> { + a((World) worldserver, blockposition, itemstack); + }); + iblockdata.dropNaturally(worldserver, blockposition, ItemStack.a); + } + + public static void c(IBlockData iblockdata, World world, BlockPosition blockposition) { + if (world instanceof WorldServer) { + a(iblockdata, (WorldServer) world, blockposition, (TileEntity) null).forEach((itemstack) -> { + a(world, blockposition, itemstack); + }); + } + + iblockdata.dropNaturally(world, blockposition, ItemStack.a); + } + public static void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, @Nullable TileEntity tileentity) { a(iblockdata, world, blockposition, tileentity); } + public static void a(IBlockData iblockdata, World world, BlockPosition blockposition, @Nullable TileEntity tileentity) { + if (world instanceof WorldServer) { + a(iblockdata, (WorldServer) world, blockposition, tileentity).forEach((itemstack) -> { + a(world, blockposition, itemstack); + }); + } + + iblockdata.dropNaturally(world, blockposition, ItemStack.a); + } + + public static void dropItems(IBlockData iblockdata, World world, BlockPosition blockposition, @Nullable TileEntity tileentity, Entity entity, ItemStack itemstack) { + if (world instanceof WorldServer) { + getDrops(iblockdata, (WorldServer) world, blockposition, tileentity, entity, itemstack).forEach((itemstack1) -> { + a(world, blockposition, itemstack1); + }); + } + + iblockdata.dropNaturally(world, blockposition, itemstack); + } + public static void a(World world, BlockPosition blockposition, ItemStack itemstack) { - if (!world.isClientSide && !itemstack.isEmpty() && world.getGameRules().getBoolean("doTileDrops")) { + if (!world.isClientSide && !itemstack.isEmpty() && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) { float f = 0.5F; double d0 = (double) (world.random.nextFloat() * 0.5F) + 0.25D; double d1 = (double) (world.random.nextFloat() * 0.5F) + 0.25D; double d2 = (double) (world.random.nextFloat() * 0.5F) + 0.25D; EntityItem entityitem = new EntityItem(world, (double) blockposition.getX() + d0, (double) blockposition.getY() + d1, (double) blockposition.getZ() + d2, itemstack); - entityitem.n(); + entityitem.defaultPickupDelay(); // CraftBukkit start if (world.captureDrops != null) { world.captureDrops.add(entityitem); @@ -474,7 +514,7 @@ public class Block implements IMaterial { } protected void dropExperience(World world, BlockPosition blockposition, int i, EntityPlayer player) { // Paper - if (!world.isClientSide && world.getGameRules().getBoolean("doTileDrops")) { + if (!world.isClientSide && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) { while (i > 0) { int j = EntityExperienceOrb.getOrbValue(i); @@ -489,21 +529,6 @@ public class Block implements IMaterial { return this.durability; } - @Nullable - public static MovingObjectPosition rayTrace(IBlockData iblockdata, World world, BlockPosition blockposition, Vec3D vec3d, Vec3D vec3d1) { - MovingObjectPosition movingobjectposition = iblockdata.getShape(world, blockposition).rayTrace(vec3d, vec3d1, blockposition); - - if (movingobjectposition != null) { - MovingObjectPosition movingobjectposition1 = iblockdata.j(world, blockposition).rayTrace(vec3d, vec3d1, blockposition); - - if (movingobjectposition1 != null && movingobjectposition1.pos.d(vec3d).c() < movingobjectposition.pos.d(vec3d).c()) { - movingobjectposition.direction = movingobjectposition1.direction; - } - } - - return movingobjectposition; - } - public void wasExploded(World world, BlockPosition blockposition, Explosion explosion) {} public TextureType c() { @@ -516,7 +541,7 @@ public class Block implements IMaterial { } @Deprecated - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { return false; } @@ -551,37 +576,16 @@ public class Block implements IMaterial { public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { entityhuman.b(StatisticList.BLOCK_MINED.b(this)); entityhuman.applyExhaustion(0.005F); - if (this.X_() && EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) > 0) { - ItemStack itemstack1 = this.t(iblockdata); - - a(world, blockposition, itemstack1); - } else { - int i = EnchantmentManager.getEnchantmentLevel(Enchantments.LOOT_BONUS_BLOCKS, itemstack); - - iblockdata.a(world, blockposition, i); - } - - } - - protected boolean X_() { - return this.getBlockData().g() && !this.isTileEntity(); - } - - protected ItemStack t(IBlockData iblockdata) { - return new ItemStack(this); - } - - public int getDropCount(IBlockData iblockdata, int i, World world, BlockPosition blockposition, Random random) { - return this.a(iblockdata, random); + dropItems(iblockdata, world, blockposition, tileentity, entityhuman, itemstack); } public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, @Nullable EntityLiving entityliving, ItemStack itemstack) {} - public boolean a() { + public boolean S_() { return !this.material.isBuildable() && !this.material.isLiquid(); } - public String m() { + public String l() { if (this.name == null) { this.name = SystemUtils.a("block", IRegistry.BLOCK.getKey(this)); } @@ -600,15 +604,11 @@ public class Block implements IMaterial { } public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) { - entity.c(f, 1.0F); + entity.b(f, 1.0F); } public void a(IBlockAccess iblockaccess, Entity entity) { - entity.motY = 0.0D; - } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - return new ItemStack(this); + entity.setMot(entity.getMot().d(1.0D, 0.0D, 1.0D)); } public void a(CreativeModeTab creativemodetab, NonNullList nonnulllist) { @@ -616,14 +616,16 @@ public class Block implements IMaterial { } @Deprecated - public Fluid h(IBlockData iblockdata) { + public Fluid g(IBlockData iblockdata) { return FluidTypes.EMPTY.i(); } - public float n() { + public float m() { return this.frictionFactor; } + public void a(World world, IBlockData iblockdata, MovingObjectPositionBlock movingobjectpositionblock, Entity entity) {} + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { world.a(entityhuman, 2001, blockposition, getCombinedId(iblockdata)); } @@ -650,7 +652,7 @@ public class Block implements IMaterial { return this.blockStateList; } - protected final void v(IBlockData iblockdata) { + protected final void o(IBlockData iblockdata) { this.blockData = iblockdata; } @@ -658,13 +660,13 @@ public class Block implements IMaterial { return this.blockData; } - public Block.EnumRandomOffset q() { + public Block.EnumRandomOffset R_() { return Block.EnumRandomOffset.NONE; } @Deprecated public Vec3D l(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - Block.EnumRandomOffset block_enumrandomoffset = this.q(); + Block.EnumRandomOffset block_enumrandomoffset = this.R_(); if (block_enumrandomoffset == Block.EnumRandomOffset.NONE) { return Vec3D.a; @@ -675,782 +677,41 @@ public class Block implements IMaterial { } } - public SoundEffectType getStepSound() { + public SoundEffectType getStepSound(IBlockData iblockdata) { return this.stepSound; } + @Override public Item getItem() { - return Item.getItemOf(this); + if (this.j == null) { + this.j = Item.getItemOf(this); + } + + return this.j; } - public boolean s() { - return this.o; + public boolean p() { + return this.g; } public String toString() { return "Block{" + IRegistry.BLOCK.getKey(this) + "}"; } - public static boolean c(Block block) { + public static boolean b(Block block) { return block == Blocks.STONE || block == Blocks.GRANITE || block == Blocks.DIORITE || block == Blocks.ANDESITE; } - public static boolean d(Block block) { + public static boolean c(Block block) { return block == Blocks.DIRT || block == Blocks.COARSE_DIRT || block == Blocks.PODZOL; } - public static void t() { - BlockAir blockair = new BlockAir(Block.Info.a(Material.AIR).a()); - - a(IRegistry.BLOCK.b(), (Block) blockair); - BlockStone blockstone = new BlockStone(Block.Info.a(Material.STONE, MaterialMapColor.m).a(1.5F, 6.0F)); - - a("stone", (Block) blockstone); - a("granite", new Block(Block.Info.a(Material.STONE, MaterialMapColor.l).a(1.5F, 6.0F))); - a("polished_granite", new Block(Block.Info.a(Material.STONE, MaterialMapColor.l).a(1.5F, 6.0F))); - a("diorite", new Block(Block.Info.a(Material.STONE, MaterialMapColor.p).a(1.5F, 6.0F))); - a("polished_diorite", new Block(Block.Info.a(Material.STONE, MaterialMapColor.p).a(1.5F, 6.0F))); - a("andesite", new Block(Block.Info.a(Material.STONE, MaterialMapColor.m).a(1.5F, 6.0F))); - a("polished_andesite", new Block(Block.Info.a(Material.STONE, MaterialMapColor.m).a(1.5F, 6.0F))); - a("grass_block", (Block) (new BlockGrass(Block.Info.a(Material.GRASS).c().b(0.6F).a(SoundEffectType.c)))); - a("dirt", new Block(Block.Info.a(Material.EARTH, MaterialMapColor.l).b(0.5F).a(SoundEffectType.b))); - a("coarse_dirt", new Block(Block.Info.a(Material.EARTH, MaterialMapColor.l).b(0.5F).a(SoundEffectType.b))); - a("podzol", (Block) (new BlockDirtSnow(Block.Info.a(Material.EARTH, MaterialMapColor.J).b(0.5F).a(SoundEffectType.b)))); - Block block = new Block(Block.Info.a(Material.STONE).a(2.0F, 6.0F)); - - a("cobblestone", block); - Block block1 = new Block(Block.Info.a(Material.WOOD, MaterialMapColor.o).a(2.0F, 3.0F).a(SoundEffectType.a)); - Block block2 = new Block(Block.Info.a(Material.WOOD, MaterialMapColor.J).a(2.0F, 3.0F).a(SoundEffectType.a)); - Block block3 = new Block(Block.Info.a(Material.WOOD, MaterialMapColor.d).a(2.0F, 3.0F).a(SoundEffectType.a)); - Block block4 = new Block(Block.Info.a(Material.WOOD, MaterialMapColor.l).a(2.0F, 3.0F).a(SoundEffectType.a)); - Block block5 = new Block(Block.Info.a(Material.WOOD, MaterialMapColor.q).a(2.0F, 3.0F).a(SoundEffectType.a)); - Block block6 = new Block(Block.Info.a(Material.WOOD, MaterialMapColor.B).a(2.0F, 3.0F).a(SoundEffectType.a)); - - a("oak_planks", block1); - a("spruce_planks", block2); - a("birch_planks", block3); - a("jungle_planks", block4); - a("acacia_planks", block5); - a("dark_oak_planks", block6); - BlockSapling blocksapling = new BlockSapling(new WorldGenTreeProviderOak(), Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)); - BlockSapling blocksapling1 = new BlockSapling(new WorldGenTreeProviderSpruce(), Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)); - BlockSapling blocksapling2 = new BlockSapling(new WorldGenTreeProviderBirch(), Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)); - BlockSapling blocksapling3 = new BlockSapling(new WorldGenMegaTreeProviderJungle(), Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)); - BlockSapling blocksapling4 = new BlockSapling(new WorldGenTreeProviderAcacia(), Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)); - BlockSapling blocksapling5 = new BlockSapling(new WorldGenMegaTreeProviderDarkOak(), Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)); - - a("oak_sapling", (Block) blocksapling); - a("spruce_sapling", (Block) blocksapling1); - a("birch_sapling", (Block) blocksapling2); - a("jungle_sapling", (Block) blocksapling3); - a("acacia_sapling", (Block) blocksapling4); - a("dark_oak_sapling", (Block) blocksapling5); - a("bedrock", (Block) (new BlockNoDrop(Block.Info.a(Material.STONE).a(-1.0F, 3600000.0F)))); - a("water", (Block) (new BlockFluids(FluidTypes.WATER, Block.Info.a(Material.WATER).a().b(100.0F)))); - a("lava", (Block) (new BlockFluids(FluidTypes.LAVA, Block.Info.a(Material.LAVA).a().c().b(100.0F).a(15)))); - a("sand", (Block) (new BlockSand(14406560, Block.Info.a(Material.SAND, MaterialMapColor.d).b(0.5F).a(SoundEffectType.h)))); - a("red_sand", (Block) (new BlockSand(11098145, Block.Info.a(Material.SAND, MaterialMapColor.q).b(0.5F).a(SoundEffectType.h)))); - a("gravel", (Block) (new BlockGravel(Block.Info.a(Material.SAND, MaterialMapColor.m).b(0.6F).a(SoundEffectType.b)))); - a("gold_ore", (Block) (new BlockOre(Block.Info.a(Material.STONE).a(3.0F, 3.0F)))); - a("iron_ore", (Block) (new BlockOre(Block.Info.a(Material.STONE).a(3.0F, 3.0F)))); - a("coal_ore", (Block) (new BlockOre(Block.Info.a(Material.STONE).a(3.0F, 3.0F)))); - a("oak_log", (Block) (new BlockLogAbstract(MaterialMapColor.o, Block.Info.a(Material.WOOD, MaterialMapColor.J).b(2.0F).a(SoundEffectType.a)))); - a("spruce_log", (Block) (new BlockLogAbstract(MaterialMapColor.J, Block.Info.a(Material.WOOD, MaterialMapColor.B).b(2.0F).a(SoundEffectType.a)))); - a("birch_log", (Block) (new BlockLogAbstract(MaterialMapColor.d, Block.Info.a(Material.WOOD, MaterialMapColor.p).b(2.0F).a(SoundEffectType.a)))); - a("jungle_log", (Block) (new BlockLogAbstract(MaterialMapColor.l, Block.Info.a(Material.WOOD, MaterialMapColor.J).b(2.0F).a(SoundEffectType.a)))); - a("acacia_log", (Block) (new BlockLogAbstract(MaterialMapColor.q, Block.Info.a(Material.WOOD, MaterialMapColor.m).b(2.0F).a(SoundEffectType.a)))); - a("dark_oak_log", (Block) (new BlockLogAbstract(MaterialMapColor.B, Block.Info.a(Material.WOOD, MaterialMapColor.B).b(2.0F).a(SoundEffectType.a)))); - a("stripped_spruce_log", (Block) (new BlockLogAbstract(MaterialMapColor.J, Block.Info.a(Material.WOOD, MaterialMapColor.J).b(2.0F).a(SoundEffectType.a)))); - a("stripped_birch_log", (Block) (new BlockLogAbstract(MaterialMapColor.d, Block.Info.a(Material.WOOD, MaterialMapColor.d).b(2.0F).a(SoundEffectType.a)))); - a("stripped_jungle_log", (Block) (new BlockLogAbstract(MaterialMapColor.l, Block.Info.a(Material.WOOD, MaterialMapColor.l).b(2.0F).a(SoundEffectType.a)))); - a("stripped_acacia_log", (Block) (new BlockLogAbstract(MaterialMapColor.q, Block.Info.a(Material.WOOD, MaterialMapColor.q).b(2.0F).a(SoundEffectType.a)))); - a("stripped_dark_oak_log", (Block) (new BlockLogAbstract(MaterialMapColor.B, Block.Info.a(Material.WOOD, MaterialMapColor.B).b(2.0F).a(SoundEffectType.a)))); - a("stripped_oak_log", (Block) (new BlockLogAbstract(MaterialMapColor.o, Block.Info.a(Material.WOOD, MaterialMapColor.o).b(2.0F).a(SoundEffectType.a)))); - a("oak_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.o).b(2.0F).a(SoundEffectType.a)))); - a("spruce_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.J).b(2.0F).a(SoundEffectType.a)))); - a("birch_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.d).b(2.0F).a(SoundEffectType.a)))); - a("jungle_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.l).b(2.0F).a(SoundEffectType.a)))); - a("acacia_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.q).b(2.0F).a(SoundEffectType.a)))); - a("dark_oak_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.B).b(2.0F).a(SoundEffectType.a)))); - a("stripped_oak_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.o).b(2.0F).a(SoundEffectType.a)))); - a("stripped_spruce_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.J).b(2.0F).a(SoundEffectType.a)))); - a("stripped_birch_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.d).b(2.0F).a(SoundEffectType.a)))); - a("stripped_jungle_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.l).b(2.0F).a(SoundEffectType.a)))); - a("stripped_acacia_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.q).b(2.0F).a(SoundEffectType.a)))); - a("stripped_dark_oak_wood", (Block) (new BlockRotatable(Block.Info.a(Material.WOOD, MaterialMapColor.B).b(2.0F).a(SoundEffectType.a)))); - a("oak_leaves", (Block) (new BlockLeaves(Block.Info.a(Material.LEAVES).b(0.2F).c().a(SoundEffectType.c)))); - a("spruce_leaves", (Block) (new BlockLeaves(Block.Info.a(Material.LEAVES).b(0.2F).c().a(SoundEffectType.c)))); - a("birch_leaves", (Block) (new BlockLeaves(Block.Info.a(Material.LEAVES).b(0.2F).c().a(SoundEffectType.c)))); - a("jungle_leaves", (Block) (new BlockLeaves(Block.Info.a(Material.LEAVES).b(0.2F).c().a(SoundEffectType.c)))); - a("acacia_leaves", (Block) (new BlockLeaves(Block.Info.a(Material.LEAVES).b(0.2F).c().a(SoundEffectType.c)))); - a("dark_oak_leaves", (Block) (new BlockLeaves(Block.Info.a(Material.LEAVES).b(0.2F).c().a(SoundEffectType.c)))); - a("sponge", (Block) (new BlockSponge(Block.Info.a(Material.SPONGE).b(0.6F).a(SoundEffectType.c)))); - a("wet_sponge", (Block) (new BlockWetSponge(Block.Info.a(Material.SPONGE).b(0.6F).a(SoundEffectType.c)))); - a("glass", (Block) (new BlockGlass(Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("lapis_ore", (Block) (new BlockOre(Block.Info.a(Material.STONE).a(3.0F, 3.0F)))); - a("lapis_block", new Block(Block.Info.a(Material.ORE, MaterialMapColor.H).a(3.0F, 3.0F))); - a("dispenser", (Block) (new BlockDispenser(Block.Info.a(Material.STONE).b(3.5F)))); - Block block7 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.d).b(0.8F)); - - a("sandstone", block7); - a("chiseled_sandstone", new Block(Block.Info.a(Material.STONE, MaterialMapColor.d).b(0.8F))); - a("cut_sandstone", new Block(Block.Info.a(Material.STONE, MaterialMapColor.d).b(0.8F))); - a("note_block", (Block) (new BlockNote(Block.Info.a(Material.WOOD).a(SoundEffectType.a).b(0.8F)))); - a("white_bed", (Block) (new BlockBed(EnumColor.WHITE, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("orange_bed", (Block) (new BlockBed(EnumColor.ORANGE, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("magenta_bed", (Block) (new BlockBed(EnumColor.MAGENTA, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("light_blue_bed", (Block) (new BlockBed(EnumColor.LIGHT_BLUE, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("yellow_bed", (Block) (new BlockBed(EnumColor.YELLOW, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("lime_bed", (Block) (new BlockBed(EnumColor.LIME, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("pink_bed", (Block) (new BlockBed(EnumColor.PINK, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("gray_bed", (Block) (new BlockBed(EnumColor.GRAY, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("light_gray_bed", (Block) (new BlockBed(EnumColor.LIGHT_GRAY, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("cyan_bed", (Block) (new BlockBed(EnumColor.CYAN, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("purple_bed", (Block) (new BlockBed(EnumColor.PURPLE, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("blue_bed", (Block) (new BlockBed(EnumColor.BLUE, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("brown_bed", (Block) (new BlockBed(EnumColor.BROWN, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("green_bed", (Block) (new BlockBed(EnumColor.GREEN, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("red_bed", (Block) (new BlockBed(EnumColor.RED, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("black_bed", (Block) (new BlockBed(EnumColor.BLACK, Block.Info.a(Material.CLOTH).a(SoundEffectType.a).b(0.2F)))); - a("powered_rail", (Block) (new BlockPoweredRail(Block.Info.a(Material.ORIENTABLE).a().b(0.7F).a(SoundEffectType.e)))); - a("detector_rail", (Block) (new BlockMinecartDetector(Block.Info.a(Material.ORIENTABLE).a().b(0.7F).a(SoundEffectType.e)))); - a("sticky_piston", (Block) (new BlockPiston(true, Block.Info.a(Material.PISTON).b(0.5F)))); - a("cobweb", (Block) (new BlockWeb(Block.Info.a(Material.WEB).a().b(4.0F)))); - BlockLongGrass blocklonggrass = new BlockLongGrass(Block.Info.a(Material.REPLACEABLE_PLANT).a().b().a(SoundEffectType.c)); - BlockLongGrass blocklonggrass1 = new BlockLongGrass(Block.Info.a(Material.REPLACEABLE_PLANT).a().b().a(SoundEffectType.c)); - BlockDeadBush blockdeadbush = new BlockDeadBush(Block.Info.a(Material.REPLACEABLE_PLANT, MaterialMapColor.o).a().b().a(SoundEffectType.c)); - - a("grass", (Block) blocklonggrass); - a("fern", (Block) blocklonggrass1); - a("dead_bush", (Block) blockdeadbush); - BlockSeaGrass blockseagrass = new BlockSeaGrass(Block.Info.a(Material.REPLACEABLE_WATER_PLANT).a().b().a(SoundEffectType.m)); - - a("seagrass", (Block) blockseagrass); - a("tall_seagrass", (Block) (new BlockTallSeaGrass(blockseagrass, Block.Info.a(Material.REPLACEABLE_WATER_PLANT).a().b().a(SoundEffectType.m)))); - a("piston", (Block) (new BlockPiston(false, Block.Info.a(Material.PISTON).b(0.5F)))); - a("piston_head", (Block) (new BlockPistonExtension(Block.Info.a(Material.PISTON).b(0.5F)))); - a("white_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.j).b(0.8F).a(SoundEffectType.g))); - a("orange_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.q).b(0.8F).a(SoundEffectType.g))); - a("magenta_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.r).b(0.8F).a(SoundEffectType.g))); - a("light_blue_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.s).b(0.8F).a(SoundEffectType.g))); - a("yellow_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.t).b(0.8F).a(SoundEffectType.g))); - a("lime_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.u).b(0.8F).a(SoundEffectType.g))); - a("pink_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.v).b(0.8F).a(SoundEffectType.g))); - a("gray_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.w).b(0.8F).a(SoundEffectType.g))); - a("light_gray_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.x).b(0.8F).a(SoundEffectType.g))); - a("cyan_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.y).b(0.8F).a(SoundEffectType.g))); - a("purple_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.z).b(0.8F).a(SoundEffectType.g))); - a("blue_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.A).b(0.8F).a(SoundEffectType.g))); - a("brown_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.B).b(0.8F).a(SoundEffectType.g))); - a("green_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.C).b(0.8F).a(SoundEffectType.g))); - a("red_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.D).b(0.8F).a(SoundEffectType.g))); - a("black_wool", new Block(Block.Info.a(Material.CLOTH, MaterialMapColor.E).b(0.8F).a(SoundEffectType.g))); - a("moving_piston", (Block) (new BlockPistonMoving(Block.Info.a(Material.PISTON).b(-1.0F).d()))); - BlockFlowers blockflowers = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - BlockFlowers blockflowers1 = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - BlockFlowers blockflowers2 = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - BlockFlowers blockflowers3 = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - BlockFlowers blockflowers4 = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - BlockFlowers blockflowers5 = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - BlockFlowers blockflowers6 = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - BlockFlowers blockflowers7 = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - BlockFlowers blockflowers8 = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - BlockFlowers blockflowers9 = new BlockFlowers(Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.c)); - - a("dandelion", (Block) blockflowers); - a("poppy", (Block) blockflowers1); - a("blue_orchid", (Block) blockflowers2); - a("allium", (Block) blockflowers3); - a("azure_bluet", (Block) blockflowers4); - a("red_tulip", (Block) blockflowers5); - a("orange_tulip", (Block) blockflowers6); - a("white_tulip", (Block) blockflowers7); - a("pink_tulip", (Block) blockflowers8); - a("oxeye_daisy", (Block) blockflowers9); - BlockMushroom blockmushroom = new BlockMushroom(Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c).a(1)); - BlockMushroom blockmushroom1 = new BlockMushroom(Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)); - - a("brown_mushroom", (Block) blockmushroom); - a("red_mushroom", (Block) blockmushroom1); - a("gold_block", new Block(Block.Info.a(Material.ORE, MaterialMapColor.F).a(3.0F, 6.0F).a(SoundEffectType.e))); - a("iron_block", new Block(Block.Info.a(Material.ORE, MaterialMapColor.h).a(5.0F, 6.0F).a(SoundEffectType.e))); - Block block8 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.D).a(2.0F, 6.0F)); - - a("bricks", block8); - a("tnt", (Block) (new BlockTNT(Block.Info.a(Material.TNT).b().a(SoundEffectType.c)))); - a("bookshelf", (Block) (new BlockBookshelf(Block.Info.a(Material.WOOD).b(1.5F).a(SoundEffectType.a)))); - a("mossy_cobblestone", new Block(Block.Info.a(Material.STONE).a(2.0F, 6.0F))); - a("obsidian", new Block(Block.Info.a(Material.STONE, MaterialMapColor.E).a(50.0F, 1200.0F))); - a("torch", (Block) (new BlockTorch(Block.Info.a(Material.ORIENTABLE).a().b().a(14).a(SoundEffectType.a)))); - a("wall_torch", (Block) (new BlockTorchWall(Block.Info.a(Material.ORIENTABLE).a().b().a(14).a(SoundEffectType.a)))); - a("fire", (Block) (new BlockFire(Block.Info.a(Material.FIRE, MaterialMapColor.f).a().c().b().a(15).a(SoundEffectType.g)))); - a("spawner", (Block) (new BlockMobSpawner(Block.Info.a(Material.STONE).b(5.0F).a(SoundEffectType.e)))); - a("oak_stairs", (Block) (new BlockStairs(block1.getBlockData(), Block.Info.a(block1)))); - a("chest", (Block) (new BlockChest(Block.Info.a(Material.WOOD).b(2.5F).a(SoundEffectType.a)))); - a("redstone_wire", (Block) (new BlockRedstoneWire(Block.Info.a(Material.ORIENTABLE).a().b()))); - a("diamond_ore", (Block) (new BlockOre(Block.Info.a(Material.STONE).a(3.0F, 3.0F)))); - a("diamond_block", new Block(Block.Info.a(Material.ORE, MaterialMapColor.G).a(5.0F, 6.0F).a(SoundEffectType.e))); - a("crafting_table", (Block) (new BlockWorkbench(Block.Info.a(Material.WOOD).b(2.5F).a(SoundEffectType.a)))); - a("wheat", (Block) (new BlockCrops(Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)))); - BlockSoil blocksoil = new BlockSoil(Block.Info.a(Material.EARTH).c().b(0.6F).a(SoundEffectType.b)); - - a("farmland", (Block) blocksoil); - a("furnace", (Block) (new BlockFurnace(Block.Info.a(Material.STONE).b(3.5F).a(13)))); - a("sign", (Block) (new BlockFloorSign(Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("oak_door", (Block) (new BlockDoor(Block.Info.a(Material.WOOD, block1.l).b(3.0F).a(SoundEffectType.a)))); - a("ladder", (Block) (new BlockLadder(Block.Info.a(Material.ORIENTABLE).b(0.4F).a(SoundEffectType.j)))); - a("rail", (Block) (new BlockMinecartTrack(Block.Info.a(Material.ORIENTABLE).a().b(0.7F).a(SoundEffectType.e)))); - a("cobblestone_stairs", (Block) (new BlockStairs(block.getBlockData(), Block.Info.a(block)))); - a("wall_sign", (Block) (new BlockWallSign(Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("lever", (Block) (new BlockLever(Block.Info.a(Material.ORIENTABLE).a().b(0.5F).a(SoundEffectType.a)))); - a("stone_pressure_plate", (Block) (new BlockPressurePlateBinary(BlockPressurePlateBinary.EnumMobType.MOBS, Block.Info.a(Material.STONE).a().b(0.5F)))); - a("iron_door", (Block) (new BlockDoor(Block.Info.a(Material.ORE, MaterialMapColor.h).b(5.0F).a(SoundEffectType.e)))); - a("oak_pressure_plate", (Block) (new BlockPressurePlateBinary(BlockPressurePlateBinary.EnumMobType.EVERYTHING, Block.Info.a(Material.WOOD, block1.l).a().b(0.5F).a(SoundEffectType.a)))); - a("spruce_pressure_plate", (Block) (new BlockPressurePlateBinary(BlockPressurePlateBinary.EnumMobType.EVERYTHING, Block.Info.a(Material.WOOD, block2.l).a().b(0.5F).a(SoundEffectType.a)))); - a("birch_pressure_plate", (Block) (new BlockPressurePlateBinary(BlockPressurePlateBinary.EnumMobType.EVERYTHING, Block.Info.a(Material.WOOD, block3.l).a().b(0.5F).a(SoundEffectType.a)))); - a("jungle_pressure_plate", (Block) (new BlockPressurePlateBinary(BlockPressurePlateBinary.EnumMobType.EVERYTHING, Block.Info.a(Material.WOOD, block4.l).a().b(0.5F).a(SoundEffectType.a)))); - a("acacia_pressure_plate", (Block) (new BlockPressurePlateBinary(BlockPressurePlateBinary.EnumMobType.EVERYTHING, Block.Info.a(Material.WOOD, block5.l).a().b(0.5F).a(SoundEffectType.a)))); - a("dark_oak_pressure_plate", (Block) (new BlockPressurePlateBinary(BlockPressurePlateBinary.EnumMobType.EVERYTHING, Block.Info.a(Material.WOOD, block6.l).a().b(0.5F).a(SoundEffectType.a)))); - a("redstone_ore", (Block) (new BlockRedstoneOre(Block.Info.a(Material.STONE).c().a(9).a(3.0F, 3.0F)))); - a("redstone_torch", (Block) (new BlockRedstoneTorch(Block.Info.a(Material.ORIENTABLE).a().b().a(7).a(SoundEffectType.a)))); - a("redstone_wall_torch", (Block) (new BlockRedstoneTorchWall(Block.Info.a(Material.ORIENTABLE).a().b().a(7).a(SoundEffectType.a)))); - a("stone_button", (Block) (new BlockStoneButton(Block.Info.a(Material.ORIENTABLE).a().b(0.5F)))); - a("snow", (Block) (new BlockSnow(Block.Info.a(Material.PACKED_ICE).c().b(0.1F).a(SoundEffectType.i)))); - a("ice", (Block) (new BlockIce(Block.Info.a(Material.ICE).a(0.98F).c().b(0.5F).a(SoundEffectType.f)))); - a("snow_block", (Block) (new BlockSnowBlock(Block.Info.a(Material.SNOW_BLOCK).c().b(0.2F).a(SoundEffectType.i)))); - BlockCactus blockcactus = new BlockCactus(Block.Info.a(Material.CACTUS).c().b(0.4F).a(SoundEffectType.g)); - - a("cactus", (Block) blockcactus); - a("clay", (Block) (new BlockClay(Block.Info.a(Material.CLAY).b(0.6F).a(SoundEffectType.b)))); - a("sugar_cane", (Block) (new BlockReed(Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)))); - a("jukebox", (Block) (new BlockJukeBox(Block.Info.a(Material.WOOD, MaterialMapColor.l).a(2.0F, 6.0F)))); - a("oak_fence", (Block) (new BlockFence(Block.Info.a(Material.WOOD, block1.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - BlockPumpkin blockpumpkin = new BlockPumpkin(Block.Info.a(Material.PUMPKIN, MaterialMapColor.q).b(1.0F).a(SoundEffectType.a)); - - a("pumpkin", (Block) blockpumpkin); - a("netherrack", new Block(Block.Info.a(Material.STONE, MaterialMapColor.K).b(0.4F))); - a("soul_sand", (Block) (new BlockSlowSand(Block.Info.a(Material.SAND, MaterialMapColor.B).c().b(0.5F).a(SoundEffectType.h)))); - a("glowstone", (Block) (new BlockLightStone(Block.Info.a(Material.SHATTERABLE, MaterialMapColor.d).b(0.3F).a(SoundEffectType.f).a(15)))); - a("nether_portal", (Block) (new BlockPortal(Block.Info.a(Material.PORTAL).a().c().b(-1.0F).a(SoundEffectType.f).a(11)))); - a("carved_pumpkin", (Block) (new BlockPumpkinCarved(Block.Info.a(Material.PUMPKIN, MaterialMapColor.q).b(1.0F).a(SoundEffectType.a)))); - a("jack_o_lantern", (Block) (new BlockPumpkinCarved(Block.Info.a(Material.PUMPKIN, MaterialMapColor.q).b(1.0F).a(SoundEffectType.a).a(15)))); - a("cake", (Block) (new BlockCake(Block.Info.a(Material.CAKE).b(0.5F).a(SoundEffectType.g)))); - a("repeater", (Block) (new BlockRepeater(Block.Info.a(Material.ORIENTABLE).b().a(SoundEffectType.a)))); - a("white_stained_glass", (Block) (new BlockStainedGlass(EnumColor.WHITE, Block.Info.a(Material.SHATTERABLE, EnumColor.WHITE).b(0.3F).a(SoundEffectType.f)))); - a("orange_stained_glass", (Block) (new BlockStainedGlass(EnumColor.ORANGE, Block.Info.a(Material.SHATTERABLE, EnumColor.ORANGE).b(0.3F).a(SoundEffectType.f)))); - a("magenta_stained_glass", (Block) (new BlockStainedGlass(EnumColor.MAGENTA, Block.Info.a(Material.SHATTERABLE, EnumColor.MAGENTA).b(0.3F).a(SoundEffectType.f)))); - a("light_blue_stained_glass", (Block) (new BlockStainedGlass(EnumColor.LIGHT_BLUE, Block.Info.a(Material.SHATTERABLE, EnumColor.LIGHT_BLUE).b(0.3F).a(SoundEffectType.f)))); - a("yellow_stained_glass", (Block) (new BlockStainedGlass(EnumColor.YELLOW, Block.Info.a(Material.SHATTERABLE, EnumColor.YELLOW).b(0.3F).a(SoundEffectType.f)))); - a("lime_stained_glass", (Block) (new BlockStainedGlass(EnumColor.LIME, Block.Info.a(Material.SHATTERABLE, EnumColor.LIME).b(0.3F).a(SoundEffectType.f)))); - a("pink_stained_glass", (Block) (new BlockStainedGlass(EnumColor.PINK, Block.Info.a(Material.SHATTERABLE, EnumColor.PINK).b(0.3F).a(SoundEffectType.f)))); - a("gray_stained_glass", (Block) (new BlockStainedGlass(EnumColor.GRAY, Block.Info.a(Material.SHATTERABLE, EnumColor.GRAY).b(0.3F).a(SoundEffectType.f)))); - a("light_gray_stained_glass", (Block) (new BlockStainedGlass(EnumColor.LIGHT_GRAY, Block.Info.a(Material.SHATTERABLE, EnumColor.LIGHT_GRAY).b(0.3F).a(SoundEffectType.f)))); - a("cyan_stained_glass", (Block) (new BlockStainedGlass(EnumColor.CYAN, Block.Info.a(Material.SHATTERABLE, EnumColor.CYAN).b(0.3F).a(SoundEffectType.f)))); - a("purple_stained_glass", (Block) (new BlockStainedGlass(EnumColor.PURPLE, Block.Info.a(Material.SHATTERABLE, EnumColor.PURPLE).b(0.3F).a(SoundEffectType.f)))); - a("blue_stained_glass", (Block) (new BlockStainedGlass(EnumColor.BLUE, Block.Info.a(Material.SHATTERABLE, EnumColor.BLUE).b(0.3F).a(SoundEffectType.f)))); - a("brown_stained_glass", (Block) (new BlockStainedGlass(EnumColor.BROWN, Block.Info.a(Material.SHATTERABLE, EnumColor.BROWN).b(0.3F).a(SoundEffectType.f)))); - a("green_stained_glass", (Block) (new BlockStainedGlass(EnumColor.GREEN, Block.Info.a(Material.SHATTERABLE, EnumColor.GREEN).b(0.3F).a(SoundEffectType.f)))); - a("red_stained_glass", (Block) (new BlockStainedGlass(EnumColor.RED, Block.Info.a(Material.SHATTERABLE, EnumColor.RED).b(0.3F).a(SoundEffectType.f)))); - a("black_stained_glass", (Block) (new BlockStainedGlass(EnumColor.BLACK, Block.Info.a(Material.SHATTERABLE, EnumColor.BLACK).b(0.3F).a(SoundEffectType.f)))); - a("oak_trapdoor", (Block) (new BlockTrapdoor(Block.Info.a(Material.WOOD, MaterialMapColor.o).b(3.0F).a(SoundEffectType.a)))); - a("spruce_trapdoor", (Block) (new BlockTrapdoor(Block.Info.a(Material.WOOD, MaterialMapColor.J).b(3.0F).a(SoundEffectType.a)))); - a("birch_trapdoor", (Block) (new BlockTrapdoor(Block.Info.a(Material.WOOD, MaterialMapColor.d).b(3.0F).a(SoundEffectType.a)))); - a("jungle_trapdoor", (Block) (new BlockTrapdoor(Block.Info.a(Material.WOOD, MaterialMapColor.l).b(3.0F).a(SoundEffectType.a)))); - a("acacia_trapdoor", (Block) (new BlockTrapdoor(Block.Info.a(Material.WOOD, MaterialMapColor.q).b(3.0F).a(SoundEffectType.a)))); - a("dark_oak_trapdoor", (Block) (new BlockTrapdoor(Block.Info.a(Material.WOOD, MaterialMapColor.B).b(3.0F).a(SoundEffectType.a)))); - Block block9 = new Block(Block.Info.a(Material.STONE).a(1.5F, 6.0F)); - Block block10 = new Block(Block.Info.a(Material.STONE).a(1.5F, 6.0F)); - Block block11 = new Block(Block.Info.a(Material.STONE).a(1.5F, 6.0F)); - Block block12 = new Block(Block.Info.a(Material.STONE).a(1.5F, 6.0F)); - - a("infested_stone", (Block) (new BlockMonsterEggs(blockstone, Block.Info.a(Material.CLAY).a(0.0F, 0.75F)))); - a("infested_cobblestone", (Block) (new BlockMonsterEggs(block, Block.Info.a(Material.CLAY).a(0.0F, 0.75F)))); - a("infested_stone_bricks", (Block) (new BlockMonsterEggs(block9, Block.Info.a(Material.CLAY).a(0.0F, 0.75F)))); - a("infested_mossy_stone_bricks", (Block) (new BlockMonsterEggs(block10, Block.Info.a(Material.CLAY).a(0.0F, 0.75F)))); - a("infested_cracked_stone_bricks", (Block) (new BlockMonsterEggs(block11, Block.Info.a(Material.CLAY).a(0.0F, 0.75F)))); - a("infested_chiseled_stone_bricks", (Block) (new BlockMonsterEggs(block12, Block.Info.a(Material.CLAY).a(0.0F, 0.75F)))); - a("stone_bricks", block9); - a("mossy_stone_bricks", block10); - a("cracked_stone_bricks", block11); - a("chiseled_stone_bricks", block12); - BlockHugeMushroom blockhugemushroom = new BlockHugeMushroom(blockmushroom, Block.Info.a(Material.WOOD, MaterialMapColor.l).b(0.2F).a(SoundEffectType.a)); - - a("brown_mushroom_block", (Block) blockhugemushroom); - BlockHugeMushroom blockhugemushroom1 = new BlockHugeMushroom(blockmushroom1, Block.Info.a(Material.WOOD, MaterialMapColor.D).b(0.2F).a(SoundEffectType.a)); - - a("red_mushroom_block", (Block) blockhugemushroom1); - a("mushroom_stem", (Block) (new BlockHugeMushroom((Block) null, Block.Info.a(Material.WOOD, MaterialMapColor.L).b(0.2F).a(SoundEffectType.a)))); - a("iron_bars", (Block) (new BlockIronBars(Block.Info.a(Material.ORE, MaterialMapColor.b).a(5.0F, 6.0F).a(SoundEffectType.e)))); - a("glass_pane", (Block) (new BlockGlassPane(Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - BlockMelon blockmelon = new BlockMelon(Block.Info.a(Material.PUMPKIN, MaterialMapColor.u).b(1.0F).a(SoundEffectType.a)); - - a("melon", (Block) blockmelon); - a("attached_pumpkin_stem", (Block) (new BlockStemAttached(blockpumpkin, Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.a)))); - a("attached_melon_stem", (Block) (new BlockStemAttached(blockmelon, Block.Info.a(Material.PLANT).a().b().a(SoundEffectType.a)))); - a("pumpkin_stem", (Block) (new BlockStem(blockpumpkin, Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.a)))); - a("melon_stem", (Block) (new BlockStem(blockmelon, Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.a)))); - a("vine", (Block) (new BlockVine(Block.Info.a(Material.REPLACEABLE_PLANT).a().c().b(0.2F).a(SoundEffectType.c)))); - a("oak_fence_gate", (Block) (new BlockFenceGate(Block.Info.a(Material.WOOD, block1.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("brick_stairs", (Block) (new BlockStairs(block8.getBlockData(), Block.Info.a(block8)))); - a("stone_brick_stairs", (Block) (new BlockStairs(block9.getBlockData(), Block.Info.a(block9)))); - a("mycelium", (Block) (new BlockMycel(Block.Info.a(Material.GRASS, MaterialMapColor.z).c().b(0.6F).a(SoundEffectType.c)))); - a("lily_pad", (Block) (new BlockWaterLily(Block.Info.a(Material.PLANT).b().a(SoundEffectType.c)))); - Block block13 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.K).a(2.0F, 6.0F)); - - a("nether_bricks", block13); - a("nether_brick_fence", (Block) (new BlockFence(Block.Info.a(Material.STONE, MaterialMapColor.K).a(2.0F, 6.0F)))); - a("nether_brick_stairs", (Block) (new BlockStairs(block13.getBlockData(), Block.Info.a(block13)))); - a("nether_wart", (Block) (new BlockNetherWart(Block.Info.a(Material.PLANT, MaterialMapColor.D).a().c()))); - a("enchanting_table", (Block) (new BlockEnchantmentTable(Block.Info.a(Material.STONE, MaterialMapColor.D).a(5.0F, 1200.0F)))); - a("brewing_stand", (Block) (new BlockBrewingStand(Block.Info.a(Material.ORE).b(0.5F).a(1)))); - a("cauldron", (Block) (new BlockCauldron(Block.Info.a(Material.ORE, MaterialMapColor.m).b(2.0F)))); - a("end_portal", (Block) (new BlockEnderPortal(Block.Info.a(Material.PORTAL, MaterialMapColor.E).a().a(15).a(-1.0F, 3600000.0F)))); - a("end_portal_frame", (Block) (new BlockEnderPortalFrame(Block.Info.a(Material.STONE, MaterialMapColor.C).a(SoundEffectType.f).a(1).a(-1.0F, 3600000.0F)))); - a("end_stone", new Block(Block.Info.a(Material.STONE, MaterialMapColor.d).a(3.0F, 9.0F))); - a("dragon_egg", (Block) (new BlockDragonEgg(Block.Info.a(Material.DRAGON_EGG, MaterialMapColor.E).a(3.0F, 9.0F).a(1)))); - a("redstone_lamp", (Block) (new BlockRedstoneLamp(Block.Info.a(Material.BUILDABLE_GLASS).a(15).b(0.3F).a(SoundEffectType.f)))); - a("cocoa", (Block) (new BlockCocoa(Block.Info.a(Material.PLANT).c().a(0.2F, 3.0F).a(SoundEffectType.a)))); - a("sandstone_stairs", (Block) (new BlockStairs(block7.getBlockData(), Block.Info.a(block7)))); - a("emerald_ore", (Block) (new BlockOre(Block.Info.a(Material.STONE).a(3.0F, 3.0F)))); - a("ender_chest", (Block) (new BlockEnderChest(Block.Info.a(Material.STONE).a(22.5F, 600.0F).a(7)))); - BlockTripwireHook blocktripwirehook = new BlockTripwireHook(Block.Info.a(Material.ORIENTABLE).a()); - - a("tripwire_hook", (Block) blocktripwirehook); - a("tripwire", (Block) (new BlockTripwire(blocktripwirehook, Block.Info.a(Material.ORIENTABLE).a()))); - a("emerald_block", new Block(Block.Info.a(Material.ORE, MaterialMapColor.I).a(5.0F, 6.0F).a(SoundEffectType.e))); - a("spruce_stairs", (Block) (new BlockStairs(block2.getBlockData(), Block.Info.a(block2)))); - a("birch_stairs", (Block) (new BlockStairs(block3.getBlockData(), Block.Info.a(block3)))); - a("jungle_stairs", (Block) (new BlockStairs(block4.getBlockData(), Block.Info.a(block4)))); - a("command_block", (Block) (new BlockCommand(Block.Info.a(Material.ORE, MaterialMapColor.B).a(-1.0F, 3600000.0F)))); - a("beacon", (Block) (new BlockBeacon(Block.Info.a(Material.SHATTERABLE, MaterialMapColor.G).b(3.0F).a(15)))); - a("cobblestone_wall", (Block) (new BlockCobbleWall(Block.Info.a(block)))); - a("mossy_cobblestone_wall", (Block) (new BlockCobbleWall(Block.Info.a(block)))); - a("flower_pot", (Block) (new BlockFlowerPot(blockair, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_oak_sapling", (Block) (new BlockFlowerPot(blocksapling, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_spruce_sapling", (Block) (new BlockFlowerPot(blocksapling1, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_birch_sapling", (Block) (new BlockFlowerPot(blocksapling2, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_jungle_sapling", (Block) (new BlockFlowerPot(blocksapling3, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_acacia_sapling", (Block) (new BlockFlowerPot(blocksapling4, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_dark_oak_sapling", (Block) (new BlockFlowerPot(blocksapling5, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_fern", (Block) (new BlockFlowerPot(blocklonggrass1, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_dandelion", (Block) (new BlockFlowerPot(blockflowers, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_poppy", (Block) (new BlockFlowerPot(blockflowers1, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_blue_orchid", (Block) (new BlockFlowerPot(blockflowers2, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_allium", (Block) (new BlockFlowerPot(blockflowers3, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_azure_bluet", (Block) (new BlockFlowerPot(blockflowers4, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_red_tulip", (Block) (new BlockFlowerPot(blockflowers5, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_orange_tulip", (Block) (new BlockFlowerPot(blockflowers6, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_white_tulip", (Block) (new BlockFlowerPot(blockflowers7, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_pink_tulip", (Block) (new BlockFlowerPot(blockflowers8, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_oxeye_daisy", (Block) (new BlockFlowerPot(blockflowers9, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_red_mushroom", (Block) (new BlockFlowerPot(blockmushroom1, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_brown_mushroom", (Block) (new BlockFlowerPot(blockmushroom, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_dead_bush", (Block) (new BlockFlowerPot(blockdeadbush, Block.Info.a(Material.ORIENTABLE).b()))); - a("potted_cactus", (Block) (new BlockFlowerPot(blockcactus, Block.Info.a(Material.ORIENTABLE).b()))); - a("carrots", (Block) (new BlockCarrots(Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)))); - a("potatoes", (Block) (new BlockPotatoes(Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)))); - a("oak_button", (Block) (new BlockWoodButton(Block.Info.a(Material.ORIENTABLE).a().b(0.5F).a(SoundEffectType.a)))); - a("spruce_button", (Block) (new BlockWoodButton(Block.Info.a(Material.ORIENTABLE).a().b(0.5F).a(SoundEffectType.a)))); - a("birch_button", (Block) (new BlockWoodButton(Block.Info.a(Material.ORIENTABLE).a().b(0.5F).a(SoundEffectType.a)))); - a("jungle_button", (Block) (new BlockWoodButton(Block.Info.a(Material.ORIENTABLE).a().b(0.5F).a(SoundEffectType.a)))); - a("acacia_button", (Block) (new BlockWoodButton(Block.Info.a(Material.ORIENTABLE).a().b(0.5F).a(SoundEffectType.a)))); - a("dark_oak_button", (Block) (new BlockWoodButton(Block.Info.a(Material.ORIENTABLE).a().b(0.5F).a(SoundEffectType.a)))); - a("skeleton_wall_skull", (Block) (new BlockSkullWall(BlockSkull.Type.SKELETON, Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("skeleton_skull", (Block) (new BlockSkull(BlockSkull.Type.SKELETON, Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("wither_skeleton_wall_skull", (Block) (new BlockWitherSkullWall(Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("wither_skeleton_skull", (Block) (new BlockWitherSkull(Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("zombie_wall_head", (Block) (new BlockSkullWall(BlockSkull.Type.ZOMBIE, Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("zombie_head", (Block) (new BlockSkull(BlockSkull.Type.ZOMBIE, Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("player_wall_head", (Block) (new BlockSkullPlayerWall(Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("player_head", (Block) (new BlockSkullPlayer(Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("creeper_wall_head", (Block) (new BlockSkullWall(BlockSkull.Type.CREEPER, Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("creeper_head", (Block) (new BlockSkull(BlockSkull.Type.CREEPER, Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("dragon_wall_head", (Block) (new BlockSkullWall(BlockSkull.Type.DRAGON, Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("dragon_head", (Block) (new BlockSkull(BlockSkull.Type.DRAGON, Block.Info.a(Material.ORIENTABLE).b(1.0F)))); - a("anvil", (Block) (new BlockAnvil(Block.Info.a(Material.HEAVY, MaterialMapColor.h).a(5.0F, 1200.0F).a(SoundEffectType.k)))); - a("chipped_anvil", (Block) (new BlockAnvil(Block.Info.a(Material.HEAVY, MaterialMapColor.h).a(5.0F, 1200.0F).a(SoundEffectType.k)))); - a("damaged_anvil", (Block) (new BlockAnvil(Block.Info.a(Material.HEAVY, MaterialMapColor.h).a(5.0F, 1200.0F).a(SoundEffectType.k)))); - a("trapped_chest", (Block) (new BlockChestTrapped(Block.Info.a(Material.WOOD).b(2.5F).a(SoundEffectType.a)))); - a("light_weighted_pressure_plate", (Block) (new BlockPressurePlateWeighted(15, Block.Info.a(Material.ORE, MaterialMapColor.F).a().b(0.5F).a(SoundEffectType.a)))); - a("heavy_weighted_pressure_plate", (Block) (new BlockPressurePlateWeighted(150, Block.Info.a(Material.ORE).a().b(0.5F).a(SoundEffectType.a)))); - a("comparator", (Block) (new BlockRedstoneComparator(Block.Info.a(Material.ORIENTABLE).b().a(SoundEffectType.a)))); - a("daylight_detector", (Block) (new BlockDaylightDetector(Block.Info.a(Material.WOOD).b(0.2F).a(SoundEffectType.a)))); - a("redstone_block", (Block) (new BlockPowered(Block.Info.a(Material.ORE, MaterialMapColor.f).a(5.0F, 6.0F).a(SoundEffectType.e)))); - a("nether_quartz_ore", (Block) (new BlockOre(Block.Info.a(Material.STONE, MaterialMapColor.K).a(3.0F, 3.0F)))); - a("hopper", (Block) (new BlockHopper(Block.Info.a(Material.ORE, MaterialMapColor.m).a(3.0F, 4.8F).a(SoundEffectType.e)))); - Block block14 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.p).b(0.8F)); - - a("quartz_block", block14); - a("chiseled_quartz_block", new Block(Block.Info.a(Material.STONE, MaterialMapColor.p).b(0.8F))); - a("quartz_pillar", (Block) (new BlockRotatable(Block.Info.a(Material.STONE, MaterialMapColor.p).b(0.8F)))); - a("quartz_stairs", (Block) (new BlockStairs(block14.getBlockData(), Block.Info.a(block14)))); - a("activator_rail", (Block) (new BlockPoweredRail(Block.Info.a(Material.ORIENTABLE).a().b(0.7F).a(SoundEffectType.e)))); - a("dropper", (Block) (new BlockDropper(Block.Info.a(Material.STONE).b(3.5F)))); - a("white_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.L).a(1.25F, 4.2F))); - a("orange_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.M).a(1.25F, 4.2F))); - a("magenta_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.N).a(1.25F, 4.2F))); - a("light_blue_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.O).a(1.25F, 4.2F))); - a("yellow_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.P).a(1.25F, 4.2F))); - a("lime_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.Q).a(1.25F, 4.2F))); - a("pink_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.R).a(1.25F, 4.2F))); - a("gray_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.S).a(1.25F, 4.2F))); - a("light_gray_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.T).a(1.25F, 4.2F))); - a("cyan_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.U).a(1.25F, 4.2F))); - a("purple_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.V).a(1.25F, 4.2F))); - a("blue_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.W).a(1.25F, 4.2F))); - a("brown_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.X).a(1.25F, 4.2F))); - a("green_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.Y).a(1.25F, 4.2F))); - a("red_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.Z).a(1.25F, 4.2F))); - a("black_terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.aa).a(1.25F, 4.2F))); - a("white_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.WHITE, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("orange_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.ORANGE, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("magenta_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.MAGENTA, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("light_blue_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.LIGHT_BLUE, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("yellow_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.YELLOW, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("lime_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.LIME, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("pink_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.PINK, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("gray_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.GRAY, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("light_gray_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.LIGHT_GRAY, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("cyan_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.CYAN, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("purple_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.PURPLE, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("blue_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.BLUE, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("brown_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.BROWN, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("green_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.GREEN, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("red_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.RED, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("black_stained_glass_pane", (Block) (new BlockStainedGlassPane(EnumColor.BLACK, Block.Info.a(Material.SHATTERABLE).b(0.3F).a(SoundEffectType.f)))); - a("acacia_stairs", (Block) (new BlockStairs(block5.getBlockData(), Block.Info.a(block5)))); - a("dark_oak_stairs", (Block) (new BlockStairs(block6.getBlockData(), Block.Info.a(block6)))); - a("slime_block", (Block) (new BlockSlime(Block.Info.a(Material.CLAY, MaterialMapColor.c).a(0.8F).a(SoundEffectType.l)))); - a("barrier", (Block) (new BlockBarrier(Block.Info.a(Material.BANNER).a(-1.0F, 3600000.8F)))); - a("iron_trapdoor", (Block) (new BlockTrapdoor(Block.Info.a(Material.ORE).b(5.0F).a(SoundEffectType.e)))); - Block block15 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.y).a(1.5F, 6.0F)); - - a("prismarine", block15); - Block block16 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.G).a(1.5F, 6.0F)); - - a("prismarine_bricks", block16); - Block block17 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.G).a(1.5F, 6.0F)); - - a("dark_prismarine", block17); - a("prismarine_stairs", (Block) (new BlockStairs(block15.getBlockData(), Block.Info.a(block15)))); - a("prismarine_brick_stairs", (Block) (new BlockStairs(block16.getBlockData(), Block.Info.a(block16)))); - a("dark_prismarine_stairs", (Block) (new BlockStairs(block17.getBlockData(), Block.Info.a(block17)))); - a("prismarine_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.y).a(1.5F, 6.0F)))); - a("prismarine_brick_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.G).a(1.5F, 6.0F)))); - a("dark_prismarine_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.G).a(1.5F, 6.0F)))); - a("sea_lantern", (Block) (new BlockSeaLantern(Block.Info.a(Material.SHATTERABLE, MaterialMapColor.p).b(0.3F).a(SoundEffectType.f).a(15)))); - a("hay_block", (Block) (new BlockHay(Block.Info.a(Material.GRASS, MaterialMapColor.t).b(0.5F).a(SoundEffectType.c)))); - a("white_carpet", (Block) (new BlockCarpet(EnumColor.WHITE, Block.Info.a(Material.WOOL, MaterialMapColor.j).b(0.1F).a(SoundEffectType.g)))); - a("orange_carpet", (Block) (new BlockCarpet(EnumColor.ORANGE, Block.Info.a(Material.WOOL, MaterialMapColor.q).b(0.1F).a(SoundEffectType.g)))); - a("magenta_carpet", (Block) (new BlockCarpet(EnumColor.MAGENTA, Block.Info.a(Material.WOOL, MaterialMapColor.r).b(0.1F).a(SoundEffectType.g)))); - a("light_blue_carpet", (Block) (new BlockCarpet(EnumColor.LIGHT_BLUE, Block.Info.a(Material.WOOL, MaterialMapColor.s).b(0.1F).a(SoundEffectType.g)))); - a("yellow_carpet", (Block) (new BlockCarpet(EnumColor.YELLOW, Block.Info.a(Material.WOOL, MaterialMapColor.t).b(0.1F).a(SoundEffectType.g)))); - a("lime_carpet", (Block) (new BlockCarpet(EnumColor.LIME, Block.Info.a(Material.WOOL, MaterialMapColor.u).b(0.1F).a(SoundEffectType.g)))); - a("pink_carpet", (Block) (new BlockCarpet(EnumColor.PINK, Block.Info.a(Material.WOOL, MaterialMapColor.v).b(0.1F).a(SoundEffectType.g)))); - a("gray_carpet", (Block) (new BlockCarpet(EnumColor.GRAY, Block.Info.a(Material.WOOL, MaterialMapColor.w).b(0.1F).a(SoundEffectType.g)))); - a("light_gray_carpet", (Block) (new BlockCarpet(EnumColor.LIGHT_GRAY, Block.Info.a(Material.WOOL, MaterialMapColor.x).b(0.1F).a(SoundEffectType.g)))); - a("cyan_carpet", (Block) (new BlockCarpet(EnumColor.CYAN, Block.Info.a(Material.WOOL, MaterialMapColor.y).b(0.1F).a(SoundEffectType.g)))); - a("purple_carpet", (Block) (new BlockCarpet(EnumColor.PURPLE, Block.Info.a(Material.WOOL, MaterialMapColor.z).b(0.1F).a(SoundEffectType.g)))); - a("blue_carpet", (Block) (new BlockCarpet(EnumColor.BLUE, Block.Info.a(Material.WOOL, MaterialMapColor.A).b(0.1F).a(SoundEffectType.g)))); - a("brown_carpet", (Block) (new BlockCarpet(EnumColor.BROWN, Block.Info.a(Material.WOOL, MaterialMapColor.B).b(0.1F).a(SoundEffectType.g)))); - a("green_carpet", (Block) (new BlockCarpet(EnumColor.GREEN, Block.Info.a(Material.WOOL, MaterialMapColor.C).b(0.1F).a(SoundEffectType.g)))); - a("red_carpet", (Block) (new BlockCarpet(EnumColor.RED, Block.Info.a(Material.WOOL, MaterialMapColor.D).b(0.1F).a(SoundEffectType.g)))); - a("black_carpet", (Block) (new BlockCarpet(EnumColor.BLACK, Block.Info.a(Material.WOOL, MaterialMapColor.E).b(0.1F).a(SoundEffectType.g)))); - a("terracotta", new Block(Block.Info.a(Material.STONE, MaterialMapColor.q).a(1.25F, 4.2F))); - a("coal_block", new Block(Block.Info.a(Material.STONE, MaterialMapColor.E).a(5.0F, 6.0F))); - a("packed_ice", (Block) (new BlockPackedIce(Block.Info.a(Material.SNOW_LAYER).a(0.98F).b(0.5F).a(SoundEffectType.f)))); - a("sunflower", (Block) (new BlockTallPlantFlower(Block.Info.a(Material.REPLACEABLE_PLANT).a().b().a(SoundEffectType.c)))); - a("lilac", (Block) (new BlockTallPlantFlower(Block.Info.a(Material.REPLACEABLE_PLANT).a().b().a(SoundEffectType.c)))); - a("rose_bush", (Block) (new BlockTallPlantFlower(Block.Info.a(Material.REPLACEABLE_PLANT).a().b().a(SoundEffectType.c)))); - a("peony", (Block) (new BlockTallPlantFlower(Block.Info.a(Material.REPLACEABLE_PLANT).a().b().a(SoundEffectType.c)))); - a("tall_grass", (Block) (new BlockTallPlantShearable(blocklonggrass, Block.Info.a(Material.REPLACEABLE_PLANT).a().b().a(SoundEffectType.c)))); - a("large_fern", (Block) (new BlockTallPlantShearable(blocklonggrass1, Block.Info.a(Material.REPLACEABLE_PLANT).a().b().a(SoundEffectType.c)))); - a("white_banner", (Block) (new BlockBanner(EnumColor.WHITE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("orange_banner", (Block) (new BlockBanner(EnumColor.ORANGE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("magenta_banner", (Block) (new BlockBanner(EnumColor.MAGENTA, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("light_blue_banner", (Block) (new BlockBanner(EnumColor.LIGHT_BLUE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("yellow_banner", (Block) (new BlockBanner(EnumColor.YELLOW, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("lime_banner", (Block) (new BlockBanner(EnumColor.LIME, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("pink_banner", (Block) (new BlockBanner(EnumColor.PINK, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("gray_banner", (Block) (new BlockBanner(EnumColor.GRAY, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("light_gray_banner", (Block) (new BlockBanner(EnumColor.LIGHT_GRAY, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("cyan_banner", (Block) (new BlockBanner(EnumColor.CYAN, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("purple_banner", (Block) (new BlockBanner(EnumColor.PURPLE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("blue_banner", (Block) (new BlockBanner(EnumColor.BLUE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("brown_banner", (Block) (new BlockBanner(EnumColor.BROWN, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("green_banner", (Block) (new BlockBanner(EnumColor.GREEN, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("red_banner", (Block) (new BlockBanner(EnumColor.RED, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("black_banner", (Block) (new BlockBanner(EnumColor.BLACK, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("white_wall_banner", (Block) (new BlockBannerWall(EnumColor.WHITE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("orange_wall_banner", (Block) (new BlockBannerWall(EnumColor.ORANGE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("magenta_wall_banner", (Block) (new BlockBannerWall(EnumColor.MAGENTA, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("light_blue_wall_banner", (Block) (new BlockBannerWall(EnumColor.LIGHT_BLUE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("yellow_wall_banner", (Block) (new BlockBannerWall(EnumColor.YELLOW, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("lime_wall_banner", (Block) (new BlockBannerWall(EnumColor.LIME, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("pink_wall_banner", (Block) (new BlockBannerWall(EnumColor.PINK, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("gray_wall_banner", (Block) (new BlockBannerWall(EnumColor.GRAY, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("light_gray_wall_banner", (Block) (new BlockBannerWall(EnumColor.LIGHT_GRAY, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("cyan_wall_banner", (Block) (new BlockBannerWall(EnumColor.CYAN, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("purple_wall_banner", (Block) (new BlockBannerWall(EnumColor.PURPLE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("blue_wall_banner", (Block) (new BlockBannerWall(EnumColor.BLUE, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("brown_wall_banner", (Block) (new BlockBannerWall(EnumColor.BROWN, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("green_wall_banner", (Block) (new BlockBannerWall(EnumColor.GREEN, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("red_wall_banner", (Block) (new BlockBannerWall(EnumColor.RED, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - a("black_wall_banner", (Block) (new BlockBannerWall(EnumColor.BLACK, Block.Info.a(Material.WOOD).a().b(1.0F).a(SoundEffectType.a)))); - Block block18 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.q).b(0.8F)); - - a("red_sandstone", block18); - a("chiseled_red_sandstone", new Block(Block.Info.a(Material.STONE, MaterialMapColor.q).b(0.8F))); - a("cut_red_sandstone", new Block(Block.Info.a(Material.STONE, MaterialMapColor.q).b(0.8F))); - a("red_sandstone_stairs", (Block) (new BlockStairs(block18.getBlockData(), Block.Info.a(block18)))); - a("oak_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.WOOD, MaterialMapColor.o).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("spruce_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.WOOD, MaterialMapColor.J).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("birch_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.WOOD, MaterialMapColor.d).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("jungle_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.WOOD, MaterialMapColor.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("acacia_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.WOOD, MaterialMapColor.q).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("dark_oak_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.WOOD, MaterialMapColor.B).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("stone_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.m).a(2.0F, 6.0F)))); - a("sandstone_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.d).a(2.0F, 6.0F)))); - a("petrified_oak_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.o).a(2.0F, 6.0F)))); - a("cobblestone_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.m).a(2.0F, 6.0F)))); - a("brick_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.D).a(2.0F, 6.0F)))); - a("stone_brick_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.m).a(2.0F, 6.0F)))); - a("nether_brick_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.K).a(2.0F, 6.0F)))); - a("quartz_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.p).a(2.0F, 6.0F)))); - a("red_sandstone_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.q).a(2.0F, 6.0F)))); - a("purpur_slab", (Block) (new BlockStepAbstract(Block.Info.a(Material.STONE, MaterialMapColor.r).a(2.0F, 6.0F)))); - a("smooth_stone", new Block(Block.Info.a(Material.STONE, MaterialMapColor.m).a(2.0F, 6.0F))); - a("smooth_sandstone", new Block(Block.Info.a(Material.STONE, MaterialMapColor.d).a(2.0F, 6.0F))); - a("smooth_quartz", new Block(Block.Info.a(Material.STONE, MaterialMapColor.p).a(2.0F, 6.0F))); - a("smooth_red_sandstone", new Block(Block.Info.a(Material.STONE, MaterialMapColor.q).a(2.0F, 6.0F))); - a("spruce_fence_gate", (Block) (new BlockFenceGate(Block.Info.a(Material.WOOD, block2.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("birch_fence_gate", (Block) (new BlockFenceGate(Block.Info.a(Material.WOOD, block3.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("jungle_fence_gate", (Block) (new BlockFenceGate(Block.Info.a(Material.WOOD, block4.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("acacia_fence_gate", (Block) (new BlockFenceGate(Block.Info.a(Material.WOOD, block5.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("dark_oak_fence_gate", (Block) (new BlockFenceGate(Block.Info.a(Material.WOOD, block6.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("spruce_fence", (Block) (new BlockFence(Block.Info.a(Material.WOOD, block2.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("birch_fence", (Block) (new BlockFence(Block.Info.a(Material.WOOD, block3.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("jungle_fence", (Block) (new BlockFence(Block.Info.a(Material.WOOD, block4.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("acacia_fence", (Block) (new BlockFence(Block.Info.a(Material.WOOD, block5.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("dark_oak_fence", (Block) (new BlockFence(Block.Info.a(Material.WOOD, block6.l).a(2.0F, 3.0F).a(SoundEffectType.a)))); - a("spruce_door", (Block) (new BlockDoor(Block.Info.a(Material.WOOD, block2.l).b(3.0F).a(SoundEffectType.a)))); - a("birch_door", (Block) (new BlockDoor(Block.Info.a(Material.WOOD, block3.l).b(3.0F).a(SoundEffectType.a)))); - a("jungle_door", (Block) (new BlockDoor(Block.Info.a(Material.WOOD, block4.l).b(3.0F).a(SoundEffectType.a)))); - a("acacia_door", (Block) (new BlockDoor(Block.Info.a(Material.WOOD, block5.l).b(3.0F).a(SoundEffectType.a)))); - a("dark_oak_door", (Block) (new BlockDoor(Block.Info.a(Material.WOOD, block6.l).b(3.0F).a(SoundEffectType.a)))); - a("end_rod", (Block) (new BlockEndRod(Block.Info.a(Material.ORIENTABLE).b().a(14).a(SoundEffectType.a)))); - BlockChorusFruit blockchorusfruit = new BlockChorusFruit(Block.Info.a(Material.PLANT, MaterialMapColor.z).b(0.4F).a(SoundEffectType.a)); - - a("chorus_plant", (Block) blockchorusfruit); - a("chorus_flower", (Block) (new BlockChorusFlower(blockchorusfruit, Block.Info.a(Material.PLANT, MaterialMapColor.z).c().b(0.4F).a(SoundEffectType.a)))); - Block block19 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.r).a(1.5F, 6.0F)); - - a("purpur_block", block19); - a("purpur_pillar", (Block) (new BlockRotatable(Block.Info.a(Material.STONE, MaterialMapColor.r).a(1.5F, 6.0F)))); - a("purpur_stairs", (Block) (new BlockStairs(block19.getBlockData(), Block.Info.a(block19)))); - a("end_stone_bricks", new Block(Block.Info.a(Material.STONE, MaterialMapColor.d).b(0.8F))); - a("beetroots", (Block) (new BlockBeetroot(Block.Info.a(Material.PLANT).a().c().b().a(SoundEffectType.c)))); - BlockGrassPath blockgrasspath = new BlockGrassPath(Block.Info.a(Material.EARTH).b(0.65F).a(SoundEffectType.c)); - - a("grass_path", (Block) blockgrasspath); - a("end_gateway", (Block) (new BlockEndGateway(Block.Info.a(Material.PORTAL, MaterialMapColor.E).a().a(15).a(-1.0F, 3600000.0F)))); - a("repeating_command_block", (Block) (new BlockCommand(Block.Info.a(Material.ORE, MaterialMapColor.z).a(-1.0F, 3600000.0F)))); - a("chain_command_block", (Block) (new BlockCommand(Block.Info.a(Material.ORE, MaterialMapColor.C).a(-1.0F, 3600000.0F)))); - a("frosted_ice", (Block) (new BlockIceFrost(Block.Info.a(Material.ICE).a(0.98F).c().b(0.5F).a(SoundEffectType.f)))); - a("magma_block", (Block) (new BlockMagma(Block.Info.a(Material.STONE, MaterialMapColor.K).a(3).c().b(0.5F)))); - a("nether_wart_block", new Block(Block.Info.a(Material.GRASS, MaterialMapColor.D).b(1.0F).a(SoundEffectType.a))); - a("red_nether_bricks", new Block(Block.Info.a(Material.STONE, MaterialMapColor.K).a(2.0F, 6.0F))); - a("bone_block", (Block) (new BlockRotatable(Block.Info.a(Material.STONE, MaterialMapColor.d).b(2.0F)))); - a("structure_void", (Block) (new BlockStructureVoid(Block.Info.a(Material.STRUCTURE_VOID).a()))); - a("observer", (Block) (new BlockObserver(Block.Info.a(Material.STONE).b(3.0F)))); - a("shulker_box", (Block) (new BlockShulkerBox((EnumColor) null, Block.Info.a(Material.STONE, MaterialMapColor.z).b(2.0F).d()))); - a("white_shulker_box", (Block) (new BlockShulkerBox(EnumColor.WHITE, Block.Info.a(Material.STONE, MaterialMapColor.j).b(2.0F).d()))); - a("orange_shulker_box", (Block) (new BlockShulkerBox(EnumColor.ORANGE, Block.Info.a(Material.STONE, MaterialMapColor.q).b(2.0F).d()))); - a("magenta_shulker_box", (Block) (new BlockShulkerBox(EnumColor.MAGENTA, Block.Info.a(Material.STONE, MaterialMapColor.r).b(2.0F).d()))); - a("light_blue_shulker_box", (Block) (new BlockShulkerBox(EnumColor.LIGHT_BLUE, Block.Info.a(Material.STONE, MaterialMapColor.s).b(2.0F).d()))); - a("yellow_shulker_box", (Block) (new BlockShulkerBox(EnumColor.YELLOW, Block.Info.a(Material.STONE, MaterialMapColor.t).b(2.0F).d()))); - a("lime_shulker_box", (Block) (new BlockShulkerBox(EnumColor.LIME, Block.Info.a(Material.STONE, MaterialMapColor.u).b(2.0F).d()))); - a("pink_shulker_box", (Block) (new BlockShulkerBox(EnumColor.PINK, Block.Info.a(Material.STONE, MaterialMapColor.v).b(2.0F).d()))); - a("gray_shulker_box", (Block) (new BlockShulkerBox(EnumColor.GRAY, Block.Info.a(Material.STONE, MaterialMapColor.w).b(2.0F).d()))); - a("light_gray_shulker_box", (Block) (new BlockShulkerBox(EnumColor.LIGHT_GRAY, Block.Info.a(Material.STONE, MaterialMapColor.x).b(2.0F).d()))); - a("cyan_shulker_box", (Block) (new BlockShulkerBox(EnumColor.CYAN, Block.Info.a(Material.STONE, MaterialMapColor.y).b(2.0F).d()))); - a("purple_shulker_box", (Block) (new BlockShulkerBox(EnumColor.PURPLE, Block.Info.a(Material.STONE, MaterialMapColor.V).b(2.0F).d()))); - a("blue_shulker_box", (Block) (new BlockShulkerBox(EnumColor.BLUE, Block.Info.a(Material.STONE, MaterialMapColor.A).b(2.0F).d()))); - a("brown_shulker_box", (Block) (new BlockShulkerBox(EnumColor.BROWN, Block.Info.a(Material.STONE, MaterialMapColor.B).b(2.0F).d()))); - a("green_shulker_box", (Block) (new BlockShulkerBox(EnumColor.GREEN, Block.Info.a(Material.STONE, MaterialMapColor.C).b(2.0F).d()))); - a("red_shulker_box", (Block) (new BlockShulkerBox(EnumColor.RED, Block.Info.a(Material.STONE, MaterialMapColor.D).b(2.0F).d()))); - a("black_shulker_box", (Block) (new BlockShulkerBox(EnumColor.BLACK, Block.Info.a(Material.STONE, MaterialMapColor.E).b(2.0F).d()))); - a("white_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.WHITE).b(1.4F)))); - a("orange_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.ORANGE).b(1.4F)))); - a("magenta_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.MAGENTA).b(1.4F)))); - a("light_blue_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.LIGHT_BLUE).b(1.4F)))); - a("yellow_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.YELLOW).b(1.4F)))); - a("lime_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.LIME).b(1.4F)))); - a("pink_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.PINK).b(1.4F)))); - a("gray_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.GRAY).b(1.4F)))); - a("light_gray_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.LIGHT_GRAY).b(1.4F)))); - a("cyan_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.CYAN).b(1.4F)))); - a("purple_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.PURPLE).b(1.4F)))); - a("blue_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.BLUE).b(1.4F)))); - a("brown_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.BROWN).b(1.4F)))); - a("green_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.GREEN).b(1.4F)))); - a("red_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.RED).b(1.4F)))); - a("black_glazed_terracotta", (Block) (new BlockGlazedTerracotta(Block.Info.a(Material.STONE, EnumColor.BLACK).b(1.4F)))); - Block block20 = new Block(Block.Info.a(Material.STONE, EnumColor.WHITE).b(1.8F)); - Block block21 = new Block(Block.Info.a(Material.STONE, EnumColor.ORANGE).b(1.8F)); - Block block22 = new Block(Block.Info.a(Material.STONE, EnumColor.MAGENTA).b(1.8F)); - Block block23 = new Block(Block.Info.a(Material.STONE, EnumColor.LIGHT_BLUE).b(1.8F)); - Block block24 = new Block(Block.Info.a(Material.STONE, EnumColor.YELLOW).b(1.8F)); - Block block25 = new Block(Block.Info.a(Material.STONE, EnumColor.LIME).b(1.8F)); - Block block26 = new Block(Block.Info.a(Material.STONE, EnumColor.PINK).b(1.8F)); - Block block27 = new Block(Block.Info.a(Material.STONE, EnumColor.GRAY).b(1.8F)); - Block block28 = new Block(Block.Info.a(Material.STONE, EnumColor.LIGHT_GRAY).b(1.8F)); - Block block29 = new Block(Block.Info.a(Material.STONE, EnumColor.CYAN).b(1.8F)); - Block block30 = new Block(Block.Info.a(Material.STONE, EnumColor.PURPLE).b(1.8F)); - Block block31 = new Block(Block.Info.a(Material.STONE, EnumColor.BLUE).b(1.8F)); - Block block32 = new Block(Block.Info.a(Material.STONE, EnumColor.BROWN).b(1.8F)); - Block block33 = new Block(Block.Info.a(Material.STONE, EnumColor.GREEN).b(1.8F)); - Block block34 = new Block(Block.Info.a(Material.STONE, EnumColor.RED).b(1.8F)); - Block block35 = new Block(Block.Info.a(Material.STONE, EnumColor.BLACK).b(1.8F)); - - a("white_concrete", block20); - a("orange_concrete", block21); - a("magenta_concrete", block22); - a("light_blue_concrete", block23); - a("yellow_concrete", block24); - a("lime_concrete", block25); - a("pink_concrete", block26); - a("gray_concrete", block27); - a("light_gray_concrete", block28); - a("cyan_concrete", block29); - a("purple_concrete", block30); - a("blue_concrete", block31); - a("brown_concrete", block32); - a("green_concrete", block33); - a("red_concrete", block34); - a("black_concrete", block35); - a("white_concrete_powder", (Block) (new BlockConcretePowder(block20, Block.Info.a(Material.SAND, EnumColor.WHITE).b(0.5F).a(SoundEffectType.h)))); - a("orange_concrete_powder", (Block) (new BlockConcretePowder(block21, Block.Info.a(Material.SAND, EnumColor.ORANGE).b(0.5F).a(SoundEffectType.h)))); - a("magenta_concrete_powder", (Block) (new BlockConcretePowder(block22, Block.Info.a(Material.SAND, EnumColor.MAGENTA).b(0.5F).a(SoundEffectType.h)))); - a("light_blue_concrete_powder", (Block) (new BlockConcretePowder(block23, Block.Info.a(Material.SAND, EnumColor.LIGHT_BLUE).b(0.5F).a(SoundEffectType.h)))); - a("yellow_concrete_powder", (Block) (new BlockConcretePowder(block24, Block.Info.a(Material.SAND, EnumColor.YELLOW).b(0.5F).a(SoundEffectType.h)))); - a("lime_concrete_powder", (Block) (new BlockConcretePowder(block25, Block.Info.a(Material.SAND, EnumColor.LIME).b(0.5F).a(SoundEffectType.h)))); - a("pink_concrete_powder", (Block) (new BlockConcretePowder(block26, Block.Info.a(Material.SAND, EnumColor.PINK).b(0.5F).a(SoundEffectType.h)))); - a("gray_concrete_powder", (Block) (new BlockConcretePowder(block27, Block.Info.a(Material.SAND, EnumColor.GRAY).b(0.5F).a(SoundEffectType.h)))); - a("light_gray_concrete_powder", (Block) (new BlockConcretePowder(block28, Block.Info.a(Material.SAND, EnumColor.LIGHT_GRAY).b(0.5F).a(SoundEffectType.h)))); - a("cyan_concrete_powder", (Block) (new BlockConcretePowder(block29, Block.Info.a(Material.SAND, EnumColor.CYAN).b(0.5F).a(SoundEffectType.h)))); - a("purple_concrete_powder", (Block) (new BlockConcretePowder(block30, Block.Info.a(Material.SAND, EnumColor.PURPLE).b(0.5F).a(SoundEffectType.h)))); - a("blue_concrete_powder", (Block) (new BlockConcretePowder(block31, Block.Info.a(Material.SAND, EnumColor.BLUE).b(0.5F).a(SoundEffectType.h)))); - a("brown_concrete_powder", (Block) (new BlockConcretePowder(block32, Block.Info.a(Material.SAND, EnumColor.BROWN).b(0.5F).a(SoundEffectType.h)))); - a("green_concrete_powder", (Block) (new BlockConcretePowder(block33, Block.Info.a(Material.SAND, EnumColor.GREEN).b(0.5F).a(SoundEffectType.h)))); - a("red_concrete_powder", (Block) (new BlockConcretePowder(block34, Block.Info.a(Material.SAND, EnumColor.RED).b(0.5F).a(SoundEffectType.h)))); - a("black_concrete_powder", (Block) (new BlockConcretePowder(block35, Block.Info.a(Material.SAND, EnumColor.BLACK).b(0.5F).a(SoundEffectType.h)))); - BlockKelp blockkelp = new BlockKelp(Block.Info.a(Material.WATER_PLANT).a().c().b().a(SoundEffectType.m)); - - a("kelp", (Block) blockkelp); - a("kelp_plant", (Block) (new BlockKelpPlant(blockkelp, Block.Info.a(Material.WATER_PLANT).a().b().a(SoundEffectType.m)))); - a("dried_kelp_block", new Block(Block.Info.a(Material.GRASS, MaterialMapColor.B).a(0.5F, 2.5F).a(SoundEffectType.c))); - a("turtle_egg", (Block) (new BlockTurtleEgg(Block.Info.a(Material.DRAGON_EGG, MaterialMapColor.x).b(0.5F).a(SoundEffectType.e).c()))); - Block block36 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.w).a(1.5F, 6.0F)); - Block block37 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.w).a(1.5F, 6.0F)); - Block block38 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.w).a(1.5F, 6.0F)); - Block block39 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.w).a(1.5F, 6.0F)); - Block block40 = new Block(Block.Info.a(Material.STONE, MaterialMapColor.w).a(1.5F, 6.0F)); - - a("dead_tube_coral_block", block36); - a("dead_brain_coral_block", block37); - a("dead_bubble_coral_block", block38); - a("dead_fire_coral_block", block39); - a("dead_horn_coral_block", block40); - a("tube_coral_block", (Block) (new BlockCoral(block36, Block.Info.a(Material.STONE, MaterialMapColor.A).a(1.5F, 6.0F).a(SoundEffectType.n)))); - a("brain_coral_block", (Block) (new BlockCoral(block37, Block.Info.a(Material.STONE, MaterialMapColor.v).a(1.5F, 6.0F).a(SoundEffectType.n)))); - a("bubble_coral_block", (Block) (new BlockCoral(block38, Block.Info.a(Material.STONE, MaterialMapColor.z).a(1.5F, 6.0F).a(SoundEffectType.n)))); - a("fire_coral_block", (Block) (new BlockCoral(block39, Block.Info.a(Material.STONE, MaterialMapColor.D).a(1.5F, 6.0F).a(SoundEffectType.n)))); - a("horn_coral_block", (Block) (new BlockCoral(block40, Block.Info.a(Material.STONE, MaterialMapColor.t).a(1.5F, 6.0F).a(SoundEffectType.n)))); - BlockCoralDead blockcoraldead = new BlockCoralDead(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralDead blockcoraldead1 = new BlockCoralDead(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralDead blockcoraldead2 = new BlockCoralDead(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralDead blockcoraldead3 = new BlockCoralDead(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralDead blockcoraldead4 = new BlockCoralDead(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - - a("dead_tube_coral", (Block) blockcoraldead); - a("dead_brain_coral", (Block) blockcoraldead1); - a("dead_bubble_coral", (Block) blockcoraldead2); - a("dead_fire_coral", (Block) blockcoraldead3); - a("dead_horn_coral", (Block) blockcoraldead4); - a("tube_coral", (Block) (new BlockCoralPlant(blockcoraldead, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.A).a().b().a(SoundEffectType.m)))); - a("brain_coral", (Block) (new BlockCoralPlant(blockcoraldead1, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.v).a().b().a(SoundEffectType.m)))); - a("bubble_coral", (Block) (new BlockCoralPlant(blockcoraldead2, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.z).a().b().a(SoundEffectType.m)))); - a("fire_coral", (Block) (new BlockCoralPlant(blockcoraldead3, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.D).a().b().a(SoundEffectType.m)))); - a("horn_coral", (Block) (new BlockCoralPlant(blockcoraldead4, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.t).a().b().a(SoundEffectType.m)))); - BlockCoralFanWallAbstract blockcoralfanwallabstract = new BlockCoralFanWallAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralFanWallAbstract blockcoralfanwallabstract1 = new BlockCoralFanWallAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralFanWallAbstract blockcoralfanwallabstract2 = new BlockCoralFanWallAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralFanWallAbstract blockcoralfanwallabstract3 = new BlockCoralFanWallAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralFanWallAbstract blockcoralfanwallabstract4 = new BlockCoralFanWallAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - - a("dead_tube_coral_wall_fan", (Block) blockcoralfanwallabstract); - a("dead_brain_coral_wall_fan", (Block) blockcoralfanwallabstract1); - a("dead_bubble_coral_wall_fan", (Block) blockcoralfanwallabstract2); - a("dead_fire_coral_wall_fan", (Block) blockcoralfanwallabstract3); - a("dead_horn_coral_wall_fan", (Block) blockcoralfanwallabstract4); - a("tube_coral_wall_fan", (Block) (new BlockCoralFanWall(blockcoralfanwallabstract, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.A).a().b().a(SoundEffectType.m)))); - a("brain_coral_wall_fan", (Block) (new BlockCoralFanWall(blockcoralfanwallabstract1, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.v).a().b().a(SoundEffectType.m)))); - a("bubble_coral_wall_fan", (Block) (new BlockCoralFanWall(blockcoralfanwallabstract2, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.z).a().b().a(SoundEffectType.m)))); - a("fire_coral_wall_fan", (Block) (new BlockCoralFanWall(blockcoralfanwallabstract3, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.D).a().b().a(SoundEffectType.m)))); - a("horn_coral_wall_fan", (Block) (new BlockCoralFanWall(blockcoralfanwallabstract4, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.t).a().b().a(SoundEffectType.m)))); - BlockCoralFanAbstract blockcoralfanabstract = new BlockCoralFanAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralFanAbstract blockcoralfanabstract1 = new BlockCoralFanAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralFanAbstract blockcoralfanabstract2 = new BlockCoralFanAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralFanAbstract blockcoralfanabstract3 = new BlockCoralFanAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - BlockCoralFanAbstract blockcoralfanabstract4 = new BlockCoralFanAbstract(Block.Info.a(Material.STONE, MaterialMapColor.w).a().b()); - - a("dead_tube_coral_fan", (Block) blockcoralfanabstract); - a("dead_brain_coral_fan", (Block) blockcoralfanabstract1); - a("dead_bubble_coral_fan", (Block) blockcoralfanabstract2); - a("dead_fire_coral_fan", (Block) blockcoralfanabstract3); - a("dead_horn_coral_fan", (Block) blockcoralfanabstract4); - a("tube_coral_fan", (Block) (new BlockCoralFan(blockcoralfanabstract, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.A).a().b().a(SoundEffectType.m)))); - a("brain_coral_fan", (Block) (new BlockCoralFan(blockcoralfanabstract1, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.v).a().b().a(SoundEffectType.m)))); - a("bubble_coral_fan", (Block) (new BlockCoralFan(blockcoralfanabstract2, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.z).a().b().a(SoundEffectType.m)))); - a("fire_coral_fan", (Block) (new BlockCoralFan(blockcoralfanabstract3, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.D).a().b().a(SoundEffectType.m)))); - a("horn_coral_fan", (Block) (new BlockCoralFan(blockcoralfanabstract4, Block.Info.a(Material.WATER_PLANT, MaterialMapColor.t).a().b().a(SoundEffectType.m)))); - a("sea_pickle", (Block) (new BlockSeaPickle(Block.Info.a(Material.WATER_PLANT, MaterialMapColor.C).a(3).a(SoundEffectType.l)))); - a("blue_ice", (Block) (new BlockBlueIce(Block.Info.a(Material.SNOW_LAYER).b(2.8F).a(0.989F).a(SoundEffectType.f)))); - a("conduit", (Block) (new BlockConduit(Block.Info.a(Material.SHATTERABLE, MaterialMapColor.G).b(3.0F).a(15)))); - a("void_air", (Block) (new BlockAir(Block.Info.a(Material.AIR).a()))); - a("cave_air", (Block) (new BlockAir(Block.Info.a(Material.AIR).a()))); - a("bubble_column", (Block) (new BlockBubbleColumn(Block.Info.a(Material.BUBBLE_COLUMN).a()))); - a("structure_block", (Block) (new BlockStructure(Block.Info.a(Material.ORE, MaterialMapColor.x).a(-1.0F, 3600000.0F)))); - Iterator iterator = IRegistry.BLOCK.iterator(); - - while (iterator.hasNext()) { - Block block41 = (Block) iterator.next(); - UnmodifiableIterator unmodifiableiterator = block41.getStates().a().iterator(); - - while (unmodifiableiterator.hasNext()) { - IBlockData iblockdata = (IBlockData) unmodifiableiterator.next(); - - Block.REGISTRY_ID.b(iblockdata); - } - } - - } - // CraftBukkit start - public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, int enchantmentLevel) { + public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { return 0; } // CraftBukkit end - private static void a(MinecraftKey minecraftkey, Block block) { - IRegistry.BLOCK.a(minecraftkey, block); // CraftBukkit - decompile error - } - - private static void a(String s, Block block) { - a(new MinecraftKey(s), block); - } - // Spigot start public static float range(float min, float value, float max) { if (value < min) { @@ -1481,7 +742,8 @@ public class Block implements IMaterial { private float g; private boolean h; private float i; - private boolean j; + private MinecraftKey j; + private boolean k; private Info(Material material, MaterialMapColor materialmapcolor) { this.d = SoundEffectType.d; @@ -1503,19 +765,18 @@ public class Block implements IMaterial { } public static Block.Info a(Block block) { - Block.Info block_info = new Block.Info(block.material, block.l); + Block.Info block_info = new Block.Info(block.material, block.t); block_info.a = block.material; block_info.g = block.strength; block_info.f = block.durability; - block_info.c = block.n; - block_info.h = block.i; - block_info.e = block.f; - block_info.a = block.material; - block_info.b = block.l; + block_info.c = block.v; + block_info.h = block.q; + block_info.e = block.n; + block_info.b = block.t; block_info.d = block.stepSound; - block_info.i = block.n(); - block_info.j = block.o; + block_info.i = block.m(); + block_info.k = block.g; return block_info; } @@ -1560,7 +821,17 @@ public class Block implements IMaterial { } protected Block.Info d() { - this.j = true; + this.k = true; + return this; + } + + protected Block.Info e() { + this.j = LootTables.a; + return this; + } + + public Block.Info b(Block block) { + this.j = block.i(); return this; } } @@ -1590,7 +861,11 @@ public class Block implements IMaterial { } public int hashCode() { - return Objects.hash(new Object[] { this.a, this.b, this.c}); + int i = this.a.hashCode(); + + i = 31 * i + this.b.hashCode(); + i = 31 * i + this.c.hashCode(); + return i; } } } diff --git a/src/main/java/net/minecraft/server/BlockAccessAir.java b/src/main/java/net/minecraft/server/BlockAccessAir.java new file mode 100644 index 000000000..d7a68a1ef --- /dev/null +++ b/src/main/java/net/minecraft/server/BlockAccessAir.java @@ -0,0 +1,38 @@ +package net.minecraft.server; + +import javax.annotation.Nullable; + +public enum BlockAccessAir implements IBlockAccess { + + INSTANCE; + + private BlockAccessAir() {} + + @Nullable + @Override + public TileEntity getTileEntity(BlockPosition blockposition) { + return null; + } + + // Paper start - If loaded util + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + return this.getFluid(blockposition); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + return this.getType(blockposition); + } + // Paper end + + @Override + public IBlockData getType(BlockPosition blockposition) { + return Blocks.AIR.getBlockData(); + } + + @Override + public Fluid getFluid(BlockPosition blockposition) { + return FluidTypes.EMPTY.i(); + } +} diff --git a/src/main/java/net/minecraft/server/BlockBamboo.java b/src/main/java/net/minecraft/server/BlockBamboo.java new file mode 100644 index 000000000..3a9c3b54a --- /dev/null +++ b/src/main/java/net/minecraft/server/BlockBamboo.java @@ -0,0 +1,219 @@ +package net.minecraft.server; + +import java.util.Random; +import javax.annotation.Nullable; + +public class BlockBamboo extends Block implements IBlockFragilePlantElement { + + protected static final VoxelShape a = Block.a(5.0D, 0.0D, 5.0D, 11.0D, 16.0D, 11.0D); + protected static final VoxelShape b = Block.a(3.0D, 0.0D, 3.0D, 13.0D, 16.0D, 13.0D); + protected static final VoxelShape c = Block.a(6.5D, 0.0D, 6.5D, 9.5D, 16.0D, 9.5D); + public static final BlockStateInteger d = BlockProperties.Y; + public static final BlockStateEnum e = BlockProperties.aF; + public static final BlockStateInteger f = BlockProperties.at; + + public BlockBamboo(Block.Info block_info) { + super(block_info); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockBamboo.d, 0)).set(BlockBamboo.e, BlockPropertyBambooSize.NONE)).set(BlockBamboo.f, 0)); + } + + @Override + protected void a(BlockStateList.a blockstatelist_a) { + blockstatelist_a.a(BlockBamboo.d, BlockBamboo.e, BlockBamboo.f); + } + + @Override + public Block.EnumRandomOffset R_() { + return Block.EnumRandomOffset.XZ; + } + + @Override + public boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return true; + } + + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + VoxelShape voxelshape = iblockdata.get(BlockBamboo.e) == BlockPropertyBambooSize.LARGE ? BlockBamboo.b : BlockBamboo.a; + Vec3D vec3d = iblockdata.l(iblockaccess, blockposition); + + return voxelshape.a(vec3d.x, vec3d.y, vec3d.z); + } + + @Override + public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { + return false; + } + + @Override + public VoxelShape b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + Vec3D vec3d = iblockdata.l(iblockaccess, blockposition); + + return BlockBamboo.c.a(vec3d.x, vec3d.y, vec3d.z); + } + + @Nullable + @Override + public IBlockData getPlacedState(BlockActionContext blockactioncontext) { + Fluid fluid = blockactioncontext.getWorld().getFluid(blockactioncontext.getClickPosition()); + + if (!fluid.isEmpty()) { + return null; + } else { + IBlockData iblockdata = blockactioncontext.getWorld().getType(blockactioncontext.getClickPosition().down()); + + if (iblockdata.a(TagsBlock.BAMBOO_PLANTABLE_ON)) { + Block block = iblockdata.getBlock(); + + if (block == Blocks.BAMBOO_SAPLING) { + return (IBlockData) this.getBlockData().set(BlockBamboo.d, 0); + } else if (block == Blocks.BAMBOO) { + int i = (Integer) iblockdata.get(BlockBamboo.d) > 0 ? 1 : 0; + + return (IBlockData) this.getBlockData().set(BlockBamboo.d, i); + } else { + return Blocks.BAMBOO_SAPLING.getBlockData(); + } + } else { + return null; + } + } + } + + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + if (!iblockdata.canPlace(world, blockposition)) { + world.b(blockposition, true); + } else if ((Integer) iblockdata.get(BlockBamboo.f) == 0) { + if (world.paperConfig.fixZeroTickInstantGrowFarms && !randomTick) return; // Paper - fix MC-113809 + if (world.random.nextInt(Math.max(1, (int) (100.0F / world.spigotConfig.bambooModifier) * 3)) == 0 && world.isEmpty(blockposition.up()) && world.getLightLevel(blockposition.up(), 0) >= 9) { // Spigot + int i = this.b((IBlockAccess) world, blockposition) + 1; + + if (i < 16) { + this.a(iblockdata, world, blockposition, random, i); + } + } + + } + } + + @Override + public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { + return iworldreader.getType(blockposition.down()).a(TagsBlock.BAMBOO_PLANTABLE_ON); + } + + @Override + public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { + if (!iblockdata.canPlace(generatoraccess, blockposition)) { + generatoraccess.getBlockTickList().a(blockposition, this, 1); + } + + if (enumdirection == EnumDirection.UP && iblockdata1.getBlock() == Blocks.BAMBOO && (Integer) iblockdata1.get(BlockBamboo.d) > (Integer) iblockdata.get(BlockBamboo.d)) { + generatoraccess.setTypeAndData(blockposition, (IBlockData) iblockdata.a((IBlockState) BlockBamboo.d), 2); + } + + return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); + } + + @Override + public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + int i = this.a(iblockaccess, blockposition); + int j = this.b(iblockaccess, blockposition); + + return i + j + 1 < 16 && (Integer) iblockaccess.getType(blockposition.up(i)).get(BlockBamboo.f) != 1; + } + + @Override + public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + return true; + } + + @Override + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + int i = this.a((IBlockAccess) world, blockposition); + int j = this.b((IBlockAccess) world, blockposition); + int k = i + j + 1; + int l = 1 + random.nextInt(2); + + for (int i1 = 0; i1 < l; ++i1) { + BlockPosition blockposition1 = blockposition.up(i); + IBlockData iblockdata1 = world.getType(blockposition1); + + if (k >= 16 || (Integer) iblockdata1.get(BlockBamboo.f) == 1 || !world.isEmpty(blockposition1.up())) { + return; + } + + this.a(iblockdata1, world, blockposition1, random, k); + ++i; + ++k; + } + + } + + @Override + public float getDamage(IBlockData iblockdata, EntityHuman entityhuman, IBlockAccess iblockaccess, BlockPosition blockposition) { + return entityhuman.getItemInMainHand().getItem() instanceof ItemSword ? 1.0F : super.getDamage(iblockdata, entityhuman, iblockaccess, blockposition); + } + + @Override + public TextureType c() { + return TextureType.CUTOUT; + } + + protected void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random, int i) { + IBlockData iblockdata1 = world.getType(blockposition.down()); + BlockPosition blockposition1 = blockposition.down(2); + IBlockData iblockdata2 = world.getType(blockposition1); + BlockPropertyBambooSize blockpropertybamboosize = BlockPropertyBambooSize.NONE; + boolean shouldUpdateOthers = false; // CraftBukkit + + if (i >= 1) { + if (iblockdata1.getBlock() == Blocks.BAMBOO && iblockdata1.get(BlockBamboo.e) != BlockPropertyBambooSize.NONE) { + if (iblockdata1.getBlock() == Blocks.BAMBOO && iblockdata1.get(BlockBamboo.e) != BlockPropertyBambooSize.NONE) { + blockpropertybamboosize = BlockPropertyBambooSize.LARGE; + if (iblockdata2.getBlock() == Blocks.BAMBOO) { + // CraftBukkit start - moved down + // world.setTypeAndData(blockposition.down(), (IBlockData) iblockdata1.set(BlockBamboo.e, BlockPropertyBambooSize.SMALL), 3); + // world.setTypeAndData(blockposition1, (IBlockData) iblockdata2.set(BlockBamboo.e, BlockPropertyBambooSize.NONE), 3); + shouldUpdateOthers = true; + // CraftBukkit end + } + } + } else { + blockpropertybamboosize = BlockPropertyBambooSize.SMALL; + } + } + + int j = (Integer) iblockdata.get(BlockBamboo.d) != 1 && iblockdata2.getBlock() != Blocks.BAMBOO ? 0 : 1; + int k = (i < 11 || random.nextFloat() >= 0.25F) && i != 15 ? 0 : 1; + + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition.up(), (IBlockData) ((IBlockData) ((IBlockData) this.getBlockData().set(BlockBamboo.d, j)).set(BlockBamboo.e, blockpropertybamboosize)).set(BlockBamboo.f, k), 3)) { + if (shouldUpdateOthers) { + world.setTypeAndData(blockposition.down(), (IBlockData) iblockdata1.set(BlockBamboo.e, BlockPropertyBambooSize.SMALL), 3); + world.setTypeAndData(blockposition1, (IBlockData) iblockdata2.set(BlockBamboo.e, BlockPropertyBambooSize.NONE), 3); + } + } + // CraftBukkit end + } + + protected int a(IBlockAccess iblockaccess, BlockPosition blockposition) { + int i; + + for (i = 0; i < 16 && iblockaccess.getType(blockposition.up(i + 1)).getBlock() == Blocks.BAMBOO; ++i) { + ; + } + + return i; + } + + protected int b(IBlockAccess iblockaccess, BlockPosition blockposition) { + int i; + + for (i = 0; i < 16 && iblockaccess.getType(blockposition.down(i + 1)).getBlock() == Blocks.BAMBOO; ++i) { + ; + } + + return i; + } +} diff --git a/src/main/java/net/minecraft/server/BlockBambooSapling.java b/src/main/java/net/minecraft/server/BlockBambooSapling.java new file mode 100644 index 000000000..473578d61 --- /dev/null +++ b/src/main/java/net/minecraft/server/BlockBambooSapling.java @@ -0,0 +1,79 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockBambooSapling extends Block implements IBlockFragilePlantElement { + + protected static final VoxelShape a = Block.a(4.0D, 0.0D, 4.0D, 12.0D, 12.0D, 12.0D); + + public BlockBambooSapling(Block.Info block_info) { + super(block_info); + } + + @Override + public Block.EnumRandomOffset R_() { + return Block.EnumRandomOffset.XZ; + } + + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + Vec3D vec3d = iblockdata.l(iblockaccess, blockposition); + + return BlockBambooSapling.a.a(vec3d.x, vec3d.y, vec3d.z); + } + + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + if (random.nextInt(3) == 0 && world.isEmpty(blockposition.up()) && world.getLightLevel(blockposition.up(), 0) >= 9) { + this.a(world, blockposition); + } + + } + + @Override + public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { + return iworldreader.getType(blockposition.down()).a(TagsBlock.BAMBOO_PLANTABLE_ON); + } + + @Override + public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { + if (!iblockdata.canPlace(generatoraccess, blockposition)) { + return Blocks.AIR.getBlockData(); + } else { + if (enumdirection == EnumDirection.UP && iblockdata1.getBlock() == Blocks.BAMBOO) { + generatoraccess.setTypeAndData(blockposition, Blocks.BAMBOO.getBlockData(), 2); + } + + return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); + } + } + + @Override + public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + return iblockaccess.getType(blockposition.up()).isAir(); + } + + @Override + public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + return true; + } + + @Override + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + this.a(world, blockposition); + } + + @Override + public float getDamage(IBlockData iblockdata, EntityHuman entityhuman, IBlockAccess iblockaccess, BlockPosition blockposition) { + return entityhuman.getItemInMainHand().getItem() instanceof ItemSword ? 1.0F : super.getDamage(iblockdata, entityhuman, iblockaccess, blockposition); + } + + @Override + public TextureType c() { + return TextureType.CUTOUT; + } + + protected void a(World world, BlockPosition blockposition) { + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition.up(), (IBlockData) Blocks.BAMBOO.getBlockData().set(BlockBamboo.e, BlockPropertyBambooSize.SMALL), 3); // CraftBukkit - BlockSpreadEvent + } +} diff --git a/src/main/java/net/minecraft/server/BlockBeacon.java b/src/main/java/net/minecraft/server/BlockBeacon.java deleted file mode 100644 index 4313b7abc..000000000 --- a/src/main/java/net/minecraft/server/BlockBeacon.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.minecraft.server; - -public class BlockBeacon extends BlockTileEntity { - - public BlockBeacon(Block.Info block_info) { - super(block_info); - } - - public TileEntity a(IBlockAccess iblockaccess) { - return new TileEntityBeacon(); - } - - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { - if (world.isClientSide) { - return true; - } else { - TileEntity tileentity = world.getTileEntity(blockposition); - - if (tileentity instanceof TileEntityBeacon) { - entityhuman.openContainer((TileEntityBeacon) tileentity); - entityhuman.a(StatisticList.INTERACT_WITH_BEACON); - } - - return true; - } - } - - public boolean a(IBlockData iblockdata) { - return false; - } - - public EnumRenderType c(IBlockData iblockdata) { - return EnumRenderType.MODEL; - } - - public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { - if (itemstack.hasName()) { - TileEntity tileentity = world.getTileEntity(blockposition); - - if (tileentity instanceof TileEntityBeacon) { - ((TileEntityBeacon) tileentity).setCustomName(itemstack.getName()); - } - } - - } - - public TextureType c() { - return TextureType.CUTOUT; - } - - public static void a(World world, BlockPosition blockposition) { - // HttpUtilities.a.submit(() -> { // CraftBukkit - dangerously threaded - Chunk chunk = world.getChunkAtWorldCoords(blockposition); - - for (int i = blockposition.getY() - 1; i >= 0; --i) { - BlockPosition blockposition1 = new BlockPosition(blockposition.getX(), i, blockposition.getZ()); - - if (!chunk.c(blockposition1)) { - break; - } - - IBlockData iblockdata = world.getType(blockposition1); - - if (iblockdata.getBlock() == Blocks.BEACON) { - //((WorldServer) world).postToMainThread(() -> { // Akarin - TileEntity tileentity = world.getTileEntity(blockposition1); - - if (tileentity instanceof TileEntityBeacon) { - ((TileEntityBeacon) tileentity).p(); - world.playBlockAction(blockposition1, Blocks.BEACON, 1, 0); - } - - //}); // Akarin - } - } - - // }); // CraftBukkit - } -} diff --git a/src/main/java/net/minecraft/server/BlockBed.java b/src/main/java/net/minecraft/server/BlockBed.java index d81a2db6c..b2525e2a2 100644 --- a/src/main/java/net/minecraft/server/BlockBed.java +++ b/src/main/java/net/minecraft/server/BlockBed.java @@ -1,26 +1,36 @@ package net.minecraft.server; -import java.util.Iterator; +import java.util.Optional; import javax.annotation.Nullable; public class BlockBed extends BlockFacingHorizontal implements ITileEntity { - public static final BlockStateEnum PART = BlockProperties.ao; - public static final BlockStateBoolean OCCUPIED = BlockProperties.q; - protected static final VoxelShape c = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D); + public static final BlockStateEnum PART = BlockProperties.aw; + public static final BlockStateBoolean OCCUPIED = BlockProperties.t; + protected static final VoxelShape c = Block.a(0.0D, 3.0D, 0.0D, 16.0D, 9.0D, 16.0D); + protected static final VoxelShape d = Block.a(0.0D, 0.0D, 0.0D, 3.0D, 3.0D, 3.0D); + protected static final VoxelShape e = Block.a(0.0D, 0.0D, 13.0D, 3.0D, 3.0D, 16.0D); + protected static final VoxelShape f = Block.a(13.0D, 0.0D, 0.0D, 16.0D, 3.0D, 3.0D); + protected static final VoxelShape g = Block.a(13.0D, 0.0D, 13.0D, 16.0D, 3.0D, 16.0D); + protected static final VoxelShape h = VoxelShapes.a(BlockBed.c, BlockBed.d, BlockBed.f); + protected static final VoxelShape i = VoxelShapes.a(BlockBed.c, BlockBed.e, BlockBed.g); + protected static final VoxelShape j = VoxelShapes.a(BlockBed.c, BlockBed.d, BlockBed.e); + protected static final VoxelShape k = VoxelShapes.a(BlockBed.c, BlockBed.f, BlockBed.g); private final EnumColor color; public BlockBed(EnumColor enumcolor, Block.Info block_info) { super(block_info); this.color = enumcolor; - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockBed.PART, BlockPropertyBedPart.FOOT)).set(BlockBed.OCCUPIED, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockBed.PART, BlockPropertyBedPart.FOOT)).set(BlockBed.OCCUPIED, false)); } - public MaterialMapColor c(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public MaterialMapColor e(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return iblockdata.get(BlockBed.PART) == BlockPropertyBedPart.FOOT ? this.color.e() : MaterialMapColor.e; } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if (world.isClientSide) { return true; } else { @@ -35,37 +45,24 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { // CraftBukkit - moved world and biome check into EntityHuman if (true || world.worldProvider.canRespawn() && world.getBiome(blockposition) != Biomes.NETHER) { if ((Boolean) iblockdata.get(BlockBed.OCCUPIED)) { - EntityHuman entityhuman1 = this.a(world, blockposition); - - if (entityhuman1 != null) { - entityhuman.a((IChatBaseComponent) (new ChatMessage("block.minecraft.bed.occupied", new Object[0])), true); - return true; - } - - iblockdata = (IBlockData) iblockdata.set(BlockBed.OCCUPIED, false); - world.setTypeAndData(blockposition, iblockdata, 4); - } - - EntityHuman.EnumBedResult entityhuman_enumbedresult = entityhuman.a(blockposition); - - if (entityhuman_enumbedresult == EntityHuman.EnumBedResult.OK) { - iblockdata = (IBlockData) iblockdata.set(BlockBed.OCCUPIED, true); - world.setTypeAndData(blockposition, iblockdata, 4); + entityhuman.a((IChatBaseComponent) (new ChatMessage("block.minecraft.bed.occupied", new Object[0])), true); return true; } else { - if (entityhuman_enumbedresult == EntityHuman.EnumBedResult.NOT_POSSIBLE_NOW) { - entityhuman.a((IChatBaseComponent) (new ChatMessage("block.minecraft.bed.no_sleep", new Object[0])), true); - } else if (entityhuman_enumbedresult == EntityHuman.EnumBedResult.NOT_SAFE) { - entityhuman.a((IChatBaseComponent) (new ChatMessage("block.minecraft.bed.not_safe", new Object[0])), true); - } else if (entityhuman_enumbedresult == EntityHuman.EnumBedResult.TOO_FAR_AWAY) { - entityhuman.a((IChatBaseComponent) (new ChatMessage("block.minecraft.bed.too_far_away", new Object[0])), true); - } - // CraftBukkit start - handling bed explosion from below here - else if (entityhuman_enumbedresult == EntityHuman.EnumBedResult.NOT_POSSIBLE_HERE) { - this.explodeBed(iblockdata, world, blockposition); - } + // CraftBukkit start + IBlockData finaliblockdata = iblockdata; + BlockPosition finalblockposition = blockposition; // CraftBukkit end + entityhuman.sleep(blockposition).ifLeft((entityhuman_enumbedresult) -> { + // CraftBukkit start - handling bed explosion from below here + if (entityhuman_enumbedresult == EntityHuman.EnumBedResult.NOT_POSSIBLE_HERE) { + this.explodeBed(finaliblockdata, world, finalblockposition); + } else + // CraftBukkit end + if (entityhuman_enumbedresult != null) { + entityhuman.a(entityhuman_enumbedresult.a(), true); + } + }); return true; } // CraftBukkit start - moved bed explosion into separate method @@ -76,55 +73,40 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { } private boolean explodeBed(IBlockData iblockdata, World world, BlockPosition blockposition) { - world.setAir(blockposition); + world.a(blockposition, false); BlockPosition blockposition1 = blockposition.shift(((EnumDirection) iblockdata.get(BlockBed.FACING)).opposite()); if (world.getType(blockposition1).getBlock() == this) { - world.setAir(blockposition1); + world.a(blockposition1, false); } - world.createExplosion((Entity) null, DamageSource.a(), (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, 5.0F, true, true); + world.createExplosion((Entity) null, DamageSource.a(), (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, 5.0F, true, Explosion.Effect.DESTROY); return true; // CraftBukkit end } - @Nullable - private EntityHuman a(World world, BlockPosition blockposition) { - Iterator iterator = world.players.iterator(); - - EntityHuman entityhuman; - - do { - if (!iterator.hasNext()) { - return null; - } - - entityhuman = (EntityHuman) iterator.next(); - } while (!entityhuman.isSleeping() || !entityhuman.bedPosition.equals(blockposition)); - - return entityhuman; - } - - public boolean a(IBlockData iblockdata) { - return false; - } - + @Override public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) { super.fallOn(world, blockposition, entity, f * 0.5F); } + @Override public void a(IBlockAccess iblockaccess, Entity entity) { if (entity.isSneaking()) { super.a(iblockaccess, entity); - } else if (entity.motY < 0.0D) { - entity.motY = -entity.motY * 0.6600000262260437D; - if (!(entity instanceof EntityLiving)) { - entity.motY *= 0.8D; + } else { + Vec3D vec3d = entity.getMot(); + + if (vec3d.y < 0.0D) { + double d0 = entity instanceof EntityLiving ? 1.0D : 0.8D; + + entity.setMot(vec3d.x, -vec3d.y * 0.6600000262260437D * d0, vec3d.z); } } } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { return enumdirection == a((BlockPropertyBedPart) iblockdata.get(BlockBed.PART), (EnumDirection) iblockdata.get(BlockBed.FACING)) ? (iblockdata1.getBlock() == this && iblockdata1.get(BlockBed.PART) != iblockdata.get(BlockBed.PART) ? (IBlockData) iblockdata.set(BlockBed.OCCUPIED, iblockdata1.get(BlockBed.OCCUPIED)) : Blocks.AIR.getBlockData()) : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } @@ -133,32 +115,25 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { return blockpropertybedpart == BlockPropertyBedPart.FOOT ? enumdirection : enumdirection.opposite(); } + @Override public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { super.a(world, entityhuman, blockposition, Blocks.AIR.getBlockData(), tileentity, itemstack); } - public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { - if (iblockdata.getBlock() != iblockdata1.getBlock()) { - super.remove(iblockdata, world, blockposition, iblockdata1, flag); - world.n(blockposition); - } - } - + @Override public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { BlockPropertyBedPart blockpropertybedpart = (BlockPropertyBedPart) iblockdata.get(BlockBed.PART); - boolean flag = blockpropertybedpart == BlockPropertyBedPart.HEAD; BlockPosition blockposition1 = blockposition.shift(a(blockpropertybedpart, (EnumDirection) iblockdata.get(BlockBed.FACING))); IBlockData iblockdata1 = world.getType(blockposition1); if (iblockdata1.getBlock() == this && iblockdata1.get(BlockBed.PART) != blockpropertybedpart) { world.setTypeAndData(blockposition1, Blocks.AIR.getBlockData(), 35); world.a(entityhuman, 2001, blockposition1, Block.getCombinedId(iblockdata1)); - if (!world.isClientSide && !entityhuman.u()) { - if (flag) { - iblockdata.a(world, blockposition, 0); - } else { - iblockdata1.a(world, blockposition1, 0); - } + if (!world.isClientSide && !entityhuman.isCreative()) { + ItemStack itemstack = entityhuman.getItemInMainHand(); + + dropItems(iblockdata, world, blockposition, (TileEntity) null, entityhuman, itemstack); + dropItems(iblockdata1, world, blockposition1, (TileEntity) null, entityhuman, itemstack); } entityhuman.b(StatisticList.BLOCK_MINED.b(this)); @@ -168,6 +143,7 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { EnumDirection enumdirection = blockactioncontext.f(); BlockPosition blockposition = blockactioncontext.getClickPosition(); @@ -176,63 +152,29 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { return blockactioncontext.getWorld().getType(blockposition1).a(blockactioncontext) ? (IBlockData) this.getBlockData().set(BlockBed.FACING, enumdirection) : null; } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return (IMaterial) (iblockdata.get(BlockBed.PART) == BlockPropertyBedPart.FOOT ? Items.AIR : super.getDropType(iblockdata, world, blockposition, i)); - } + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockBed.FACING); + EnumDirection enumdirection1 = iblockdata.get(BlockBed.PART) == BlockPropertyBedPart.HEAD ? enumdirection : enumdirection.opposite(); - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return BlockBed.c; - } - - @Nullable - public static BlockPosition a(IBlockAccess iblockaccess, BlockPosition blockposition, int i) { - EnumDirection enumdirection = (EnumDirection) iblockaccess.getType(blockposition).get(BlockBed.FACING); - // Paper - replace whole method - World world = (World) iblockaccess; - int radius = world.paperConfig.bedSearchRadius; - for (int r = 1; r <= radius; r++) { - int x = -r; - int z = r; - - // Iterates the edge of half of the box; then negates for other half. - while (x <= r && z > -r) { - for (int y = -1; y <= 1; y++) { - BlockPosition pos = blockposition.add(x, y, z); - if (isSafeRespawn(world, pos)) { - if (i-- <= 0) { - return pos; - } - } - pos = blockposition.add(-x, y, -z); - if (isSafeRespawn(world, pos)) { - if (i-- <= 0) { - return pos; - } - } - - pos = blockposition.add(enumdirection.getAdjacentX() + x, y, enumdirection.getAdjacentZ() + z); - if (isSafeRespawn(world, pos)) { - if (i-- <= 0) { - return pos; - } - } - - pos = blockposition.add(enumdirection.getAdjacentX() - x, y, enumdirection.getAdjacentZ() - z); - if (isSafeRespawn(world, pos)) { - if (i-- <= 0) { - return pos; - } - } - } - if (x < r) { - x++; - } else { - z--; - } - } + switch (enumdirection1) { + case NORTH: + return BlockBed.h; + case SOUTH: + return BlockBed.i; + case WEST: + return BlockBed.j; + default: + return BlockBed.k; } + } - return null; /* // Paper comment out + public static Optional a(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition, int i) { + EnumDirection enumdirection = (EnumDirection) iworldreader.getType(blockposition).get(BlockBed.FACING); + // Paper start - configurable bed search radius + return findSafePosition(entitytypes, (World) iworldreader, enumdirection, blockposition); + } + /* int j = blockposition.getX(); int k = blockposition.getY(); int l = blockposition.getZ(); @@ -246,10 +188,11 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { for (int j2 = j1; j2 <= l1; ++j2) { for (int k2 = k1; k2 <= i2; ++k2) { BlockPosition blockposition1 = new BlockPosition(j2, k, k2); + Optional optional = a(entitytypes, iworldreader, blockposition1); - if (a(iblockaccess, blockposition1)) { + if (optional.isPresent()) { if (i <= 0) { - return blockposition1; + return optional; } --i; @@ -258,40 +201,162 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { } } - return null;*/ // Paper - } - - protected static boolean isSafeRespawn(IBlockAccess iblockaccess, BlockPosition blockposition) { // Paper - OBFHELPER + behavior improvement - return a(iblockaccess, blockposition) && iblockaccess.getType(blockposition.down()).getMaterial().isBuildable(); // Paper - ensure solid block - } - protected static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) { - return iblockaccess.getType(blockposition.down()).q() && !iblockaccess.getType(blockposition).getMaterial().isBuildable() && !iblockaccess.getType(blockposition.up()).getMaterial().isBuildable(); + return Optional.empty(); + } + */ + + private static Optional findSafePosition(EntityTypes entitytypes, World world, EnumDirection updirection, BlockPosition blockposition){ + int radius = world.paperConfig.bedSearchRadius; + double angle = Math.PI / 2; + int tmpX = (int)(updirection.getAdjacentX() * Math.cos(angle) - updirection.getAdjacentZ() * Math.sin(angle)); + int tmpZ = (int)(updirection.getAdjacentX() * Math.sin(angle) + updirection.getAdjacentZ() * Math.cos(angle)); + + EnumDirection rightDirection = EnumDirection.a(tmpX, 0, tmpZ); + EnumDirection downDirection = updirection.opposite(); + EnumDirection leftDirection = rightDirection.opposite(); + + EnumDirection[] corePositionOutDirection = new EnumDirection[6]; + corePositionOutDirection[0] = updirection; + corePositionOutDirection[1] = leftDirection; + corePositionOutDirection[2] = leftDirection; + corePositionOutDirection[3] = downDirection; + corePositionOutDirection[4] = rightDirection; + corePositionOutDirection[5] = rightDirection; + + BlockPosition[] corePosition = new BlockPosition[6]; + corePosition[0] = blockposition.add(updirection.getAdjacentX(), 0, updirection.getAdjacentZ()); + corePosition[1] = blockposition.add(leftDirection.getAdjacentX(), 0, leftDirection.getAdjacentZ()); + corePosition[2] = corePosition[1].add(downDirection.getAdjacentX(), 0, downDirection.getAdjacentZ()); + corePosition[3] = blockposition.add(2 * downDirection.getAdjacentX(), 0, 2 * downDirection.getAdjacentZ()); + corePosition[5] = blockposition.add(rightDirection.getAdjacentX(), 0, rightDirection.getAdjacentZ()); + corePosition[4] = corePosition[5].add(downDirection.getAdjacentX(), 0, downDirection.getAdjacentZ()); + + BlockPosition[] tmpPosition = new BlockPosition[8]; + EnumDirection[] tmpPositionDirection = new EnumDirection[8]; + tmpPositionDirection[0] = rightDirection; + tmpPositionDirection[1] = leftDirection; + tmpPositionDirection[2] = updirection; + tmpPositionDirection[3] = downDirection; + tmpPositionDirection[4] = leftDirection; + tmpPositionDirection[5] = rightDirection; + tmpPositionDirection[6] = downDirection; + tmpPositionDirection[7] = updirection; + + BlockPosition pos; + Optional vector; + for (int r = 1; r <= radius; r++) { + int h = 0; + while (h <= 1) { + int numIterated = 0; + for (int index = (int)(Math.random() * corePosition.length); numIterated < corePosition.length; index = (index+1) % corePosition.length) { + numIterated++; + + pos = corePosition[index].add(0, h, 0); + vector = isSafeRespawn(entitytypes, world, pos); + if (vector.isPresent()) { + return vector; + } + } + tmpPosition[0] = corePosition[0].add(0, h, 0); + tmpPosition[1] = corePosition[0].add(0, h, 0); + tmpPosition[2] = corePosition[1].add(0, h, 0); + tmpPosition[3] = corePosition[2].add(0, h, 0); + tmpPosition[4] = corePosition[3].add(0, h, 0); + tmpPosition[5] = corePosition[3].add(0, h, 0); + tmpPosition[6] = corePosition[4].add(0, h, 0); + tmpPosition[7] = corePosition[5].add(0, h, 0); + for (int rr = 1; rr <= r; rr++){ + numIterated = 0; + for (int index = (int)(Math.random() * tmpPosition.length); numIterated < tmpPosition.length; index = (index+1) % tmpPosition.length) { + numIterated++; + tmpPosition[index] = tmpPosition[index].add(tmpPositionDirection[index].getAdjacentX(), 0, tmpPositionDirection[index].getAdjacentZ()); + pos = tmpPosition[index]; + + vector = isSafeRespawn(entitytypes, world, pos); + if (vector.isPresent()) { + return vector; + } + } + } + switch (h) { + case -1: + h = 1; + break; + case 0: + h = -1; + break; + case 1: + h = Integer.MAX_VALUE; + break; + } + } + for (int index = 0; index < corePosition.length; index++) { + EnumDirection tmp = corePositionOutDirection[index]; + corePosition[index] = corePosition[index].add(tmp.getAdjacentX(), 0, tmp.getAdjacentZ()); + } + } + return Optional.empty(); + } + // Paper end + + protected static Optional isSafeRespawn(EntityTypes entityTypes, IWorldReader iworldreader, BlockPosition blockPosition) { return a(entityTypes, iworldreader, blockPosition); } // Paper -- obfhelper + protected static Optional a(EntityTypes entitytypes, IWorldReader iworldreader, BlockPosition blockposition) { + VoxelShape voxelshape = iworldreader.getType(blockposition).getCollisionShape(iworldreader, blockposition); + + if (voxelshape.c(EnumDirection.EnumAxis.Y) > 0.4375D) { + return Optional.empty(); + } else { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(blockposition); + + while (blockposition_mutableblockposition.getY() >= 0 && blockposition.getY() - blockposition_mutableblockposition.getY() <= 2 && iworldreader.getType(blockposition_mutableblockposition).getCollisionShape(iworldreader, blockposition_mutableblockposition).isEmpty()) { + blockposition_mutableblockposition.c(EnumDirection.DOWN); + } + + VoxelShape voxelshape1 = iworldreader.getType(blockposition_mutableblockposition).getCollisionShape(iworldreader, blockposition_mutableblockposition); + + if (voxelshape1.isEmpty()) { + return Optional.empty(); + } else { + double d0 = (double) blockposition_mutableblockposition.getY() + voxelshape1.c(EnumDirection.EnumAxis.Y) + 2.0E-7D; + + if ((double) blockposition.getY() - d0 > 2.0D) { + return Optional.empty(); + } else { + float f = entitytypes.i() / 2.0F; + Vec3D vec3d = new Vec3D((double) blockposition_mutableblockposition.getX() + 0.5D, d0, (double) blockposition_mutableblockposition.getZ() + 0.5D); + + return iworldreader.c(new AxisAlignedBB(vec3d.x - (double) f, vec3d.y, vec3d.z - (double) f, vec3d.x + (double) f, vec3d.y + (double) entitytypes.j(), vec3d.z + (double) f)) ? Optional.of(vec3d) : Optional.empty(); + } + } + } } + @Override public EnumPistonReaction getPushReaction(IBlockData iblockdata) { return EnumPistonReaction.DESTROY; } + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override public EnumRenderType c(IBlockData iblockdata) { return EnumRenderType.ENTITYBLOCK_ANIMATED; } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockBed.FACING, BlockBed.PART, BlockBed.OCCUPIED); } - public TileEntity a(IBlockAccess iblockaccess) { + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { return new TileEntityBed(this.color); } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, @Nullable EntityLiving entityliving, ItemStack itemstack) { super.postPlace(world, blockposition, iblockdata, entityliving, itemstack); if (!world.isClientSide) { @@ -299,11 +364,12 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity { world.setTypeAndData(blockposition1, (IBlockData) iblockdata.set(BlockBed.PART, BlockPropertyBedPart.HEAD), 3); world.update(blockposition, Blocks.AIR); - iblockdata.a((GeneratorAccess) world, blockposition, 3); + iblockdata.a(world, blockposition, 3); } } + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { return false; } diff --git a/src/main/java/net/minecraft/server/BlockButtonAbstract.java b/src/main/java/net/minecraft/server/BlockButtonAbstract.java index 19559ab00..1fa20d8a7 100644 --- a/src/main/java/net/minecraft/server/BlockButtonAbstract.java +++ b/src/main/java/net/minecraft/server/BlockButtonAbstract.java @@ -11,75 +11,74 @@ import org.bukkit.event.entity.EntityInteractEvent; public abstract class BlockButtonAbstract extends BlockAttachable { - public static final BlockStateBoolean POWERED = BlockProperties.t; + public static final BlockStateBoolean POWERED = BlockProperties.w; protected static final VoxelShape b = Block.a(6.0D, 14.0D, 5.0D, 10.0D, 16.0D, 11.0D); protected static final VoxelShape c = Block.a(5.0D, 14.0D, 6.0D, 11.0D, 16.0D, 10.0D); - protected static final VoxelShape o = Block.a(6.0D, 0.0D, 5.0D, 10.0D, 2.0D, 11.0D); - protected static final VoxelShape p = Block.a(5.0D, 0.0D, 6.0D, 11.0D, 2.0D, 10.0D); - protected static final VoxelShape q = Block.a(5.0D, 6.0D, 14.0D, 11.0D, 10.0D, 16.0D); - protected static final VoxelShape r = Block.a(5.0D, 6.0D, 0.0D, 11.0D, 10.0D, 2.0D); - protected static final VoxelShape s = Block.a(14.0D, 6.0D, 5.0D, 16.0D, 10.0D, 11.0D); - protected static final VoxelShape t = Block.a(0.0D, 6.0D, 5.0D, 2.0D, 10.0D, 11.0D); - protected static final VoxelShape u = Block.a(6.0D, 15.0D, 5.0D, 10.0D, 16.0D, 11.0D); - protected static final VoxelShape v = Block.a(5.0D, 15.0D, 6.0D, 11.0D, 16.0D, 10.0D); + protected static final VoxelShape d = Block.a(6.0D, 0.0D, 5.0D, 10.0D, 2.0D, 11.0D); + protected static final VoxelShape e = Block.a(5.0D, 0.0D, 6.0D, 11.0D, 2.0D, 10.0D); + protected static final VoxelShape f = Block.a(5.0D, 6.0D, 14.0D, 11.0D, 10.0D, 16.0D); + protected static final VoxelShape g = Block.a(5.0D, 6.0D, 0.0D, 11.0D, 10.0D, 2.0D); + protected static final VoxelShape h = Block.a(14.0D, 6.0D, 5.0D, 16.0D, 10.0D, 11.0D); + protected static final VoxelShape i = Block.a(0.0D, 6.0D, 5.0D, 2.0D, 10.0D, 11.0D); + protected static final VoxelShape j = Block.a(6.0D, 15.0D, 5.0D, 10.0D, 16.0D, 11.0D); + protected static final VoxelShape k = Block.a(5.0D, 15.0D, 6.0D, 11.0D, 16.0D, 10.0D); protected static final VoxelShape w = Block.a(6.0D, 0.0D, 5.0D, 10.0D, 1.0D, 11.0D); protected static final VoxelShape x = Block.a(5.0D, 0.0D, 6.0D, 11.0D, 1.0D, 10.0D); protected static final VoxelShape y = Block.a(5.0D, 6.0D, 15.0D, 11.0D, 10.0D, 16.0D); protected static final VoxelShape z = Block.a(5.0D, 6.0D, 0.0D, 11.0D, 10.0D, 1.0D); protected static final VoxelShape A = Block.a(15.0D, 6.0D, 5.0D, 16.0D, 10.0D, 11.0D); protected static final VoxelShape B = Block.a(0.0D, 6.0D, 5.0D, 1.0D, 10.0D, 11.0D); - private final boolean E; + private final boolean D; protected BlockButtonAbstract(boolean flag, Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockButtonAbstract.FACING, EnumDirection.NORTH)).set(BlockButtonAbstract.POWERED, false)).set(BlockButtonAbstract.FACE, BlockPropertyAttachPosition.WALL)); - this.E = flag; + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockButtonAbstract.FACING, EnumDirection.NORTH)).set(BlockButtonAbstract.POWERED, false)).set(BlockButtonAbstract.FACE, BlockPropertyAttachPosition.WALL)); + this.D = flag; } + @Override public int a(IWorldReader iworldreader) { - return this.E ? 30 : 20; + return this.D ? 30 : 20; } - public boolean a(IBlockData iblockdata) { - return false; - } - - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING); boolean flag = (Boolean) iblockdata.get(BlockButtonAbstract.POWERED); switch ((BlockPropertyAttachPosition) iblockdata.get(BlockButtonAbstract.FACE)) { - case FLOOR: - if (enumdirection.k() == EnumDirection.EnumAxis.X) { - return flag ? BlockButtonAbstract.w : BlockButtonAbstract.o; - } + case FLOOR: + if (enumdirection.k() == EnumDirection.EnumAxis.X) { + return flag ? BlockButtonAbstract.w : BlockButtonAbstract.d; + } - return flag ? BlockButtonAbstract.x : BlockButtonAbstract.p; - case WALL: - switch (enumdirection) { - case EAST: - return flag ? BlockButtonAbstract.B : BlockButtonAbstract.t; - case WEST: - return flag ? BlockButtonAbstract.A : BlockButtonAbstract.s; - case SOUTH: - return flag ? BlockButtonAbstract.z : BlockButtonAbstract.r; - case NORTH: + return flag ? BlockButtonAbstract.x : BlockButtonAbstract.e; + case WALL: + switch (enumdirection) { + case EAST: + return flag ? BlockButtonAbstract.B : BlockButtonAbstract.i; + case WEST: + return flag ? BlockButtonAbstract.A : BlockButtonAbstract.h; + case SOUTH: + return flag ? BlockButtonAbstract.z : BlockButtonAbstract.g; + case NORTH: + default: + return flag ? BlockButtonAbstract.y : BlockButtonAbstract.f; + } + case CEILING: default: - return flag ? BlockButtonAbstract.y : BlockButtonAbstract.q; - } - case CEILING: - default: - return enumdirection.k() == EnumDirection.EnumAxis.X ? (flag ? BlockButtonAbstract.u : BlockButtonAbstract.b) : (flag ? BlockButtonAbstract.v : BlockButtonAbstract.c); + return enumdirection.k() == EnumDirection.EnumAxis.X ? (flag ? BlockButtonAbstract.j : BlockButtonAbstract.b) : (flag ? BlockButtonAbstract.k : BlockButtonAbstract.c); } } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if ((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)) { return true; } else { // CraftBukkit start boolean powered = ((Boolean) iblockdata.get(POWERED)); - org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); int old = (powered) ? 15 : 0; int current = (!powered) ? 15 : 0; @@ -92,47 +91,52 @@ public abstract class BlockButtonAbstract extends BlockAttachable { // CraftBukkit end world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockButtonAbstract.POWERED, true), 3); this.a(entityhuman, world, blockposition, true); - this.c(iblockdata, world, blockposition); + this.e(iblockdata, world, blockposition); world.getBlockTickList().a(blockposition, this, this.a((IWorldReader) world)); return true; } } protected void a(@Nullable EntityHuman entityhuman, GeneratorAccess generatoraccess, BlockPosition blockposition, boolean flag) { - generatoraccess.a(flag ? entityhuman : null, blockposition, this.a(flag), SoundCategory.BLOCKS, 0.3F, flag ? 0.6F : 0.5F); + generatoraccess.playSound(flag ? entityhuman : null, blockposition, this.a(flag), SoundCategory.BLOCKS, 0.3F, flag ? 0.6F : 0.5F); } protected abstract SoundEffect a(boolean flag); + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (!flag && iblockdata.getBlock() != iblockdata1.getBlock()) { if ((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)) { - this.c(iblockdata, world, blockposition); + this.e(iblockdata, world, blockposition); } super.remove(iblockdata, world, blockposition, iblockdata1, flag); } } + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return (Boolean) iblockdata.get(BlockButtonAbstract.POWERED) ? 15 : 0; } + @Override public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - return (Boolean) iblockdata.get(BlockButtonAbstract.POWERED) && k(iblockdata) == enumdirection ? 15 : 0; + return (Boolean) iblockdata.get(BlockButtonAbstract.POWERED) && j(iblockdata) == enumdirection ? 15 : 0; } + @Override public boolean isPowerSource(IBlockData iblockdata) { return true; } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!world.isClientSide && (Boolean) iblockdata.get(BlockButtonAbstract.POWERED)) { - if (this.E) { - this.b(iblockdata, world, blockposition); + if (this.D) { + this.d(iblockdata, world, blockposition); } else { // CraftBukkit start - org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); world.getServer().getPluginManager().callEvent(eventRedstone); @@ -142,27 +146,28 @@ public abstract class BlockButtonAbstract extends BlockAttachable { } // CraftBukkit end world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockButtonAbstract.POWERED, false), 3); - this.c(iblockdata, world, blockposition); + this.e(iblockdata, world, blockposition); this.a((EntityHuman) null, world, blockposition, false); } } } + @Override public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { - if (!world.isClientSide && this.E && !(Boolean) iblockdata.get(BlockButtonAbstract.POWERED)) { - this.b(iblockdata, world, blockposition); + if (!world.isClientSide && this.D && !(Boolean) iblockdata.get(BlockButtonAbstract.POWERED)) { + this.d(iblockdata, world, blockposition); } } - private void b(IBlockData iblockdata, World world, BlockPosition blockposition) { + private void d(IBlockData iblockdata, World world, BlockPosition blockposition) { List list = world.a(EntityArrow.class, iblockdata.getShape(world, blockposition).getBoundingBox().a(blockposition)); boolean flag = !list.isEmpty(); boolean flag1 = (Boolean) iblockdata.get(BlockButtonAbstract.POWERED); // CraftBukkit start - Call interact event when arrows turn on wooden buttons if (flag1 != flag && flag) { - org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); boolean allowed = false; // If all of the events are cancelled block the button press, else allow @@ -187,7 +192,7 @@ public abstract class BlockButtonAbstract extends BlockAttachable { if (flag != flag1) { // CraftBukkit start boolean powered = flag1; - org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); int old = (powered) ? 15 : 0; int current = (!powered) ? 15 : 0; @@ -199,7 +204,7 @@ public abstract class BlockButtonAbstract extends BlockAttachable { } // CraftBukkit end world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockButtonAbstract.POWERED, flag), 3); - this.c(iblockdata, world, blockposition); + this.e(iblockdata, world, blockposition); this.a((EntityHuman) null, world, blockposition, flag); } @@ -209,16 +214,13 @@ public abstract class BlockButtonAbstract extends BlockAttachable { } - private void c(IBlockData iblockdata, World world, BlockPosition blockposition) { + private void e(IBlockData iblockdata, World world, BlockPosition blockposition) { world.applyPhysics(blockposition, this); - world.applyPhysics(blockposition.shift(k(iblockdata).opposite()), this); + world.applyPhysics(blockposition.shift(j(iblockdata).opposite()), this); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockButtonAbstract.FACING, BlockButtonAbstract.POWERED, BlockButtonAbstract.FACE); } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockCactus.java b/src/main/java/net/minecraft/server/BlockCactus.java index fc8b0b928..124b4b4b0 100644 --- a/src/main/java/net/minecraft/server/BlockCactus.java +++ b/src/main/java/net/minecraft/server/BlockCactus.java @@ -7,19 +7,21 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockCactus extends Block { - public static final BlockStateInteger AGE = BlockProperties.X; + public static final BlockStateInteger AGE = BlockProperties.ad; protected static final VoxelShape b = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 15.0D, 15.0D); protected static final VoxelShape c = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D); protected BlockCactus(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCactus.AGE, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCactus.AGE, 0)); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!iblockdata.canPlace(world, blockposition)) { - world.setAir(blockposition, true); + world.b(blockposition, true); } else { + if (world.paperConfig.fixZeroTickInstantGrowFarms && !randomTick) return; // Paper - fix MC-113809 BlockPosition blockposition1 = blockposition.up(); if (world.isEmpty(blockposition1)) { @@ -37,7 +39,7 @@ public class BlockCactus extends Block { IBlockData iblockdata1 = (IBlockData) iblockdata.set(BlockCactus.AGE, 0); world.setTypeAndData(blockposition, iblockdata1, 4); - iblockdata1.doPhysics(world, blockposition1, this, blockposition); + iblockdata1.doPhysics(world, blockposition1, this, blockposition, false); } else { world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockCactus.AGE, j + 1), 4); } @@ -47,22 +49,22 @@ public class BlockCactus extends Block { } } - public VoxelShape f(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockCactus.b; } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockCactus.c; } + @Override public boolean f(IBlockData iblockdata) { return true; } - public boolean a(IBlockData iblockdata) { - return false; - } - + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (!iblockdata.canPlace(generatoraccess, blockposition)) { generatoraccess.getBlockTickList().a(blockposition, this, 1); @@ -71,6 +73,7 @@ public class BlockCactus extends Block { return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); @@ -93,24 +96,24 @@ public class BlockCactus extends Block { return false; } + @Override public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { - CraftEventFactory.blockDamage = world.getWorld().getBlockAt(blockposition); // CraftBukkit // Akarin + CraftEventFactory.blockDamage = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); // CraftBukkit entity.damageEntity(DamageSource.CACTUS, 1.0F); CraftEventFactory.blockDamage = null; // CraftBukkit } + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockCactus.AGE); } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { return false; } diff --git a/src/main/java/net/minecraft/server/BlockCake.java b/src/main/java/net/minecraft/server/BlockCake.java index d49dca986..815be80e0 100644 --- a/src/main/java/net/minecraft/server/BlockCake.java +++ b/src/main/java/net/minecraft/server/BlockCake.java @@ -2,23 +2,21 @@ package net.minecraft.server; public class BlockCake extends Block { - public static final BlockStateInteger BITES = BlockProperties.Z; - protected static final VoxelShape[] b = new VoxelShape[] { Block.a(1.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(3.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(5.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(7.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(9.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(11.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(13.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D)}; + public static final BlockStateInteger BITES = BlockProperties.af; + protected static final VoxelShape[] b = new VoxelShape[]{Block.a(1.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(3.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(5.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(7.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(9.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(11.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D), Block.a(13.0D, 0.0D, 1.0D, 15.0D, 8.0D, 15.0D)}; protected BlockCake(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCake.BITES, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCake.BITES, 0)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockCake.b[(Integer) iblockdata.get(BlockCake.BITES)]; } - public boolean a(IBlockData iblockdata) { - return false; - } - - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if (!world.isClientSide) { return this.a((GeneratorAccess) world, blockposition, iblockdata, entityhuman); } else { @@ -29,7 +27,7 @@ public class BlockCake extends Block { } private boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { - if (!entityhuman.q(false)) { + if (!entityhuman.p(false)) { return false; } else { entityhuman.a(StatisticList.EAT_CAKE_SLICE); @@ -50,41 +48,39 @@ public class BlockCake extends Block { if (i < 6) { generatoraccess.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockCake.BITES, i + 1), 3); } else { - generatoraccess.setAir(blockposition); + generatoraccess.a(blockposition, false); } return true; } } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { return enumdirection == EnumDirection.DOWN && !iblockdata.canPlace(generatoraccess, blockposition) ? Blocks.AIR.getBlockData() : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { return iworldreader.getType(blockposition.down()).getMaterial().isBuildable(); } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.AIR; - } - + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockCake.BITES); } + @Override public int a(IBlockData iblockdata, World world, BlockPosition blockposition) { return (7 - (Integer) iblockdata.get(BlockCake.BITES)) * 2; } + @Override public boolean isComplexRedstone(IBlockData iblockdata) { return true; } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { return false; } diff --git a/src/main/java/net/minecraft/server/BlockCampfire.java b/src/main/java/net/minecraft/server/BlockCampfire.java new file mode 100644 index 000000000..9d59e339c --- /dev/null +++ b/src/main/java/net/minecraft/server/BlockCampfire.java @@ -0,0 +1,196 @@ +package net.minecraft.server; + +import java.util.Optional; +import java.util.Random; +import javax.annotation.Nullable; + +public class BlockCampfire extends BlockTileEntity implements IBlockWaterlogged { + + protected static final VoxelShape a = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 7.0D, 16.0D); + public static final BlockStateBoolean b = BlockProperties.r; + public static final BlockStateBoolean c = BlockProperties.y; + public static final BlockStateBoolean d = BlockProperties.C; + public static final BlockStateDirection e = BlockProperties.N; + + public BlockCampfire(Block.Info block_info) { + super(block_info); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCampfire.b, true)).set(BlockCampfire.c, false)).set(BlockCampfire.d, false)).set(BlockCampfire.e, EnumDirection.NORTH)); + } + + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { + if ((Boolean) iblockdata.get(BlockCampfire.b)) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityCampfire) { + TileEntityCampfire tileentitycampfire = (TileEntityCampfire) tileentity; + ItemStack itemstack = entityhuman.b(enumhand); + Optional optional = tileentitycampfire.a(itemstack); + + if (optional.isPresent()) { + if (!world.isClientSide && tileentitycampfire.a(entityhuman.abilities.canInstantlyBuild ? itemstack.cloneItemStack() : itemstack, ((RecipeCampfire) optional.get()).e())) { + entityhuman.a(StatisticList.INTERACT_WITH_CAMPFIRE); + } + + return true; + } + } + } + + return false; + } + + @Override + public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { + if (!entity.isFireProof() && (Boolean) iblockdata.get(BlockCampfire.b) && entity instanceof EntityLiving && !EnchantmentManager.i((EntityLiving) entity)) { + entity.damageEntity(DamageSource.FIRE, 1.0F); + } + + super.a(iblockdata, world, blockposition, entity); + } + + @Override + public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { + if (iblockdata.getBlock() != iblockdata1.getBlock()) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityCampfire) { + InventoryUtils.a(world, blockposition, ((TileEntityCampfire) tileentity).getItems()); + } + + super.remove(iblockdata, world, blockposition, iblockdata1, flag); + } + } + + @Nullable + @Override + public IBlockData getPlacedState(BlockActionContext blockactioncontext) { + World world = blockactioncontext.getWorld(); + BlockPosition blockposition = blockactioncontext.getClickPosition(); + boolean flag = world.getFluid(blockposition).getType() == FluidTypes.WATER; + + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.getBlockData().set(BlockCampfire.d, flag)).set(BlockCampfire.c, this.j(world.getType(blockposition.down())))).set(BlockCampfire.b, !flag)).set(BlockCampfire.e, blockactioncontext.f()); + } + + @Override + public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { + if ((Boolean) iblockdata.get(BlockCampfire.d)) { + generatoraccess.getFluidTickList().a(blockposition, FluidTypes.WATER, FluidTypes.WATER.a((IWorldReader) generatoraccess)); + } + + return enumdirection == EnumDirection.DOWN ? (IBlockData) iblockdata.set(BlockCampfire.c, this.j(iblockdata1)) : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); + } + + private boolean j(IBlockData iblockdata) { + return iblockdata.getBlock() == Blocks.HAY_BLOCK; + } + + @Override + public int a(IBlockData iblockdata) { + return (Boolean) iblockdata.get(BlockCampfire.b) ? super.a(iblockdata) : 0; + } + + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return BlockCampfire.a; + } + + @Override + public EnumRenderType c(IBlockData iblockdata) { + return EnumRenderType.MODEL; + } + + @Override + public TextureType c() { + return TextureType.CUTOUT; + } + + @Override + public boolean place(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid) { + if (!(Boolean) iblockdata.get(BlockProperties.C) && fluid.getType() == FluidTypes.WATER) { + boolean flag = (Boolean) iblockdata.get(BlockCampfire.b); + + if (flag) { + if (generatoraccess.e()) { + for (int i = 0; i < 20; ++i) { + a(generatoraccess.getMinecraftWorld(), blockposition, (Boolean) iblockdata.get(BlockCampfire.c), true); + } + } else { + generatoraccess.playSound((EntityHuman) null, blockposition, SoundEffects.ENTITY_GENERIC_EXTINGUISH_FIRE, SoundCategory.BLOCKS, 1.0F, 1.0F); + } + + TileEntity tileentity = generatoraccess.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityCampfire) { + ((TileEntityCampfire) tileentity).f(); + } + } + + generatoraccess.setTypeAndData(blockposition, (IBlockData) ((IBlockData) iblockdata.set(BlockCampfire.d, true)).set(BlockCampfire.b, false), 3); + generatoraccess.getFluidTickList().a(blockposition, fluid.getType(), fluid.getType().a((IWorldReader) generatoraccess)); + return true; + } else { + return false; + } + } + + @Override + public void a(World world, IBlockData iblockdata, MovingObjectPositionBlock movingobjectpositionblock, Entity entity) { + if (!world.isClientSide && entity instanceof EntityArrow) { + EntityArrow entityarrow = (EntityArrow) entity; + + if (entityarrow.isBurning() && !(Boolean) iblockdata.get(BlockCampfire.b) && !(Boolean) iblockdata.get(BlockCampfire.d)) { + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition(); + + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, entityarrow).isCancelled()) { + return; + } + // CraftBukkit end + world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockProperties.r, true), 11); + } + } + + } + + public static void a(World world, BlockPosition blockposition, boolean flag, boolean flag1) { + Random random = world.getRandom(); + ParticleType particletype = flag ? Particles.CAMPFIRE_SIGNAL_SMOKE : Particles.CAMPFIRE_COSY_SMOKE; + + world.b(particletype, true, (double) blockposition.getX() + 0.5D + random.nextDouble() / 3.0D * (double) (random.nextBoolean() ? 1 : -1), (double) blockposition.getY() + random.nextDouble() + random.nextDouble(), (double) blockposition.getZ() + 0.5D + random.nextDouble() / 3.0D * (double) (random.nextBoolean() ? 1 : -1), 0.0D, 0.07D, 0.0D); + if (flag1) { + world.addParticle(Particles.SMOKE, (double) blockposition.getX() + 0.25D + random.nextDouble() / 2.0D * (double) (random.nextBoolean() ? 1 : -1), (double) blockposition.getY() + 0.4D, (double) blockposition.getZ() + 0.25D + random.nextDouble() / 2.0D * (double) (random.nextBoolean() ? 1 : -1), 0.0D, 0.005D, 0.0D); + } + + } + + @Override + public Fluid g(IBlockData iblockdata) { + return (Boolean) iblockdata.get(BlockCampfire.d) ? FluidTypes.WATER.a(false) : super.g(iblockdata); + } + + @Override + public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { + return (IBlockData) iblockdata.set(BlockCampfire.e, enumblockrotation.a((EnumDirection) iblockdata.get(BlockCampfire.e))); + } + + @Override + public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { + return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockCampfire.e))); + } + + @Override + protected void a(BlockStateList.a blockstatelist_a) { + blockstatelist_a.a(BlockCampfire.b, BlockCampfire.c, BlockCampfire.d, BlockCampfire.e); + } + + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { + return new TileEntityCampfire(); + } + + @Override + public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { + return false; + } +} diff --git a/src/main/java/net/minecraft/server/BlockCauldron.java b/src/main/java/net/minecraft/server/BlockCauldron.java index 764d589eb..44ffa2708 100644 --- a/src/main/java/net/minecraft/server/BlockCauldron.java +++ b/src/main/java/net/minecraft/server/BlockCauldron.java @@ -4,31 +4,31 @@ import org.bukkit.event.block.CauldronLevelChangeEvent; // CraftBukkit public class BlockCauldron extends Block { - public static final BlockStateInteger LEVEL = BlockProperties.af; - protected static final VoxelShape b = Block.a(2.0D, 4.0D, 2.0D, 14.0D, 16.0D, 14.0D); - protected static final VoxelShape c = VoxelShapes.a(VoxelShapes.b(), BlockCauldron.b, OperatorBoolean.ONLY_FIRST); + public static final BlockStateInteger LEVEL = BlockProperties.al; + private static final VoxelShape c = a(2.0D, 4.0D, 2.0D, 14.0D, 16.0D, 14.0D); + protected static final VoxelShape b = VoxelShapes.a(VoxelShapes.b(), VoxelShapes.a(a(0.0D, 0.0D, 4.0D, 16.0D, 3.0D, 12.0D), a(4.0D, 0.0D, 0.0D, 12.0D, 3.0D, 16.0D), a(2.0D, 0.0D, 2.0D, 14.0D, 3.0D, 14.0D), BlockCauldron.c), OperatorBoolean.ONLY_FIRST); public BlockCauldron(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCauldron.LEVEL, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCauldron.LEVEL, 0)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return BlockCauldron.c; + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return BlockCauldron.b; } + @Override public boolean f(IBlockData iblockdata) { return false; } - public VoxelShape h(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return BlockCauldron.b; - } - - public boolean a(IBlockData iblockdata) { - return false; + @Override + public VoxelShape i(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return BlockCauldron.c; } + @Override public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { int i = (Integer) iblockdata.get(BlockCauldron.LEVEL); float f = (float) blockposition.getY() + (6.0F + (float) (3 * i)) / 16.0F; @@ -45,7 +45,8 @@ public class BlockCauldron extends Block { } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { ItemStack itemstack = entityhuman.b(enumhand); if (itemstack.isEmpty()) { @@ -67,7 +68,7 @@ public class BlockCauldron extends Block { entityhuman.a(StatisticList.FILL_CAULDRON); // this.a(world, blockposition, iblockdata, 3); // CraftBukkit end - world.a((EntityHuman) null, blockposition, SoundEffects.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 1.0F, 1.0F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 1.0F, 1.0F); } return true; @@ -89,7 +90,7 @@ public class BlockCauldron extends Block { entityhuman.a(StatisticList.USE_CAULDRON); // this.a(world, blockposition, iblockdata, 0); // CraftBukkit end - world.a((EntityHuman) null, blockposition, SoundEffects.ITEM_BUCKET_FILL, SoundCategory.BLOCKS, 1.0F, 1.0F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.ITEM_BUCKET_FILL, SoundCategory.BLOCKS, 1.0F, 1.0F); } return true; @@ -103,7 +104,7 @@ public class BlockCauldron extends Block { return true; } if (!entityhuman.abilities.canInstantlyBuild) { - itemstack1 = PotionUtil.a(new ItemStack(Items.POTION), Potions.b); + itemstack1 = PotionUtil.a(new ItemStack(Items.POTION), Potions.WATER); entityhuman.a(StatisticList.USE_CAULDRON); itemstack.subtract(1); if (itemstack.isEmpty()) { @@ -115,13 +116,13 @@ public class BlockCauldron extends Block { } } - world.a((EntityHuman) null, blockposition, SoundEffects.ITEM_BOTTLE_FILL, SoundCategory.BLOCKS, 1.0F, 1.0F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.ITEM_BOTTLE_FILL, SoundCategory.BLOCKS, 1.0F, 1.0F); // this.a(world, blockposition, iblockdata, i - 1); // CraftBukkit end } return true; - } else if (item == Items.POTION && PotionUtil.d(itemstack) == Potions.b) { + } else if (item == Items.POTION && PotionUtil.d(itemstack) == Potions.WATER) { if (i < 3 && !world.isClientSide) { // CraftBukkit start if (!this.changeLevel(world, blockposition, iblockdata, i + 1, entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY)) { @@ -136,22 +137,22 @@ public class BlockCauldron extends Block { } } - world.a((EntityHuman) null, blockposition, SoundEffects.ITEM_BOTTLE_EMPTY, SoundCategory.BLOCKS, 1.0F, 1.0F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.ITEM_BOTTLE_EMPTY, SoundCategory.BLOCKS, 1.0F, 1.0F); // this.a(world, blockposition, iblockdata, i + 1); // CraftBukkit end } return true; } else { - if (i > 0 && item instanceof ItemArmorColorable) { - ItemArmorColorable itemarmorcolorable = (ItemArmorColorable) item; + if (i > 0 && item instanceof IDyeable) { + IDyeable idyeable = (IDyeable) item; - if (itemarmorcolorable.e(itemstack) && !world.isClientSide) { + if (idyeable.a(itemstack) && !world.isClientSide) { // CraftBukkit start if (!this.changeLevel(world, blockposition, iblockdata, i - 1, entityhuman, CauldronLevelChangeEvent.ChangeReason.ARMOR_WASH)) { return true; } - itemarmorcolorable.g(itemstack); + idyeable.c(itemstack); // this.a(world, blockposition, iblockdata, i - 1); // CraftBukkit end entityhuman.a(StatisticList.CLEAN_ARMOR); @@ -217,7 +218,7 @@ public class BlockCauldron extends Block { private boolean changeLevel(World world, BlockPosition blockposition, IBlockData iblockdata, int i, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) { int newLevel = Integer.valueOf(MathHelper.clamp(i, 0, 3)); CauldronLevelChangeEvent event = new CauldronLevelChangeEvent( - world.getWorld().getBlockAt(blockposition), // Akarin + world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), (entity == null) ? null : entity.getBukkitEntity(), reason, iblockdata.get(BlockCauldron.LEVEL), newLevel ); world.getServer().getPluginManager().callEvent(event); @@ -230,6 +231,7 @@ public class BlockCauldron extends Block { // CraftBukkit end } + @Override public void c(World world, BlockPosition blockposition) { if (world.random.nextInt(20) == 1) { float f = world.getBiome(blockposition).getAdjustedTemperature(blockposition); @@ -245,22 +247,22 @@ public class BlockCauldron extends Block { } } + @Override public boolean isComplexRedstone(IBlockData iblockdata) { return true; } + @Override public int a(IBlockData iblockdata, World world, BlockPosition blockposition) { return (Integer) iblockdata.get(BlockCauldron.LEVEL); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockCauldron.LEVEL); } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return enumdirection == EnumDirection.UP ? EnumBlockFaceShape.BOWL : (enumdirection == EnumDirection.DOWN ? EnumBlockFaceShape.UNDEFINED : EnumBlockFaceShape.SOLID); - } - + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { return false; } diff --git a/src/main/java/net/minecraft/server/BlockChest.java b/src/main/java/net/minecraft/server/BlockChest.java index c61721bc3..8183a61c9 100644 --- a/src/main/java/net/minecraft/server/BlockChest.java +++ b/src/main/java/net/minecraft/server/BlockChest.java @@ -4,30 +4,84 @@ import java.util.Iterator; import java.util.List; import javax.annotation.Nullable; -public class BlockChest extends BlockTileEntity implements IFluidSource, IFluidContainer { +public class BlockChest extends BlockTileEntity implements IBlockWaterlogged { public static final BlockStateDirection FACING = BlockFacingHorizontal.FACING; - public static final BlockStateEnum b = BlockProperties.ap; - public static final BlockStateBoolean c = BlockProperties.y; - protected static final VoxelShape o = Block.a(1.0D, 0.0D, 0.0D, 15.0D, 14.0D, 15.0D); - protected static final VoxelShape p = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 16.0D); - protected static final VoxelShape q = Block.a(0.0D, 0.0D, 1.0D, 15.0D, 14.0D, 15.0D); - protected static final VoxelShape r = Block.a(1.0D, 0.0D, 1.0D, 16.0D, 14.0D, 15.0D); - protected static final VoxelShape s = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 15.0D); + public static final BlockStateEnum b = BlockProperties.ax; + public static final BlockStateBoolean c = BlockProperties.C; + protected static final VoxelShape d = Block.a(1.0D, 0.0D, 0.0D, 15.0D, 14.0D, 15.0D); + protected static final VoxelShape e = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 16.0D); + protected static final VoxelShape f = Block.a(0.0D, 0.0D, 1.0D, 15.0D, 14.0D, 15.0D); + protected static final VoxelShape g = Block.a(1.0D, 0.0D, 1.0D, 16.0D, 14.0D, 15.0D); + protected static final VoxelShape h = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 15.0D); + private static final BlockChest.ChestFinder i = new BlockChest.ChestFinder() { + @Override + public IInventory b(TileEntityChest tileentitychest, TileEntityChest tileentitychest1) { + return new InventoryLargeChest(tileentitychest, tileentitychest1); + } + + @Override + public IInventory b(TileEntityChest tileentitychest) { + return tileentitychest; + } + }; + private static final BlockChest.ChestFinder j = new BlockChest.ChestFinder() { + @Override + public ITileInventory b(final TileEntityChest tileentitychest, final TileEntityChest tileentitychest1) { + final InventoryLargeChest inventorylargechest = new InventoryLargeChest(tileentitychest, tileentitychest1); + + return new DoubleInventory(tileentitychest, tileentitychest1, inventorylargechest); // CraftBukkit + } + + @Override + public ITileInventory b(TileEntityChest tileentitychest) { + return tileentitychest; + } + }; + + // CraftBukkit start + public static class DoubleInventory implements ITileInventory { + + private final TileEntityChest tileentitychest; + private final TileEntityChest tileentitychest1; + public final InventoryLargeChest inventorylargechest; + + public DoubleInventory(TileEntityChest tileentitychest, TileEntityChest tileentitychest1, InventoryLargeChest inventorylargechest) { + this.tileentitychest = tileentitychest; + this.tileentitychest1 = tileentitychest1; + this.inventorylargechest = inventorylargechest; + } + + @Nullable + @Override + public Container createMenu(int i, PlayerInventory playerinventory, EntityHuman entityhuman) { + if (tileentitychest.e(entityhuman) && tileentitychest1.e(entityhuman)) { + tileentitychest.d(playerinventory.player); + tileentitychest1.d(playerinventory.player); + return ContainerChest.b(i, playerinventory, inventorylargechest); + } else { + return null; + } + } + + @Override + public IChatBaseComponent getScoreboardDisplayName() { + return (IChatBaseComponent) (tileentitychest.hasCustomName() ? tileentitychest.getScoreboardDisplayName() : (tileentitychest1.hasCustomName() ? tileentitychest1.getScoreboardDisplayName() : new ChatMessage("container.chestDouble", new Object[0]))); + } + }; + // CraftBukkit end protected BlockChest(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockChest.FACING, EnumDirection.NORTH)).set(BlockChest.b, BlockPropertyChestType.SINGLE)).set(BlockChest.c, false)); - } - - public boolean a(IBlockData iblockdata) { - return false; + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockChest.FACING, EnumDirection.NORTH)).set(BlockChest.b, BlockPropertyChestType.SINGLE)).set(BlockChest.c, false)); } + @Override public EnumRenderType c(IBlockData iblockdata) { return EnumRenderType.ENTITYBLOCK_ANIMATED; } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if ((Boolean) iblockdata.get(BlockChest.c)) { generatoraccess.getFluidTickList().a(blockposition, FluidTypes.WATER, FluidTypes.WATER.a((IWorldReader) generatoraccess)); @@ -36,40 +90,42 @@ public class BlockChest extends BlockTileEntity implements IFluidSource, IFluidC if (iblockdata1.getBlock() == this && enumdirection.k().c()) { BlockPropertyChestType blockpropertychesttype = (BlockPropertyChestType) iblockdata1.get(BlockChest.b); - if (iblockdata.get(BlockChest.b) == BlockPropertyChestType.SINGLE && blockpropertychesttype != BlockPropertyChestType.SINGLE && iblockdata.get(BlockChest.FACING) == iblockdata1.get(BlockChest.FACING) && k(iblockdata1) == enumdirection.opposite()) { + if (iblockdata.get(BlockChest.b) == BlockPropertyChestType.SINGLE && blockpropertychesttype != BlockPropertyChestType.SINGLE && iblockdata.get(BlockChest.FACING) == iblockdata1.get(BlockChest.FACING) && j(iblockdata1) == enumdirection.opposite()) { return (IBlockData) iblockdata.set(BlockChest.b, blockpropertychesttype.a()); } - } else if (k(iblockdata) == enumdirection) { + } else if (j(iblockdata) == enumdirection) { return (IBlockData) iblockdata.set(BlockChest.b, BlockPropertyChestType.SINGLE); } return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { if (iblockdata.get(BlockChest.b) == BlockPropertyChestType.SINGLE) { - return BlockChest.s; + return BlockChest.h; } else { - switch (k(iblockdata)) { - case NORTH: - default: - return BlockChest.o; - case SOUTH: - return BlockChest.p; - case WEST: - return BlockChest.q; - case EAST: - return BlockChest.r; + switch (j(iblockdata)) { + case NORTH: + default: + return BlockChest.d; + case SOUTH: + return BlockChest.e; + case WEST: + return BlockChest.f; + case EAST: + return BlockChest.g; } } } - public static EnumDirection k(IBlockData iblockdata) { + public static EnumDirection j(IBlockData iblockdata) { EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockChest.FACING); return iblockdata.get(BlockChest.b) == BlockPropertyChestType.LEFT ? enumdirection.e() : enumdirection.f(); } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { BlockPropertyChestType blockpropertychesttype = BlockPropertyChestType.SINGLE; EnumDirection enumdirection = blockactioncontext.f().opposite(); @@ -94,37 +150,12 @@ public class BlockChest extends BlockTileEntity implements IFluidSource, IFluidC } } - return (IBlockData) ((IBlockData) ((IBlockData) this.getBlockData().set(BlockChest.FACING, enumdirection)).set(BlockChest.b, blockpropertychesttype)).set(BlockChest.c, fluid.c() == FluidTypes.WATER); + return (IBlockData) ((IBlockData) ((IBlockData) this.getBlockData().set(BlockChest.FACING, enumdirection)).set(BlockChest.b, blockpropertychesttype)).set(BlockChest.c, fluid.getType() == FluidTypes.WATER); } - public FluidType removeFluid(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata) { - if ((Boolean) iblockdata.get(BlockChest.c)) { - generatoraccess.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockChest.c, false), 3); - return FluidTypes.WATER; - } else { - return FluidTypes.EMPTY; - } - } - - public Fluid h(IBlockData iblockdata) { - return (Boolean) iblockdata.get(BlockChest.c) ? FluidTypes.WATER.a(false) : super.h(iblockdata); - } - - public boolean canPlace(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, FluidType fluidtype) { - return !(Boolean) iblockdata.get(BlockChest.c) && fluidtype == FluidTypes.WATER; - } - - public boolean place(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid) { - if (!(Boolean) iblockdata.get(BlockChest.c) && fluid.c() == FluidTypes.WATER) { - if (!generatoraccess.e()) { - generatoraccess.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockChest.c, true), 3); - generatoraccess.getFluidTickList().a(blockposition, FluidTypes.WATER, FluidTypes.WATER.a((IWorldReader) generatoraccess)); - } - - return true; - } else { - return false; - } + @Override + public Fluid g(IBlockData iblockdata) { + return (Boolean) iblockdata.get(BlockChest.c) ? FluidTypes.WATER.a(false) : super.g(iblockdata); } @Nullable @@ -134,6 +165,7 @@ public class BlockChest extends BlockTileEntity implements IFluidSource, IFluidC return iblockdata.getBlock() == this && iblockdata.get(BlockChest.b) == BlockPropertyChestType.SINGLE ? (EnumDirection) iblockdata.get(BlockChest.FACING) : null; } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { if (itemstack.hasName()) { TileEntity tileentity = world.getTileEntity(blockposition); @@ -145,6 +177,7 @@ public class BlockChest extends BlockTileEntity implements IFluidSource, IFluidC } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata.getBlock() != iblockdata1.getBlock()) { TileEntity tileentity = world.getTileEntity(blockposition); @@ -158,11 +191,12 @@ public class BlockChest extends BlockTileEntity implements IFluidSource, IFluidC } } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if (world.isClientSide) { return true; } else { - ITileInventory itileinventory = this.getInventory(iblockdata, world, blockposition, false); + ITileInventory itileinventory = this.getInventory(iblockdata, world, blockposition); if (itileinventory != null) { entityhuman.openContainer(itileinventory); @@ -178,79 +212,93 @@ public class BlockChest extends BlockTileEntity implements IFluidSource, IFluidC } @Nullable - public ITileInventory getInventory(IBlockData iblockdata, World world, BlockPosition blockposition, boolean flag) { - TileEntity tileentity = world.getTileEntity(blockposition); + public static T getInventory(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition, boolean flag, BlockChest.ChestFinder blockchest_chestfinder) { + TileEntity tileentity = generatoraccess.getTileEntity(blockposition); if (!(tileentity instanceof TileEntityChest)) { return null; - } else if (!flag && this.a(world, blockposition)) { + } else if (!flag && a(generatoraccess, blockposition)) { return null; } else { - Object object = (TileEntityChest) tileentity; + TileEntityChest tileentitychest = (TileEntityChest) tileentity; BlockPropertyChestType blockpropertychesttype = (BlockPropertyChestType) iblockdata.get(BlockChest.b); if (blockpropertychesttype == BlockPropertyChestType.SINGLE) { - return (ITileInventory) object; + return blockchest_chestfinder.b(tileentitychest); } else { - BlockPosition blockposition1 = blockposition.shift(k(iblockdata)); + BlockPosition blockposition1 = blockposition.shift(j(iblockdata)); // Paper start - don't load chunks if the other side of the chest is in unloaded chunk - final IBlockData iblockdata1 = world.getTypeIfLoaded(blockposition1); // Paper - if (iblockdata1 == null) { + IBlockData iblockdata1 = generatoraccess.getTypeIfLoaded(blockposition1); + if (iblockdata1 == null) { return null; } // Paper end - if (iblockdata1.getBlock() == this) { + if (iblockdata1.getBlock() == iblockdata.getBlock()) { BlockPropertyChestType blockpropertychesttype1 = (BlockPropertyChestType) iblockdata1.get(BlockChest.b); if (blockpropertychesttype1 != BlockPropertyChestType.SINGLE && blockpropertychesttype != blockpropertychesttype1 && iblockdata1.get(BlockChest.FACING) == iblockdata.get(BlockChest.FACING)) { - if (!flag && this.a(world, blockposition1)) { + if (!flag && a(generatoraccess, blockposition1)) { return null; } - TileEntity tileentity1 = world.getTileEntity(blockposition1); + TileEntity tileentity1 = generatoraccess.getTileEntity(blockposition1); if (tileentity1 instanceof TileEntityChest) { - Object object1 = blockpropertychesttype == BlockPropertyChestType.RIGHT ? object : (ITileInventory) tileentity1; - Object object2 = blockpropertychesttype == BlockPropertyChestType.RIGHT ? (ITileInventory) tileentity1 : object; + TileEntityChest tileentitychest1 = blockpropertychesttype == BlockPropertyChestType.RIGHT ? tileentitychest : (TileEntityChest) tileentity1; + TileEntityChest tileentitychest2 = blockpropertychesttype == BlockPropertyChestType.RIGHT ? (TileEntityChest) tileentity1 : tileentitychest; - object = new InventoryLargeChest(new ChatMessage("container.chestDouble", new Object[0]), (ITileInventory) object1, (ITileInventory) object2); + return blockchest_chestfinder.b(tileentitychest1, tileentitychest2); } } } - return (ITileInventory) object; + return blockchest_chestfinder.b(tileentitychest); } } } - public TileEntity a(IBlockAccess iblockaccess) { + @Nullable + public static IInventory getInventory(IBlockData iblockdata, World world, BlockPosition blockposition, boolean flag) { + return (IInventory) getInventory(iblockdata, world, blockposition, flag, BlockChest.i); + } + + @Nullable + @Override + public ITileInventory getInventory(IBlockData iblockdata, World world, BlockPosition blockposition) { + return (ITileInventory) getInventory(iblockdata, world, blockposition, false, BlockChest.j); + } + + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { return new TileEntityChest(); } - private boolean a(World world, BlockPosition blockposition) { - return this.a((IBlockAccess) world, blockposition) || this.b(world, blockposition); + private static boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition) { + return a((IBlockAccess) generatoraccess, blockposition) || b(generatoraccess, blockposition); } - private boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) { - return iblockaccess.getType(blockposition.up()).isOccluding(); + private static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) { + BlockPosition blockposition1 = blockposition.up(); + + return iblockaccess.getType(blockposition1).isOccluding(iblockaccess, blockposition1); } - private boolean b(World world, BlockPosition blockposition) { + private static boolean b(GeneratorAccess generatoraccess, BlockPosition blockposition) { // Paper start - Option to disable chest cat detection - if (world.paperConfig.disableChestCatDetection) { + if (((World) generatoraccess).paperConfig.disableChestCatDetection) { return false; } // Paper end - List list = world.a(EntityOcelot.class, new AxisAlignedBB((double) blockposition.getX(), (double) (blockposition.getY() + 1), (double) blockposition.getZ(), (double) (blockposition.getX() + 1), (double) (blockposition.getY() + 2), (double) (blockposition.getZ() + 1))); + List list = generatoraccess.a(EntityCat.class, new AxisAlignedBB((double) blockposition.getX(), (double) (blockposition.getY() + 1), (double) blockposition.getZ(), (double) (blockposition.getX() + 1), (double) (blockposition.getY() + 2), (double) (blockposition.getZ() + 1))); if (!list.isEmpty()) { Iterator iterator = list.iterator(); while (iterator.hasNext()) { - EntityOcelot entityocelot = (EntityOcelot) iterator.next(); + EntityCat entitycat = (EntityCat) iterator.next(); - if (entityocelot.isSitting()) { + if (entitycat.isSitting()) { return true; } } @@ -259,31 +307,40 @@ public class BlockChest extends BlockTileEntity implements IFluidSource, IFluidC return false; } + @Override public boolean isComplexRedstone(IBlockData iblockdata) { return true; } + @Override public int a(IBlockData iblockdata, World world, BlockPosition blockposition) { - return Container.b((IInventory) this.getInventory(iblockdata, world, blockposition, false)); + return Container.b(getInventory(iblockdata, world, blockposition, false)); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { return (IBlockData) iblockdata.set(BlockChest.FACING, enumblockrotation.a((EnumDirection) iblockdata.get(BlockChest.FACING))); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockChest.FACING))); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockChest.FACING, BlockChest.b, BlockChest.c); } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { return false; } + + interface ChestFinder { + + T b(TileEntityChest tileentitychest, TileEntityChest tileentitychest1); + + T b(TileEntityChest tileentitychest); + } } diff --git a/src/main/java/net/minecraft/server/BlockChorusFlower.java b/src/main/java/net/minecraft/server/BlockChorusFlower.java index 5063c94c0..cde2524ca 100644 --- a/src/main/java/net/minecraft/server/BlockChorusFlower.java +++ b/src/main/java/net/minecraft/server/BlockChorusFlower.java @@ -8,23 +8,21 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockChorusFlower extends Block { - public static final BlockStateInteger AGE = BlockProperties.V; + public static final BlockStateInteger AGE = BlockProperties.ab; private final BlockChorusFruit b; protected BlockChorusFlower(BlockChorusFruit blockchorusfruit, Block.Info block_info) { super(block_info); this.b = blockchorusfruit; - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockChorusFlower.AGE, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockChorusFlower.AGE, 0)); } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.AIR; - } - - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!iblockdata.canPlace(world, blockposition)) { - world.setAir(blockposition, true); + world.b(blockposition, true); } else { + if (world.paperConfig.fixZeroTickInstantGrowFarms && !randomTick) return; // Paper - fix MC-113809 BlockPosition blockposition1 = blockposition.up(); if (world.isEmpty(blockposition1) && blockposition1.getY() < 256) { @@ -62,7 +60,7 @@ public class BlockChorusFlower extends Block { flag = true; } - if (flag && a((IWorldReader) world, blockposition1, (EnumDirection) null) && world.isEmpty(blockposition.up(2))) { + if (flag && b((IWorldReader) world, blockposition1, (EnumDirection) null) && world.isEmpty(blockposition.up(2))) { // CraftBukkit start - add event if (CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition1, this.getBlockData().set(BlockChorusFlower.AGE, Integer.valueOf(i)), 2)) { world.setTypeAndData(blockposition, this.b.a((IBlockAccess) world, blockposition), 2); @@ -81,7 +79,7 @@ public class BlockChorusFlower extends Block { EnumDirection enumdirection = EnumDirection.EnumDirectionLimit.HORIZONTAL.a(random); BlockPosition blockposition2 = blockposition.shift(enumdirection); - if (world.isEmpty(blockposition2) && world.isEmpty(blockposition2.down()) && a((IWorldReader) world, blockposition2, enumdirection.opposite())) { + if (world.isEmpty(blockposition2) && world.isEmpty(blockposition2.down()) && b((IWorldReader) world, blockposition2, enumdirection.opposite())) { // CraftBukkit start - add event if (CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition2, this.getBlockData().set(BlockChorusFlower.AGE, Integer.valueOf(i + 1)), 2)) { this.b(world, blockposition2, i + 1); @@ -123,7 +121,7 @@ public class BlockChorusFlower extends Block { world.triggerEffect(1034, blockposition, 0); } - private static boolean a(IWorldReader iworldreader, BlockPosition blockposition, @Nullable EnumDirection enumdirection) { + private static boolean b(IWorldReader iworldreader, BlockPosition blockposition, @Nullable EnumDirection enumdirection) { Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); EnumDirection enumdirection1; @@ -139,10 +137,7 @@ public class BlockChorusFlower extends Block { return false; } - public boolean a(IBlockData iblockdata) { - return false; - } - + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (enumdirection != EnumDirection.UP && !iblockdata.canPlace(generatoraccess, blockposition)) { generatoraccess.getBlockTickList().a(blockposition, this, 1); @@ -151,6 +146,7 @@ public class BlockChorusFlower extends Block { return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { IBlockData iblockdata1 = iworldreader.getType(blockposition.down()); Block block = iblockdata1.getBlock(); @@ -184,19 +180,12 @@ public class BlockChorusFlower extends Block { } } - public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { - super.a(world, entityhuman, blockposition, iblockdata, tileentity, itemstack); - a(world, blockposition, new ItemStack(this)); - } - - protected ItemStack t(IBlockData iblockdata) { - return ItemStack.a; - } - + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockChorusFlower.AGE); } @@ -217,7 +206,7 @@ public class BlockChorusFlower extends Block { for (int l = 0; l < k; ++l) { BlockPosition blockposition2 = blockposition.up(l + 1); - if (!a((IWorldReader) generatoraccess, blockposition2, (EnumDirection) null)) { + if (!b((IWorldReader) generatoraccess, blockposition2, (EnumDirection) null)) { return; } @@ -238,7 +227,7 @@ public class BlockChorusFlower extends Block { EnumDirection enumdirection = EnumDirection.EnumDirectionLimit.HORIZONTAL.a(random); BlockPosition blockposition3 = blockposition.up(k).shift(enumdirection); - if (Math.abs(blockposition3.getX() - blockposition1.getX()) < i && Math.abs(blockposition3.getZ() - blockposition1.getZ()) < i && generatoraccess.isEmpty(blockposition3) && generatoraccess.isEmpty(blockposition3.down()) && a((IWorldReader) generatoraccess, blockposition3, enumdirection.opposite())) { + if (Math.abs(blockposition3.getX() - blockposition1.getX()) < i && Math.abs(blockposition3.getZ() - blockposition1.getZ()) < i && generatoraccess.isEmpty(blockposition3) && generatoraccess.isEmpty(blockposition3.down()) && b((IWorldReader) generatoraccess, blockposition3, enumdirection.opposite())) { flag = true; generatoraccess.setTypeAndData(blockposition3, blockchorusfruit.a((IBlockAccess) generatoraccess, blockposition3), 2); generatoraccess.setTypeAndData(blockposition3.shift(enumdirection.opposite()), blockchorusfruit.a((IBlockAccess) generatoraccess, blockposition3.shift(enumdirection.opposite())), 2); @@ -253,7 +242,11 @@ public class BlockChorusFlower extends Block { } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; + @Override + public void a(World world, IBlockData iblockdata, MovingObjectPositionBlock movingobjectpositionblock, Entity entity) { + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition(); + + a(world, blockposition, new ItemStack(this)); + world.b(blockposition, true); } } diff --git a/src/main/java/net/minecraft/server/BlockCocoa.java b/src/main/java/net/minecraft/server/BlockCocoa.java index a69b2f043..ee9f294f4 100644 --- a/src/main/java/net/minecraft/server/BlockCocoa.java +++ b/src/main/java/net/minecraft/server/BlockCocoa.java @@ -7,18 +7,19 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockCocoa extends BlockFacingHorizontal implements IBlockFragilePlantElement { - public static final BlockStateInteger AGE = BlockProperties.T; - protected static final VoxelShape[] b = new VoxelShape[] { Block.a(11.0D, 7.0D, 6.0D, 15.0D, 12.0D, 10.0D), Block.a(9.0D, 5.0D, 5.0D, 15.0D, 12.0D, 11.0D), Block.a(7.0D, 3.0D, 4.0D, 15.0D, 12.0D, 12.0D)}; - protected static final VoxelShape[] c = new VoxelShape[] { Block.a(1.0D, 7.0D, 6.0D, 5.0D, 12.0D, 10.0D), Block.a(1.0D, 5.0D, 5.0D, 7.0D, 12.0D, 11.0D), Block.a(1.0D, 3.0D, 4.0D, 9.0D, 12.0D, 12.0D)}; - protected static final VoxelShape[] o = new VoxelShape[] { Block.a(6.0D, 7.0D, 1.0D, 10.0D, 12.0D, 5.0D), Block.a(5.0D, 5.0D, 1.0D, 11.0D, 12.0D, 7.0D), Block.a(4.0D, 3.0D, 1.0D, 12.0D, 12.0D, 9.0D)}; - protected static final VoxelShape[] p = new VoxelShape[] { Block.a(6.0D, 7.0D, 11.0D, 10.0D, 12.0D, 15.0D), Block.a(5.0D, 5.0D, 9.0D, 11.0D, 12.0D, 15.0D), Block.a(4.0D, 3.0D, 7.0D, 12.0D, 12.0D, 15.0D)}; + public static final BlockStateInteger AGE = BlockProperties.Z; + protected static final VoxelShape[] b = new VoxelShape[]{Block.a(11.0D, 7.0D, 6.0D, 15.0D, 12.0D, 10.0D), Block.a(9.0D, 5.0D, 5.0D, 15.0D, 12.0D, 11.0D), Block.a(7.0D, 3.0D, 4.0D, 15.0D, 12.0D, 12.0D)}; + protected static final VoxelShape[] c = new VoxelShape[]{Block.a(1.0D, 7.0D, 6.0D, 5.0D, 12.0D, 10.0D), Block.a(1.0D, 5.0D, 5.0D, 7.0D, 12.0D, 11.0D), Block.a(1.0D, 3.0D, 4.0D, 9.0D, 12.0D, 12.0D)}; + protected static final VoxelShape[] d = new VoxelShape[]{Block.a(6.0D, 7.0D, 1.0D, 10.0D, 12.0D, 5.0D), Block.a(5.0D, 5.0D, 1.0D, 11.0D, 12.0D, 7.0D), Block.a(4.0D, 3.0D, 1.0D, 12.0D, 12.0D, 9.0D)}; + protected static final VoxelShape[] e = new VoxelShape[]{Block.a(6.0D, 7.0D, 11.0D, 10.0D, 12.0D, 15.0D), Block.a(5.0D, 5.0D, 9.0D, 11.0D, 12.0D, 15.0D), Block.a(4.0D, 3.0D, 7.0D, 12.0D, 12.0D, 15.0D)}; public BlockCocoa(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCocoa.FACING, EnumDirection.NORTH)).set(BlockCocoa.AGE, 0)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCocoa.FACING, EnumDirection.NORTH)).set(BlockCocoa.AGE, 0)); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (world.random.nextInt(Math.max(1, (int) (100.0F / world.spigotConfig.cocoaModifier) * 5)) == 0) { // Spigot int i = (Integer) iblockdata.get(BlockCocoa.AGE); @@ -29,33 +30,32 @@ public class BlockCocoa extends BlockFacingHorizontal implements IBlockFragilePl } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { Block block = iworldreader.getType(blockposition.shift((EnumDirection) iblockdata.get(BlockCocoa.FACING))).getBlock(); return block.a(TagsBlock.JUNGLE_LOGS); } - public boolean a(IBlockData iblockdata) { - return false; - } - - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { int i = (Integer) iblockdata.get(BlockCocoa.AGE); switch ((EnumDirection) iblockdata.get(BlockCocoa.FACING)) { - case SOUTH: - return BlockCocoa.p[i]; - case NORTH: - default: - return BlockCocoa.o[i]; - case WEST: - return BlockCocoa.c[i]; - case EAST: - return BlockCocoa.b[i]; + case SOUTH: + return BlockCocoa.e[i]; + case NORTH: + default: + return BlockCocoa.d[i]; + case WEST: + return BlockCocoa.c[i]; + case EAST: + return BlockCocoa.b[i]; } } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { IBlockData iblockdata = this.getBlockData(); World world = blockactioncontext.getWorld(); @@ -77,49 +77,33 @@ public class BlockCocoa extends BlockFacingHorizontal implements IBlockFragilePl return null; } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { return enumdirection == iblockdata.get(BlockCocoa.FACING) && !iblockdata.canPlace(generatoraccess, blockposition) ? Blocks.AIR.getBlockData() : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - int j = (Integer) iblockdata.get(BlockCocoa.AGE); - byte b0 = 1; - - if (j >= 2) { - b0 = 3; - } - - for (int k = 0; k < b0; ++k) { - a(world, blockposition, new ItemStack(Items.COCOA_BEANS)); - } - - } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - return new ItemStack(Items.COCOA_BEANS); - } - + @Override public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { return (Integer) iblockdata.get(BlockCocoa.AGE) < 2; } + @Override public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { return true; } + @Override public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { CraftEventFactory.handleBlockGrowEvent(world, blockposition, (IBlockData) iblockdata.set(BlockCocoa.AGE, (Integer) iblockdata.get(BlockCocoa.AGE) + 1), 2); // CraftBukkit } + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockCocoa.FACING, BlockCocoa.AGE); } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockCommand.java b/src/main/java/net/minecraft/server/BlockCommand.java index 43d78566e..e3b090898 100644 --- a/src/main/java/net/minecraft/server/BlockCommand.java +++ b/src/main/java/net/minecraft/server/BlockCommand.java @@ -8,44 +8,46 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit public class BlockCommand extends BlockTileEntity { - private static final Logger c = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public static final BlockStateDirection a = BlockDirectional.FACING; - public static final BlockStateBoolean b = BlockProperties.b; + public static final BlockStateBoolean b = BlockProperties.c; public BlockCommand(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCommand.a, EnumDirection.NORTH)).set(BlockCommand.b, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockCommand.a, EnumDirection.NORTH)).set(BlockCommand.b, false)); } - public TileEntity a(IBlockAccess iblockaccess) { + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { TileEntityCommand tileentitycommand = new TileEntityCommand(); tileentitycommand.b(this == Blocks.CHAIN_COMMAND_BLOCK); return tileentitycommand; } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if (!world.isClientSide) { TileEntity tileentity = world.getTileEntity(blockposition); if (tileentity instanceof TileEntityCommand) { TileEntityCommand tileentitycommand = (TileEntityCommand) tileentity; - boolean flag = world.isBlockIndirectlyPowered(blockposition); - boolean flag1 = tileentitycommand.d(); + boolean flag1 = world.isBlockIndirectlyPowered(blockposition); + boolean flag2 = tileentitycommand.f(); // CraftBukkit start - org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition); // Akarin - int old = flag1 ? 15 : 0; - int current = flag ? 15 : 0; + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + int old = flag2 ? 15 : 0; + int current = flag1 ? 15 : 0; BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, old, current); world.getServer().getPluginManager().callEvent(eventRedstone); - flag = eventRedstone.getNewCurrent() > 0; + flag1 = eventRedstone.getNewCurrent() > 0; // CraftBukkit end - tileentitycommand.a(flag); - if (!flag1 && !tileentitycommand.e() && tileentitycommand.j() != TileEntityCommand.Type.SEQUENCE) { - if (flag) { - tileentitycommand.h(); + tileentitycommand.a(flag1); + if (!flag2 && !tileentitycommand.g() && tileentitycommand.u() != TileEntityCommand.Type.SEQUENCE) { + if (flag1) { + tileentitycommand.s(); world.getBlockTickList().a(blockposition, this, this.a((IWorldReader) world)); } @@ -54,7 +56,8 @@ public class BlockCommand extends BlockTileEntity { } } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!world.isClientSide) { TileEntity tileentity = world.getTileEntity(blockposition); @@ -62,24 +65,24 @@ public class BlockCommand extends BlockTileEntity { TileEntityCommand tileentitycommand = (TileEntityCommand) tileentity; CommandBlockListenerAbstract commandblocklistenerabstract = tileentitycommand.getCommandBlock(); boolean flag = !UtilColor.b(commandblocklistenerabstract.getCommand()); - TileEntityCommand.Type tileentitycommand_type = tileentitycommand.j(); - boolean flag1 = tileentitycommand.f(); + TileEntityCommand.Type tileentitycommand_type = tileentitycommand.u(); + boolean flag1 = tileentitycommand.h(); if (tileentitycommand_type == TileEntityCommand.Type.AUTO) { - tileentitycommand.h(); + tileentitycommand.s(); if (flag1) { this.a(iblockdata, world, blockposition, commandblocklistenerabstract, flag); - } else if (tileentitycommand.k()) { + } else if (tileentitycommand.v()) { commandblocklistenerabstract.a(0); } - if (tileentitycommand.d() || tileentitycommand.e()) { + if (tileentitycommand.f() || tileentitycommand.g()) { world.getBlockTickList().a(blockposition, this, this.a((IWorldReader) world)); } } else if (tileentitycommand_type == TileEntityCommand.Type.REDSTONE) { if (flag1) { this.a(iblockdata, world, blockposition, commandblocklistenerabstract, flag); - } else if (tileentitycommand.k()) { + } else if (tileentitycommand.v()) { commandblocklistenerabstract.a(0); } } @@ -100,11 +103,13 @@ public class BlockCommand extends BlockTileEntity { a(world, blockposition, (EnumDirection) iblockdata.get(BlockCommand.a)); } + @Override public int a(IWorldReader iworldreader) { return 1; } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { TileEntity tileentity = world.getTileEntity(blockposition); if (tileentity instanceof TileEntityCommand && entityhuman.isCreativeAndOp()) { @@ -115,16 +120,19 @@ public class BlockCommand extends BlockTileEntity { } } + @Override public boolean isComplexRedstone(IBlockData iblockdata) { return true; } + @Override public int a(IBlockData iblockdata, World world, BlockPosition blockposition) { TileEntity tileentity = world.getTileEntity(blockposition); return tileentity instanceof TileEntityCommand ? ((TileEntityCommand) tileentity).getCommandBlock().i() : 0; } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { TileEntity tileentity = world.getTileEntity(blockposition); @@ -138,11 +146,11 @@ public class BlockCommand extends BlockTileEntity { if (!world.isClientSide) { if (itemstack.b("BlockEntityTag") == null) { - commandblocklistenerabstract.a(world.getGameRules().getBoolean("sendCommandFeedback")); + commandblocklistenerabstract.a(world.getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK)); tileentitycommand.b(this == Blocks.CHAIN_COMMAND_BLOCK); } - if (tileentitycommand.j() == TileEntityCommand.Type.SEQUENCE) { + if (tileentitycommand.u() == TileEntityCommand.Type.SEQUENCE) { boolean flag = world.isBlockIndirectlyPowered(blockposition); tileentitycommand.a(flag); @@ -152,26 +160,27 @@ public class BlockCommand extends BlockTileEntity { } } - public int a(IBlockData iblockdata, Random random) { - return 0; - } - + @Override public EnumRenderType c(IBlockData iblockdata) { return EnumRenderType.MODEL; } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { return (IBlockData) iblockdata.set(BlockCommand.a, enumblockrotation.a((EnumDirection) iblockdata.get(BlockCommand.a))); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockCommand.a))); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockCommand.a, BlockCommand.b); } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return (IBlockData) this.getBlockData().set(BlockCommand.a, blockactioncontext.d().opposite()); } @@ -183,7 +192,7 @@ public class BlockCommand extends BlockTileEntity { IBlockData iblockdata; int i; - for (i = gamerules.c("maxCommandChainLength"); i-- > 0; enumdirection = (EnumDirection) iblockdata.get(BlockCommand.a)) { + for (i = gamerules.getInt(GameRules.MAX_COMMAND_CHAIN_LENGTH); i-- > 0; enumdirection = (EnumDirection) iblockdata.get(BlockCommand.a)) { blockposition_mutableblockposition.c(enumdirection); iblockdata = world.getType(blockposition_mutableblockposition); Block block = iblockdata.getBlock(); @@ -200,29 +209,29 @@ public class BlockCommand extends BlockTileEntity { TileEntityCommand tileentitycommand = (TileEntityCommand) tileentity; - if (tileentitycommand.j() != TileEntityCommand.Type.SEQUENCE) { + if (tileentitycommand.u() != TileEntityCommand.Type.SEQUENCE) { break; } - if (tileentitycommand.d() || tileentitycommand.e()) { + if (tileentitycommand.f() || tileentitycommand.g()) { CommandBlockListenerAbstract commandblocklistenerabstract = tileentitycommand.getCommandBlock(); - if (tileentitycommand.h()) { + if (tileentitycommand.s()) { if (!commandblocklistenerabstract.a(world)) { break; } world.updateAdjacentComparators(blockposition_mutableblockposition, block); - } else if (tileentitycommand.k()) { + } else if (tileentitycommand.v()) { commandblocklistenerabstract.a(0); } } } if (i <= 0) { - int j = Math.max(gamerules.c("maxCommandChainLength"), 0); + int j = Math.max(gamerules.getInt(GameRules.MAX_COMMAND_CHAIN_LENGTH), 0); - BlockCommand.c.warn("Command Block chain tried to execute more than {} steps!", j); + BlockCommand.LOGGER.warn("Command Block chain tried to execute more than {} steps!", j); } } diff --git a/src/main/java/net/minecraft/server/BlockComposter.java b/src/main/java/net/minecraft/server/BlockComposter.java new file mode 100644 index 000000000..dedb706bb --- /dev/null +++ b/src/main/java/net/minecraft/server/BlockComposter.java @@ -0,0 +1,340 @@ +package net.minecraft.server; + +import it.unimi.dsi.fastutil.objects.Object2FloatMap; +import it.unimi.dsi.fastutil.objects.Object2FloatOpenHashMap; +import java.util.Random; +import javax.annotation.Nullable; +import org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder; // CraftBukkit + +public class BlockComposter extends Block implements IInventoryHolder { + + public static final BlockStateInteger a = BlockProperties.am; + public static final Object2FloatMap b = new Object2FloatOpenHashMap(); + public static final VoxelShape c = VoxelShapes.b(); + private static final VoxelShape[] d = (VoxelShape[]) SystemUtils.a((new VoxelShape[9]), (avoxelshape) -> { // CraftBukkit - decompile error + for (int i = 0; i < 8; ++i) { + avoxelshape[i] = VoxelShapes.a(BlockComposter.c, Block.a(2.0D, (double) Math.max(2, 1 + i * 2), 2.0D, 14.0D, 16.0D, 14.0D), OperatorBoolean.ONLY_FIRST); + } + + avoxelshape[8] = avoxelshape[7]; + }); + + public static void d() { + BlockComposter.b.defaultReturnValue(-1.0F); + float f = 0.3F; + float f1 = 0.5F; + float f2 = 0.65F; + float f3 = 0.85F; + float f4 = 1.0F; + + a(0.3F, Items.ah); + a(0.3F, Items.ae); + a(0.3F, Items.af); + a(0.3F, Items.aj); + a(0.3F, Items.ai); + a(0.3F, Items.ag); + a(0.3F, Items.t); + a(0.3F, Items.u); + a(0.3F, Items.v); + a(0.3F, Items.w); + a(0.3F, Items.x); + a(0.3F, Items.y); + a(0.3F, Items.BEETROOT_SEEDS); + a(0.3F, Items.DRIED_KELP); + a(0.3F, Items.ay); + a(0.3F, Items.kO); + a(0.3F, Items.MELON_SEEDS); + a(0.3F, Items.PUMPKIN_SEEDS); + a(0.3F, Items.aB); + a(0.3F, Items.SWEET_BERRIES); + a(0.3F, Items.WHEAT_SEEDS); + a(0.5F, Items.kP); + a(0.5F, Items.fp); + a(0.5F, Items.cw); + a(0.5F, Items.kN); + a(0.5F, Items.dh); + a(0.5F, Items.MELON_SLICE); + a(0.65F, Items.aC); + a(0.65F, Items.dr); + a(0.65F, Items.cF); + a(0.65F, Items.cG); + a(0.65F, Items.dg); + a(0.65F, Items.APPLE); + a(0.65F, Items.BEETROOT); + a(0.65F, Items.CARROT); + a(0.65F, Items.COCOA_BEANS); + a(0.65F, Items.POTATO); + a(0.65F, Items.WHEAT); + a(0.65F, Items.bh); + a(0.65F, Items.bi); + a(0.65F, Items.dd); + a(0.65F, Items.aU); + a(0.65F, Items.aV); + a(0.65F, Items.aW); + a(0.65F, Items.aX); + a(0.65F, Items.aY); + a(0.65F, Items.aZ); + a(0.65F, Items.ba); + a(0.65F, Items.bb); + a(0.65F, Items.bc); + a(0.65F, Items.bd); + a(0.65F, Items.be); + a(0.65F, Items.bf); + a(0.65F, Items.bg); + a(0.65F, Items.az); + a(0.65F, Items.fl); + a(0.65F, Items.fm); + a(0.65F, Items.fn); + a(0.65F, Items.fo); + a(0.65F, Items.fq); + a(0.85F, Items.eN); + a(0.85F, Items.db); + a(0.85F, Items.dc); + a(0.85F, Items.BREAD); + a(0.85F, Items.BAKED_POTATO); + a(0.85F, Items.COOKIE); + a(1.0F, Items.lD); + a(1.0F, Items.PUMPKIN_PIE); + } + + private static void a(float f, IMaterial imaterial) { + BlockComposter.b.put(imaterial.getItem(), f); + } + + public BlockComposter(Block.Info block_info) { + super(block_info); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockComposter.a, 0)); + } + + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return BlockComposter.d[(Integer) iblockdata.get(BlockComposter.a)]; + } + + @Override + public VoxelShape i(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return BlockComposter.c; + } + + @Override + public VoxelShape b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return BlockComposter.d[0]; + } + + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { + if ((Integer) iblockdata.get(BlockComposter.a) == 7) { + world.getBlockTickList().a(blockposition, iblockdata.getBlock(), 20); + } + + } + + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { + int i = (Integer) iblockdata.get(BlockComposter.a); + ItemStack itemstack = entityhuman.b(enumhand); + + if (i < 8 && BlockComposter.b.containsKey(itemstack.getItem())) { + if (i < 7 && !world.isClientSide) { + boolean flag = b(iblockdata, (GeneratorAccess) world, blockposition, itemstack); + + world.triggerEffect(1500, blockposition, flag ? 1 : 0); + if (!entityhuman.abilities.canInstantlyBuild) { + itemstack.subtract(1); + } + } + + return true; + } else if (i == 8) { + if (!world.isClientSide) { + float f = 0.7F; + double d0 = (double) (world.random.nextFloat() * 0.7F) + 0.15000000596046448D; + double d1 = (double) (world.random.nextFloat() * 0.7F) + 0.06000000238418579D + 0.6D; + double d2 = (double) (world.random.nextFloat() * 0.7F) + 0.15000000596046448D; + EntityItem entityitem = new EntityItem(world, (double) blockposition.getX() + d0, (double) blockposition.getY() + d1, (double) blockposition.getZ() + d2, new ItemStack(Items.BONE_MEAL)); + + entityitem.defaultPickupDelay(); + world.addEntity(entityitem); + } + + d(iblockdata, (GeneratorAccess) world, blockposition); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_COMPOSTER_EMPTY, SoundCategory.BLOCKS, 1.0F, 1.0F); + return true; + } else { + return false; + } + } + + private static void d(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition) { + generatoraccess.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockComposter.a, 0), 3); + } + + private static boolean b(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition, ItemStack itemstack) { + int i = (Integer) iblockdata.get(BlockComposter.a); + float f = BlockComposter.b.getFloat(itemstack.getItem()); + + if ((i != 0 || f <= 0.0F) && generatoraccess.getRandom().nextDouble() >= (double) f) { + return false; + } else { + int j = i + 1; + + generatoraccess.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockComposter.a, j), 3); + if (j == 7) { + generatoraccess.getBlockTickList().a(blockposition, iblockdata.getBlock(), 20); + } + + return true; + } + } + + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + if ((Integer) iblockdata.get(BlockComposter.a) == 7) { + world.setTypeAndData(blockposition, (IBlockData) iblockdata.a((IBlockState) BlockComposter.a), 3); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_COMPOSTER_READY, SoundCategory.BLOCKS, 1.0F, 1.0F); + } + + super.tick(iblockdata, world, blockposition, random); + } + + @Override + public boolean isComplexRedstone(IBlockData iblockdata) { + return true; + } + + @Override + public int a(IBlockData iblockdata, World world, BlockPosition blockposition) { + return (Integer) iblockdata.get(BlockComposter.a); + } + + @Override + protected void a(BlockStateList.a blockstatelist_a) { + blockstatelist_a.a(BlockComposter.a); + } + + @Override + public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { + return false; + } + + @Override + public IWorldInventory a(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition) { + int i = (Integer) iblockdata.get(BlockComposter.a); + + // CraftBukkit - empty generatoraccess, blockposition + return (IWorldInventory) (i == 8 ? new BlockComposter.ContainerOutput(iblockdata, generatoraccess, blockposition, new ItemStack(Items.BONE_MEAL)) : (i < 7 ? new BlockComposter.ContainerInput(iblockdata, generatoraccess, blockposition) : new BlockComposter.ContainerEmpty(generatoraccess, blockposition))); + } + + static class ContainerInput extends InventorySubcontainer implements IWorldInventory { + + private final IBlockData a; + private final GeneratorAccess b; + private final BlockPosition c; + private boolean d; + + public ContainerInput(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition) { + super(1); + this.bukkitOwner = new CraftBlockInventoryHolder(generatoraccess, blockposition, this); // CraftBukkit + this.a = iblockdata; + this.b = generatoraccess; + this.c = blockposition; + } + + @Override + public int getMaxStackSize() { + return 1; + } + + @Override + public int[] getSlotsForFace(EnumDirection enumdirection) { + return enumdirection == EnumDirection.UP ? new int[]{0} : new int[0]; + } + + @Override + public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, @Nullable EnumDirection enumdirection) { + return !this.d && enumdirection == EnumDirection.UP && BlockComposter.b.containsKey(itemstack.getItem()); + } + + @Override + public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { + return false; + } + + @Override + public void update() { + ItemStack itemstack = this.getItem(0); + + if (!itemstack.isEmpty()) { + this.d = true; + BlockComposter.b(this.a, this.b, this.c, itemstack); + this.splitWithoutUpdate(0); + } + + } + } + + static class ContainerOutput extends InventorySubcontainer implements IWorldInventory { + + private final IBlockData a; + private final GeneratorAccess b; + private final BlockPosition c; + private boolean d; + + public ContainerOutput(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition, ItemStack itemstack) { + super(itemstack); + this.a = iblockdata; + this.b = generatoraccess; + this.c = blockposition; + this.bukkitOwner = new CraftBlockInventoryHolder(generatoraccess, blockposition, this); // CraftBukkit + } + + @Override + public int getMaxStackSize() { + return 1; + } + + @Override + public int[] getSlotsForFace(EnumDirection enumdirection) { + return enumdirection == EnumDirection.DOWN ? new int[]{0} : new int[0]; + } + + @Override + public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, @Nullable EnumDirection enumdirection) { + return false; + } + + @Override + public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { + return !this.d && enumdirection == EnumDirection.DOWN && itemstack.getItem() == Items.BONE_MEAL; + } + + @Override + public void update() { + BlockComposter.d(this.a, this.b, this.c); + this.d = true; + } + } + + static class ContainerEmpty extends InventorySubcontainer implements IWorldInventory { + + public ContainerEmpty(GeneratorAccess generatoraccess, BlockPosition blockposition) { // CraftBukkit + super(0); + this.bukkitOwner = new CraftBlockInventoryHolder(generatoraccess, blockposition, this); // CraftBukkit + } + + @Override + public int[] getSlotsForFace(EnumDirection enumdirection) { + return new int[0]; + } + + @Override + public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, @Nullable EnumDirection enumdirection) { + return false; + } + + @Override + public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { + return false; + } + } +} diff --git a/src/main/java/net/minecraft/server/BlockConcretePowder.java b/src/main/java/net/minecraft/server/BlockConcretePowder.java index b071ca114..618a358aa 100644 --- a/src/main/java/net/minecraft/server/BlockConcretePowder.java +++ b/src/main/java/net/minecraft/server/BlockConcretePowder.java @@ -14,19 +14,21 @@ public class BlockConcretePowder extends BlockFalling { this.a = block.getBlockData(); } + @Override public void a(World world, BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) { - if (x(iblockdata1)) { + if (canHarden(iblockdata1)) { org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, blockposition, this.a, 3); // CraftBukkit } } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { World world = blockactioncontext.getWorld(); BlockPosition blockposition = blockactioncontext.getClickPosition(); // CraftBukkit start - if (!x(world.getType(blockposition)) && !a((IBlockAccess) world, blockposition)) { + if (!canHarden(world.getType(blockposition)) && !a((IBlockAccess) world, blockposition)) { return super.getPlacedState(blockactioncontext); } @@ -55,10 +57,10 @@ public class BlockConcretePowder extends BlockFalling { EnumDirection enumdirection = aenumdirection[j]; IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); - if (enumdirection != EnumDirection.DOWN || x(iblockdata)) { + if (enumdirection != EnumDirection.DOWN || canHarden(iblockdata)) { blockposition_mutableblockposition.g(blockposition).c(enumdirection); iblockdata = iblockaccess.getType(blockposition_mutableblockposition); - if (x(iblockdata) && !Block.a(iblockdata.getCollisionShape(iblockaccess, blockposition), enumdirection.opposite())) { + if (canHarden(iblockdata) && !iblockdata.d(iblockaccess, blockposition, enumdirection.opposite())) { flag = true; break; } @@ -68,10 +70,11 @@ public class BlockConcretePowder extends BlockFalling { return flag; } - private static boolean x(IBlockData iblockdata) { - return iblockdata.s().a(TagsFluid.WATER); + private static boolean canHarden(IBlockData iblockdata) { + return iblockdata.p().a(TagsFluid.WATER); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { // CraftBukkit start if (a((IBlockAccess) generatoraccess, blockposition)) { diff --git a/src/main/java/net/minecraft/server/BlockCoral.java b/src/main/java/net/minecraft/server/BlockCoral.java index 66ce0a4d9..5f35ec2a0 100644 --- a/src/main/java/net/minecraft/server/BlockCoral.java +++ b/src/main/java/net/minecraft/server/BlockCoral.java @@ -12,7 +12,8 @@ public class BlockCoral extends Block { this.a = block; } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!this.a((IBlockAccess) world, blockposition)) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, blockposition, this.a.getBlockData()).isCancelled()) { @@ -24,9 +25,10 @@ public class BlockCoral extends Block { } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (!this.a((IBlockAccess) generatoraccess, blockposition)) { - generatoraccess.getBlockTickList().a(blockposition, this, 60 + generatoraccess.m().nextInt(40)); + generatoraccess.getBlockTickList().a(blockposition, this, 60 + generatoraccess.getRandom().nextInt(40)); } return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); @@ -49,19 +51,12 @@ public class BlockCoral extends Block { } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { if (!this.a((IBlockAccess) blockactioncontext.getWorld(), blockactioncontext.getClickPosition())) { - blockactioncontext.getWorld().getBlockTickList().a(blockactioncontext.getClickPosition(), this, 60 + blockactioncontext.getWorld().m().nextInt(40)); + blockactioncontext.getWorld().getBlockTickList().a(blockactioncontext.getClickPosition(), this, 60 + blockactioncontext.getWorld().getRandom().nextInt(40)); } return this.getBlockData(); } - - protected boolean X_() { - return true; - } - - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return this.a; - } } diff --git a/src/main/java/net/minecraft/server/BlockCoralFan.java b/src/main/java/net/minecraft/server/BlockCoralFan.java index 6d0c68319..df80a7bba 100644 --- a/src/main/java/net/minecraft/server/BlockCoralFan.java +++ b/src/main/java/net/minecraft/server/BlockCoralFan.java @@ -11,11 +11,13 @@ public class BlockCoralFan extends BlockCoralFanAbstract { this.a = block; } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { this.a(iblockdata, (GeneratorAccess) world, blockposition); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!b_(iblockdata, world, blockposition)) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, blockposition, this.a.getBlockData().set(BlockCoralFan.b, false)).isCancelled()) { @@ -27,6 +29,7 @@ public class BlockCoralFan extends BlockCoralFanAbstract { } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (enumdirection == EnumDirection.DOWN && !iblockdata.canPlace(generatoraccess, blockposition)) { return Blocks.AIR.getBlockData(); diff --git a/src/main/java/net/minecraft/server/BlockCoralFanWall.java b/src/main/java/net/minecraft/server/BlockCoralFanWall.java index 997746ec8..52b88bde9 100644 --- a/src/main/java/net/minecraft/server/BlockCoralFanWall.java +++ b/src/main/java/net/minecraft/server/BlockCoralFanWall.java @@ -11,11 +11,13 @@ public class BlockCoralFanWall extends BlockCoralFanWallAbstract { this.c = block; } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { this.a(iblockdata, (GeneratorAccess) world, blockposition); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!b_(iblockdata, world, blockposition)) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, blockposition, this.c.getBlockData().set(BlockCoralFanWall.b, false).set(BlockCoralFanWall.a, iblockdata.get(BlockCoralFanWall.a))).isCancelled()) { @@ -27,6 +29,7 @@ public class BlockCoralFanWall extends BlockCoralFanWallAbstract { } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (enumdirection.opposite() == iblockdata.get(BlockCoralFanWall.a) && !iblockdata.canPlace(generatoraccess, blockposition)) { return Blocks.AIR.getBlockData(); diff --git a/src/main/java/net/minecraft/server/BlockCoralPlant.java b/src/main/java/net/minecraft/server/BlockCoralPlant.java index 1e6d83988..660950285 100644 --- a/src/main/java/net/minecraft/server/BlockCoralPlant.java +++ b/src/main/java/net/minecraft/server/BlockCoralPlant.java @@ -12,11 +12,13 @@ public class BlockCoralPlant extends BlockCoralBase { this.c = block; } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { this.a(iblockdata, (GeneratorAccess) world, blockposition); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!b_(iblockdata, world, blockposition)) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, blockposition, this.c.getBlockData().set(BlockCoralPlant.b, false)).isCancelled()) { @@ -28,6 +30,7 @@ public class BlockCoralPlant extends BlockCoralBase { } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (enumdirection == EnumDirection.DOWN && !iblockdata.canPlace(generatoraccess, blockposition)) { return Blocks.AIR.getBlockData(); @@ -41,7 +44,8 @@ public class BlockCoralPlant extends BlockCoralBase { } } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockCoralPlant.a; } } diff --git a/src/main/java/net/minecraft/server/BlockCrops.java b/src/main/java/net/minecraft/server/BlockCrops.java index 9d53f1118..e042612f5 100644 --- a/src/main/java/net/minecraft/server/BlockCrops.java +++ b/src/main/java/net/minecraft/server/BlockCrops.java @@ -6,19 +6,21 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement { - public static final BlockStateInteger AGE = BlockProperties.W; - private static final VoxelShape[] a = new VoxelShape[] { Block.a(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 4.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 6.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 10.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 12.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 14.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D)}; + public static final BlockStateInteger AGE = BlockProperties.ac; + private static final VoxelShape[] a = new VoxelShape[]{Block.a(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 4.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 6.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 10.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 12.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 14.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D)}; protected BlockCrops(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(this.d(), 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(this.d(), 0)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockCrops.a[(Integer) iblockdata.get(this.d())]; } - protected boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + protected boolean a_(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return iblockdata.getBlock() == Blocks.FARMLAND; } @@ -30,7 +32,7 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement return 7; } - protected int k(IBlockData iblockdata) { + protected int j(IBlockData iblockdata) { return (Integer) iblockdata.get(this.d()); } @@ -38,14 +40,15 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement return (IBlockData) this.getBlockData().set(this.d(), i); } - public boolean w(IBlockData iblockdata) { + public boolean isRipe(IBlockData iblockdata) { return (Integer) iblockdata.get(this.d()) >= this.e(); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { - super.a(iblockdata, world, blockposition, random); - if (world.isLightLevel(blockposition.up(), 9)) { // Paper - int i = this.k(iblockdata); + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + super.tick(iblockdata, world, blockposition, random); + if (world.getLightLevel(blockposition, 0) >= 9) { + int i = this.j(iblockdata); if (i < this.e()) { float f = a((Block) this, (IBlockAccess) world, blockposition); @@ -72,7 +75,7 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement } public void a(World world, BlockPosition blockposition, IBlockData iblockdata) { - int i = this.k(iblockdata) + this.a(world); + int i = this.j(iblockdata) + this.a(world); int j = this.e(); if (i > j) { @@ -93,7 +96,7 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement for (int i = -1; i <= 1; ++i) { for (int j = -1; j <= 1; ++j) { float f1 = 0.0F; - IBlockData iblockdata = iblockaccess.getType(blockposition1.a(i, 0, j)); + IBlockData iblockdata = iblockaccess.getType(blockposition1.b(i, 0, j)); if (iblockdata.getBlock() == Blocks.FARMLAND) { f1 = 1.0F; @@ -130,56 +133,36 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement return f; } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { - return (iworldreader.getLightLevel(blockposition, 0) >= 8 || iworldreader.e(blockposition)) && super.canPlace(iblockdata, iworldreader, blockposition); + return (iworldreader.getLightLevel(blockposition, 0) >= 8 || iworldreader.f(blockposition)) && super.canPlace(iblockdata, iworldreader, blockposition); } - protected IMaterial f() { - return Items.WHEAT_SEEDS; - } - - protected IMaterial g() { - return Items.WHEAT; - } - - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - super.dropNaturally(iblockdata, world, blockposition, f, 0); - if (!world.isClientSide) { - int j = this.k(iblockdata); - - if (j >= this.e()) { - int k = 3 + i; - - for (int l = 0; l < k; ++l) { - if (world.random.nextInt(2 * this.e()) <= j) { - a(world, blockposition, new ItemStack(this.f())); - } - } - } - + @Override + public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { + if (entity instanceof EntityRavager && !CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition, Blocks.AIR.getBlockData(), !world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)).isCancelled()) { // CraftBukkit + world.b(blockposition, true); } + + super.a(iblockdata, world, blockposition, entity); } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return this.w(iblockdata) ? this.g() : this.f(); - } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - return new ItemStack(this.f()); - } - + @Override public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { - return !this.w(iblockdata); + return !this.isRipe(iblockdata); } + @Override public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { return true; } + @Override public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { this.a(world, blockposition, iblockdata); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockCrops.AGE); } diff --git a/src/main/java/net/minecraft/server/BlockData.java b/src/main/java/net/minecraft/server/BlockData.java deleted file mode 100644 index 1b226a77e..000000000 --- a/src/main/java/net/minecraft/server/BlockData.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.ImmutableMap; -import org.bukkit.craftbukkit.block.data.CraftBlockData; - -public class BlockData extends BlockDataAbstract implements IBlockData { - - public BlockData(Block block, ImmutableMap, Comparable> immutablemap) { - super(block, immutablemap); - } - - public Block getBlock() { - return (Block) this.e_; - } - - // Paper start - impl cached craft block data, lazy load to fix issue with loading at the wrong time - private CraftBlockData cachedCraftBlockData; - - @Override - public CraftBlockData createCraftBlockData() { - if(cachedCraftBlockData == null) cachedCraftBlockData = CraftBlockData.createData(this); - return (CraftBlockData) cachedCraftBlockData.clone(); - } - // Paper end -} diff --git a/src/main/java/net/minecraft/server/BlockDataAbstract.java b/src/main/java/net/minecraft/server/BlockDataAbstract.java new file mode 100644 index 000000000..b3fe95d85 --- /dev/null +++ b/src/main/java/net/minecraft/server/BlockDataAbstract.java @@ -0,0 +1,162 @@ +package net.minecraft.server; + +import com.google.common.collect.ArrayTable; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.common.collect.Table; +import com.google.common.collect.UnmodifiableIterator; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.annotation.Nullable; + +public abstract class BlockDataAbstract implements IBlockDataHolder { + + public static final Function, Comparable>, String> STATE_TO_VALUE = new Function, Comparable>, String>() { + public String apply(@Nullable Entry, Comparable> entry) { + if (entry == null) { + return ""; + } else { + IBlockState iblockstate = (IBlockState) entry.getKey(); + + return iblockstate.a() + "=" + this.a(iblockstate, (Comparable) entry.getValue()); + } + } + + private > String a(IBlockState iblockstate, Comparable comparable) { + return iblockstate.a((T) comparable); // Paper - decompiler fix + } + }; + protected final O a; + private final ImmutableMap, Comparable> d; + private final int e; + private Table, Comparable, S> f; + + protected BlockDataAbstract(O o0, ImmutableMap, Comparable> immutablemap) { + this.a = o0; + this.d = immutablemap; + this.e = immutablemap.hashCode(); + } + + public > S a(IBlockState iblockstate) { + return this.set(iblockstate, a(iblockstate.getValues(), this.get(iblockstate))); // Paper - decompile fix + } + + protected static T a(Collection collection, T t0) { + Iterator iterator = collection.iterator(); // Paper - decompiler fix + + do { + if (!iterator.hasNext()) { + return iterator.next(); + } + } while (!iterator.next().equals(t0)); + + if (iterator.hasNext()) { + return iterator.next(); + } else { + return collection.iterator().next(); + } + } + + public String toString() { + StringBuilder stringbuilder = new StringBuilder(); + + stringbuilder.append(this.a); + if (!this.getStateMap().isEmpty()) { + stringbuilder.append('['); + stringbuilder.append((String) this.getStateMap().entrySet().stream().map(BlockDataAbstract.STATE_TO_VALUE).collect(Collectors.joining(","))); + stringbuilder.append(']'); + } + + return stringbuilder.toString(); + } + + public Collection> a() { + return Collections.unmodifiableCollection(this.d.keySet()); + } + + public final > boolean hasProperty(IBlockState iblockstate) { return this.b(iblockstate); } // Paper - OBFHELPER + public > boolean b(IBlockState iblockstate) { + return this.d.containsKey(iblockstate); + } + + @Override + public > T get(IBlockState iblockstate) { + Comparable comparable = (Comparable) this.d.get(iblockstate); + + if (comparable == null) { + throw new IllegalArgumentException("Cannot get property " + iblockstate + " as it does not exist in " + this.a); + } else { + return iblockstate.b().cast(comparable); // Paper - decompiler fix + } + } + + @Override + public , V extends T> S set(IBlockState iblockstate, V v0) { + Comparable comparable = (Comparable) this.d.get(iblockstate); + + if (comparable == null) { + throw new IllegalArgumentException("Cannot set property " + iblockstate + " as it does not exist in " + this.a); + } else if (comparable == v0) { + return (S) this; // Paper - decompiler fix + } else { + S s0 = this.f.get(iblockstate, v0); + + if (s0 == null) { + throw new IllegalArgumentException("Cannot set property " + iblockstate + " to " + v0 + " on " + this.a + ", it is not an allowed value"); + } else { + return s0; + } + } + } + + public void a(Map, Comparable>, S> map) { + if (this.f != null) { + throw new IllegalStateException(); + } else { + Table, Comparable, S> table = HashBasedTable.create(); + UnmodifiableIterator unmodifiableiterator = this.d.entrySet().iterator(); + + while (unmodifiableiterator.hasNext()) { + Entry, Comparable> entry = (Entry) unmodifiableiterator.next(); + IBlockState iblockstate = (IBlockState) entry.getKey(); + Iterator iterator = iblockstate.getValues().iterator(); + + while (iterator.hasNext()) { + Comparable comparable = (Comparable) iterator.next(); + + if (comparable != entry.getValue()) { + table.put(iblockstate, comparable, map.get(this.c(iblockstate, comparable))); + } + } + } + + this.f = (Table) (table.isEmpty() ? table : ArrayTable.create(table)); + } + } + + private Map, Comparable> c(IBlockState iblockstate, Comparable comparable) { + Map, Comparable> map = Maps.newHashMap(this.d); + + map.put(iblockstate, comparable); + return map; + } + + @Override + public ImmutableMap, Comparable> getStateMap() { + return this.d; + } + + public boolean equals(Object object) { + return this == object; + } + + public int hashCode() { + return this.e; + } +} diff --git a/src/main/java/net/minecraft/server/BlockDaylightDetector.java b/src/main/java/net/minecraft/server/BlockDaylightDetector.java index cf12f96fb..783ae1d2b 100644 --- a/src/main/java/net/minecraft/server/BlockDaylightDetector.java +++ b/src/main/java/net/minecraft/server/BlockDaylightDetector.java @@ -2,27 +2,34 @@ package net.minecraft.server; public class BlockDaylightDetector extends BlockTileEntity { - public static final BlockStateInteger POWER = BlockProperties.al; - public static final BlockStateBoolean b = BlockProperties.m; + public static final BlockStateInteger POWER = BlockProperties.as; + public static final BlockStateBoolean b = BlockProperties.p; protected static final VoxelShape c = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 6.0D, 16.0D); public BlockDaylightDetector(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockDaylightDetector.POWER, 0)).set(BlockDaylightDetector.b, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockDaylightDetector.POWER, 0)).set(BlockDaylightDetector.b, false)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockDaylightDetector.c; } + @Override + public boolean n(IBlockData iblockdata) { + return true; + } + + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return (Integer) iblockdata.get(BlockDaylightDetector.POWER); } - public static void b(IBlockData iblockdata, World world, BlockPosition blockposition) { + public static void d(IBlockData iblockdata, World world, BlockPosition blockposition) { if (world.worldProvider.g()) { int i = world.getBrightness(EnumSkyBlock.SKY, blockposition) - world.c(); - float f = world.c(1.0F); + float f = world.b(1.0F); boolean flag = (Boolean) iblockdata.get(BlockDaylightDetector.b); if (flag) { @@ -43,43 +50,40 @@ public class BlockDaylightDetector extends BlockTileEntity { } } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { - if (entityhuman.dy()) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { + if (entityhuman.dQ()) { if (world.isClientSide) { return true; } else { IBlockData iblockdata1 = (IBlockData) iblockdata.a((IBlockState) BlockDaylightDetector.b); world.setTypeAndData(blockposition, iblockdata1, 4); - b(iblockdata1, world, blockposition); + d(iblockdata1, world, blockposition); return true; } } else { - return super.interact(iblockdata, world, blockposition, entityhuman, enumhand, enumdirection, f, f1, f2); + return super.interact(iblockdata, world, blockposition, entityhuman, enumhand, movingobjectpositionblock); } } - public boolean a(IBlockData iblockdata) { - return false; - } - + @Override public EnumRenderType c(IBlockData iblockdata) { return EnumRenderType.MODEL; } + @Override public boolean isPowerSource(IBlockData iblockdata) { return true; } - public TileEntity a(IBlockAccess iblockaccess) { + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { return new TileEntityLightDetector(); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockDaylightDetector.POWER, BlockDaylightDetector.b); } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return enumdirection == EnumDirection.DOWN ? EnumBlockFaceShape.SOLID : EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockDiodeAbstract.java b/src/main/java/net/minecraft/server/BlockDiodeAbstract.java index b09e9fe3a..d7e0684ca 100644 --- a/src/main/java/net/minecraft/server/BlockDiodeAbstract.java +++ b/src/main/java/net/minecraft/server/BlockDiodeAbstract.java @@ -7,25 +7,24 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public abstract class BlockDiodeAbstract extends BlockFacingHorizontal { protected static final VoxelShape b = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D); - public static final BlockStateBoolean c = BlockProperties.t; + public static final BlockStateBoolean c = BlockProperties.w; protected BlockDiodeAbstract(Block.Info block_info) { super(block_info); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockDiodeAbstract.b; } - public boolean a(IBlockData iblockdata) { - return false; - } - + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { - return iworldreader.getType(blockposition.down()).q(); + return c((IBlockAccess) iworldreader, blockposition.down()); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!this.a((IWorldReader) world, blockposition, iblockdata)) { boolean flag = (Boolean) iblockdata.get(BlockDiodeAbstract.c); boolean flag1 = this.a(world, blockposition, iblockdata); @@ -45,27 +44,32 @@ public abstract class BlockDiodeAbstract extends BlockFacingHorizontal { // CraftBukkit end world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockDiodeAbstract.c, true), 2); if (!flag1) { - world.getBlockTickList().a(blockposition, this, this.k(iblockdata), TickListPriority.HIGH); + world.getBlockTickList().a(blockposition, this, this.j(iblockdata), TickListPriority.HIGH); } } } } + @Override public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - return iblockdata.a(iblockaccess, blockposition, enumdirection); + return iblockdata.b(iblockaccess, blockposition, enumdirection); } + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return !(Boolean) iblockdata.get(BlockDiodeAbstract.c) ? 0 : (iblockdata.get(BlockDiodeAbstract.FACING) == enumdirection ? this.b(iblockaccess, blockposition, iblockdata) : 0); } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if (iblockdata.canPlace(world, blockposition)) { this.c(world, blockposition, iblockdata); } else { - iblockdata.a(world, blockposition, 0); - world.setAir(blockposition); + TileEntity tileentity = this.isTileEntity() ? world.getTileEntity(blockposition) : null; + + a(iblockdata, world, blockposition, tileentity); + world.a(blockposition, false); EnumDirection[] aenumdirection = EnumDirection.values(); int i = aenumdirection.length; @@ -92,7 +96,7 @@ public abstract class BlockDiodeAbstract extends BlockFacingHorizontal { ticklistpriority = TickListPriority.VERY_HIGH; } - world.getBlockTickList().a(blockposition, this, this.k(iblockdata), ticklistpriority); + world.getBlockTickList().a(blockposition, this, this.j(iblockdata), ticklistpriority); } } @@ -125,24 +129,27 @@ public abstract class BlockDiodeAbstract extends BlockFacingHorizontal { EnumDirection enumdirection1 = enumdirection.e(); EnumDirection enumdirection2 = enumdirection.f(); - return Math.max(this.a(iworldreader, blockposition.shift(enumdirection1), enumdirection1), this.a(iworldreader, blockposition.shift(enumdirection2), enumdirection2)); + return Math.max(this.b(iworldreader, blockposition.shift(enumdirection1), enumdirection1), this.b(iworldreader, blockposition.shift(enumdirection2), enumdirection2)); } - protected int a(IWorldReader iworldreader, BlockPosition blockposition, EnumDirection enumdirection) { + protected int b(IWorldReader iworldreader, BlockPosition blockposition, EnumDirection enumdirection) { IBlockData iblockdata = iworldreader.getType(blockposition); Block block = iblockdata.getBlock(); - return this.w(iblockdata) ? (block == Blocks.REDSTONE_BLOCK ? 15 : (block == Blocks.REDSTONE_WIRE ? (Integer) iblockdata.get(BlockRedstoneWire.POWER) : iworldreader.a(blockposition, enumdirection))) : 0; + return this.q(iblockdata) ? (block == Blocks.REDSTONE_BLOCK ? 15 : (block == Blocks.REDSTONE_WIRE ? (Integer) iblockdata.get(BlockRedstoneWire.POWER) : iworldreader.c(blockposition, enumdirection))) : 0; } + @Override public boolean isPowerSource(IBlockData iblockdata) { return true; } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return (IBlockData) this.getBlockData().set(BlockDiodeAbstract.FACING, blockactioncontext.f().opposite()); } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { if (this.a(world, blockposition, iblockdata)) { world.getBlockTickList().a(blockposition, this, 1); @@ -150,20 +157,19 @@ public abstract class BlockDiodeAbstract extends BlockFacingHorizontal { } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { this.d(world, blockposition, iblockdata); } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (!flag && iblockdata.getBlock() != iblockdata1.getBlock()) { super.remove(iblockdata, world, blockposition, iblockdata1, flag); - this.a(world, blockposition); this.d(world, blockposition, iblockdata); } } - protected void a(World world, BlockPosition blockposition) {} - protected void d(World world, BlockPosition blockposition, IBlockData iblockdata) { EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockDiodeAbstract.FACING); BlockPosition blockposition1 = blockposition.shift(enumdirection.opposite()); @@ -172,7 +178,7 @@ public abstract class BlockDiodeAbstract extends BlockFacingHorizontal { world.a(blockposition1, (Block) this, enumdirection); } - protected boolean w(IBlockData iblockdata) { + protected boolean q(IBlockData iblockdata) { return iblockdata.isPowerSource(); } @@ -191,17 +197,15 @@ public abstract class BlockDiodeAbstract extends BlockFacingHorizontal { return isDiode(iblockdata1) && iblockdata1.get(BlockDiodeAbstract.FACING) != enumdirection; } - protected abstract int k(IBlockData iblockdata); + protected abstract int j(IBlockData iblockdata); + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override public boolean f(IBlockData iblockdata) { return true; } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return enumdirection == EnumDirection.DOWN ? EnumBlockFaceShape.SOLID : EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockDirtSnowSpreadable.java b/src/main/java/net/minecraft/server/BlockDirtSnowSpreadable.java index f1174825c..cb90b74ca 100644 --- a/src/main/java/net/minecraft/server/BlockDirtSnowSpreadable.java +++ b/src/main/java/net/minecraft/server/BlockDirtSnowSpreadable.java @@ -8,22 +8,30 @@ public abstract class BlockDirtSnowSpreadable extends BlockDirtSnow { super(block_info); } - private static boolean a(IWorldReader iworldreader, BlockPosition blockposition) { + private static boolean b(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { BlockPosition blockposition1 = blockposition.up(); + IBlockData iblockdata1 = iworldreader.getType(blockposition1); - return iworldreader.getLightLevel(blockposition1) >= 4 || iworldreader.getType(blockposition1).b(iworldreader, blockposition1) < iworldreader.K(); + if (iblockdata1.getBlock() == Blocks.SNOW && (Integer) iblockdata1.get(BlockSnow.LAYERS) == 1) { + return true; + } else { + int i = LightEngineLayer.a(iworldreader, iblockdata, blockposition, iblockdata1, blockposition1, EnumDirection.UP, iblockdata1.b((IBlockAccess) iworldreader, blockposition1)); + + return i < iworldreader.H(); + } } - private static boolean b(IWorldReader iworldreader, BlockPosition blockposition) { + private static boolean c(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { BlockPosition blockposition1 = blockposition.up(); - return iworldreader.getLightLevel(blockposition1) >= 4 && iworldreader.getType(blockposition1).b(iworldreader, blockposition1) < iworldreader.K() && !iworldreader.getFluid(blockposition1).a(TagsFluid.WATER); + return b(iblockdata, iworldreader, blockposition) && !iworldreader.getFluid(blockposition1).a(TagsFluid.WATER); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (this instanceof BlockGrass && world.paperConfig.grassUpdateRate != 1 && (world.paperConfig.grassUpdateRate < 1 || (MinecraftServer.currentTick + blockposition.hashCode()) % world.paperConfig.grassUpdateRate != 0)) { return; } // Paper if (!world.isClientSide) { - if (!a((IWorldReader) world, blockposition)) { + if (!b(iblockdata, (IWorldReader) world, blockposition)) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, blockposition, Blocks.DIRT.getBlockData()).isCancelled()) { return; @@ -32,15 +40,13 @@ public abstract class BlockDirtSnowSpreadable extends BlockDirtSnow { world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); } else { if (world.getLightLevel(blockposition.up()) >= 9) { + IBlockData iblockdata1 = this.getBlockData(); + for (int i = 0; i < 4; ++i) { - BlockPosition blockposition1 = blockposition.a(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1); + BlockPosition blockposition1 = blockposition.b(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1); - if (!world.p(blockposition1)) { - return; - } - - if (world.getType(blockposition1).getBlock() == Blocks.DIRT && b(world, blockposition1)) { - org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition1, this.getBlockData()); // CraftBukkit + if (world.getType(blockposition1).getBlock() == Blocks.DIRT && c(iblockdata1, (IWorldReader) world, blockposition1)) { + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition1, (IBlockData) iblockdata1.set(BlockDirtSnowSpreadable.a, world.getType(blockposition1.up()).getBlock() == Blocks.SNOW)); // CraftBukkit } } } diff --git a/src/main/java/net/minecraft/server/BlockDispenser.java b/src/main/java/net/minecraft/server/BlockDispenser.java index a0b81abaf..88a210b1d 100644 --- a/src/main/java/net/minecraft/server/BlockDispenser.java +++ b/src/main/java/net/minecraft/server/BlockDispenser.java @@ -7,7 +7,7 @@ import java.util.Random; public class BlockDispenser extends BlockTileEntity { public static final BlockStateDirection FACING = BlockDirectional.FACING; - public static final BlockStateBoolean TRIGGERED = BlockProperties.w; + public static final BlockStateBoolean TRIGGERED = BlockProperties.A; public static final Map REGISTRY = (Map) SystemUtils.a((new Object2ObjectOpenHashMap()), (object2objectopenhashmap) -> { // CraftBukkit - decompile error object2objectopenhashmap.defaultReturnValue(new DispenseBehaviorItem()); }); @@ -19,14 +19,16 @@ public class BlockDispenser extends BlockTileEntity { protected BlockDispenser(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockDispenser.FACING, EnumDirection.NORTH)).set(BlockDispenser.TRIGGERED, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockDispenser.FACING, EnumDirection.NORTH)).set(BlockDispenser.TRIGGERED, false)); } + @Override public int a(IWorldReader iworldreader) { return 4; } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if (world.isClientSide) { return true; } else { @@ -48,7 +50,7 @@ public class BlockDispenser extends BlockTileEntity { public void dispense(World world, BlockPosition blockposition) { SourceBlock sourceblock = new SourceBlock(world, blockposition); TileEntityDispenser tileentitydispenser = (TileEntityDispenser) sourceblock.getTileEntity(); - int i = tileentitydispenser.p(); + int i = tileentitydispenser.h(); if (i < 0) { world.triggerEffect(1001, blockposition, 0); @@ -68,34 +70,39 @@ public class BlockDispenser extends BlockTileEntity { return (IDispenseBehavior) BlockDispenser.REGISTRY.get(itemstack.getItem()); } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { - boolean flag = world.isBlockIndirectlyPowered(blockposition) || world.isBlockIndirectlyPowered(blockposition.up()); - boolean flag1 = (Boolean) iblockdata.get(BlockDispenser.TRIGGERED); + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { + boolean flag1 = world.isBlockIndirectlyPowered(blockposition) || world.isBlockIndirectlyPowered(blockposition.up()); + boolean flag2 = (Boolean) iblockdata.get(BlockDispenser.TRIGGERED); - if (flag && !flag1) { + if (flag1 && !flag2) { world.getBlockTickList().a(blockposition, this, this.a((IWorldReader) world)); world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockDispenser.TRIGGERED, true), 4); - } else if (!flag && flag1) { + } else if (!flag1 && flag2) { world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockDispenser.TRIGGERED, false), 4); } } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!world.isClientSide) { this.dispense(world, blockposition); } } - public TileEntity a(IBlockAccess iblockaccess) { + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { return new TileEntityDispenser(); } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return (IBlockData) this.getBlockData().set(BlockDispenser.FACING, blockactioncontext.d().opposite()); } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { if (itemstack.hasName()) { TileEntity tileentity = world.getTileEntity(blockposition); @@ -107,6 +114,7 @@ public class BlockDispenser extends BlockTileEntity { } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata.getBlock() != iblockdata1.getBlock()) { TileEntity tileentity = world.getTileEntity(blockposition); @@ -121,7 +129,7 @@ public class BlockDispenser extends BlockTileEntity { } public static IPosition a(ISourceBlock isourceblock) { - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); double d0 = isourceblock.getX() + 0.7D * (double) enumdirection.getAdjacentX(); double d1 = isourceblock.getY() + 0.7D * (double) enumdirection.getAdjacentY(); double d2 = isourceblock.getZ() + 0.7D * (double) enumdirection.getAdjacentZ(); @@ -129,26 +137,32 @@ public class BlockDispenser extends BlockTileEntity { return new Position(d0, d1, d2); } + @Override public boolean isComplexRedstone(IBlockData iblockdata) { return true; } + @Override public int a(IBlockData iblockdata, World world, BlockPosition blockposition) { return Container.a(world.getTileEntity(blockposition)); } + @Override public EnumRenderType c(IBlockData iblockdata) { return EnumRenderType.MODEL; } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { return (IBlockData) iblockdata.set(BlockDispenser.FACING, enumblockrotation.a((EnumDirection) iblockdata.get(BlockDispenser.FACING))); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockDispenser.FACING))); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockDispenser.FACING, BlockDispenser.TRIGGERED); } diff --git a/src/main/java/net/minecraft/server/BlockDoor.java b/src/main/java/net/minecraft/server/BlockDoor.java index 1b35ddb49..a1a25771b 100644 --- a/src/main/java/net/minecraft/server/BlockDoor.java +++ b/src/main/java/net/minecraft/server/BlockDoor.java @@ -7,86 +7,85 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit public class BlockDoor extends Block { public static final BlockStateDirection FACING = BlockFacingHorizontal.FACING; - public static final BlockStateBoolean OPEN = BlockProperties.r; - public static final BlockStateEnum HINGE = BlockProperties.ar; - public static final BlockStateBoolean POWERED = BlockProperties.t; - public static final BlockStateEnum HALF = BlockProperties.P; - protected static final VoxelShape q = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 3.0D); - protected static final VoxelShape r = Block.a(0.0D, 0.0D, 13.0D, 16.0D, 16.0D, 16.0D); - protected static final VoxelShape s = Block.a(13.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); - protected static final VoxelShape t = Block.a(0.0D, 0.0D, 0.0D, 3.0D, 16.0D, 16.0D); + public static final BlockStateBoolean OPEN = BlockProperties.u; + public static final BlockStateEnum HINGE = BlockProperties.az; + public static final BlockStateBoolean POWERED = BlockProperties.w; + public static final BlockStateEnum HALF = BlockProperties.U; + protected static final VoxelShape f = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 3.0D); + protected static final VoxelShape g = Block.a(0.0D, 0.0D, 13.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape h = Block.a(13.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape i = Block.a(0.0D, 0.0D, 0.0D, 3.0D, 16.0D, 16.0D); protected BlockDoor(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockDoor.FACING, EnumDirection.NORTH)).set(BlockDoor.OPEN, false)).set(BlockDoor.HINGE, BlockPropertyDoorHinge.LEFT)).set(BlockDoor.POWERED, false)).set(BlockDoor.HALF, BlockPropertyDoubleBlockHalf.LOWER)); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockDoor.FACING, EnumDirection.NORTH)).set(BlockDoor.OPEN, false)).set(BlockDoor.HINGE, BlockPropertyDoorHinge.LEFT)).set(BlockDoor.POWERED, false)).set(BlockDoor.HALF, BlockPropertyDoubleBlockHalf.LOWER)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockDoor.FACING); boolean flag = !(Boolean) iblockdata.get(BlockDoor.OPEN); boolean flag1 = iblockdata.get(BlockDoor.HINGE) == BlockPropertyDoorHinge.RIGHT; switch (enumdirection) { - case EAST: - default: - return flag ? BlockDoor.t : (flag1 ? BlockDoor.r : BlockDoor.q); - case SOUTH: - return flag ? BlockDoor.q : (flag1 ? BlockDoor.t : BlockDoor.s); - case WEST: - return flag ? BlockDoor.s : (flag1 ? BlockDoor.q : BlockDoor.r); - case NORTH: - return flag ? BlockDoor.r : (flag1 ? BlockDoor.s : BlockDoor.t); + case EAST: + default: + return flag ? BlockDoor.i : (flag1 ? BlockDoor.g : BlockDoor.f); + case SOUTH: + return flag ? BlockDoor.f : (flag1 ? BlockDoor.i : BlockDoor.h); + case WEST: + return flag ? BlockDoor.h : (flag1 ? BlockDoor.f : BlockDoor.g); + case NORTH: + return flag ? BlockDoor.g : (flag1 ? BlockDoor.h : BlockDoor.i); } } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { BlockPropertyDoubleBlockHalf blockpropertydoubleblockhalf = (BlockPropertyDoubleBlockHalf) iblockdata.get(BlockDoor.HALF); return enumdirection.k() == EnumDirection.EnumAxis.Y && blockpropertydoubleblockhalf == BlockPropertyDoubleBlockHalf.LOWER == (enumdirection == EnumDirection.UP) ? (iblockdata1.getBlock() == this && iblockdata1.get(BlockDoor.HALF) != blockpropertydoubleblockhalf ? (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockDoor.FACING, iblockdata1.get(BlockDoor.FACING))).set(BlockDoor.OPEN, iblockdata1.get(BlockDoor.OPEN))).set(BlockDoor.HINGE, iblockdata1.get(BlockDoor.HINGE))).set(BlockDoor.POWERED, iblockdata1.get(BlockDoor.POWERED)) : Blocks.AIR.getBlockData()) : (blockpropertydoubleblockhalf == BlockPropertyDoubleBlockHalf.LOWER && enumdirection == EnumDirection.DOWN && !iblockdata.canPlace(generatoraccess, blockposition) ? Blocks.AIR.getBlockData() : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1)); } + @Override public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { super.a(world, entityhuman, blockposition, Blocks.AIR.getBlockData(), tileentity, itemstack); } + @Override public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { BlockPropertyDoubleBlockHalf blockpropertydoubleblockhalf = (BlockPropertyDoubleBlockHalf) iblockdata.get(BlockDoor.HALF); - boolean flag = blockpropertydoubleblockhalf == BlockPropertyDoubleBlockHalf.LOWER; - BlockPosition blockposition1 = flag ? blockposition.up() : blockposition.down(); + BlockPosition blockposition1 = blockpropertydoubleblockhalf == BlockPropertyDoubleBlockHalf.LOWER ? blockposition.up() : blockposition.down(); IBlockData iblockdata1 = world.getType(blockposition1); if (iblockdata1.getBlock() == this && iblockdata1.get(BlockDoor.HALF) != blockpropertydoubleblockhalf) { world.setTypeAndData(blockposition1, Blocks.AIR.getBlockData(), 35); world.a(entityhuman, 2001, blockposition1, Block.getCombinedId(iblockdata1)); - if (!world.isClientSide && !entityhuman.u()) { - if (flag) { - iblockdata.a(world, blockposition, 0); - } else { - iblockdata1.a(world, blockposition1, 0); - } + ItemStack itemstack = entityhuman.getItemInMainHand(); + + if (!world.isClientSide && !entityhuman.isCreative()) { + Block.dropItems(iblockdata, world, blockposition, (TileEntity) null, entityhuman, itemstack); + Block.dropItems(iblockdata1, world, blockposition1, (TileEntity) null, entityhuman, itemstack); } } super.a(world, blockposition, iblockdata, entityhuman); } + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { switch (pathmode) { - case LAND: - return (Boolean) iblockdata.get(BlockDoor.OPEN); - case WATER: - return false; - case AIR: - return (Boolean) iblockdata.get(BlockDoor.OPEN); - default: - return false; + case LAND: + return (Boolean) iblockdata.get(BlockDoor.OPEN); + case WATER: + return false; + case AIR: + return (Boolean) iblockdata.get(BlockDoor.OPEN); + default: + return false; } } - public boolean a(IBlockData iblockdata) { - return false; - } - private int d() { return this.material == Material.ORE ? 1011 : 1012; } @@ -96,6 +95,7 @@ public class BlockDoor extends Block { } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { BlockPosition blockposition = blockactioncontext.getClickPosition(); @@ -109,6 +109,7 @@ public class BlockDoor extends Block { } } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { world.setTypeAndData(blockposition.up(), (IBlockData) iblockdata.set(BlockDoor.HALF, BlockPropertyDoubleBlockHalf.UPPER), 3); } @@ -119,12 +120,16 @@ public class BlockDoor extends Block { EnumDirection enumdirection = blockactioncontext.f(); BlockPosition blockposition1 = blockposition.up(); EnumDirection enumdirection1 = enumdirection.f(); - IBlockData iblockdata = world.getType(blockposition.shift(enumdirection1)); - IBlockData iblockdata1 = world.getType(blockposition1.shift(enumdirection1)); + BlockPosition blockposition2 = blockposition.shift(enumdirection1); + IBlockData iblockdata = world.getType(blockposition2); + BlockPosition blockposition3 = blockposition1.shift(enumdirection1); + IBlockData iblockdata1 = world.getType(blockposition3); EnumDirection enumdirection2 = enumdirection.e(); - IBlockData iblockdata2 = world.getType(blockposition.shift(enumdirection2)); - IBlockData iblockdata3 = world.getType(blockposition1.shift(enumdirection2)); - int i = (iblockdata.k() ? -1 : 0) + (iblockdata1.k() ? -1 : 0) + (iblockdata2.k() ? 1 : 0) + (iblockdata3.k() ? 1 : 0); + BlockPosition blockposition4 = blockposition.shift(enumdirection2); + IBlockData iblockdata2 = world.getType(blockposition4); + BlockPosition blockposition5 = blockposition1.shift(enumdirection2); + IBlockData iblockdata3 = world.getType(blockposition5); + int i = (iblockdata.o(world, blockposition2) ? -1 : 0) + (iblockdata1.o(world, blockposition3) ? -1 : 0) + (iblockdata2.o(world, blockposition4) ? 1 : 0) + (iblockdata3.o(world, blockposition5) ? 1 : 0); boolean flag = iblockdata.getBlock() == this && iblockdata.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.LOWER; boolean flag1 = iblockdata2.getBlock() == this && iblockdata2.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.LOWER; @@ -132,10 +137,11 @@ public class BlockDoor extends Block { if ((!flag1 || flag) && i >= 0) { int j = enumdirection.getAdjacentX(); int k = enumdirection.getAdjacentZ(); - float f = blockactioncontext.m(); - float f1 = blockactioncontext.o(); + Vec3D vec3d = blockactioncontext.j(); + double d0 = vec3d.x - (double) blockposition.getX(); + double d1 = vec3d.z - (double) blockposition.getZ(); - return (j >= 0 || f1 >= 0.5F) && (j <= 0 || f1 <= 0.5F) && (k >= 0 || f <= 0.5F) && (k <= 0 || f >= 0.5F) ? BlockPropertyDoorHinge.LEFT : BlockPropertyDoorHinge.RIGHT; + return (j >= 0 || d1 >= 0.5D) && (j <= 0 || d1 <= 0.5D) && (k >= 0 || d0 <= 0.5D) && (k <= 0 || d0 >= 0.5D) ? BlockPropertyDoorHinge.LEFT : BlockPropertyDoorHinge.RIGHT; } else { return BlockPropertyDoorHinge.LEFT; } @@ -144,7 +150,8 @@ public class BlockDoor extends Block { } } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if (this.material == Material.ORE) { return false; } else { @@ -164,13 +171,14 @@ public class BlockDoor extends Block { } } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { // CraftBukkit start BlockPosition otherHalf = blockposition.shift(iblockdata.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.LOWER ? EnumDirection.UP : EnumDirection.DOWN); - org.bukkit.craftbukkit.CraftWorld bworld = world.getWorld(); // Akarin - CraftWorld - org.bukkit.block.Block bukkitBlock = bworld.getBlockAt(blockposition); // Akarin - org.bukkit.block.Block blockTop = bworld.getBlockAt(otherHalf); // Akarin + org.bukkit.World bworld = world.getWorld(); + org.bukkit.block.Block bukkitBlock = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.Block blockTop = bworld.getBlockAt(otherHalf.getX(), otherHalf.getY(), otherHalf.getZ()); int power = bukkitBlock.getBlockPower(); int powerTop = blockTop.getBlockPower(); @@ -181,52 +189,51 @@ public class BlockDoor extends Block { BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, oldPower, power); world.getServer().getPluginManager().callEvent(eventRedstone); - boolean flag = eventRedstone.getNewCurrent() > 0; + boolean flag1 = eventRedstone.getNewCurrent() > 0; // CraftBukkit end - if (flag != (Boolean) iblockdata.get(BlockDoor.OPEN)) { - this.b(world, blockposition, flag); + if (flag1 != (Boolean) iblockdata.get(BlockDoor.OPEN)) { + this.b(world, blockposition, flag1); } - world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) iblockdata.set(BlockDoor.POWERED, flag)).set(BlockDoor.OPEN, flag), 2); + world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) iblockdata.set(BlockDoor.POWERED, flag1)).set(BlockDoor.OPEN, flag1), 2); } } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { - IBlockData iblockdata1 = iworldreader.getType(blockposition.down()); + BlockPosition blockposition1 = blockposition.down(); + IBlockData iblockdata1 = iworldreader.getType(blockposition1); - return iblockdata.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.LOWER ? iblockdata1.q() : iblockdata1.getBlock() == this; + return iblockdata.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.LOWER ? iblockdata1.d(iworldreader, blockposition1, EnumDirection.UP) : iblockdata1.getBlock() == this; } private void b(World world, BlockPosition blockposition, boolean flag) { world.a((EntityHuman) null, flag ? this.e() : this.d(), blockposition, 0); } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return (IMaterial) (iblockdata.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.UPPER ? Items.AIR : super.getDropType(iblockdata, world, blockposition, i)); - } - + @Override public EnumPistonReaction getPushReaction(IBlockData iblockdata) { return EnumPistonReaction.DESTROY; } + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { return (IBlockData) iblockdata.set(BlockDoor.FACING, enumblockrotation.a((EnumDirection) iblockdata.get(BlockDoor.FACING))); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { return enumblockmirror == EnumBlockMirror.NONE ? iblockdata : (IBlockData) iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockDoor.FACING))).a((IBlockState) BlockDoor.HINGE); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockDoor.HALF, BlockDoor.FACING, BlockDoor.OPEN, BlockDoor.HINGE, BlockDoor.POWERED); } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockDragonEgg.java b/src/main/java/net/minecraft/server/BlockDragonEgg.java index 293be989a..270bf7f6b 100644 --- a/src/main/java/net/minecraft/server/BlockDragonEgg.java +++ b/src/main/java/net/minecraft/server/BlockDragonEgg.java @@ -10,27 +10,30 @@ public class BlockDragonEgg extends BlockFalling { super(block_info); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockDragonEgg.a; } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { - this.b(iblockdata, world, blockposition); + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { + this.d(iblockdata, world, blockposition); return true; } + @Override public void attack(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman) { - this.b(iblockdata, world, blockposition); + this.d(iblockdata, world, blockposition); } - private void b(IBlockData iblockdata, World world, BlockPosition blockposition) { + private void d(IBlockData iblockdata, World world, BlockPosition blockposition) { for (int i = 0; i < 1000; ++i) { - BlockPosition blockposition1 = blockposition.a(world.random.nextInt(16) - world.random.nextInt(16), world.random.nextInt(8) - world.random.nextInt(8), world.random.nextInt(16) - world.random.nextInt(16)); + BlockPosition blockposition1 = blockposition.b(world.random.nextInt(16) - world.random.nextInt(16), world.random.nextInt(8) - world.random.nextInt(8), world.random.nextInt(16) - world.random.nextInt(16)); if (world.getType(blockposition1).isAir()) { // CraftBukkit start - org.bukkit.block.Block from = world.getWorld().getBlockAt(blockposition); // Akarin - org.bukkit.block.Block to = world.getWorld().getBlockAt(blockposition1); // Akarin + org.bukkit.block.Block from = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.Block to = world.getWorld().getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); BlockFromToEvent event = new BlockFromToEvent(from, to); org.bukkit.Bukkit.getPluginManager().callEvent(event); @@ -46,15 +49,15 @@ public class BlockDragonEgg extends BlockFalling { float f = (world.random.nextFloat() - 0.5F) * 0.2F; float f1 = (world.random.nextFloat() - 0.5F) * 0.2F; float f2 = (world.random.nextFloat() - 0.5F) * 0.2F; - double d1 = (double) blockposition1.getX() + (double) (blockposition.getX() - blockposition1.getX()) * d0 + (world.random.nextDouble() - 0.5D) + 0.5D; - double d2 = (double) blockposition1.getY() + (double) (blockposition.getY() - blockposition1.getY()) * d0 + world.random.nextDouble() - 0.5D; - double d3 = (double) blockposition1.getZ() + (double) (blockposition.getZ() - blockposition1.getZ()) * d0 + (world.random.nextDouble() - 0.5D) + 0.5D; + double d1 = MathHelper.d(d0, (double) blockposition1.getX(), (double) blockposition.getX()) + (world.random.nextDouble() - 0.5D) + 0.5D; + double d2 = MathHelper.d(d0, (double) blockposition1.getY(), (double) blockposition.getY()) + world.random.nextDouble() - 0.5D; + double d3 = MathHelper.d(d0, (double) blockposition1.getZ(), (double) blockposition.getZ()) + (world.random.nextDouble() - 0.5D) + 0.5D; - world.addParticle(Particles.K, d1, d2, d3, (double) f, (double) f1, (double) f2); + world.addParticle(Particles.PORTAL, d1, d2, d3, (double) f, (double) f1, (double) f2); } } else { world.setTypeAndData(blockposition1, iblockdata, 2); - world.setAir(blockposition); + world.a(blockposition, false); } return; @@ -63,18 +66,12 @@ public class BlockDragonEgg extends BlockFalling { } + @Override public int a(IWorldReader iworldreader) { return 5; } - public boolean a(IBlockData iblockdata) { - return false; - } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { return false; } diff --git a/src/main/java/net/minecraft/server/BlockDropper.java b/src/main/java/net/minecraft/server/BlockDropper.java index 6bff4c1b3..e2f1dc02e 100644 --- a/src/main/java/net/minecraft/server/BlockDropper.java +++ b/src/main/java/net/minecraft/server/BlockDropper.java @@ -13,18 +13,21 @@ public class BlockDropper extends BlockDispenser { super(block_info); } + @Override protected IDispenseBehavior a(ItemStack itemstack) { return BlockDropper.c; } - public TileEntity a(IBlockAccess iblockaccess) { + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { return new TileEntityDropper(); } + @Override public void dispense(World world, BlockPosition blockposition) { SourceBlock sourceblock = new SourceBlock(world, blockposition); TileEntityDispenser tileentitydispenser = (TileEntityDispenser) sourceblock.getTileEntity(); - int i = tileentitydispenser.p(); + int i = tileentitydispenser.h(); if (i < 0) { world.triggerEffect(1001, blockposition, 0); diff --git a/src/main/java/net/minecraft/server/BlockEnderPortal.java b/src/main/java/net/minecraft/server/BlockEnderPortal.java index d060037a1..161996cbd 100644 --- a/src/main/java/net/minecraft/server/BlockEnderPortal.java +++ b/src/main/java/net/minecraft/server/BlockEnderPortal.java @@ -1,8 +1,9 @@ package net.minecraft.server; -import java.util.Random; - -import org.bukkit.event.entity.EntityPortalEnterEvent; // CraftBukkit +// CraftBukkit start +import org.bukkit.event.entity.EntityPortalEnterEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +// CraftBukkit end public class BlockEnderPortal extends BlockTileEntity { @@ -12,38 +13,30 @@ public class BlockEnderPortal extends BlockTileEntity { super(block_info); } - public TileEntity a(IBlockAccess iblockaccess) { + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { return new TileEntityEnderPortal(); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockEnderPortal.a; } - public boolean a(IBlockData iblockdata) { - return false; - } - - public int a(IBlockData iblockdata, Random random) { - return 0; - } - + @Override public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { - if (!world.isClientSide && !entity.isPassenger() && !entity.isVehicle() && entity.bm() && VoxelShapes.c(VoxelShapes.a(entity.getBoundingBox().d((double) (-blockposition.getX()), (double) (-blockposition.getY()), (double) (-blockposition.getZ()))), iblockdata.getShape(world, blockposition), OperatorBoolean.AND)) { + if (!world.isClientSide && !entity.isPassenger() && !entity.isVehicle() && entity.canPortal() && VoxelShapes.c(VoxelShapes.a(entity.getBoundingBox().d((double) (-blockposition.getX()), (double) (-blockposition.getY()), (double) (-blockposition.getZ()))), iblockdata.getShape(world, blockposition), OperatorBoolean.AND)) { // CraftBukkit start - Entity in portal EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ())); world.getServer().getPluginManager().callEvent(event); + + if (entity instanceof EntityPlayer) { + ((EntityPlayer) entity).a(world.worldProvider.getDimensionManager().getType() == DimensionManager.THE_END ? DimensionManager.OVERWORLD : DimensionManager.THE_END, PlayerTeleportEvent.TeleportCause.END_PORTAL); + return; + } + entity.a(world.worldProvider.getDimensionManager().getType() == DimensionManager.THE_END ? DimensionManager.OVERWORLD : DimensionManager.THE_END); // CraftBukkit end - entity.a(DimensionManager.THE_END); } } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - return ItemStack.a; - } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockFire.java b/src/main/java/net/minecraft/server/BlockFire.java index 21ecf04a5..135c6ae47 100644 --- a/src/main/java/net/minecraft/server/BlockFire.java +++ b/src/main/java/net/minecraft/server/BlockFire.java @@ -9,7 +9,6 @@ import java.util.Map.Entry; import javax.annotation.Nullable; // CraftBukkit start - import org.bukkit.Bukkit; import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.event.CraftEventFactory; @@ -20,27 +19,29 @@ import org.bukkit.event.block.BlockSpreadEvent; public class BlockFire extends Block { - public static final BlockStateInteger AGE = BlockProperties.X; + public static final BlockStateInteger AGE = BlockProperties.ad; public static final BlockStateBoolean NORTH = BlockSprawling.a; public static final BlockStateBoolean EAST = BlockSprawling.b; public static final BlockStateBoolean SOUTH = BlockSprawling.c; - public static final BlockStateBoolean WEST = BlockSprawling.o; - public static final BlockStateBoolean UPPER = BlockSprawling.p; - private static final Map r = (Map) BlockSprawling.r.entrySet().stream().filter((entry) -> { + public static final BlockStateBoolean WEST = BlockSprawling.d; + public static final BlockStateBoolean UPPER = BlockSprawling.e; + private static final Map g = (Map) BlockSprawling.g.entrySet().stream().filter((entry) -> { return entry.getKey() != EnumDirection.DOWN; }).collect(SystemUtils.a()); private final Object2IntMap flameChances = new Object2IntOpenHashMap(); - private final Object2IntMap t = new Object2IntOpenHashMap(); + private final Object2IntMap i = new Object2IntOpenHashMap(); protected BlockFire(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockFire.AGE, 0)).set(BlockFire.NORTH, false)).set(BlockFire.EAST, false)).set(BlockFire.SOUTH, false)).set(BlockFire.WEST, false)).set(BlockFire.UPPER, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockFire.AGE, 0)).set(BlockFire.NORTH, false)).set(BlockFire.EAST, false)).set(BlockFire.SOUTH, false)).set(BlockFire.WEST, false)).set(BlockFire.UPPER, false)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return VoxelShapes.a(); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { // CraftBukkit start if (!iblockdata.canPlace(generatoraccess, blockposition)) { @@ -59,24 +60,26 @@ public class BlockFire extends Block { } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return this.a((IBlockAccess) blockactioncontext.getWorld(), blockactioncontext.getClickPosition()); } public IBlockData a(IBlockAccess iblockaccess, BlockPosition blockposition) { - IBlockData iblockdata = iblockaccess.getType(blockposition.down()); + BlockPosition blockposition1 = blockposition.down(); + IBlockData iblockdata = iblockaccess.getType(blockposition1); - if (!iblockdata.q() && !this.k(iblockdata)) { + if (!this.j(iblockdata) && !iblockdata.d(iblockaccess, blockposition1, EnumDirection.UP)) { IBlockData iblockdata1 = this.getBlockData(); EnumDirection[] aenumdirection = EnumDirection.values(); int i = aenumdirection.length; for (int j = 0; j < i; ++j) { EnumDirection enumdirection = aenumdirection[j]; - BlockStateBoolean blockstateboolean = (BlockStateBoolean) BlockFire.r.get(enumdirection); + BlockStateBoolean blockstateboolean = (BlockStateBoolean) BlockFire.g.get(enumdirection); if (blockstateboolean != null) { - iblockdata1 = (IBlockData) iblockdata1.set(blockstateboolean, this.k(iblockaccess.getType(blockposition.shift(enumdirection)))); + iblockdata1 = (IBlockData) iblockdata1.set(blockstateboolean, this.j(iblockaccess.getType(blockposition.shift(enumdirection)))); } } @@ -86,24 +89,21 @@ public class BlockFire extends Block { } } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { - return iworldreader.getType(blockposition.down()).q() || this.d(iworldreader, blockposition); - } - - public boolean a(IBlockData iblockdata) { - return false; - } - - public int a(IBlockData iblockdata, Random random) { - return 0; + BlockPosition blockposition1 = blockposition.down(); + + return iworldreader.getType(blockposition1).d(iworldreader, blockposition1, EnumDirection.UP) || this.canBurn(iworldreader, blockposition); } + @Override public int a(IWorldReader iworldreader) { return 30; } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { - if (world.getGameRules().getBoolean("doFireTick")) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + if (world.getGameRules().getBoolean(GameRules.DO_FIRE_TICK)) { if (!iblockdata.canPlace(world, blockposition)) { fireExtinguished(world, blockposition); // CraftBukkit - invalid place location } @@ -124,21 +124,23 @@ public class BlockFire extends Block { if (!flag) { world.getBlockTickList().a(blockposition, this, this.a((IWorldReader) world) + random.nextInt(10)); - if (!this.d(world, blockposition)) { - if (!world.getType(blockposition.down()).q() || i > 3) { + if (!this.canBurn(world, blockposition)) { + BlockPosition blockposition1 = blockposition.down(); + + if (!world.getType(blockposition1).d(world, blockposition1, EnumDirection.UP) || i > 3) { fireExtinguished(world, blockposition); // CraftBukkit } return; } - if (i == 15 && random.nextInt(4) == 0 && !this.k(world.getType(blockposition.down()))) { + if (i == 15 && random.nextInt(4) == 0 && !this.j(world.getType(blockposition.down()))) { fireExtinguished(world, blockposition); // CraftBukkit return; } } - boolean flag1 = world.x(blockposition); + boolean flag1 = world.s(blockposition); int k = flag1 ? -50 : 0; // CraftBukkit start - add source blockposition to burn calls @@ -161,7 +163,7 @@ public class BlockFire extends Block { k1 += (j1 - 1) * 100; } - blockposition_mutableblockposition.g(blockposition).d(l, j1, i1); + blockposition_mutableblockposition.g(blockposition).e(l, j1, i1); if (!world.isLoaded(blockposition_mutableblockposition)) continue; // Paper int l1 = this.a((IWorldReader) world, (BlockPosition) blockposition_mutableblockposition); @@ -176,7 +178,7 @@ public class BlockFire extends Block { int j2 = Math.min(15, i + random.nextInt(5) / 4); // CraftBukkit start - Call to stop spread of fire - if (world.getType(blockposition_mutableblockposition) != Blocks.FIRE) { + if (world.getType(blockposition_mutableblockposition).getBlock() != Blocks.FIRE) { if (CraftEventFactory.callBlockIgniteEvent(world, blockposition_mutableblockposition, blockposition).isCancelled()) { continue; } @@ -199,27 +201,29 @@ public class BlockFire extends Block { return world.isRainingAt(blockposition) || world.isRainingAt(blockposition.west()) || world.isRainingAt(blockposition.east()) || world.isRainingAt(blockposition.north()) || world.isRainingAt(blockposition.south()); } - private int f(Block block) { - return this.t.getInt(block); + private int q(IBlockData iblockdata) { + return iblockdata.b((IBlockState) BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C) ? 0 : this.i.getInt(iblockdata.getBlock()); } - private int g(Block block) { - return this.flameChances.getInt(block); + private int r(IBlockData iblockdata) { + return iblockdata.b((IBlockState) BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C) ? 0 : this.flameChances.getInt(iblockdata.getBlock()); } private void a(World world, BlockPosition blockposition, int i, Random random, int j, BlockPosition sourceposition) { // CraftBukkit add sourceposition // Paper start final IBlockData iblockdata = world.getTypeIfLoaded(blockposition); - if (iblockdata == null) return; - int k = this.f(iblockdata.getBlock()); + if (iblockdata == null) { + return; + } + int k = this.q(iblockdata); // Paper end if (random.nextInt(i) < k) { //IBlockData iblockdata = world.getType(blockposition); // Paper // CraftBukkit start - org.bukkit.block.Block theBlock = world.getWorld().getBlockAt(blockposition); // Akarin - org.bukkit.block.Block sourceBlock = world.getWorld().getBlockAt(sourceposition); // Akarin + org.bukkit.block.Block theBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.Block sourceBlock = world.getWorld().getBlockAt(sourceposition.getX(), sourceposition.getY(), sourceposition.getZ()); BlockBurnEvent event = new BlockBurnEvent(theBlock, sourceBlock); world.getServer().getPluginManager().callEvent(event); @@ -234,33 +238,34 @@ public class BlockFire extends Block { world.setTypeAndData(blockposition, (IBlockData) this.a((IBlockAccess) world, blockposition).set(BlockFire.AGE, l), 3); } else { - if(iblockdata.getBlock() != Blocks.TNT) world.setAir(blockposition); // Paper - TNTPrimeEvent - We might be cancelling it below, move the setAir down + if(iblockdata.getBlock() != Blocks.TNT) world.a(blockposition, false); // Paper - TNTPrimeEvent - We might be cancelling it below, move the setAir down } Block block = iblockdata.getBlock(); if (block instanceof BlockTNT) { + BlockTNT blocktnt = (BlockTNT) block; + // Paper start - TNTPrimeEvent org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition); if (!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) { return; } - world.setAir(blockposition); // setair after non cancelled event, it would usually be air by now // Paper end - ((BlockTNT) block).a(world, blockposition); + BlockTNT.a(world, blockposition); } } } - private boolean d(IBlockAccess iblockaccess, BlockPosition blockposition) { + private boolean canBurn(IBlockAccess iblockaccess, BlockPosition blockposition) { EnumDirection[] aenumdirection = EnumDirection.values(); int i = aenumdirection.length; for (int j = 0; j < i; ++j) { EnumDirection enumdirection = aenumdirection[j]; - if (this.k(iblockaccess.getType(blockposition.shift(enumdirection)))) { + if (this.j(iblockaccess.getType(blockposition.shift(enumdirection)))) { return true; } } @@ -278,29 +283,28 @@ public class BlockFire extends Block { for (int k = 0; k < j; ++k) { EnumDirection enumdirection = aenumdirection[k]; - // Paper start - final IBlockData type = ((World)iworldreader).getTypeIfLoaded(blockposition.shift(enumdirection)); - if (type == null) continue; - i = Math.max(this.g(type.getBlock()), i); + IBlockData iblockdata = iworldreader.getTypeIfLoaded(blockposition.shift(enumdirection)); + if (iblockdata == null) { + continue; + } // Paper end + i = Math.max(this.r(iblockdata), i); } return i; } } - public boolean j() { - return false; + public boolean j(IBlockData iblockdata) { + return this.r(iblockdata) > 0; } - public boolean k(IBlockData iblockdata) { - return this.g(iblockdata.getBlock()) > 0; - } - - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata1.getBlock() != iblockdata.getBlock()) { - if (world.worldProvider.getDimensionManager() != DimensionManager.OVERWORLD && world.worldProvider.getDimensionManager() != DimensionManager.NETHER || !((BlockPortal) Blocks.NETHER_PORTAL).a((GeneratorAccess) world, blockposition)) { + // CraftBukkit - getType() + if (world.worldProvider.getDimensionManager().getType() != DimensionManager.OVERWORLD && world.worldProvider.getDimensionManager().getType() != DimensionManager.NETHER || !((BlockPortal) Blocks.NETHER_PORTAL).a((GeneratorAccess) world, blockposition)) { if (!iblockdata.canPlace(world, blockposition)) { fireExtinguished(world, blockposition); // CraftBukkit - fuel block broke } else { @@ -310,21 +314,19 @@ public class BlockFire extends Block { } } + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockFire.AGE, BlockFire.NORTH, BlockFire.EAST, BlockFire.SOUTH, BlockFire.WEST, BlockFire.UPPER); } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - public void a(Block block, int i, int j) { this.flameChances.put(block, i); - this.t.put(block, j); + this.i.put(block, j); } public static void d() { @@ -411,6 +413,9 @@ public class BlockFire extends Block { blockfire.a(Blocks.WHITE_TULIP, 60, 100); blockfire.a(Blocks.PINK_TULIP, 60, 100); blockfire.a(Blocks.OXEYE_DAISY, 60, 100); + blockfire.a(Blocks.CORNFLOWER, 60, 100); + blockfire.a(Blocks.LILY_OF_THE_VALLEY, 60, 100); + blockfire.a(Blocks.WITHER_ROSE, 60, 100); blockfire.a(Blocks.WHITE_WOOL, 30, 60); blockfire.a(Blocks.ORANGE_WOOL, 30, 60); blockfire.a(Blocks.MAGENTA_WOOL, 30, 60); @@ -447,12 +452,17 @@ public class BlockFire extends Block { blockfire.a(Blocks.RED_CARPET, 60, 20); blockfire.a(Blocks.BLACK_CARPET, 60, 20); blockfire.a(Blocks.DRIED_KELP_BLOCK, 30, 60); + blockfire.a(Blocks.BAMBOO, 60, 60); + blockfire.a(Blocks.SCAFFOLDING, 60, 60); + blockfire.a(Blocks.LECTERN, 30, 20); + blockfire.a(Blocks.COMPOSTER, 5, 20); + blockfire.a(Blocks.SWEET_BERRY_BUSH, 60, 100); } // CraftBukkit start private void fireExtinguished(GeneratorAccess world, BlockPosition position) { if (!CraftEventFactory.callBlockFadeEvent(world, position, Blocks.AIR.getBlockData()).isCancelled()) { - world.setAir(position); + world.a(position, false); } } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/BlockFluids.java b/src/main/java/net/minecraft/server/BlockFluids.java index a4a85d1cf..56bf0b1d8 100644 --- a/src/main/java/net/minecraft/server/BlockFluids.java +++ b/src/main/java/net/minecraft/server/BlockFluids.java @@ -1,17 +1,15 @@ package net.minecraft.server; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Random; public class BlockFluids extends Block implements IFluidSource { - public static final BlockStateInteger LEVEL = BlockProperties.ah; + public static final BlockStateInteger LEVEL = BlockProperties.ao; protected final FluidTypeFlowing b; private final List c; - private final Map o = Maps.newIdentityHashMap(); protected BlockFluids(FluidTypeFlowing fluidtypeflowing, Block.Info block_info) { super(block_info); @@ -24,60 +22,55 @@ public class BlockFluids extends Block implements IFluidSource { } this.c.add(fluidtypeflowing.a(8, true)); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockFluids.LEVEL, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockFluids.LEVEL, 0)); } - public void b(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void c(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { world.getFluid(blockposition).b(world, blockposition, random); } - public boolean a_(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return false; } + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { return !this.b.a(TagsFluid.LAVA); } - public Fluid h(IBlockData iblockdata) { + @Override + public Fluid g(IBlockData iblockdata) { int i = (Integer) iblockdata.get(BlockFluids.LEVEL); return (Fluid) this.c.get(Math.min(i, 8)); } - public boolean a(IBlockData iblockdata) { - return false; - } - - public boolean isCollidable(IBlockData iblockdata) { - return false; - } - - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - Fluid fluid = iblockaccess.getFluid(blockposition.up()); - - return fluid.c().a((FluidType) this.b) ? VoxelShapes.b() : (VoxelShape) this.o.computeIfAbsent(iblockdata, (iblockdata1) -> { - Fluid fluid1 = iblockdata1.s(); - - return VoxelShapes.create(0.0D, 0.0D, 0.0D, 1.0D, (double) fluid1.getHeight(), 1.0D); - }); - } - + @Override public EnumRenderType c(IBlockData iblockdata) { return EnumRenderType.INVISIBLE; } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.AIR; + @Override + public List a(IBlockData iblockdata, LootTableInfo.Builder loottableinfo_builder) { + return Collections.emptyList(); } + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return VoxelShapes.a(); + } + + @Override public int a(IWorldReader iworldreader) { return this.b.a(iworldreader); } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (this.a(world, blockposition, iblockdata)) { - world.getFluidTickList().a(blockposition, iblockdata.s().c(), this.getFlowSpeed(world, blockposition)); // Paper + world.getFluidTickList().a(blockposition, iblockdata.p().getType(), this.getFlowSpeed(world, blockposition)); // Paper } } @@ -98,17 +91,19 @@ public class BlockFluids extends Block implements IFluidSource { } // Paper end + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - if (iblockdata.s().d() || iblockdata1.s().d()) { - generatoraccess.getFluidTickList().a(blockposition, iblockdata.s().c(), this.a((IWorldReader) generatoraccess)); + if (iblockdata.p().isSource() || iblockdata1.p().isSource()) { + generatoraccess.getFluidTickList().a(blockposition, iblockdata.p().getType(), this.a((IWorldReader) generatoraccess)); } return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if (this.a(world, blockposition, iblockdata)) { - world.getFluidTickList().a(blockposition, iblockdata.s().c(), this.getFlowSpeed(world, blockposition)); // Paper + world.getFluidTickList().a(blockposition, iblockdata.p().getType(), this.getFlowSpeed(world, blockposition)); // Paper } } @@ -131,7 +126,7 @@ public class BlockFluids extends Block implements IFluidSource { if (flag) { Fluid fluid = world.getFluid(blockposition); - if (fluid.d()) { + if (fluid.isSource()) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, blockposition, Blocks.OBSIDIAN.getBlockData())) { this.fizz(world, blockposition); @@ -140,7 +135,7 @@ public class BlockFluids extends Block implements IFluidSource { return false; } - if (fluid.getHeight() >= 0.44444445F) { + if (fluid.getHeight(world, blockposition) >= 0.44444445F) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, blockposition, Blocks.COBBLESTONE.getBlockData())) { this.fizz(world, blockposition); @@ -154,35 +149,16 @@ public class BlockFluids extends Block implements IFluidSource { return true; } - protected void fizz(GeneratorAccess generatoraccess, BlockPosition blockposition) { - // Akarin start - this handle by client - /* - double d0 = (double) blockposition.getX(); - double d1 = (double) blockposition.getY(); - double d2 = (double) blockposition.getZ(); - */ - // Akarin end - - generatoraccess.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, 2.6F + (generatoraccess.m().nextFloat() - generatoraccess.m().nextFloat()) * 0.8F); - - // Akarin start - this handle by client - /* - for (int i = 0; i < 8; ++i) { - generatoraccess.addParticle(Particles.F, d0 + Math.random(), d1 + 1.2D, d2 + Math.random(), 0.0D, 0.0D, 0.0D); - } - */ - // Akarin end - + private void fizz(GeneratorAccess generatoraccess, BlockPosition blockposition) { + generatoraccess.triggerEffect(1501, blockposition, 0); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockFluids.LEVEL); } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - + @Override public FluidType removeFluid(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata) { if ((Integer) iblockdata.get(BlockFluids.LEVEL) == 0) { generatoraccess.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 11); @@ -191,4 +167,12 @@ public class BlockFluids extends Block implements IFluidSource { return FluidTypes.EMPTY; } } + + @Override + public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { + if (this.b.a(TagsFluid.LAVA)) { + entity.aC(); + } + + } } diff --git a/src/main/java/net/minecraft/server/BlockGrass.java b/src/main/java/net/minecraft/server/BlockGrass.java index 50936b8ba..7168b3ead 100644 --- a/src/main/java/net/minecraft/server/BlockGrass.java +++ b/src/main/java/net/minecraft/server/BlockGrass.java @@ -9,14 +9,17 @@ public class BlockGrass extends BlockDirtSnowSpreadable implements IBlockFragile super(block_info); } + @Override public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { return iblockaccess.getType(blockposition.up()).isAir(); } + @Override public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { return true; } + @Override public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { BlockPosition blockposition1 = blockposition.up(); IBlockData iblockdata1 = Blocks.GRASS.getBlockData(); @@ -28,8 +31,8 @@ public class BlockGrass extends BlockDirtSnowSpreadable implements IBlockFragile while (true) { if (j < i / 16) { - blockposition2 = blockposition2.a(random.nextInt(3) - 1, (random.nextInt(3) - 1) * random.nextInt(3) / 2, random.nextInt(3) - 1); - if (world.getType(blockposition2.down()).getBlock() == this && !world.getType(blockposition2).k()) { + blockposition2 = blockposition2.b(random.nextInt(3) - 1, (random.nextInt(3) - 1) * random.nextInt(3) / 2, random.nextInt(3) - 1); + if (world.getType(blockposition2.down()).getBlock() == this && !world.getType(blockposition2).o(world, blockposition2)) { ++j; continue; } @@ -46,13 +49,13 @@ public class BlockGrass extends BlockDirtSnowSpreadable implements IBlockFragile IBlockData iblockdata3; if (random.nextInt(8) == 0) { - List> list = world.getBiome(blockposition2).f(); + List> list = world.getBiome(blockposition2).e(); if (list.isEmpty()) { break label38; } - iblockdata3 = ((WorldGenFeatureCompositeFlower) list.get(0)).a(random, blockposition2); + iblockdata3 = ((WorldGenFlowers) ((WorldGenFeatureCompositeConfiguration) ((WorldGenFeatureConfigured) list.get(0)).b).a.a).a(random, blockposition2); } else { iblockdata3 = iblockdata1; } @@ -71,10 +74,12 @@ public class BlockGrass extends BlockDirtSnowSpreadable implements IBlockFragile } + @Override public boolean f(IBlockData iblockdata) { return true; } + @Override public TextureType c() { return TextureType.CUTOUT_MIPPED; } diff --git a/src/main/java/net/minecraft/server/BlockIce.java b/src/main/java/net/minecraft/server/BlockIce.java index 35e2fe918..b2043a669 100644 --- a/src/main/java/net/minecraft/server/BlockIce.java +++ b/src/main/java/net/minecraft/server/BlockIce.java @@ -9,28 +9,20 @@ public class BlockIce extends BlockHalfTransparent { super(block_info); } - public int j(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return Blocks.WATER.getBlockData().b(iblockaccess, blockposition); - } - + @Override public TextureType c() { return TextureType.TRANSLUCENT; } + @Override public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { - entityhuman.b(StatisticList.BLOCK_MINED.b(this)); - entityhuman.applyExhaustion(0.005F); - if (this.X_() && EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) > 0) { - a(world, blockposition, this.t(iblockdata)); - } else { + super.a(world, entityhuman, blockposition, iblockdata, tileentity, itemstack); + if (EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) == 0) { if (world.worldProvider.isNether()) { - world.setAir(blockposition); + world.a(blockposition, false); return; } - int i = EnchantmentManager.getEnchantmentLevel(Enchantments.LOOT_BONUS_BLOCKS, itemstack); - - iblockdata.a(world, blockposition, i); Material material = world.getType(blockposition.down()).getMaterial(); if (material.isSolid() || material.isLiquid()) { @@ -40,33 +32,35 @@ public class BlockIce extends BlockHalfTransparent { } - public int a(IBlockData iblockdata, Random random) { - return 0; - } - - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { - if (world.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 11 - iblockdata.b(world, blockposition)) { - this.b(iblockdata, world, blockposition); + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + if (world.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 11 - iblockdata.b((IBlockAccess) world, blockposition)) { + this.melt(iblockdata, world, blockposition); } } - protected void b(IBlockData iblockdata, World world, BlockPosition blockposition) { + protected void melt(IBlockData iblockdata, World world, BlockPosition blockposition) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, blockposition, world.worldProvider.isNether() ? Blocks.AIR.getBlockData() : Blocks.WATER.getBlockData()).isCancelled()) { return; } // CraftBukkit end if (world.worldProvider.isNether()) { - world.setAir(blockposition); + world.a(blockposition, false); } else { - iblockdata.a(world, blockposition, 0); world.setTypeUpdate(blockposition, Blocks.WATER.getBlockData()); world.a(blockposition, Blocks.WATER, blockposition); } } + @Override public EnumPistonReaction getPushReaction(IBlockData iblockdata) { return EnumPistonReaction.NORMAL; } + + @Override + public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EntityTypes entitytypes) { + return entitytypes == EntityTypes.POLAR_BEAR; + } } diff --git a/src/main/java/net/minecraft/server/BlockIceFrost.java b/src/main/java/net/minecraft/server/BlockIceFrost.java index 2c4bbc789..881dfb123 100644 --- a/src/main/java/net/minecraft/server/BlockIceFrost.java +++ b/src/main/java/net/minecraft/server/BlockIceFrost.java @@ -4,16 +4,17 @@ import java.util.Random; public class BlockIceFrost extends BlockIce { - public static final BlockStateInteger a = BlockProperties.U; + public static final BlockStateInteger a = BlockProperties.aa; public BlockIceFrost(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockIceFrost.a, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockIceFrost.a, 0)); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!world.paperConfig.frostedIceEnabled) return; // Paper - add ability to disable frosted ice - if ((random.nextInt(3) == 0 || this.a(world, blockposition, 4)) && world.getLightLevel(blockposition) > 11 - (Integer) iblockdata.get(BlockIceFrost.a) - iblockdata.b(world, blockposition) && this.c(iblockdata, world, blockposition)) { + if ((random.nextInt(3) == 0 || this.a(world, blockposition, 4)) && world.getLightLevel(blockposition) > 11 - (Integer) iblockdata.get(BlockIceFrost.a) - iblockdata.b((IBlockAccess) world, blockposition) && this.e(iblockdata, world, blockposition)) { BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); Throwable throwable = null; @@ -28,7 +29,7 @@ public class BlockIceFrost extends BlockIce { IBlockData iblockdata1 = world.getTypeIfLoaded(blockposition_pooledblockposition); // Paper - don't load chunks if (iblockdata1 == null) continue; // Paper - if (iblockdata1.getBlock() == this && !this.c(iblockdata1, world, blockposition_pooledblockposition)) { + if (iblockdata1.getBlock() == this && !this.e(iblockdata1, world, blockposition_pooledblockposition)) { world.getBlockTickList().a(blockposition_pooledblockposition, this, MathHelper.nextInt(random, world.paperConfig.frostedIceDelayMin, world.paperConfig.frostedIceDelayMax)); // Paper - use configurable min/max delay } } @@ -55,24 +56,25 @@ public class BlockIceFrost extends BlockIce { } } - private boolean c(IBlockData iblockdata, World world, BlockPosition blockposition) { + private boolean e(IBlockData iblockdata, World world, BlockPosition blockposition) { int i = (Integer) iblockdata.get(BlockIceFrost.a); if (i < 3) { world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockIceFrost.a, i + 1), 2); return false; } else { - this.b(iblockdata, world, blockposition); + this.melt(iblockdata, world, blockposition); return true; } } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if (block == this && this.a(world, blockposition, 2)) { - this.b(iblockdata, world, blockposition); + this.melt(iblockdata, world, blockposition); } - super.doPhysics(iblockdata, world, blockposition, block, blockposition1); + super.doPhysics(iblockdata, world, blockposition, block, blockposition1, flag); } private boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, int i) { @@ -118,11 +120,8 @@ public class BlockIceFrost extends BlockIce { } } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockIceFrost.a); } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - return ItemStack.a; - } } diff --git a/src/main/java/net/minecraft/server/BlockJukeBox.java b/src/main/java/net/minecraft/server/BlockJukeBox.java index 3bea2e928..6fc71fe76 100644 --- a/src/main/java/net/minecraft/server/BlockJukeBox.java +++ b/src/main/java/net/minecraft/server/BlockJukeBox.java @@ -2,14 +2,15 @@ package net.minecraft.server; public class BlockJukeBox extends BlockTileEntity { - public static final BlockStateBoolean HAS_RECORD = BlockProperties.l; + public static final BlockStateBoolean HAS_RECORD = BlockProperties.n; protected BlockJukeBox(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockJukeBox.HAS_RECORD, false)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockJukeBox.HAS_RECORD, false)); } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if ((Boolean) iblockdata.get(BlockJukeBox.HAS_RECORD)) { this.dropRecord(world, blockposition); iblockdata = (IBlockData) iblockdata.set(BlockJukeBox.HAS_RECORD, false); @@ -45,8 +46,7 @@ public class BlockJukeBox extends BlockTileEntity { if (!itemstack.isEmpty()) { world.triggerEffect(1010, blockposition, 0); - //world.a(blockposition, (SoundEffect) null); // Akarin - tileentityjukebox.setRecord(ItemStack.a); + tileentityjukebox.clear(); float f = 0.7F; double d0 = (double) (world.random.nextFloat() * 0.7F) + 0.15000000596046448D; double d1 = (double) (world.random.nextFloat() * 0.7F) + 0.06000000238418579D + 0.6D; @@ -54,13 +54,14 @@ public class BlockJukeBox extends BlockTileEntity { ItemStack itemstack1 = itemstack.cloneItemStack(); EntityItem entityitem = new EntityItem(world, (double) blockposition.getX() + d0, (double) blockposition.getY() + d1, (double) blockposition.getZ() + d2, itemstack1); - entityitem.n(); + entityitem.defaultPickupDelay(); world.addEntity(entityitem); } } } } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata.getBlock() != iblockdata1.getBlock()) { this.dropRecord(world, blockposition); @@ -68,20 +69,17 @@ public class BlockJukeBox extends BlockTileEntity { } } - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - if (!world.isClientSide) { - super.dropNaturally(iblockdata, world, blockposition, f, 0); - } - } - - public TileEntity a(IBlockAccess iblockaccess) { + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { return new TileEntityJukeBox(); } + @Override public boolean isComplexRedstone(IBlockData iblockdata) { return true; } + @Override public int a(IBlockData iblockdata, World world, BlockPosition blockposition) { TileEntity tileentity = world.getTileEntity(blockposition); @@ -96,10 +94,12 @@ public class BlockJukeBox extends BlockTileEntity { return 0; } + @Override public EnumRenderType c(IBlockData iblockdata) { return EnumRenderType.MODEL; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockJukeBox.HAS_RECORD); } diff --git a/src/main/java/net/minecraft/server/BlockKelp.java b/src/main/java/net/minecraft/server/BlockKelp.java index 63155e23a..29c7d291f 100644 --- a/src/main/java/net/minecraft/server/BlockKelp.java +++ b/src/main/java/net/minecraft/server/BlockKelp.java @@ -5,23 +5,21 @@ import javax.annotation.Nullable; public class BlockKelp extends Block implements IFluidContainer { - public static final BlockStateInteger a = BlockProperties.Y; + public static final BlockStateInteger a = BlockProperties.ae; protected static final VoxelShape b = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D); protected BlockKelp(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockKelp.a, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockKelp.a, 0)); } - public boolean a(IBlockData iblockdata) { - return false; - } - - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockKelp.b; } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { Fluid fluid = blockactioncontext.getWorld().getFluid(blockactioncontext.getClickPosition()); @@ -29,43 +27,44 @@ public class BlockKelp extends Block implements IFluidContainer { } public IBlockData a(GeneratorAccess generatoraccess) { - return (IBlockData) this.getBlockData().set(BlockKelp.a, generatoraccess.m().nextInt(25)); + return (IBlockData) this.getBlockData().set(BlockKelp.a, generatoraccess.getRandom().nextInt(25)); } + @Override public TextureType c() { return TextureType.CUTOUT; } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - - public Fluid h(IBlockData iblockdata) { + @Override + public Fluid g(IBlockData iblockdata) { return FluidTypes.WATER.a(false); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!iblockdata.canPlace(world, blockposition)) { - world.setAir(blockposition, true); + world.b(blockposition, true); } else { BlockPosition blockposition1 = blockposition.up(); IBlockData iblockdata1 = world.getType(blockposition1); - if (iblockdata1.getBlock() == Blocks.WATER && (Integer) iblockdata.get(BlockKelp.a) < 25 && random.nextDouble() < 0.14D) { + if (iblockdata1.getBlock() == Blocks.WATER && (Integer) iblockdata.get(BlockKelp.a) < 25 && random.nextDouble() < (100.0D / world.spigotConfig.kelpModifier) * 0.14D) { // Spigot org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition1, (IBlockData) iblockdata.a((IBlockState) BlockKelp.a)); // CraftBukkit } } } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { BlockPosition blockposition1 = blockposition.down(); IBlockData iblockdata1 = iworldreader.getType(blockposition1); Block block = iblockdata1.getBlock(); - return block == Blocks.MAGMA_BLOCK ? false : block == this || block == Blocks.KELP_PLANT || Block.a(iblockdata1.getCollisionShape(iworldreader, blockposition1), EnumDirection.UP); + return block == Blocks.MAGMA_BLOCK ? false : block == this || block == Blocks.KELP_PLANT || iblockdata1.d(iworldreader, blockposition1, EnumDirection.UP); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (!iblockdata.canPlace(generatoraccess, blockposition)) { if (enumdirection == EnumDirection.DOWN) { @@ -83,14 +82,17 @@ public class BlockKelp extends Block implements IFluidContainer { } } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockKelp.a); } + @Override public boolean canPlace(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, FluidType fluidtype) { return false; } + @Override public boolean place(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid) { return false; } diff --git a/src/main/java/net/minecraft/server/BlockLeaves.java b/src/main/java/net/minecraft/server/BlockLeaves.java index 6ab32a5b7..840e66a05 100644 --- a/src/main/java/net/minecraft/server/BlockLeaves.java +++ b/src/main/java/net/minecraft/server/BlockLeaves.java @@ -1,51 +1,55 @@ package net.minecraft.server; import java.util.Random; -import javax.annotation.Nullable; import org.bukkit.event.block.LeavesDecayEvent; // CraftBukkit public class BlockLeaves extends Block { - public static final BlockStateInteger DISTANCE = BlockProperties.ab; - public static final BlockStateBoolean PERSISTENT = BlockProperties.s; + public static final BlockStateInteger DISTANCE = BlockProperties.ah; + public static final BlockStateBoolean PERSISTENT = BlockProperties.v; protected static boolean c; public BlockLeaves(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockLeaves.DISTANCE, 7)).set(BlockLeaves.PERSISTENT, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockLeaves.DISTANCE, 7)).set(BlockLeaves.PERSISTENT, false)); } + @Override public boolean isTicking(IBlockData iblockdata) { return (Integer) iblockdata.get(BlockLeaves.DISTANCE) == 7 && !(Boolean) iblockdata.get(BlockLeaves.PERSISTENT); } - public void b(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void c(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!(Boolean) iblockdata.get(BlockLeaves.PERSISTENT) && (Integer) iblockdata.get(BlockLeaves.DISTANCE) == 7) { // CraftBukkit start - LeavesDecayEvent event = new LeavesDecayEvent(world.getWorld().getBlockAt(blockposition)); // Akarin + LeavesDecayEvent event = new LeavesDecayEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); world.getServer().getPluginManager().callEvent(event); if (event.isCancelled() || world.getType(blockposition).getBlock() != this) { return; } // CraftBukkit end - iblockdata.a(world, blockposition, 0); - world.setAir(blockposition); + c(iblockdata, world, blockposition); + world.a(blockposition, false); } } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { world.setTypeAndData(blockposition, a(iblockdata, (GeneratorAccess) world, blockposition), 3); } - public int j(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public int k(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return 1; } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - int i = w(iblockdata1) + 1; + int i = j(iblockdata1) + 1; if (i != 1 || (Integer) iblockdata.get(BlockLeaves.DISTANCE) != i) { generatoraccess.getBlockTickList().a(blockposition, this, 1); @@ -67,7 +71,7 @@ public class BlockLeaves extends Block { EnumDirection enumdirection = aenumdirection[k]; blockposition_pooledblockposition.g(blockposition).c(enumdirection); - i = Math.min(i, w(generatoraccess.getType(blockposition_pooledblockposition)) + 1); + i = Math.min(i, j(generatoraccess.getType(blockposition_pooledblockposition)) + 1); if (i == 1) { break; } @@ -93,81 +97,36 @@ public class BlockLeaves extends Block { return (IBlockData) iblockdata.set(BlockLeaves.DISTANCE, i); } - private static int w(IBlockData iblockdata) { + private static int j(IBlockData iblockdata) { return TagsBlock.LOGS.isTagged(iblockdata.getBlock()) ? 0 : (iblockdata.getBlock() instanceof BlockLeaves ? (Integer) iblockdata.get(BlockLeaves.DISTANCE) : 7); } - public int a(IBlockData iblockdata, Random random) { - return random.nextInt(20) == 0 ? 1 : 0; - } - - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - Block block = iblockdata.getBlock(); - - return block == Blocks.OAK_LEAVES ? Blocks.OAK_SAPLING : (block == Blocks.SPRUCE_LEAVES ? Blocks.SPRUCE_SAPLING : (block == Blocks.BIRCH_LEAVES ? Blocks.BIRCH_SAPLING : (block == Blocks.JUNGLE_LEAVES ? Blocks.JUNGLE_SAPLING : (block == Blocks.ACACIA_LEAVES ? Blocks.ACACIA_SAPLING : (block == Blocks.DARK_OAK_LEAVES ? Blocks.DARK_OAK_SAPLING : Blocks.OAK_SAPLING))))); - } - - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - if (!world.isClientSide) { - int j = this.k(iblockdata); - - if (i > 0) { - j -= 2 << i; - if (j < 10) { - j = 10; - } - } - - if (world.random.nextInt(j) == 0) { - a(world, blockposition, new ItemStack(this.getDropType(iblockdata, world, blockposition, i))); - } - - j = 200; - if (i > 0) { - j -= 10 << i; - if (j < 40) { - j = 40; - } - } - - this.a(world, blockposition, iblockdata, j); - } - - } - - protected void a(World world, BlockPosition blockposition, IBlockData iblockdata, int i) { - if ((iblockdata.getBlock() == Blocks.OAK_LEAVES || iblockdata.getBlock() == Blocks.DARK_OAK_LEAVES) && world.random.nextInt(i) == 0) { - a(world, blockposition, new ItemStack(Items.APPLE)); - } - - } - - protected int k(IBlockData iblockdata) { - return iblockdata.getBlock() == Blocks.JUNGLE_LEAVES ? 40 : 20; + @Override + public boolean f(IBlockData iblockdata) { + return false; } + @Override public TextureType c() { return BlockLeaves.c ? TextureType.CUTOUT_MIPPED : TextureType.SOLID; } - public boolean q(IBlockData iblockdata) { + @Override + public boolean c(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return false; } - public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { - if (!world.isClientSide && itemstack.getItem() == Items.SHEARS) { - entityhuman.b(StatisticList.BLOCK_MINED.b(this)); - entityhuman.applyExhaustion(0.005F); - a(world, blockposition, new ItemStack(this)); - } else { - super.a(world, entityhuman, blockposition, iblockdata, tileentity, itemstack); - } + @Override + public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EntityTypes entitytypes) { + return entitytypes == EntityTypes.OCELOT || entitytypes == EntityTypes.PARROT; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockLeaves.DISTANCE, BlockLeaves.PERSISTENT); } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return a((IBlockData) this.getBlockData().set(BlockLeaves.PERSISTENT, true), (GeneratorAccess) blockactioncontext.getWorld(), blockactioncontext.getClickPosition()); } diff --git a/src/main/java/net/minecraft/server/BlockLever.java b/src/main/java/net/minecraft/server/BlockLever.java index 2fb3c2b0e..68b644140 100644 --- a/src/main/java/net/minecraft/server/BlockLever.java +++ b/src/main/java/net/minecraft/server/BlockLever.java @@ -4,60 +4,58 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit public class BlockLever extends BlockAttachable { - public static final BlockStateBoolean POWERED = BlockProperties.t; + public static final BlockStateBoolean POWERED = BlockProperties.w; protected static final VoxelShape b = Block.a(5.0D, 4.0D, 10.0D, 11.0D, 12.0D, 16.0D); protected static final VoxelShape c = Block.a(5.0D, 4.0D, 0.0D, 11.0D, 12.0D, 6.0D); - protected static final VoxelShape o = Block.a(10.0D, 4.0D, 5.0D, 16.0D, 12.0D, 11.0D); - protected static final VoxelShape p = Block.a(0.0D, 4.0D, 5.0D, 6.0D, 12.0D, 11.0D); - protected static final VoxelShape q = Block.a(5.0D, 0.0D, 4.0D, 11.0D, 6.0D, 12.0D); - protected static final VoxelShape r = Block.a(4.0D, 0.0D, 5.0D, 12.0D, 6.0D, 11.0D); - protected static final VoxelShape s = Block.a(5.0D, 10.0D, 4.0D, 11.0D, 16.0D, 12.0D); - protected static final VoxelShape t = Block.a(4.0D, 10.0D, 5.0D, 12.0D, 16.0D, 11.0D); + protected static final VoxelShape d = Block.a(10.0D, 4.0D, 5.0D, 16.0D, 12.0D, 11.0D); + protected static final VoxelShape e = Block.a(0.0D, 4.0D, 5.0D, 6.0D, 12.0D, 11.0D); + protected static final VoxelShape f = Block.a(5.0D, 0.0D, 4.0D, 11.0D, 6.0D, 12.0D); + protected static final VoxelShape g = Block.a(4.0D, 0.0D, 5.0D, 12.0D, 6.0D, 11.0D); + protected static final VoxelShape h = Block.a(5.0D, 10.0D, 4.0D, 11.0D, 16.0D, 12.0D); + protected static final VoxelShape i = Block.a(4.0D, 10.0D, 5.0D, 12.0D, 16.0D, 11.0D); protected BlockLever(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockLever.FACING, EnumDirection.NORTH)).set(BlockLever.POWERED, false)).set(BlockLever.FACE, BlockPropertyAttachPosition.WALL)); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockLever.FACING, EnumDirection.NORTH)).set(BlockLever.POWERED, false)).set(BlockLever.FACE, BlockPropertyAttachPosition.WALL)); } - public boolean a(IBlockData iblockdata) { - return false; - } - - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { switch ((BlockPropertyAttachPosition) iblockdata.get(BlockLever.FACE)) { - case FLOOR: - switch (((EnumDirection) iblockdata.get(BlockLever.FACING)).k()) { - case X: - return BlockLever.r; - case Z: + case FLOOR: + switch (((EnumDirection) iblockdata.get(BlockLever.FACING)).k()) { + case X: + return BlockLever.g; + case Z: + default: + return BlockLever.f; + } + case WALL: + switch ((EnumDirection) iblockdata.get(BlockLever.FACING)) { + case EAST: + return BlockLever.e; + case WEST: + return BlockLever.d; + case SOUTH: + return BlockLever.c; + case NORTH: + default: + return BlockLever.b; + } + case CEILING: default: - return BlockLever.q; - } - case WALL: - switch ((EnumDirection) iblockdata.get(BlockLever.FACING)) { - case EAST: - return BlockLever.p; - case WEST: - return BlockLever.o; - case SOUTH: - return BlockLever.c; - case NORTH: - default: - return BlockLever.b; - } - case CEILING: - default: - switch (((EnumDirection) iblockdata.get(BlockLever.FACING)).k()) { - case X: - return BlockLever.t; - case Z: - default: - return BlockLever.s; - } + switch (((EnumDirection) iblockdata.get(BlockLever.FACING)).k()) { + case X: + return BlockLever.i; + case Z: + default: + return BlockLever.h; + } } } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { iblockdata = (IBlockData) iblockdata.a((IBlockState) BlockLever.POWERED); boolean flag = (Boolean) iblockdata.get(BlockLever.POWERED); @@ -70,7 +68,7 @@ public class BlockLever extends BlockAttachable { } else { // CraftBukkit start - Interact Lever boolean powered = !flag; // Old powered state - org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); int old = (powered) ? 15 : 0; int current = (!powered) ? 15 : 0; @@ -83,17 +81,17 @@ public class BlockLever extends BlockAttachable { // CraftBukkit end world.setTypeAndData(blockposition, iblockdata, 3); - float f3 = flag ? 0.6F : 0.5F; + float f = flag ? 0.6F : 0.5F; - world.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.3F, f3); - this.b(iblockdata, world, blockposition); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.3F, f); + this.d(iblockdata, world, blockposition); return true; } } private static void a(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition, float f) { EnumDirection enumdirection = ((EnumDirection) iblockdata.get(BlockLever.FACING)).opposite(); - EnumDirection enumdirection1 = k(iblockdata).opposite(); + EnumDirection enumdirection1 = j(iblockdata).opposite(); double d0 = (double) blockposition.getX() + 0.5D + 0.1D * (double) enumdirection.getAdjacentX() + 0.2D * (double) enumdirection1.getAdjacentX(); double d1 = (double) blockposition.getY() + 0.5D + 0.1D * (double) enumdirection.getAdjacentY() + 0.2D * (double) enumdirection1.getAdjacentY(); double d2 = (double) blockposition.getZ() + 0.5D + 0.1D * (double) enumdirection.getAdjacentZ() + 0.2D * (double) enumdirection1.getAdjacentZ(); @@ -101,38 +99,39 @@ public class BlockLever extends BlockAttachable { generatoraccess.addParticle(new ParticleParamRedstone(1.0F, 0.0F, 0.0F, f), d0, d1, d2, 0.0D, 0.0D, 0.0D); } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (!flag && iblockdata.getBlock() != iblockdata1.getBlock()) { if ((Boolean) iblockdata.get(BlockLever.POWERED)) { - this.b(iblockdata, world, blockposition); + this.d(iblockdata, world, blockposition); } super.remove(iblockdata, world, blockposition, iblockdata1, flag); } } + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return (Boolean) iblockdata.get(BlockLever.POWERED) ? 15 : 0; } + @Override public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - return (Boolean) iblockdata.get(BlockLever.POWERED) && k(iblockdata) == enumdirection ? 15 : 0; + return (Boolean) iblockdata.get(BlockLever.POWERED) && j(iblockdata) == enumdirection ? 15 : 0; } + @Override public boolean isPowerSource(IBlockData iblockdata) { return true; } - private void b(IBlockData iblockdata, World world, BlockPosition blockposition) { + private void d(IBlockData iblockdata, World world, BlockPosition blockposition) { world.applyPhysics(blockposition, this); - world.applyPhysics(blockposition.shift(k(iblockdata).opposite()), this); + world.applyPhysics(blockposition.shift(j(iblockdata).opposite()), this); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockLever.FACE, BlockLever.FACING, BlockLever.POWERED); } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockMagma.java b/src/main/java/net/minecraft/server/BlockMagma.java index ed8e5d040..89cedeac1 100644 --- a/src/main/java/net/minecraft/server/BlockMagma.java +++ b/src/main/java/net/minecraft/server/BlockMagma.java @@ -8,9 +8,10 @@ public class BlockMagma extends Block { super(block_info); } + @Override public void stepOn(World world, BlockPosition blockposition, Entity entity) { if (!entity.isFireProof() && entity instanceof EntityLiving && !EnchantmentManager.i((EntityLiving) entity)) { - org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = world.getWorld().getBlockAt(blockposition); // CraftBukkit // Akarin + org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); // CraftBukkit entity.damageEntity(DamageSource.HOT_FLOOR, 1.0F); org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = null; // CraftBukkit } @@ -18,10 +19,12 @@ public class BlockMagma extends Block { super.stepOn(world, blockposition, entity); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { BlockBubbleColumn.a(world, blockposition.up(), true); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (enumdirection == EnumDirection.UP && iblockdata1.getBlock() == Blocks.WATER) { generatoraccess.getBlockTickList().a(blockposition, this, this.a((IWorldReader) generatoraccess)); @@ -30,31 +33,36 @@ public class BlockMagma extends Block { return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } - public void b(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void c(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { BlockPosition blockposition1 = blockposition.up(); if (world.getFluid(blockposition).a(TagsFluid.WATER)) { - world.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); if (world instanceof WorldServer) { - ((WorldServer) world).a(Particles.F, (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.25D, (double) blockposition1.getZ() + 0.5D, 8, 0.5D, 0.25D, 0.5D, 0.0D); + ((WorldServer) world).a(Particles.LARGE_SMOKE, (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.25D, (double) blockposition1.getZ() + 0.5D, 8, 0.5D, 0.25D, 0.5D, 0.0D); } } } + @Override public int a(IWorldReader iworldreader) { return 20; } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { world.getBlockTickList().a(blockposition, this, this.a((IWorldReader) world)); } - public boolean a(IBlockData iblockdata, Entity entity) { - return entity.isFireProof(); + @Override + public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EntityTypes entitytypes) { + return entitytypes.c(); } - public boolean e(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public boolean g(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return true; } } diff --git a/src/main/java/net/minecraft/server/BlockMinecartDetector.java b/src/main/java/net/minecraft/server/BlockMinecartDetector.java index c36fa2584..c5481d295 100644 --- a/src/main/java/net/minecraft/server/BlockMinecartDetector.java +++ b/src/main/java/net/minecraft/server/BlockMinecartDetector.java @@ -10,22 +10,25 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit public class BlockMinecartDetector extends BlockMinecartTrackAbstract { - public static final BlockStateEnum SHAPE = BlockProperties.S; - public static final BlockStateBoolean POWERED = BlockProperties.t; + public static final BlockStateEnum SHAPE = BlockProperties.X; + public static final BlockStateBoolean POWERED = BlockProperties.w; public BlockMinecartDetector(Block.Info block_info) { super(true, block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockMinecartDetector.POWERED, false)).set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockMinecartDetector.POWERED, false)).set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH)); } + @Override public int a(IWorldReader iworldreader) { return 20; } + @Override public boolean isPowerSource(IBlockData iblockdata) { return true; } + @Override public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { if (!world.isClientSide) { if (!(Boolean) iblockdata.get(BlockMinecartDetector.POWERED)) { @@ -34,16 +37,19 @@ public class BlockMinecartDetector extends BlockMinecartTrackAbstract { } } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!world.isClientSide && (Boolean) iblockdata.get(BlockMinecartDetector.POWERED)) { this.a(world, blockposition, iblockdata); } } + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return (Boolean) iblockdata.get(BlockMinecartDetector.POWERED) ? 15 : 0; } + @Override public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return !(Boolean) iblockdata.get(BlockMinecartDetector.POWERED) ? 0 : (enumdirection == EnumDirection.UP ? 15 : 0); } @@ -57,9 +63,10 @@ public class BlockMinecartDetector extends BlockMinecartTrackAbstract { flag1 = true; } + IBlockData iblockdata1; // CraftBukkit start if (flag != flag1) { - org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, flag ? 15 : 0, flag1 ? 15 : 0); world.getServer().getPluginManager().callEvent(eventRedstone); @@ -69,19 +76,21 @@ public class BlockMinecartDetector extends BlockMinecartTrackAbstract { // CraftBukkit end if (flag1 && !flag) { - world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockMinecartDetector.POWERED, true), 3); - this.b(world, blockposition, iblockdata, true); + iblockdata1 = (IBlockData) iblockdata.set(BlockMinecartDetector.POWERED, true); + world.setTypeAndData(blockposition, iblockdata1, 3); + this.b(world, blockposition, iblockdata1, true); world.applyPhysics(blockposition, this); world.applyPhysics(blockposition.down(), this); - //world.a(blockposition, blockposition); // Akarin + world.b(blockposition, iblockdata, iblockdata1); } if (!flag1 && flag) { - world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockMinecartDetector.POWERED, false), 3); - this.b(world, blockposition, iblockdata, false); + iblockdata1 = (IBlockData) iblockdata.set(BlockMinecartDetector.POWERED, false); + world.setTypeAndData(blockposition, iblockdata1, 3); + this.b(world, blockposition, iblockdata1, false); world.applyPhysics(blockposition, this); world.applyPhysics(blockposition.down(), this); - //world.a(blockposition, blockposition); // Akarin + world.b(blockposition, iblockdata, iblockdata1); } if (flag1) { @@ -100,26 +109,30 @@ public class BlockMinecartDetector extends BlockMinecartTrackAbstract { BlockPosition blockposition1 = (BlockPosition) iterator.next(); IBlockData iblockdata1 = world.getType(blockposition1); - iblockdata1.doPhysics(world, blockposition1, iblockdata1.getBlock(), blockposition); + iblockdata1.doPhysics(world, blockposition1, iblockdata1.getBlock(), blockposition, false); } } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata1.getBlock() != iblockdata.getBlock()) { - super.onPlace(iblockdata, world, blockposition, iblockdata1); + super.onPlace(iblockdata, world, blockposition, iblockdata1, flag); this.a(world, blockposition, iblockdata); } } + @Override public IBlockState e() { return BlockMinecartDetector.SHAPE; } + @Override public boolean isComplexRedstone(IBlockData iblockdata) { return true; } + @Override public int a(IBlockData iblockdata, World world, BlockPosition blockposition) { if ((Boolean) iblockdata.get(BlockMinecartDetector.POWERED)) { List list = this.a(world, blockposition, EntityMinecartCommandBlock.class, (Predicate) null); @@ -148,123 +161,126 @@ public class BlockMinecartDetector extends BlockMinecartTrackAbstract { return new AxisAlignedBB((double) ((float) blockposition.getX() + 0.2F), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + 0.2F), (double) ((float) (blockposition.getX() + 1) - 0.2F), (double) ((float) (blockposition.getY() + 1) - 0.2F), (double) ((float) (blockposition.getZ() + 1) - 0.2F)); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { switch (enumblockrotation) { - case CLOCKWISE_180: - switch ((BlockPropertyTrackPosition) iblockdata.get(BlockMinecartDetector.SHAPE)) { - case ASCENDING_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); - case ASCENDING_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); - case ASCENDING_NORTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); - case ASCENDING_SOUTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - } - case COUNTERCLOCKWISE_90: - switch ((BlockPropertyTrackPosition) iblockdata.get(BlockMinecartDetector.SHAPE)) { - case ASCENDING_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); - case ASCENDING_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); - case ASCENDING_NORTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); - case ASCENDING_SOUTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - case NORTH_SOUTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.EAST_WEST); - case EAST_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH); - } - case CLOCKWISE_90: - switch ((BlockPropertyTrackPosition) iblockdata.get(BlockMinecartDetector.SHAPE)) { - case ASCENDING_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); - case ASCENDING_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); - case ASCENDING_NORTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); - case ASCENDING_SOUTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - case NORTH_SOUTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.EAST_WEST); - case EAST_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH); - } - default: - return iblockdata; + case CLOCKWISE_180: + switch ((BlockPropertyTrackPosition) iblockdata.get(BlockMinecartDetector.SHAPE)) { + case ASCENDING_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); + case ASCENDING_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); + case ASCENDING_NORTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); + case ASCENDING_SOUTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + } + case COUNTERCLOCKWISE_90: + switch ((BlockPropertyTrackPosition) iblockdata.get(BlockMinecartDetector.SHAPE)) { + case ASCENDING_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); + case ASCENDING_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); + case ASCENDING_NORTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); + case ASCENDING_SOUTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + case NORTH_SOUTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.EAST_WEST); + case EAST_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH); + } + case CLOCKWISE_90: + switch ((BlockPropertyTrackPosition) iblockdata.get(BlockMinecartDetector.SHAPE)) { + case ASCENDING_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); + case ASCENDING_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); + case ASCENDING_NORTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); + case ASCENDING_SOUTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + case NORTH_SOUTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.EAST_WEST); + case EAST_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH); + } + default: + return iblockdata; } } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { BlockPropertyTrackPosition blockpropertytrackposition = (BlockPropertyTrackPosition) iblockdata.get(BlockMinecartDetector.SHAPE); switch (enumblockmirror) { - case LEFT_RIGHT: - switch (blockpropertytrackposition) { - case ASCENDING_NORTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); - case ASCENDING_SOUTH: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - default: - return super.a(iblockdata, enumblockmirror); - } - case FRONT_BACK: - switch (blockpropertytrackposition) { - case ASCENDING_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); - case ASCENDING_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); - case ASCENDING_NORTH: - case ASCENDING_SOUTH: - default: - break; - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - } + case LEFT_RIGHT: + switch (blockpropertytrackposition) { + case ASCENDING_NORTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); + case ASCENDING_SOUTH: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + default: + return super.a(iblockdata, enumblockmirror); + } + case FRONT_BACK: + switch (blockpropertytrackposition) { + case ASCENDING_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); + case ASCENDING_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); + case ASCENDING_NORTH: + case ASCENDING_SOUTH: + default: + break; + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockMinecartDetector.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + } } return super.a(iblockdata, enumblockmirror); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockMinecartDetector.SHAPE, BlockMinecartDetector.POWERED); } diff --git a/src/main/java/net/minecraft/server/BlockMobSpawner.java b/src/main/java/net/minecraft/server/BlockMobSpawner.java index 4e26969c6..bb77d916a 100644 --- a/src/main/java/net/minecraft/server/BlockMobSpawner.java +++ b/src/main/java/net/minecraft/server/BlockMobSpawner.java @@ -6,40 +6,36 @@ public class BlockMobSpawner extends BlockTileEntity { super(block_info); } - public TileEntity a(IBlockAccess iblockaccess) { + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { return new TileEntityMobSpawner(); } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.AIR; - } - - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - super.dropNaturally(iblockdata, world, blockposition, f, i); + @Override + public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { + super.dropNaturally(iblockdata, world, blockposition, itemstack); /* CraftBukkit start - Delegate to getExpDrop - int j = 15 + world.random.nextInt(15) + world.random.nextInt(15); + int i = 15 + world.random.nextInt(15) + world.random.nextInt(15); - this.dropExperience(world, blockposition, j); + this.dropExperience(world, blockposition, i); */ } @Override - public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, int enchantmentLevel) { - int j = 15 + world.random.nextInt(15) + world.random.nextInt(15); + public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { + int i = 15 + world.random.nextInt(15) + world.random.nextInt(15); - return j; + return i; // CraftBukkit end } + @Override public EnumRenderType c(IBlockData iblockdata) { return EnumRenderType.MODEL; } + @Override public TextureType c() { return TextureType.CUTOUT; } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - return ItemStack.a; - } } diff --git a/src/main/java/net/minecraft/server/BlockMonsterEggs.java b/src/main/java/net/minecraft/server/BlockMonsterEggs.java index 1af5e016a..46d77d172 100644 --- a/src/main/java/net/minecraft/server/BlockMonsterEggs.java +++ b/src/main/java/net/minecraft/server/BlockMonsterEggs.java @@ -2,14 +2,13 @@ package net.minecraft.server; import com.google.common.collect.Maps; import java.util.Map; -import java.util.Random; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; // CraftBukkit public class BlockMonsterEggs extends Block { private final Block a; - private static final Map b = com.koloboke.collect.map.hash.HashObjObjMaps.getDefaultFactory().withNullKeyAllowed(true).withKeyEquivalence(com.koloboke.collect.Equivalence.identity()).newUpdatableMap(); + private static final Map b = Maps.newIdentityHashMap(); public BlockMonsterEggs(Block block, Block.Info block_info) { super(block_info); @@ -17,25 +16,19 @@ public class BlockMonsterEggs extends Block { BlockMonsterEggs.b.put(block, this); } - public int a(IBlockData iblockdata, Random random) { - return 0; - } - public Block d() { return this.a; } - public static boolean k(IBlockData iblockdata) { + public static boolean j(IBlockData iblockdata) { return BlockMonsterEggs.b.containsKey(iblockdata.getBlock()); } - protected ItemStack t(IBlockData iblockdata) { - return new ItemStack(this.a); - } - - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - if (!world.isClientSide && world.getGameRules().getBoolean("doTileDrops")) { - EntitySilverfish entitysilverfish = EntityTypes.SILVERFISH.create(world); // Paper + @Override + public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { + super.dropNaturally(iblockdata, world, blockposition, itemstack); + if (!world.isClientSide && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS) && EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) == 0) { + EntitySilverfish entitysilverfish = (EntitySilverfish) EntityTypes.SILVERFISH.a(world); entitysilverfish.setPositionRotation((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, 0.0F, 0.0F); world.addEntity(entitysilverfish, SpawnReason.SILVERFISH_BLOCK); // CraftBukkit - add SpawnReason @@ -44,7 +37,7 @@ public class BlockMonsterEggs extends Block { } - public static IBlockData f(Block block) { + public static IBlockData e(Block block) { return ((Block) BlockMonsterEggs.b.get(block)).getBlockData(); } } diff --git a/src/main/java/net/minecraft/server/BlockMushroom.java b/src/main/java/net/minecraft/server/BlockMushroom.java index 7cc30a4f3..9a260cbaa 100644 --- a/src/main/java/net/minecraft/server/BlockMushroom.java +++ b/src/main/java/net/minecraft/server/BlockMushroom.java @@ -15,15 +15,17 @@ public class BlockMushroom extends BlockPlant implements IBlockFragilePlantEleme super(block_info); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockMushroom.a; } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (random.nextInt(Math.max(1, (int) (100.0F / world.spigotConfig.mushroomModifier) * 25)) == 0) { // Spigot int i = 5; boolean flag = true; - Iterator iterator = BlockPosition.b(blockposition.a(-4, -1, -4), blockposition.a(4, 1, 4)).iterator(); + Iterator iterator = BlockPosition.a(blockposition.b(-4, -1, -4), blockposition.b(4, 1, 4)).iterator(); while (iterator.hasNext()) { BlockPosition blockposition1 = (BlockPosition) iterator.next(); @@ -36,14 +38,14 @@ public class BlockMushroom extends BlockPlant implements IBlockFragilePlantEleme } } - BlockPosition blockposition2 = blockposition.a(random.nextInt(3) - 1, random.nextInt(2) - random.nextInt(2), random.nextInt(3) - 1); + BlockPosition blockposition2 = blockposition.b(random.nextInt(3) - 1, random.nextInt(2) - random.nextInt(2), random.nextInt(3) - 1); for (int j = 0; j < 4; ++j) { if (world.isEmpty(blockposition2) && iblockdata.canPlace(world, blockposition2)) { blockposition = blockposition2; } - blockposition2 = blockposition.a(random.nextInt(3) - 1, random.nextInt(2) - random.nextInt(2), random.nextInt(3) - 1); + blockposition2 = blockposition.b(random.nextInt(3) - 1, random.nextInt(2) - random.nextInt(2), random.nextInt(3) - 1); } if (world.isEmpty(blockposition2) && iblockdata.canPlace(world, blockposition2)) { @@ -53,31 +55,33 @@ public class BlockMushroom extends BlockPlant implements IBlockFragilePlantEleme } - protected boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return iblockdata.f(iblockaccess, blockposition); + @Override + protected boolean a_(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockdata.g(iblockaccess, blockposition); } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { BlockPosition blockposition1 = blockposition.down(); IBlockData iblockdata1 = iworldreader.getType(blockposition1); Block block = iblockdata1.getBlock(); - return block != Blocks.MYCELIUM && block != Blocks.PODZOL ? iworldreader.getLightLevel(blockposition, 0) < 13 && this.b(iblockdata1, (IBlockAccess) iworldreader, blockposition1) : true; + return block != Blocks.MYCELIUM && block != Blocks.PODZOL ? iworldreader.getLightLevel(blockposition, 0) < 13 && this.a_(iblockdata1, iworldreader, blockposition1) : true; } public boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata, Random random) { - generatoraccess.setAir(blockposition); - WorldGenerator worldgenerator = null; + generatoraccess.a(blockposition, false); + WorldGenerator worldgenerator = null; if (this == Blocks.BROWN_MUSHROOM) { BlockSapling.treeType = TreeType.BROWN_MUSHROOM; // CraftBukkit - worldgenerator = WorldGenerator.U; + worldgenerator = WorldGenerator.HUGE_BROWN_MUSHROOM; } else if (this == Blocks.RED_MUSHROOM) { BlockSapling.treeType = TreeType.RED_MUSHROOM; // CraftBukkit - worldgenerator = WorldGenerator.T; + worldgenerator = WorldGenerator.HUGE_RED_MUSHROOM; } - if (worldgenerator != null && worldgenerator.generate(generatoraccess, generatoraccess.getChunkProvider().getChunkGenerator(), random, blockposition, WorldGenFeatureConfiguration.e)) { + if (worldgenerator != null && worldgenerator.generate(generatoraccess, generatoraccess.getChunkProvider().getChunkGenerator(), random, blockposition, new WorldGenHugeMushroomConfiguration(true))) { return true; } else { generatoraccess.setTypeAndData(blockposition, iblockdata, 3); @@ -85,19 +89,23 @@ public class BlockMushroom extends BlockPlant implements IBlockFragilePlantEleme } } + @Override public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { return true; } + @Override public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { return (double) random.nextFloat() < 0.4D; } + @Override public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { this.a((GeneratorAccess) world, blockposition, iblockdata, random); } - public boolean e(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public boolean g(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return true; } } diff --git a/src/main/java/net/minecraft/server/BlockNetherWart.java b/src/main/java/net/minecraft/server/BlockNetherWart.java index 3934230ac..fbd242eb6 100644 --- a/src/main/java/net/minecraft/server/BlockNetherWart.java +++ b/src/main/java/net/minecraft/server/BlockNetherWart.java @@ -4,23 +4,26 @@ import java.util.Random; public class BlockNetherWart extends BlockPlant { - public static final BlockStateInteger AGE = BlockProperties.U; - private static final VoxelShape[] b = new VoxelShape[] { Block.a(0.0D, 0.0D, 0.0D, 16.0D, 5.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 11.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 14.0D, 16.0D)}; + public static final BlockStateInteger AGE = BlockProperties.aa; + private static final VoxelShape[] b = new VoxelShape[]{Block.a(0.0D, 0.0D, 0.0D, 16.0D, 5.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 11.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 14.0D, 16.0D)}; protected BlockNetherWart(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockNetherWart.AGE, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockNetherWart.AGE, 0)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockNetherWart.b[(Integer) iblockdata.get(BlockNetherWart.AGE)]; } - protected boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + protected boolean a_(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return iblockdata.getBlock() == Blocks.SOUL_SAND; } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { int i = (Integer) iblockdata.get(BlockNetherWart.AGE); if (i < 3 && random.nextInt(Math.max(1, (int) (100.0F / world.spigotConfig.wartModifier) * 10)) == 0) { // Spigot @@ -28,35 +31,10 @@ public class BlockNetherWart extends BlockPlant { org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, blockposition, iblockdata, 2); // CraftBukkit } - super.a(iblockdata, world, blockposition, random); - } - - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - if (!world.isClientSide) { - int j = 1; - - if ((Integer) iblockdata.get(BlockNetherWart.AGE) >= 3) { - j = 2 + world.random.nextInt(3); - if (i > 0) { - j += world.random.nextInt(i + 1); - } - } - - for (int k = 0; k < j; ++k) { - a(world, blockposition, new ItemStack(Items.NETHER_WART)); - } - - } - } - - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.AIR; - } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - return new ItemStack(Items.NETHER_WART); + super.tick(iblockdata, world, blockposition, random); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockNetherWart.AGE); } diff --git a/src/main/java/net/minecraft/server/BlockNote.java b/src/main/java/net/minecraft/server/BlockNote.java index d41dd5c6a..703379efe 100644 --- a/src/main/java/net/minecraft/server/BlockNote.java +++ b/src/main/java/net/minecraft/server/BlockNote.java @@ -2,32 +2,35 @@ package net.minecraft.server; public class BlockNote extends Block { - public static final BlockStateEnum INSTRUMENT = BlockProperties.as; - public static final BlockStateBoolean POWERED = BlockProperties.t; - public static final BlockStateInteger NOTE = BlockProperties.aj; + public static final BlockStateEnum INSTRUMENT = BlockProperties.aA; + public static final BlockStateBoolean POWERED = BlockProperties.w; + public static final BlockStateInteger NOTE = BlockProperties.aq; public BlockNote(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockNote.INSTRUMENT, BlockPropertyInstrument.HARP)).set(BlockNote.NOTE, 0)).set(BlockNote.POWERED, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockNote.INSTRUMENT, BlockPropertyInstrument.HARP)).set(BlockNote.NOTE, 0)).set(BlockNote.POWERED, false)); } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return (IBlockData) this.getBlockData().set(BlockNote.INSTRUMENT, BlockPropertyInstrument.a(blockactioncontext.getWorld().getType(blockactioncontext.getClickPosition().down()))); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { return enumdirection == EnumDirection.DOWN ? (IBlockData) iblockdata.set(BlockNote.INSTRUMENT, BlockPropertyInstrument.a(iblockdata1)) : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { - boolean flag = world.isBlockIndirectlyPowered(blockposition); + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { + boolean flag1 = world.isBlockIndirectlyPowered(blockposition); - if (flag != (Boolean) iblockdata.get(BlockNote.POWERED)) { - if (flag) { + if (flag1 != (Boolean) iblockdata.get(BlockNote.POWERED)) { + if (flag1) { this.play(world, blockposition, iblockdata); // CraftBukkit } - world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockNote.POWERED, flag), 3); + world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockNote.POWERED, flag1), 3); } } @@ -44,7 +47,8 @@ public class BlockNote extends Block { } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if (world.isClientSide) { return true; } else { @@ -56,6 +60,7 @@ public class BlockNote extends Block { } } + @Override public void attack(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman) { if (!world.isClientSide) { this.play(world, blockposition, iblockdata); // CraftBukkit @@ -63,15 +68,17 @@ public class BlockNote extends Block { } } + @Override public boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, int i, int j) { int k = (Integer) iblockdata.get(BlockNote.NOTE); float f = (float) Math.pow(2.0D, (double) (k - 12) / 12.0D); - world.a((EntityHuman) null, blockposition, ((BlockPropertyInstrument) iblockdata.get(BlockNote.INSTRUMENT)).a(), SoundCategory.RECORDS, 3.0F, f); - //world.addParticle(Particles.I, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 1.2D, (double) blockposition.getZ() + 0.5D, (double) k / 24.0D, 0.0D, 0.0D); // Akarin - this handle by client + world.playSound((EntityHuman) null, blockposition, ((BlockPropertyInstrument) iblockdata.get(BlockNote.INSTRUMENT)).a(), SoundCategory.RECORDS, 3.0F, f); + world.addParticle(Particles.NOTE, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 1.2D, (double) blockposition.getZ() + 0.5D, (double) k / 24.0D, 0.0D, 0.0D); return true; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockNote.INSTRUMENT, BlockNote.POWERED, BlockNote.NOTE); } diff --git a/src/main/java/net/minecraft/server/BlockObserver.java b/src/main/java/net/minecraft/server/BlockObserver.java index 958e268d4..80fde17c0 100644 --- a/src/main/java/net/minecraft/server/BlockObserver.java +++ b/src/main/java/net/minecraft/server/BlockObserver.java @@ -6,26 +6,30 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockObserver extends BlockDirectional { - public static final BlockStateBoolean b = BlockProperties.t; + public static final BlockStateBoolean b = BlockProperties.w; public BlockObserver(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockObserver.FACING, EnumDirection.SOUTH)).set(BlockObserver.b, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockObserver.FACING, EnumDirection.SOUTH)).set(BlockObserver.b, false)); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockObserver.FACING, BlockObserver.b); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { return (IBlockData) iblockdata.set(BlockObserver.FACING, enumblockrotation.a((EnumDirection) iblockdata.get(BlockObserver.FACING))); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockObserver.FACING))); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if ((Boolean) iblockdata.get(BlockObserver.b)) { // CraftBukkit start if (CraftEventFactory.callRedstoneChange(world, blockposition, 15, 0).getNewCurrent() != 0) { @@ -46,6 +50,7 @@ public class BlockObserver extends BlockDirectional { this.a(world, blockposition, iblockdata); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (iblockdata.get(BlockObserver.FACING) == enumdirection && !(Boolean) iblockdata.get(BlockObserver.b)) { this.a(generatoraccess, blockposition); @@ -69,19 +74,23 @@ public class BlockObserver extends BlockDirectional { world.a(blockposition1, (Block) this, enumdirection); } + @Override public boolean isPowerSource(IBlockData iblockdata) { return true; } + @Override public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - return iblockdata.a(iblockaccess, blockposition, enumdirection); + return iblockdata.b(iblockaccess, blockposition, enumdirection); } + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return (Boolean) iblockdata.get(BlockObserver.b) && iblockdata.get(BlockObserver.FACING) == enumdirection ? 15 : 0; } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata.getBlock() != iblockdata1.getBlock()) { if (!world.e() && (Boolean) iblockdata.get(BlockObserver.b) && !world.getBlockTickList().a(blockposition, this)) { IBlockData iblockdata2 = (IBlockData) iblockdata.set(BlockObserver.b, false); @@ -93,6 +102,7 @@ public class BlockObserver extends BlockDirectional { } } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata.getBlock() != iblockdata1.getBlock()) { if (!world.isClientSide && (Boolean) iblockdata.get(BlockObserver.b) && world.getBlockTickList().a(blockposition, this)) { @@ -102,6 +112,7 @@ public class BlockObserver extends BlockDirectional { } } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return (IBlockData) this.getBlockData().set(BlockObserver.FACING, blockactioncontext.d().opposite().opposite()); } diff --git a/src/main/java/net/minecraft/server/BlockOre.java b/src/main/java/net/minecraft/server/BlockOre.java index 9c8780e43..c9782f4fb 100644 --- a/src/main/java/net/minecraft/server/BlockOre.java +++ b/src/main/java/net/minecraft/server/BlockOre.java @@ -8,77 +8,36 @@ public class BlockOre extends Block { super(block_info); } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return (IMaterial) (this == Blocks.COAL_ORE ? Items.COAL : (this == Blocks.DIAMOND_ORE ? Items.DIAMOND : (this == Blocks.LAPIS_ORE ? Items.LAPIS_LAZULI : (this == Blocks.EMERALD_ORE ? Items.EMERALD : (this == Blocks.NETHER_QUARTZ_ORE ? Items.QUARTZ : this))))); + protected int a(Random random) { + return this == Blocks.COAL_ORE ? MathHelper.nextInt(random, 0, 2) : (this == Blocks.DIAMOND_ORE ? MathHelper.nextInt(random, 3, 7) : (this == Blocks.EMERALD_ORE ? MathHelper.nextInt(random, 3, 7) : (this == Blocks.LAPIS_ORE ? MathHelper.nextInt(random, 2, 5) : (this == Blocks.NETHER_QUARTZ_ORE ? MathHelper.nextInt(random, 2, 5) : 0)))); } - public int a(IBlockData iblockdata, Random random) { - return this == Blocks.LAPIS_ORE ? 4 + random.nextInt(5) : 1; - } - - public int getDropCount(IBlockData iblockdata, int i, World world, BlockPosition blockposition, Random random) { - if (i > 0 && this != this.getDropType((IBlockData) this.getStates().a().iterator().next(), world, blockposition, i)) { - int j = random.nextInt(i + 2) - 1; - - if (j < 0) { - j = 0; - } - - return this.a(iblockdata, random) * (j + 1); - } else { - return this.a(iblockdata, random); - } - } - - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - super.dropNaturally(iblockdata, world, blockposition, f, i); + @Override + public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { + super.dropNaturally(iblockdata, world, blockposition, itemstack); /* CraftBukkit start - Delegated to getExpDrop - if (this.getDropType(iblockdata, world, blockposition, i) != this) { - int j = 0; + if (EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) == 0) { + int i = this.a(world.random); - if (this == Blocks.COAL_ORE) { - j = MathHelper.nextInt(world.random, 0, 2); - } else if (this == Blocks.DIAMOND_ORE) { - j = MathHelper.nextInt(world.random, 3, 7); - } else if (this == Blocks.EMERALD_ORE) { - j = MathHelper.nextInt(world.random, 3, 7); - } else if (this == Blocks.LAPIS_ORE) { - j = MathHelper.nextInt(world.random, 2, 5); - } else if (this == Blocks.NETHER_QUARTZ_ORE) { - j = MathHelper.nextInt(world.random, 2, 5); + if (i > 0) { + this.dropExperience(world, blockposition, i); } - - this.dropExperience(world, blockposition, j); } // */ } @Override - public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, int enchantmentLevel) { - if (this.getDropType(iblockdata, world, blockposition, enchantmentLevel) != this) { - int j = 0; + public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { + if (EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) == 0) { + int i = this.a(world.random); - if (this == Blocks.COAL_ORE) { - j = MathHelper.nextInt(world.random, 0, 2); - } else if (this == Blocks.DIAMOND_ORE) { - j = MathHelper.nextInt(world.random, 3, 7); - } else if (this == Blocks.EMERALD_ORE) { - j = MathHelper.nextInt(world.random, 3, 7); - } else if (this == Blocks.LAPIS_ORE) { - j = MathHelper.nextInt(world.random, 2, 5); - } else if (this == Blocks.NETHER_QUARTZ_ORE) { - j = MathHelper.nextInt(world.random, 2, 5); + if (i > 0) { + return i; } - - return j; } return 0; // CraftBukkit end } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - return new ItemStack(this); - } } diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java index bbfb16576..de804348f 100644 --- a/src/main/java/net/minecraft/server/BlockPiston.java +++ b/src/main/java/net/minecraft/server/BlockPiston.java @@ -7,14 +7,8 @@ import java.util.List; import java.util.Set; // CraftBukkit start -import java.util.AbstractList; -import java.util.Collection; -import java.util.Iterator; -import java.util.ListIterator; - import com.google.common.collect.ImmutableList; - -import org.bukkit.craftbukkit.CraftWorld; +import java.util.AbstractList; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPistonExtendEvent; @@ -22,51 +16,55 @@ import org.bukkit.event.block.BlockPistonExtendEvent; public class BlockPiston extends BlockDirectional { - public static final BlockStateBoolean EXTENDED = BlockProperties.f; + public static final BlockStateBoolean EXTENDED = BlockProperties.g; protected static final VoxelShape c = Block.a(0.0D, 0.0D, 0.0D, 12.0D, 16.0D, 16.0D); - protected static final VoxelShape o = Block.a(4.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); - protected static final VoxelShape p = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 12.0D); - protected static final VoxelShape q = Block.a(0.0D, 0.0D, 4.0D, 16.0D, 16.0D, 16.0D); - protected static final VoxelShape r = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 12.0D, 16.0D); - protected static final VoxelShape s = Block.a(0.0D, 4.0D, 0.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape d = Block.a(4.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape e = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 12.0D); + protected static final VoxelShape f = Block.a(0.0D, 0.0D, 4.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape g = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 12.0D, 16.0D); + protected static final VoxelShape h = Block.a(0.0D, 4.0D, 0.0D, 16.0D, 16.0D, 16.0D); private final boolean sticky; public BlockPiston(boolean flag, Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPiston.FACING, EnumDirection.NORTH)).set(BlockPiston.EXTENDED, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPiston.FACING, EnumDirection.NORTH)).set(BlockPiston.EXTENDED, false)); this.sticky = flag; } - public boolean q(IBlockData iblockdata) { + @Override + public boolean c(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return !(Boolean) iblockdata.get(BlockPiston.EXTENDED); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { if ((Boolean) iblockdata.get(BlockPiston.EXTENDED)) { switch ((EnumDirection) iblockdata.get(BlockPiston.FACING)) { - case DOWN: - return BlockPiston.s; - case UP: - default: - return BlockPiston.r; - case NORTH: - return BlockPiston.q; - case SOUTH: - return BlockPiston.p; - case WEST: - return BlockPiston.o; - case EAST: - return BlockPiston.c; + case DOWN: + return BlockPiston.h; + case UP: + default: + return BlockPiston.g; + case NORTH: + return BlockPiston.f; + case SOUTH: + return BlockPiston.e; + case WEST: + return BlockPiston.d; + case EAST: + return BlockPiston.c; } } else { return VoxelShapes.b(); } } - public boolean r(IBlockData iblockdata) { - return !(Boolean) iblockdata.get(BlockPiston.EXTENDED) || iblockdata.get(BlockPiston.FACING) == EnumDirection.DOWN; + @Override + public boolean isOccluding(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return false; } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { if (!world.isClientSide) { this.a(world, blockposition, iblockdata); @@ -74,14 +72,16 @@ public class BlockPiston extends BlockDirectional { } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if (!world.isClientSide) { this.a(world, blockposition, iblockdata); } } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata1.getBlock() != iblockdata.getBlock()) { if (!world.isClientSide && world.getTileEntity(blockposition) == null) { this.a(world, blockposition, iblockdata); @@ -90,6 +90,7 @@ public class BlockPiston extends BlockDirectional { } } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return (IBlockData) ((IBlockData) this.getBlockData().set(BlockPiston.FACING, blockactioncontext.d().opposite())).set(BlockPiston.EXTENDED, false); } @@ -113,7 +114,7 @@ public class BlockPiston extends BlockDirectional { if (tileentity instanceof TileEntityPiston) { TileEntityPiston tileentitypiston = (TileEntityPiston) tileentity; - if (tileentitypiston.c() && (tileentitypiston.a(0.0F) < 0.5F || world.getTime() == tileentitypiston.k() || ((WorldServer) world).j_())) { + if (tileentitypiston.d() && (tileentitypiston.a(0.0F) < 0.5F || world.getTime() == tileentitypiston.v() || ((WorldServer) world).b())) { b0 = 2; } } @@ -121,7 +122,7 @@ public class BlockPiston extends BlockDirectional { // CraftBukkit start //if (!this.sticky) { // Paper - Prevents empty sticky pistons from firing retract - history behind is odd - org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.of(), CraftBlock.notchToBlockFace(enumdirection)); world.getServer().getPluginManager().callEvent(event); @@ -170,6 +171,7 @@ public class BlockPiston extends BlockDirectional { } } + @Override public boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, int i, int j) { EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockPiston.FACING); @@ -192,18 +194,18 @@ public class BlockPiston extends BlockDirectional { } world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockPiston.EXTENDED, true), 67); - world.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5F, world.random.nextFloat() * 0.25F + 0.6F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5F, world.random.nextFloat() * 0.25F + 0.6F); } else if (i == 1 || i == 2) { TileEntity tileentity = world.getTileEntity(blockposition.shift(enumdirection)); if (tileentity instanceof TileEntityPiston) { - ((TileEntityPiston) tileentity).j(); + ((TileEntityPiston) tileentity).u(); } world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT), 3); world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true)); if (this.sticky) { - BlockPosition blockposition1 = blockposition.a(enumdirection.getAdjacentX() * 2, enumdirection.getAdjacentY() * 2, enumdirection.getAdjacentZ() * 2); + BlockPosition blockposition1 = blockposition.b(enumdirection.getAdjacentX() * 2, enumdirection.getAdjacentY() * 2, enumdirection.getAdjacentZ() * 2); IBlockData iblockdata1 = world.getType(blockposition1); Block block = iblockdata1.getBlock(); boolean flag1 = false; @@ -214,8 +216,8 @@ public class BlockPiston extends BlockDirectional { if (tileentity1 instanceof TileEntityPiston) { TileEntityPiston tileentitypiston = (TileEntityPiston) tileentity1; - if (tileentitypiston.d() == enumdirection && tileentitypiston.c()) { - tileentitypiston.j(); + if (tileentitypiston.f() == enumdirection && tileentitypiston.d()) { + tileentitypiston.u(); flag1 = true; } } @@ -225,23 +227,19 @@ public class BlockPiston extends BlockDirectional { if (i == 1 && !iblockdata1.isAir() && a(iblockdata1, world, blockposition1, enumdirection.opposite(), false, enumdirection) && (iblockdata1.getPushReaction() == EnumPistonReaction.NORMAL || block == Blocks.PISTON || block == Blocks.STICKY_PISTON)) { this.a(world, blockposition, enumdirection, false); } else { - world.setAir(blockposition.shift(enumdirection)); + world.a(blockposition.shift(enumdirection), false); } } } else { - world.setAir(blockposition.shift(enumdirection)); + world.a(blockposition.shift(enumdirection), false); } - world.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_PISTON_CONTRACT, SoundCategory.BLOCKS, 0.5F, world.random.nextFloat() * 0.15F + 0.6F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_PISTON_CONTRACT, SoundCategory.BLOCKS, 0.5F, world.random.nextFloat() * 0.15F + 0.6F); } return true; } - public boolean a(IBlockData iblockdata) { - return false; - } - public static boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, EnumDirection enumdirection, boolean flag, EnumDirection enumdirection1) { Block block = iblockdata.getBlock(); @@ -250,19 +248,19 @@ public class BlockPiston extends BlockDirectional { } else if (!world.getWorldBorder().a(blockposition)) { return false; } else if (blockposition.getY() >= 0 && (enumdirection != EnumDirection.DOWN || blockposition.getY() != 0)) { - if (blockposition.getY() <= world.getHeight() - 1 && (enumdirection != EnumDirection.UP || blockposition.getY() != world.getHeight() - 1)) { + if (blockposition.getY() <= world.getBuildHeight() - 1 && (enumdirection != EnumDirection.UP || blockposition.getY() != world.getBuildHeight() - 1)) { if (block != Blocks.PISTON && block != Blocks.STICKY_PISTON) { - if (iblockdata.e(world, blockposition) == -1.0F) { + if (iblockdata.f(world, blockposition) == -1.0F) { return false; } switch (iblockdata.getPushReaction()) { - case BLOCK: - return false; - case DESTROY: - return flag; - case PUSH_ONLY: - return enumdirection == enumdirection1; + case BLOCK: + return false; + case DESTROY: + return flag; + case PUSH_ONLY: + return enumdirection == enumdirection1; } } else if ((Boolean) iblockdata.get(BlockPiston.EXTENDED)) { return false; @@ -304,7 +302,7 @@ public class BlockPiston extends BlockDirectional { EnumDirection enumdirection1 = flag ? enumdirection : enumdirection.opposite(); Set set = Sets.newHashSet(list); // CraftBukkit start - final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(blockposition); // Akarin + final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); final List moved = pistonextendschecker.getMovedBlocks(); final List broken = pistonextendschecker.getBrokenBlocks(); @@ -322,7 +320,7 @@ public class BlockPiston extends BlockDirectional { throw new ArrayIndexOutOfBoundsException(index); } BlockPosition pos = (BlockPosition) (index < moved.size() ? moved.get(index) : broken.get(index - moved.size())); - return ((CraftWorld) bblock.getWorld()).getBlockAt(pos); // Akarin + return bblock.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); } }; org.bukkit.event.block.BlockPistonEvent event; @@ -353,7 +351,9 @@ public class BlockPiston extends BlockDirectional { for (k = list2.size() - 1; k >= 0; --k) { blockposition3 = (BlockPosition) list2.get(k); iblockdata = world.getType(blockposition3); - iblockdata.a(world, blockposition3, 0); + TileEntity tileentity = iblockdata.getBlock().isTileEntity() ? world.getTileEntity(blockposition3) : null; + + a(iblockdata, world, blockposition3, tileentity); world.setTypeAndData(blockposition3, Blocks.AIR.getBlockData(), 18); --j; aiblockdata[j] = iblockdata; @@ -409,26 +409,27 @@ public class BlockPiston extends BlockDirectional { } } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { return (IBlockData) iblockdata.set(BlockPiston.FACING, enumblockrotation.a((EnumDirection) iblockdata.get(BlockPiston.FACING))); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockPiston.FACING))); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockPiston.FACING, BlockPiston.EXTENDED); } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return iblockdata.get(BlockPiston.FACING) != enumdirection.opposite() && (Boolean) iblockdata.get(BlockPiston.EXTENDED) ? EnumBlockFaceShape.UNDEFINED : EnumBlockFaceShape.SOLID; - } - - public int j(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return 0; + @Override + public boolean n(IBlockData iblockdata) { + return (Boolean) iblockdata.get(BlockPiston.EXTENDED); } + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { return false; } diff --git a/src/main/java/net/minecraft/server/BlockPlant.java b/src/main/java/net/minecraft/server/BlockPlant.java index 317ae1634..0526af776 100644 --- a/src/main/java/net/minecraft/server/BlockPlant.java +++ b/src/main/java/net/minecraft/server/BlockPlant.java @@ -6,12 +6,13 @@ public class BlockPlant extends Block { super(block_info); } - protected boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + protected boolean a_(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { Block block = iblockdata.getBlock(); return block == Blocks.GRASS_BLOCK || block == Blocks.DIRT || block == Blocks.COARSE_DIRT || block == Blocks.PODZOL || block == Blocks.FARMLAND; } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { // CraftBukkit start if (!iblockdata.canPlace(generatoraccess, blockposition)) { @@ -23,25 +24,20 @@ public class BlockPlant extends Block { // CraftBukkit end } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { BlockPosition blockposition1 = blockposition.down(); - return this.b(iworldreader.getType(blockposition1), (IBlockAccess) iworldreader, blockposition1); - } - - public boolean a(IBlockData iblockdata) { - return false; + return this.a_(iworldreader.getType(blockposition1), iworldreader, blockposition1); } + @Override public TextureType c() { return TextureType.CUTOUT; } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - - public int j(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return 0; + @Override + public boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return true; } } diff --git a/src/main/java/net/minecraft/server/BlockPortal.java b/src/main/java/net/minecraft/server/BlockPortal.java index 638bcd156..4eef7127a 100644 --- a/src/main/java/net/minecraft/server/BlockPortal.java +++ b/src/main/java/net/minecraft/server/BlockPortal.java @@ -6,57 +6,52 @@ import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.event.entity.EntityPortalEnterEvent; import org.bukkit.event.world.PortalCreateEvent; // CraftBukkit end public class BlockPortal extends Block { - public static final BlockStateEnum AXIS = BlockProperties.z; + public static final BlockStateEnum AXIS = BlockProperties.D; protected static final VoxelShape b = Block.a(0.0D, 0.0D, 6.0D, 16.0D, 16.0D, 10.0D); protected static final VoxelShape c = Block.a(6.0D, 0.0D, 0.0D, 10.0D, 16.0D, 16.0D); public BlockPortal(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPortal.AXIS, EnumDirection.EnumAxis.X)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPortal.AXIS, EnumDirection.EnumAxis.X)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { switch ((EnumDirection.EnumAxis) iblockdata.get(BlockPortal.AXIS)) { - case Z: - return BlockPortal.c; - case X: - default: - return BlockPortal.b; + case Z: + return BlockPortal.c; + case X: + default: + return BlockPortal.b; } } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { - if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.worldProvider.isOverworld() && world.getGameRules().getBoolean("doMobSpawning") && random.nextInt(2000) < world.getDifficulty().a()) { // Spigot - int i = blockposition.getY(); - - BlockPosition blockposition1; - - for (blockposition1 = blockposition; !world.getType(blockposition1).q() && blockposition1.getY() > 0; blockposition1 = blockposition1.down()) { - ; + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.worldProvider.isOverworld() && world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && random.nextInt(2000) < world.getDifficulty().a()) { // Spigot + while (world.getType(blockposition).getBlock() == this) { + blockposition = blockposition.down(); } - if (i > 0 && !world.getType(blockposition1.up()).isOccluding()) { + if (world.getType(blockposition).a((IBlockAccess) world, blockposition, EntityTypes.ZOMBIE_PIGMAN)) { // CraftBukkit - set spawn reason to NETHER_PORTAL - Entity entity = EntityTypes.ZOMBIE_PIGMAN.spawnCreature(world, (NBTTagCompound) null, (IChatBaseComponent) null, (EntityHuman) null, blockposition1.up(), false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL); + Entity entity = EntityTypes.ZOMBIE_PIGMAN.spawnCreature(world, (NBTTagCompound) null, (IChatBaseComponent) null, (EntityHuman) null, blockposition.up(), EnumMobSpawn.STRUCTURE, false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL); if (entity != null) { - entity.portalCooldown = entity.aQ(); + entity.portalCooldown = entity.aX(); } } } } - public boolean a(IBlockData iblockdata) { - return false; - } - public boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition) { BlockPortal.Shape blockportal_shape = this.b(generatoraccess, blockposition); @@ -83,6 +78,7 @@ public class BlockPortal extends Block { } } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { EnumDirection.EnumAxis enumdirection_enumaxis = enumdirection.k(); EnumDirection.EnumAxis enumdirection_enumaxis1 = (EnumDirection.EnumAxis) iblockdata.get(BlockPortal.AXIS); @@ -91,46 +87,42 @@ public class BlockPortal extends Block { return !flag && iblockdata1.getBlock() != this && !(new BlockPortal.Shape(generatoraccess, blockposition, enumdirection_enumaxis1)).f() ? Blocks.AIR.getBlockData() : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } - public int a(IBlockData iblockdata, Random random) { - return 0; - } - + @Override public TextureType c() { return TextureType.TRANSLUCENT; } + @Override public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { - if (!entity.isPassenger() && !entity.isVehicle() && entity.bm()) { + if (!entity.isPassenger() && !entity.isVehicle() && entity.canPortal()) { // CraftBukkit start - Entity in portal EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ())); world.getServer().getPluginManager().callEvent(event); // CraftBukkit end - entity.e(blockposition); + entity.c(blockposition); } } - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - return ItemStack.a; - } - + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { switch (enumblockrotation) { - case COUNTERCLOCKWISE_90: - case CLOCKWISE_90: - switch ((EnumDirection.EnumAxis) iblockdata.get(BlockPortal.AXIS)) { - case Z: - return (IBlockData) iblockdata.set(BlockPortal.AXIS, EnumDirection.EnumAxis.X); - case X: - return (IBlockData) iblockdata.set(BlockPortal.AXIS, EnumDirection.EnumAxis.Z); + case COUNTERCLOCKWISE_90: + case CLOCKWISE_90: + switch ((EnumDirection.EnumAxis) iblockdata.get(BlockPortal.AXIS)) { + case Z: + return (IBlockData) iblockdata.set(BlockPortal.AXIS, EnumDirection.EnumAxis.X); + case X: + return (IBlockData) iblockdata.set(BlockPortal.AXIS, EnumDirection.EnumAxis.Z); + default: + return iblockdata; + } default: return iblockdata; - } - default: - return iblockdata; } } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockPortal.AXIS); } @@ -138,7 +130,7 @@ public class BlockPortal extends Block { public ShapeDetector.ShapeDetectorCollection c(GeneratorAccess generatoraccess, BlockPosition blockposition) { EnumDirection.EnumAxis enumdirection_enumaxis = EnumDirection.EnumAxis.Z; BlockPortal.Shape blockportal_shape = new BlockPortal.Shape(generatoraccess, blockposition, EnumDirection.EnumAxis.X); - com.github.benmanes.caffeine.cache.LoadingCache loadingcache = ShapeDetector.a(generatoraccess, true); // Akarin - caffeine + LoadingCache loadingcache = ShapeDetector.a(generatoraccess, true); if (!blockportal_shape.d()) { enumdirection_enumaxis = EnumDirection.EnumAxis.X; @@ -188,10 +180,6 @@ public class BlockPortal extends Block { } } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - public static class Shape { private final GeneratorAccess a; @@ -199,10 +187,11 @@ public class BlockPortal extends Block { private final EnumDirection c; private final EnumDirection d; private int e; + @Nullable private BlockPosition position; private int height; private int width; - java.util.Collection blocks = new java.util.HashSet(); // CraftBukkit - add field + java.util.List blocks = new java.util.ArrayList(); // CraftBukkit - add field public Shape(GeneratorAccess generatoraccess, BlockPosition blockposition, EnumDirection.EnumAxis enumdirection_enumaxis) { this.a = generatoraccess; @@ -289,7 +278,7 @@ public class BlockPortal extends Block { // CraftBukkit start - add the block to our list } else { BlockPosition pos = blockposition.shift(this.d); - blocks.add(CraftBlock.at(this.a, pos)); + blocks.add(CraftBlock.at(this.a, pos).getState()); // CraftBukkit end } } else if (i == this.width - 1) { @@ -299,7 +288,7 @@ public class BlockPortal extends Block { // CraftBukkit start - add the block to our list } else { BlockPosition pos = blockposition.shift(this.c); - blocks.add(CraftBlock.at(this.a, pos)); + blocks.add(CraftBlock.at(this.a, pos).getState()); // CraftBukkit end } } @@ -313,7 +302,7 @@ public class BlockPortal extends Block { // CraftBukkit start - add the block to our list } else { BlockPosition pos = this.position.shift(this.c, i).up(this.height); - blocks.add(CraftBlock.at(this.a, pos)); + blocks.add(CraftBlock.at(this.a, pos).getState()); // CraftBukkit end } } @@ -340,7 +329,7 @@ public class BlockPortal extends Block { // CraftBukkit start - return boolean public boolean createPortal() { - org.bukkit.craftbukkit.CraftWorld bworld = this.a.getMinecraftWorld().getWorld(); // Akarin + org.bukkit.World bworld = this.a.getMinecraftWorld().getWorld(); // Copy below for loop for (int i = 0; i < this.width; ++i) { @@ -348,11 +337,13 @@ public class BlockPortal extends Block { for (int j = 0; j < this.height; ++j) { BlockPosition pos = blockposition.up(j); - blocks.add(bworld.getBlockAt(pos)); // Akarin + CraftBlockState state = CraftBlockState.getBlockState(this.a.getMinecraftWorld(), pos, 18); + state.setData((IBlockData) Blocks.NETHER_PORTAL.getBlockData().set(BlockPortal.AXIS, this.b)); + blocks.add(state); } } - PortalCreateEvent event = new PortalCreateEvent(blocks, bworld, PortalCreateEvent.CreateReason.FIRE); + PortalCreateEvent event = new PortalCreateEvent(blocks, bworld, null, PortalCreateEvent.CreateReason.FIRE); this.a.getMinecraftWorld().getMinecraftServer().server.getPluginManager().callEvent(event); if (event.isCancelled()) { diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java index 5ce18f54c..16f093040 100644 --- a/src/main/java/net/minecraft/server/BlockPosition.java +++ b/src/main/java/net/minecraft/server/BlockPosition.java @@ -2,24 +2,32 @@ package net.minecraft.server; import com.google.common.collect.AbstractIterator; import com.google.common.collect.Lists; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.DynamicOps; import java.util.List; +import java.util.Spliterator.OfInt; +import java.util.Spliterators.AbstractSpliterator; +import java.util.function.Consumer; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; import javax.annotation.concurrent.Immutable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @Immutable -public class BlockPosition extends BaseBlockPosition { +public class BlockPosition extends BaseBlockPosition implements MinecraftSerializable { - //private static final Logger b = LogManager.getLogger(); // Paper - variable name conflict, logger isn't used + private static final Logger LOGGER = LogManager.getLogger(); public static final BlockPosition ZERO = new BlockPosition(0, 0, 0); private static final int c = 1 + MathHelper.e(MathHelper.c(30000000)); private static final int d = BlockPosition.c; private static final int f = 64 - BlockPosition.c - BlockPosition.d; - private static final int g = 0 + BlockPosition.d; - private static final int h = BlockPosition.g + BlockPosition.f; - private static final long i = (1L << BlockPosition.c) - 1L; - private static final long j = (1L << BlockPosition.f) - 1L; - private static final long k = (1L << BlockPosition.d) - 1L; + private static final long g = (1L << BlockPosition.c) - 1L; + private static final long h = (1L << BlockPosition.f) - 1L; + private static final long i = (1L << BlockPosition.d) - 1L; + private static final int j = BlockPosition.f; + private static final int k = BlockPosition.f + BlockPosition.d; public BlockPosition(int i, int j, int k) { super(i, j, k); @@ -37,25 +45,92 @@ public class BlockPosition extends BaseBlockPosition { this(vec3d.x, vec3d.y, vec3d.z); } + public BlockPosition(IPosition iposition) { + this(iposition.getX(), iposition.getY(), iposition.getZ()); + } + public BlockPosition(BaseBlockPosition baseblockposition) { this(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); } + public static BlockPosition a(Dynamic dynamic) { + OfInt ofint = dynamic.asIntStream().spliterator(); + int[] aint = new int[3]; + + if (ofint.tryAdvance((Consumer) (i) -> { // Paper - decomile fix + aint[0] = i; + }) && ofint.tryAdvance((Consumer) (i) -> { // Paper - decompile fix + aint[1] = i; + })) { + ofint.tryAdvance((Consumer) (i) -> { // Paper - decompile fix + aint[2] = i; + }); + } + + return new BlockPosition(aint[0], aint[1], aint[2]); + } + + @Override + public T a(DynamicOps dynamicops) { + return dynamicops.createIntList(IntStream.of(new int[]{this.getX(), this.getY(), this.getZ()})); + } + + public static long a(long i, EnumDirection enumdirection) { + return a(i, enumdirection.getAdjacentX(), enumdirection.getAdjacentY(), enumdirection.getAdjacentZ()); + } + + public static long a(long i, int j, int k, int l) { + return a(b(i) + j, c(i) + k, d(i) + l); + } + + public static int b(long i) { + return (int) (i << 64 - BlockPosition.k - BlockPosition.c >> 64 - BlockPosition.c); + } + + public static int c(long i) { + return (int) (i << 64 - BlockPosition.f >> 64 - BlockPosition.f); + } + + public static int d(long i) { + return (int) (i << 64 - BlockPosition.j - BlockPosition.d >> 64 - BlockPosition.d); + } + + public static BlockPosition fromLong(long i) { + return new BlockPosition(b(i), c(i), d(i)); + } + + public static long a(int i, int j, int k) { + long l = 0L; + + l |= ((long) i & BlockPosition.g) << BlockPosition.k; + l |= ((long) j & BlockPosition.h) << 0; + l |= ((long) k & BlockPosition.i) << BlockPosition.j; + return l; + } + + public static long f(long i) { + return i & -16L; + } + + public long asLong() { + return a(this.getX(), this.getY(), this.getZ()); + } + public BlockPosition a(double d0, double d1, double d2) { return d0 == 0.0D && d1 == 0.0D && d2 == 0.0D ? this : new BlockPosition((double) this.getX() + d0, (double) this.getY() + d1, (double) this.getZ() + d2); } - public BlockPosition add(int i, int j, int k) {return a(i, j, k);} // Paper - OBFHELPER - public BlockPosition a(int i, int j, int k) { + public BlockPosition add(int i, int j, int k) {return b(i, j, k);} // Paper - OBFHELPER + public BlockPosition b(int i, int j, int k) { return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k); } public BlockPosition a(BaseBlockPosition baseblockposition) { - return this.a(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); + return this.b(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); } public BlockPosition b(BaseBlockPosition baseblockposition) { - return this.a(-baseblockposition.getX(), -baseblockposition.getY(), -baseblockposition.getZ()); + return this.b(-baseblockposition.getX(), -baseblockposition.getY(), -baseblockposition.getZ()); } public BlockPosition up() { @@ -133,108 +208,61 @@ public class BlockPosition extends BaseBlockPosition { public BlockPosition a(EnumBlockRotation enumblockrotation) { switch (enumblockrotation) { - case NONE: - default: - return this; - case CLOCKWISE_90: - return new BlockPosition(-this.getZ(), this.getY(), this.getX()); - case CLOCKWISE_180: - return new BlockPosition(-this.getX(), this.getY(), -this.getZ()); - case COUNTERCLOCKWISE_90: - return new BlockPosition(this.getZ(), this.getY(), -this.getX()); + case NONE: + default: + return this; + case CLOCKWISE_90: + return new BlockPosition(-this.getZ(), this.getY(), this.getX()); + case CLOCKWISE_180: + return new BlockPosition(-this.getX(), this.getY(), -this.getZ()); + case COUNTERCLOCKWISE_90: + return new BlockPosition(this.getZ(), this.getY(), -this.getX()); } } + @Override public BlockPosition d(BaseBlockPosition baseblockposition) { return new BlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX()); } - public long asLong() { - return ((long) this.getX() & BlockPosition.i) << BlockPosition.h | ((long) this.getY() & BlockPosition.j) << BlockPosition.g | ((long) this.getZ() & BlockPosition.k) << 0; - } - - public static BlockPosition fromLong(long i) { - int j = (int) (i << 64 - BlockPosition.h - BlockPosition.c >> 64 - BlockPosition.c); - int k = (int) (i << 64 - BlockPosition.g - BlockPosition.f >> 64 - BlockPosition.f); - int l = (int) (i << 64 - BlockPosition.d >> 64 - BlockPosition.d); - - return new BlockPosition(j, k, l); - } - - public static Iterable a(BlockPosition blockposition, BlockPosition blockposition1) { - return a(Math.min(blockposition.getX(), blockposition1.getX()), Math.min(blockposition.getY(), blockposition1.getY()), Math.min(blockposition.getZ(), blockposition1.getZ()), Math.max(blockposition.getX(), blockposition1.getX()), Math.max(blockposition.getY(), blockposition1.getY()), Math.max(blockposition.getZ(), blockposition1.getZ())); - } - - public static Iterable a(int ix, int jx, int kx, int l, int i1, int j1) { // Paper - decompile fix - return () -> { - return new AbstractIterator() { - private boolean g = true; - private int h; - private int i; - private int j; - - protected BlockPosition computeNext() { - if (this.g) { - this.g = false; - this.h = ix; // Paper - decompile fix - this.i = jx; // Paper - decompile fix - this.j = kx; // Paper - decompile fix - return new BlockPosition(ix, jx, kx); - } else if (this.h == l && this.i == i1 && this.j == j1) { - return (BlockPosition) this.endOfData(); - } else { - if (this.h < l) { - ++this.h; - } else if (this.i < i1) { - this.h = ix; // Paper - decompile fix - ++this.i; - } else if (this.j < j1) { - this.h = ix; // Paper - decompile fix - this.i = jx; // Paper - decompile fix - ++this.j; - } - - return new BlockPosition(this.h, this.i, this.j); - } - } - }; - }; - } - - public BlockPosition asImmutable() { return h(); } // Paper - OBFHELPER - public BlockPosition h() { + @Deprecated // We'll replace this... + public BlockPosition asImmutable() { return immutableCopy(); } // Paper - OBFHELPER + public BlockPosition immutableCopy() { return this; } - public static Iterable b(BlockPosition blockposition, BlockPosition blockposition1) { + public static Iterable a(BlockPosition blockposition, BlockPosition blockposition1) { return b(Math.min(blockposition.getX(), blockposition1.getX()), Math.min(blockposition.getY(), blockposition1.getY()), Math.min(blockposition.getZ(), blockposition1.getZ()), Math.max(blockposition.getX(), blockposition1.getX()), Math.max(blockposition.getY(), blockposition1.getY()), Math.max(blockposition.getZ(), blockposition1.getZ())); } - public static Iterable b(int i, int j, int k, int l, int i1, int j1) { + public static Stream b(BlockPosition blockposition, BlockPosition blockposition1) { + return a(Math.min(blockposition.getX(), blockposition1.getX()), Math.min(blockposition.getY(), blockposition1.getY()), Math.min(blockposition.getZ(), blockposition1.getZ()), Math.max(blockposition.getX(), blockposition1.getX()), Math.max(blockposition.getY(), blockposition1.getY()), Math.max(blockposition.getZ(), blockposition1.getZ())); + } + + public static Stream a(final int i, final int j, final int k, final int l, final int i1, final int j1) { + return StreamSupport.stream(new AbstractSpliterator((long) ((l - i + 1) * (i1 - j + 1) * (j1 - k + 1)), 64) { + final CursorPosition a = new CursorPosition(i, j, k, l, i1, j1); + final BlockPosition.MutableBlockPosition b = new BlockPosition.MutableBlockPosition(); + + public boolean tryAdvance(Consumer consumer) { + if (this.a.a()) { + consumer.accept(this.b.d(this.a.b(), this.a.c(), this.a.d())); + return true; + } else { + return false; + } + } + }, false); + } + + public static Iterable b(int i, int j, int k, int l, int i1, int j1) { return () -> { - return new AbstractIterator() { - private BlockPosition.MutableBlockPosition g; + return new AbstractIterator() { + final CursorPosition a = new CursorPosition(i, j, k, l, i1, j1); + final BlockPosition.MutableBlockPosition b = new BlockPosition.MutableBlockPosition(); - protected BlockPosition.MutableBlockPosition computeNext() { - if (this.g == null) { - this.g = new BlockPosition.MutableBlockPosition(i, j, k); - return this.g; - } else if (this.g.x == l && this.g.y == i1 && this.g.z == j1) { - return (BlockPosition.MutableBlockPosition) this.endOfData(); - } else { - if (this.g.x < l) { - ++this.g.x; - } else if (this.g.y < i1) { - this.g.x = i; // Paper - decompile fix Readd line removed by the decompiler - ++this.g.y; - } else if (this.g.z < j1) { - this.g.x = i; // Paper - decompile fix Readd line removed by the decompiler - this.g.y = j; // Paper - decompile fix Readd line removed by the decompiler - ++this.g.z; - } - - return this.g; - } + protected BlockPosition computeNext() { + return (BlockPosition) (this.a.a() ? this.b.d(this.a.b(), this.a.c(), this.a.d()) : (BlockPosition) this.endOfData()); } }; }; @@ -250,7 +278,7 @@ public class BlockPosition extends BaseBlockPosition { } public static BlockPosition.PooledBlockPosition r() { - return e(0, 0, 0); + return f(0, 0, 0); } public static BlockPosition.PooledBlockPosition b(Entity entity) { @@ -258,17 +286,17 @@ public class BlockPosition extends BaseBlockPosition { } public static BlockPosition.PooledBlockPosition d(double d0, double d1, double d2) { - return e(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); + return f(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); } - public static BlockPosition.PooledBlockPosition e(int i, int j, int k) { + public static BlockPosition.PooledBlockPosition f(int i, int j, int k) { synchronized (BlockPosition.PooledBlockPosition.g) { if (!BlockPosition.PooledBlockPosition.g.isEmpty()) { BlockPosition.PooledBlockPosition blockposition_pooledblockposition = (BlockPosition.PooledBlockPosition) BlockPosition.PooledBlockPosition.g.remove(BlockPosition.PooledBlockPosition.g.size() - 1); if (blockposition_pooledblockposition != null && blockposition_pooledblockposition.f) { blockposition_pooledblockposition.f = false; - blockposition_pooledblockposition.c(i, j, k); + blockposition_pooledblockposition.d(i, j, k); return blockposition_pooledblockposition; } } @@ -277,28 +305,39 @@ public class BlockPosition extends BaseBlockPosition { return new BlockPosition.PooledBlockPosition(i, j, k); } - public BlockPosition.PooledBlockPosition c(int i, int j, int k) { - return (BlockPosition.PooledBlockPosition) super.c(i, j, k); + @Override + public BlockPosition.PooledBlockPosition d(int i, int j, int k) { + return (BlockPosition.PooledBlockPosition) super.d(i, j, k); } + @Override + public BlockPosition.PooledBlockPosition a(Entity entity) { + return (BlockPosition.PooledBlockPosition) super.a(entity); + } + + @Override public BlockPosition.PooledBlockPosition c(double d0, double d1, double d2) { return (BlockPosition.PooledBlockPosition) super.c(d0, d1, d2); } + @Override public BlockPosition.PooledBlockPosition g(BaseBlockPosition baseblockposition) { return (BlockPosition.PooledBlockPosition) super.g(baseblockposition); } + @Override public BlockPosition.PooledBlockPosition c(EnumDirection enumdirection) { return (BlockPosition.PooledBlockPosition) super.c(enumdirection); } + @Override public BlockPosition.PooledBlockPosition c(EnumDirection enumdirection, int i) { return (BlockPosition.PooledBlockPosition) super.c(enumdirection, i); } - public BlockPosition.PooledBlockPosition d(int i, int j, int k) { - return (BlockPosition.PooledBlockPosition) super.d(i, j, k); + @Override + public BlockPosition.PooledBlockPosition e(int i, int j, int k) { + return (BlockPosition.PooledBlockPosition) super.e(i, j, k); } public void close() { @@ -348,39 +387,51 @@ public class BlockPosition extends BaseBlockPosition { // Paper end } + public MutableBlockPosition(double d0, double d1, double d2) { + this(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); + } + + @Override public BlockPosition a(double d0, double d1, double d2) { - return super.a(d0, d1, d2).h(); + return super.a(d0, d1, d2).immutableCopy(); } - public BlockPosition a(int i, int j, int k) { - return super.a(i, j, k).h(); + @Override + public BlockPosition b(int i, int j, int k) { + return super.b(i, j, k).immutableCopy(); } + @Override public BlockPosition shift(EnumDirection enumdirection, int i) { - return super.shift(enumdirection, i).h(); + return super.shift(enumdirection, i).immutableCopy(); } + @Override public BlockPosition a(EnumBlockRotation enumblockrotation) { - return super.a(enumblockrotation).h(); + return super.a(enumblockrotation).immutableCopy(); } + /* // Paper start - use parent getters + @Override public int getX() { return this.b; } + @Override public int getY() { return this.c; } + @Override public int getZ() { return this.d; }*/ // Paper end - public BlockPosition.MutableBlockPosition setValues(int i, int j, int k) { return c(i, j, k);} // Paper - OBFHELPER - public BlockPosition.MutableBlockPosition c(int i, int j, int k) { + public BlockPosition.MutableBlockPosition setValues(int i, int j, int k) { return d(i, j, k);} // Paper - OBFHELPER + public BlockPosition.MutableBlockPosition d(int i, int j, int k) { // Paper start - use xyz this.x = i; this.y = j; @@ -389,13 +440,25 @@ public class BlockPosition extends BaseBlockPosition { return this; } + public BlockPosition.MutableBlockPosition a(Entity entity) { + return this.c(entity.locX, entity.locY, entity.locZ); + } + public BlockPosition.MutableBlockPosition setValues(double d0, double d1, double d2) { return c(d0, d1, d2);} // Paper - OBFHELPER public BlockPosition.MutableBlockPosition c(double d0, double d1, double d2) { - return this.c(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); + return this.d(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); } public BlockPosition.MutableBlockPosition g(BaseBlockPosition baseblockposition) { - return this.c(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); + return this.d(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); + } + + public BlockPosition.MutableBlockPosition g(long i) { + return this.d(b(i), c(i), d(i)); + } + + public BlockPosition.MutableBlockPosition a(EnumAxisCycle enumaxiscycle, int i, int j, int k) { + return this.d(enumaxiscycle.a(i, j, k, EnumDirection.EnumAxis.X), enumaxiscycle.a(i, j, k, EnumDirection.EnumAxis.Y), enumaxiscycle.a(i, j, k, EnumDirection.EnumAxis.Z)); } public BlockPosition.MutableBlockPosition c(EnumDirection enumdirection) { @@ -403,19 +466,27 @@ public class BlockPosition extends BaseBlockPosition { } public BlockPosition.MutableBlockPosition c(EnumDirection enumdirection, int i) { - return this.c(x + enumdirection.getAdjacentX() * i, y + enumdirection.getAdjacentY() * i, z + enumdirection.getAdjacentZ() * i); // Paper - use xyz + return this.d(this.x + enumdirection.getAdjacentX() * i, this.y + enumdirection.getAdjacentY() * i, this.z + enumdirection.getAdjacentZ() * i); } - public BlockPosition.MutableBlockPosition d(int i, int j, int k) { - return this.c(x + i, y + j, z + k); // Paper - use xyz + public BlockPosition.MutableBlockPosition e(int i, int j, int k) { + return this.d(this.x + i, this.y + j, this.z + k); + } + + public void o(int i) { + this.x = i; // Paper change to x } public void p(int i) { this.y = i; // Paper change to y } - public BlockPosition toBlockPosition() { return h(); } // Paper - OBFHELPER - public BlockPosition h() { + public void q(int i) { + this.z = i; // Paper change to z + } + + @Override + public BlockPosition immutableCopy() { return new BlockPosition(this); } } diff --git a/src/main/java/net/minecraft/server/BlockPoweredRail.java b/src/main/java/net/minecraft/server/BlockPoweredRail.java index 6e85aebd4..8799dcdab 100644 --- a/src/main/java/net/minecraft/server/BlockPoweredRail.java +++ b/src/main/java/net/minecraft/server/BlockPoweredRail.java @@ -4,12 +4,12 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockPoweredRail extends BlockMinecartTrackAbstract { - public static final BlockStateEnum SHAPE = BlockProperties.S; - public static final BlockStateBoolean POWERED = BlockProperties.t; + public static final BlockStateEnum SHAPE = BlockProperties.X; + public static final BlockStateBoolean POWERED = BlockProperties.w; protected BlockPoweredRail(Block.Info block_info) { super(true, block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH)).set(BlockPoweredRail.POWERED, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH)).set(BlockPoweredRail.POWERED, false)); } protected boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag, int i) { @@ -23,63 +23,63 @@ public class BlockPoweredRail extends BlockMinecartTrackAbstract { BlockPropertyTrackPosition blockpropertytrackposition = (BlockPropertyTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE); switch (blockpropertytrackposition) { - case NORTH_SOUTH: - if (flag) { - ++l; - } else { - --l; - } - break; - case EAST_WEST: - if (flag) { - --j; - } else { - ++j; - } - break; - case ASCENDING_EAST: - if (flag) { - --j; - } else { - ++j; - ++k; - flag1 = false; - } + case NORTH_SOUTH: + if (flag) { + ++l; + } else { + --l; + } + break; + case EAST_WEST: + if (flag) { + --j; + } else { + ++j; + } + break; + case ASCENDING_EAST: + if (flag) { + --j; + } else { + ++j; + ++k; + flag1 = false; + } - blockpropertytrackposition = BlockPropertyTrackPosition.EAST_WEST; - break; - case ASCENDING_WEST: - if (flag) { - --j; - ++k; - flag1 = false; - } else { - ++j; - } + blockpropertytrackposition = BlockPropertyTrackPosition.EAST_WEST; + break; + case ASCENDING_WEST: + if (flag) { + --j; + ++k; + flag1 = false; + } else { + ++j; + } - blockpropertytrackposition = BlockPropertyTrackPosition.EAST_WEST; - break; - case ASCENDING_NORTH: - if (flag) { - ++l; - } else { - --l; - ++k; - flag1 = false; - } + blockpropertytrackposition = BlockPropertyTrackPosition.EAST_WEST; + break; + case ASCENDING_NORTH: + if (flag) { + ++l; + } else { + --l; + ++k; + flag1 = false; + } - blockpropertytrackposition = BlockPropertyTrackPosition.NORTH_SOUTH; - break; - case ASCENDING_SOUTH: - if (flag) { - ++l; - ++k; - flag1 = false; - } else { - --l; - } + blockpropertytrackposition = BlockPropertyTrackPosition.NORTH_SOUTH; + break; + case ASCENDING_SOUTH: + if (flag) { + ++l; + ++k; + flag1 = false; + } else { + --l; + } - blockpropertytrackposition = BlockPropertyTrackPosition.NORTH_SOUTH; + blockpropertytrackposition = BlockPropertyTrackPosition.NORTH_SOUTH; } return this.a(world, new BlockPosition(j, k, l), flag, i, blockpropertytrackposition) ? true : flag1 && this.a(world, new BlockPosition(j, k - 1, l), flag, i, blockpropertytrackposition); @@ -98,6 +98,7 @@ public class BlockPoweredRail extends BlockMinecartTrackAbstract { } } + @Override protected void a(IBlockData iblockdata, World world, BlockPosition blockposition, Block block) { boolean flag = (Boolean) iblockdata.get(BlockPoweredRail.POWERED); boolean flag1 = world.isBlockIndirectlyPowered(blockposition) || this.a(world, blockposition, iblockdata, true, 0) || this.a(world, blockposition, iblockdata, false, 0); @@ -119,127 +120,131 @@ public class BlockPoweredRail extends BlockMinecartTrackAbstract { } + @Override public IBlockState e() { return BlockPoweredRail.SHAPE; } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { switch (enumblockrotation) { - case CLOCKWISE_180: - switch ((BlockPropertyTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE)) { - case ASCENDING_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); - case ASCENDING_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); - case ASCENDING_NORTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); - case ASCENDING_SOUTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - } - case COUNTERCLOCKWISE_90: - switch ((BlockPropertyTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE)) { - case NORTH_SOUTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.EAST_WEST); - case EAST_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH); - case ASCENDING_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); - case ASCENDING_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); - case ASCENDING_NORTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); - case ASCENDING_SOUTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - } - case CLOCKWISE_90: - switch ((BlockPropertyTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE)) { - case NORTH_SOUTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.EAST_WEST); - case EAST_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH); - case ASCENDING_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); - case ASCENDING_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); - case ASCENDING_NORTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); - case ASCENDING_SOUTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - } - default: - return iblockdata; + case CLOCKWISE_180: + switch ((BlockPropertyTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE)) { + case ASCENDING_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); + case ASCENDING_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); + case ASCENDING_NORTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); + case ASCENDING_SOUTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + } + case COUNTERCLOCKWISE_90: + switch ((BlockPropertyTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE)) { + case NORTH_SOUTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.EAST_WEST); + case EAST_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH); + case ASCENDING_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); + case ASCENDING_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); + case ASCENDING_NORTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); + case ASCENDING_SOUTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + } + case CLOCKWISE_90: + switch ((BlockPropertyTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE)) { + case NORTH_SOUTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.EAST_WEST); + case EAST_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_SOUTH); + case ASCENDING_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); + case ASCENDING_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); + case ASCENDING_NORTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); + case ASCENDING_SOUTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + } + default: + return iblockdata; } } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { BlockPropertyTrackPosition blockpropertytrackposition = (BlockPropertyTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE); switch (enumblockmirror) { - case LEFT_RIGHT: - switch (blockpropertytrackposition) { - case ASCENDING_NORTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); - case ASCENDING_SOUTH: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - default: - return super.a(iblockdata, enumblockmirror); - } - case FRONT_BACK: - switch (blockpropertytrackposition) { - case ASCENDING_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); - case ASCENDING_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); - case ASCENDING_NORTH: - case ASCENDING_SOUTH: - default: - break; - case SOUTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); - case SOUTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); - case NORTH_WEST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); - case NORTH_EAST: - return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); - } + case LEFT_RIGHT: + switch (blockpropertytrackposition) { + case ASCENDING_NORTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_SOUTH); + case ASCENDING_SOUTH: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_NORTH); + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + default: + return super.a(iblockdata, enumblockmirror); + } + case FRONT_BACK: + switch (blockpropertytrackposition) { + case ASCENDING_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_WEST); + case ASCENDING_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.ASCENDING_EAST); + case ASCENDING_NORTH: + case ASCENDING_SOUTH: + default: + break; + case SOUTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_WEST); + case SOUTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.SOUTH_EAST); + case NORTH_WEST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_EAST); + case NORTH_EAST: + return (IBlockData) iblockdata.set(BlockPoweredRail.SHAPE, BlockPropertyTrackPosition.NORTH_WEST); + } } return super.a(iblockdata, enumblockmirror); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockPoweredRail.SHAPE, BlockPoweredRail.POWERED); } diff --git a/src/main/java/net/minecraft/server/BlockPressurePlateAbstract.java b/src/main/java/net/minecraft/server/BlockPressurePlateAbstract.java index ac612e0e1..90cdcaf73 100644 --- a/src/main/java/net/minecraft/server/BlockPressurePlateAbstract.java +++ b/src/main/java/net/minecraft/server/BlockPressurePlateAbstract.java @@ -14,33 +14,35 @@ public abstract class BlockPressurePlateAbstract extends Block { super(block_info); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return this.getPower(iblockdata) > 0 ? BlockPressurePlateAbstract.a : BlockPressurePlateAbstract.b; } + @Override public int a(IWorldReader iworldreader) { return 20; } - public boolean a(IBlockData iblockdata) { - return false; - } - - public boolean a() { + @Override + public boolean S_() { return true; } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { return enumdirection == EnumDirection.DOWN && !iblockdata.canPlace(generatoraccess, blockposition) ? Blocks.AIR.getBlockData() : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { - IBlockData iblockdata1 = iworldreader.getType(blockposition.down()); + BlockPosition blockposition1 = blockposition.down(); - return iblockdata1.q() || iblockdata1.getBlock() instanceof BlockFence; + return c((IBlockAccess) iworldreader, blockposition1) || a(iworldreader, blockposition1, EnumDirection.UP); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!world.isClientSide) { int i = this.getPower(iblockdata); @@ -51,6 +53,7 @@ public abstract class BlockPressurePlateAbstract extends Block { } } + @Override public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { if (!world.isClientSide) { int i = this.getPower(iblockdata); @@ -68,11 +71,11 @@ public abstract class BlockPressurePlateAbstract extends Block { boolean flag1 = j > 0; // CraftBukkit start - Interact Pressure Plate - org.bukkit.craftbukkit.CraftWorld bworld = world.getWorld(); // Akarin - CraftWorld + org.bukkit.World bworld = world.getWorld(); org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); if (flag != flag1) { - BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bworld.getBlockAt(blockposition), i, j); // Akarin + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), i, j); manager.callEvent(eventRedstone); flag1 = eventRedstone.getNewCurrent() > 0; @@ -81,10 +84,11 @@ public abstract class BlockPressurePlateAbstract extends Block { // CraftBukkit end if (i != j) { - iblockdata = this.a(iblockdata, j); - world.setTypeAndData(blockposition, iblockdata, 2); + IBlockData iblockdata1 = this.a(iblockdata, j); + + world.setTypeAndData(blockposition, iblockdata1, 2); this.a(world, blockposition); - //world.a(blockposition, blockposition); // Akarin + world.b(blockposition, iblockdata, iblockdata1); } if (!flag1 && flag) { @@ -103,6 +107,7 @@ public abstract class BlockPressurePlateAbstract extends Block { protected abstract void b(GeneratorAccess generatoraccess, BlockPosition blockposition); + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (!flag && iblockdata.getBlock() != iblockdata1.getBlock()) { if (this.getPower(iblockdata) > 0) { @@ -118,18 +123,22 @@ public abstract class BlockPressurePlateAbstract extends Block { world.applyPhysics(blockposition.down(), this); } + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return this.getPower(iblockdata); } + @Override public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return enumdirection == EnumDirection.UP ? this.getPower(iblockdata) : 0; } + @Override public boolean isPowerSource(IBlockData iblockdata) { return true; } + @Override public EnumPistonReaction getPushReaction(IBlockData iblockdata) { return EnumPistonReaction.DESTROY; } @@ -139,8 +148,4 @@ public abstract class BlockPressurePlateAbstract extends Block { protected abstract int getPower(IBlockData iblockdata); protected abstract IBlockData a(IBlockData iblockdata, int i); - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockPressurePlateBinary.java b/src/main/java/net/minecraft/server/BlockPressurePlateBinary.java index 59c39ddce..e063373e8 100644 --- a/src/main/java/net/minecraft/server/BlockPressurePlateBinary.java +++ b/src/main/java/net/minecraft/server/BlockPressurePlateBinary.java @@ -7,54 +7,59 @@ import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit public class BlockPressurePlateBinary extends BlockPressurePlateAbstract { - public static final BlockStateBoolean POWERED = BlockProperties.t; - private final BlockPressurePlateBinary.EnumMobType p; + public static final BlockStateBoolean POWERED = BlockProperties.w; + private final BlockPressurePlateBinary.EnumMobType e; protected BlockPressurePlateBinary(BlockPressurePlateBinary.EnumMobType blockpressureplatebinary_enummobtype, Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPressurePlateBinary.POWERED, false)); - this.p = blockpressureplatebinary_enummobtype; + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPressurePlateBinary.POWERED, false)); + this.e = blockpressureplatebinary_enummobtype; } + @Override protected int getPower(IBlockData iblockdata) { return (Boolean) iblockdata.get(BlockPressurePlateBinary.POWERED) ? 15 : 0; } + @Override protected IBlockData a(IBlockData iblockdata, int i) { return (IBlockData) iblockdata.set(BlockPressurePlateBinary.POWERED, i > 0); } + @Override protected void a(GeneratorAccess generatoraccess, BlockPosition blockposition) { if (this.material == Material.WOOD) { - generatoraccess.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_WOODEN_PRESSURE_PLATE_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.8F); + generatoraccess.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_WOODEN_PRESSURE_PLATE_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.8F); } else { - generatoraccess.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_STONE_PRESSURE_PLATE_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.6F); + generatoraccess.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_STONE_PRESSURE_PLATE_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.6F); } } + @Override protected void b(GeneratorAccess generatoraccess, BlockPosition blockposition) { if (this.material == Material.WOOD) { - generatoraccess.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_WOODEN_PRESSURE_PLATE_CLICK_OFF, SoundCategory.BLOCKS, 0.3F, 0.7F); + generatoraccess.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_WOODEN_PRESSURE_PLATE_CLICK_OFF, SoundCategory.BLOCKS, 0.3F, 0.7F); } else { - generatoraccess.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_STONE_PRESSURE_PLATE_CLICK_OFF, SoundCategory.BLOCKS, 0.3F, 0.5F); + generatoraccess.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_STONE_PRESSURE_PLATE_CLICK_OFF, SoundCategory.BLOCKS, 0.3F, 0.5F); } } + @Override protected int b(World world, BlockPosition blockposition) { AxisAlignedBB axisalignedbb = BlockPressurePlateBinary.c.a(blockposition); List list; - switch (this.p) { - case EVERYTHING: - list = world.getEntities((Entity) null, axisalignedbb); - break; - case MOBS: - list = world.a(EntityLiving.class, axisalignedbb); - break; - default: - return 0; + switch (this.e) { + case EVERYTHING: + list = world.getEntities((Entity) null, axisalignedbb); + break; + case MOBS: + list = world.a(EntityLiving.class, axisalignedbb); + break; + default: + return 0; } if (!list.isEmpty()) { @@ -65,14 +70,14 @@ public class BlockPressurePlateBinary extends BlockPressurePlateAbstract { // CraftBukkit start - Call interact event when turning on a pressure plate if (this.getPower(world.getType(blockposition)) == 0) { - org.bukkit.craftbukkit.CraftWorld bworld = world.getWorld(); // Akarin - CraftWorld + org.bukkit.World bworld = world.getWorld(); org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); org.bukkit.event.Cancellable cancellable; if (entity instanceof EntityHuman) { cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null, null); } else { - cancellable = new EntityInteractEvent(entity.getBukkitEntity(), bworld.getBlockAt(blockposition)); // Akarin + cancellable = new EntityInteractEvent(entity.getBukkitEntity(), bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); manager.callEvent((EntityInteractEvent) cancellable); } @@ -92,6 +97,7 @@ public class BlockPressurePlateBinary extends BlockPressurePlateAbstract { return 0; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockPressurePlateBinary.POWERED); } diff --git a/src/main/java/net/minecraft/server/BlockPressurePlateWeighted.java b/src/main/java/net/minecraft/server/BlockPressurePlateWeighted.java index 6c79c082c..867d096a4 100644 --- a/src/main/java/net/minecraft/server/BlockPressurePlateWeighted.java +++ b/src/main/java/net/minecraft/server/BlockPressurePlateWeighted.java @@ -4,15 +4,16 @@ import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit public class BlockPressurePlateWeighted extends BlockPressurePlateAbstract { - public static final BlockStateInteger POWER = BlockProperties.al; + public static final BlockStateInteger POWER = BlockProperties.as; private final int weight; protected BlockPressurePlateWeighted(int i, Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPressurePlateWeighted.POWER, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPressurePlateWeighted.POWER, 0)); this.weight = i; } + @Override protected int b(World world, BlockPosition blockposition) { // CraftBukkit start // int i = Math.min(world.a(Entity.class, BlockPressurePlateWeighted.c.a(blockposition)).size(), this.weight); @@ -27,7 +28,7 @@ public class BlockPressurePlateWeighted extends BlockPressurePlateAbstract { if (entity instanceof EntityHuman) { cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null, null); } else { - cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition)); // Akarin + cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); world.getServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); } @@ -49,26 +50,32 @@ public class BlockPressurePlateWeighted extends BlockPressurePlateAbstract { } } + @Override protected void a(GeneratorAccess generatoraccess, BlockPosition blockposition) { - generatoraccess.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_METAL_PRESSURE_PLATE_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.90000004F); + generatoraccess.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_METAL_PRESSURE_PLATE_CLICK_ON, SoundCategory.BLOCKS, 0.3F, 0.90000004F); } + @Override protected void b(GeneratorAccess generatoraccess, BlockPosition blockposition) { - generatoraccess.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_METAL_PRESSURE_PLATE_CLICK_OFF, SoundCategory.BLOCKS, 0.3F, 0.75F); + generatoraccess.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_METAL_PRESSURE_PLATE_CLICK_OFF, SoundCategory.BLOCKS, 0.3F, 0.75F); } + @Override protected int getPower(IBlockData iblockdata) { return (Integer) iblockdata.get(BlockPressurePlateWeighted.POWER); } + @Override protected IBlockData a(IBlockData iblockdata, int i) { return (IBlockData) iblockdata.set(BlockPressurePlateWeighted.POWER, i); } + @Override public int a(IWorldReader iworldreader) { return 10; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockPressurePlateWeighted.POWER); } diff --git a/src/main/java/net/minecraft/server/BlockPumpkinCarved.java b/src/main/java/net/minecraft/server/BlockPumpkinCarved.java index c413aa1a0..27096a5cf 100644 --- a/src/main/java/net/minecraft/server/BlockPumpkinCarved.java +++ b/src/main/java/net/minecraft/server/BlockPumpkinCarved.java @@ -2,6 +2,7 @@ package net.minecraft.server; import java.util.Iterator; import java.util.function.Predicate; +import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.craftbukkit.util.BlockStateListPopulator; @@ -12,20 +13,25 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; public class BlockPumpkinCarved extends BlockFacingHorizontal { public static final BlockStateDirection a = BlockFacingHorizontal.FACING; + @Nullable private ShapeDetector b; + @Nullable private ShapeDetector c; - private ShapeDetector o; - private ShapeDetector p; - private static final Predicate q = (iblockdata) -> { + @Nullable + private ShapeDetector d; + @Nullable + private ShapeDetector e; + private static final Predicate f = (iblockdata) -> { return iblockdata != null && (iblockdata.getBlock() == Blocks.CARVED_PUMPKIN || iblockdata.getBlock() == Blocks.JACK_O_LANTERN); }; protected BlockPumpkinCarved(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPumpkinCarved.a, EnumDirection.NORTH)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockPumpkinCarved.a, EnumDirection.NORTH)); } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata1.getBlock() != iblockdata.getBlock()) { this.a(world, blockposition); } @@ -36,23 +42,22 @@ public class BlockPumpkinCarved extends BlockFacingHorizontal { } private void a(World world, BlockPosition blockposition) { - ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = this.e().a(world, blockposition); + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = this.getSnowmanShape().a(world, blockposition); int i; Iterator iterator; EntityPlayer entityplayer; int j; - ShapeDetectorBlock shapedetectorblock; - int k; BlockStateListPopulator blockList = new BlockStateListPopulator(world); // CraftBukkit - Use BlockStateListPopulator if (shapedetector_shapedetectorcollection != null) { - for (i = 0; i < this.e().b(); ++i) { - ShapeDetectorBlock shapedetectorblock1 = shapedetector_shapedetectorcollection.a(0, i, 0); + for (i = 0; i < this.getSnowmanShape().b(); ++i) { + ShapeDetectorBlock shapedetectorblock = shapedetector_shapedetectorcollection.a(0, i, 0); - blockList.setTypeAndData(shapedetectorblock1.getPosition(), Blocks.AIR.getBlockData(), 2); // CraftBukkit + blockList.setTypeAndData(shapedetectorblock.getPosition(), Blocks.AIR.getBlockData(), 2); // CraftBukkit + // world.triggerEffect(2001, shapedetectorblock.getPosition(), Block.getCombinedId(shapedetectorblock.a())); // CraftBukkit } - EntitySnowman entitysnowman = EntityTypes.SNOW_GOLEM.create(world); // Paper + EntitySnowman entitysnowman = (EntitySnowman) EntityTypes.SNOW_GOLEM.a(world); BlockPosition blockposition1 = shapedetector_shapedetectorcollection.a(0, 2, 0).getPosition(); entitysnowman.setPositionRotation((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.05D, (double) blockposition1.getZ() + 0.5D, 0.0F, 0.0F); @@ -60,6 +65,9 @@ public class BlockPumpkinCarved extends BlockFacingHorizontal { if (!world.addEntity(entitysnowman, SpawnReason.BUILD_SNOWMAN)) { return; } + for (BlockPosition pos : blockList.getBlocks()) { + world.triggerEffect(2001, pos, Block.getCombinedId(world.getType(pos))); + } blockList.updateList(); // CraftBukkit end iterator = world.a(EntityPlayer.class, entitysnowman.getBoundingBox().g(5.0D)).iterator(); @@ -69,25 +77,25 @@ public class BlockPumpkinCarved extends BlockFacingHorizontal { CriterionTriggers.n.a(entityplayer, (Entity) entitysnowman); } - j = Block.getCombinedId(Blocks.SNOW_BLOCK.getBlockData()); - world.triggerEffect(2001, blockposition1, j); - world.triggerEffect(2001, blockposition1.up(), j); + for (j = 0; j < this.getSnowmanShape().b(); ++j) { + ShapeDetectorBlock shapedetectorblock1 = shapedetector_shapedetectorcollection.a(0, j, 0); - for (k = 0; k < this.e().b(); ++k) { - shapedetectorblock = shapedetector_shapedetectorcollection.a(0, k, 0); - world.update(shapedetectorblock.getPosition(), Blocks.AIR); + world.update(shapedetectorblock1.getPosition(), Blocks.AIR); } } else { - shapedetector_shapedetectorcollection = this.g().a(world, blockposition); + shapedetector_shapedetectorcollection = this.getIronGolemShape().a(world, blockposition); if (shapedetector_shapedetectorcollection != null) { - for (i = 0; i < this.g().c(); ++i) { - for (int l = 0; l < this.g().b(); ++l) { - blockList.setTypeAndData(shapedetector_shapedetectorcollection.a(i, l, 0).getPosition(), Blocks.AIR.getBlockData(), 2); // CraftBukkit + for (i = 0; i < this.getIronGolemShape().c(); ++i) { + for (int k = 0; k < this.getIronGolemShape().b(); ++k) { + ShapeDetectorBlock shapedetectorblock2 = shapedetector_shapedetectorcollection.a(i, k, 0); + + blockList.setTypeAndData(shapedetectorblock2.getPosition(), Blocks.AIR.getBlockData(), 2); // CraftBukkit + // world.triggerEffect(2001, shapedetectorblock2.getPosition(), Block.getCombinedId(shapedetectorblock2.a())); // CraftBukkit } } BlockPosition blockposition2 = shapedetector_shapedetectorcollection.a(1, 2, 0).getPosition(); - EntityIronGolem entityirongolem = EntityTypes.IRON_GOLEM.create(world); // Paper + EntityIronGolem entityirongolem = (EntityIronGolem) EntityTypes.IRON_GOLEM.a(world); entityirongolem.setPlayerCreated(true); entityirongolem.setPositionRotation((double) blockposition2.getX() + 0.5D, (double) blockposition2.getY() + 0.05D, (double) blockposition2.getZ() + 0.5D, 0.0F, 0.0F); @@ -95,6 +103,9 @@ public class BlockPumpkinCarved extends BlockFacingHorizontal { if (!world.addEntity(entityirongolem, SpawnReason.BUILD_IRONGOLEM)) { return; } + for (BlockPosition pos : blockList.getBlocks()) { + world.triggerEffect(2001, pos, Block.getCombinedId(world.getType(pos))); + } blockList.updateList(); // CraftBukkit end iterator = world.a(EntityPlayer.class, entityirongolem.getBoundingBox().g(5.0D)).iterator(); @@ -104,18 +115,11 @@ public class BlockPumpkinCarved extends BlockFacingHorizontal { CriterionTriggers.n.a(entityplayer, (Entity) entityirongolem); } - // Akarin start - this handle by client - /* - for (j = 0; j < 120; ++j) { - world.addParticle(Particles.E, (double) blockposition2.getX() + world.random.nextDouble(), (double) blockposition2.getY() + world.random.nextDouble() * 3.9D, (double) blockposition2.getZ() + world.random.nextDouble(), 0.0D, 0.0D, 0.0D); - } - */ - // Akarin end + for (j = 0; j < this.getIronGolemShape().c(); ++j) { + for (int l = 0; l < this.getIronGolemShape().b(); ++l) { + ShapeDetectorBlock shapedetectorblock3 = shapedetector_shapedetectorcollection.a(j, l, 0); - for (j = 0; j < this.g().c(); ++j) { - for (k = 0; k < this.g().b(); ++k) { - shapedetectorblock = shapedetector_shapedetectorcollection.a(j, k, 0); - world.update(shapedetectorblock.getPosition(), Blocks.AIR); + world.update(shapedetectorblock3.getPosition(), Blocks.AIR); } } } @@ -123,15 +127,17 @@ public class BlockPumpkinCarved extends BlockFacingHorizontal { } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return (IBlockData) this.getBlockData().set(BlockPumpkinCarved.a, blockactioncontext.f().opposite()); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockPumpkinCarved.a); } - protected ShapeDetector d() { + private ShapeDetector d() { if (this.b == null) { this.b = ShapeDetectorBuilder.a().a(" ", "#", "#").a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SNOW_BLOCK))).b(); } @@ -139,27 +145,27 @@ public class BlockPumpkinCarved extends BlockFacingHorizontal { return this.b; } - protected ShapeDetector e() { + private ShapeDetector getSnowmanShape() { if (this.c == null) { - this.c = ShapeDetectorBuilder.a().a("^", "#", "#").a('^', ShapeDetectorBlock.a(BlockPumpkinCarved.q)).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SNOW_BLOCK))).b(); + this.c = ShapeDetectorBuilder.a().a("^", "#", "#").a('^', ShapeDetectorBlock.a(BlockPumpkinCarved.f)).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SNOW_BLOCK))).b(); } return this.c; } - protected ShapeDetector f() { - if (this.o == null) { - this.o = ShapeDetectorBuilder.a().a("~ ~", "###", "~#~").a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.IRON_BLOCK))).a('~', ShapeDetectorBlock.a(MaterialPredicate.a(Material.AIR))).b(); + private ShapeDetector f() { + if (this.d == null) { + this.d = ShapeDetectorBuilder.a().a("~ ~", "###", "~#~").a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.IRON_BLOCK))).a('~', ShapeDetectorBlock.a(MaterialPredicate.a(Material.AIR))).b(); } - return this.o; + return this.d; } - protected ShapeDetector g() { - if (this.p == null) { - this.p = ShapeDetectorBuilder.a().a("~^~", "###", "~#~").a('^', ShapeDetectorBlock.a(BlockPumpkinCarved.q)).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.IRON_BLOCK))).a('~', ShapeDetectorBlock.a(MaterialPredicate.a(Material.AIR))).b(); + private ShapeDetector getIronGolemShape() { + if (this.e == null) { + this.e = ShapeDetectorBuilder.a().a("~^~", "###", "~#~").a('^', ShapeDetectorBlock.a(BlockPumpkinCarved.f)).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.IRON_BLOCK))).a('~', ShapeDetectorBlock.a(MaterialPredicate.a(Material.AIR))).b(); } - return this.p; + return this.e; } } diff --git a/src/main/java/net/minecraft/server/BlockRedstoneComparator.java b/src/main/java/net/minecraft/server/BlockRedstoneComparator.java index 58d58bd14..6ff9c8744 100644 --- a/src/main/java/net/minecraft/server/BlockRedstoneComparator.java +++ b/src/main/java/net/minecraft/server/BlockRedstoneComparator.java @@ -8,37 +8,37 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockRedstoneComparator extends BlockDiodeAbstract implements ITileEntity { - public static final BlockStateEnum MODE = BlockProperties.aq; + public static final BlockStateEnum MODE = BlockProperties.ay; public BlockRedstoneComparator(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockRedstoneComparator.FACING, EnumDirection.NORTH)).set(BlockRedstoneComparator.c, false)).set(BlockRedstoneComparator.MODE, BlockPropertyComparatorMode.COMPARE)); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockRedstoneComparator.FACING, EnumDirection.NORTH)).set(BlockRedstoneComparator.c, false)).set(BlockRedstoneComparator.MODE, BlockPropertyComparatorMode.COMPARE)); } - protected int k(IBlockData iblockdata) { + @Override + protected int j(IBlockData iblockdata) { return 2; } + @Override protected int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { TileEntity tileentity = iblockaccess.getTileEntity(blockposition); - return tileentity instanceof TileEntityComparator ? ((TileEntityComparator) tileentity).c() : 0; + return tileentity instanceof TileEntityComparator ? ((TileEntityComparator) tileentity).d() : 0; } private int e(World world, BlockPosition blockposition, IBlockData iblockdata) { return iblockdata.get(BlockRedstoneComparator.MODE) == BlockPropertyComparatorMode.SUBTRACT ? Math.max(this.b(world, blockposition, iblockdata) - this.b((IWorldReader) world, blockposition, iblockdata), 0) : this.b(world, blockposition, iblockdata); } + @Override protected boolean a(World world, BlockPosition blockposition, IBlockData iblockdata) { int i = this.b(world, blockposition, iblockdata); return i >= 15 ? true : (i == 0 ? false : i >= this.b((IWorldReader) world, blockposition, iblockdata)); } - protected void a(World world, BlockPosition blockposition) { - world.n(blockposition); - } - + @Override protected int b(World world, BlockPosition blockposition, IBlockData iblockdata) { int i = super.b(world, blockposition, iblockdata); EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockRedstoneComparator.FACING); @@ -47,7 +47,7 @@ public class BlockRedstoneComparator extends BlockDiodeAbstract implements ITile if (iblockdata1.isComplexRedstone()) { i = iblockdata1.a(world, blockposition1); - } else if (i < 15 && iblockdata1.isOccluding()) { + } else if (i < 15 && iblockdata1.isOccluding(world, blockposition1)) { blockposition1 = blockposition1.shift(enumdirection); iblockdata1 = world.getType(blockposition1); if (iblockdata1.isComplexRedstone()) { @@ -74,25 +74,27 @@ public class BlockRedstoneComparator extends BlockDiodeAbstract implements ITile return list.size() == 1 ? (EntityItemFrame) list.get(0) : null; } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if (!entityhuman.abilities.mayBuild) { return false; } else { iblockdata = (IBlockData) iblockdata.a((IBlockState) BlockRedstoneComparator.MODE); - float f3 = iblockdata.get(BlockRedstoneComparator.MODE) == BlockPropertyComparatorMode.SUBTRACT ? 0.55F : 0.5F; + float f = iblockdata.get(BlockRedstoneComparator.MODE) == BlockPropertyComparatorMode.SUBTRACT ? 0.55F : 0.5F; - world.a(entityhuman, blockposition, SoundEffects.BLOCK_COMPARATOR_CLICK, SoundCategory.BLOCKS, 0.3F, f3); + world.playSound(entityhuman, blockposition, SoundEffects.BLOCK_COMPARATOR_CLICK, SoundCategory.BLOCKS, 0.3F, f); world.setTypeAndData(blockposition, iblockdata, 2); this.f(world, blockposition, iblockdata); return true; } } + @Override protected void c(World world, BlockPosition blockposition, IBlockData iblockdata) { if (!world.getBlockTickList().b(blockposition, this)) { int i = this.e(world, blockposition, iblockdata); TileEntity tileentity = world.getTileEntity(blockposition); - int j = tileentity instanceof TileEntityComparator ? ((TileEntityComparator) tileentity).c() : 0; + int j = tileentity instanceof TileEntityComparator ? ((TileEntityComparator) tileentity).d() : 0; if (i != j || (Boolean) iblockdata.get(BlockRedstoneComparator.c) != this.a(world, blockposition, iblockdata)) { TickListPriority ticklistpriority = this.c((IBlockAccess) world, blockposition, iblockdata) ? TickListPriority.HIGH : TickListPriority.NORMAL; @@ -111,7 +113,7 @@ public class BlockRedstoneComparator extends BlockDiodeAbstract implements ITile if (tileentity instanceof TileEntityComparator) { TileEntityComparator tileentitycomparator = (TileEntityComparator) tileentity; - j = tileentitycomparator.c(); + j = tileentitycomparator.d(); tileentitycomparator.a(i); } @@ -140,21 +142,25 @@ public class BlockRedstoneComparator extends BlockDiodeAbstract implements ITile } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { this.f(world, blockposition, iblockdata); } + @Override public boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, int i, int j) { super.a(iblockdata, world, blockposition, i, j); TileEntity tileentity = world.getTileEntity(blockposition); - return tileentity != null && tileentity.c(i, j); + return tileentity != null && tileentity.setProperty(i, j); } - public TileEntity a(IBlockAccess iblockaccess) { + @Override + public TileEntity createTile(IBlockAccess iblockaccess) { return new TileEntityComparator(); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockRedstoneComparator.FACING, BlockRedstoneComparator.MODE, BlockRedstoneComparator.c); } diff --git a/src/main/java/net/minecraft/server/BlockRedstoneLamp.java b/src/main/java/net/minecraft/server/BlockRedstoneLamp.java index 8fdbbd74e..907680b7d 100644 --- a/src/main/java/net/minecraft/server/BlockRedstoneLamp.java +++ b/src/main/java/net/minecraft/server/BlockRedstoneLamp.java @@ -11,28 +11,32 @@ public class BlockRedstoneLamp extends Block { public BlockRedstoneLamp(Block.Info block_info) { super(block_info); - this.v((IBlockData) this.getBlockData().set(BlockRedstoneLamp.a, false)); + this.o((IBlockData) this.getBlockData().set(BlockRedstoneLamp.a, false)); } - public int m(IBlockData iblockdata) { - return (Boolean) iblockdata.get(BlockRedstoneLamp.a) ? super.m(iblockdata) : 0; + @Override + public int a(IBlockData iblockdata) { + return (Boolean) iblockdata.get(BlockRedstoneLamp.a) ? super.a(iblockdata) : 0; } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { - super.onPlace(iblockdata, world, blockposition, iblockdata1); + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { + super.onPlace(iblockdata, world, blockposition, iblockdata1, flag); } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return (IBlockData) this.getBlockData().set(BlockRedstoneLamp.a, blockactioncontext.getWorld().isBlockIndirectlyPowered(blockactioncontext.getClickPosition())); } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if (!world.isClientSide) { - boolean flag = (Boolean) iblockdata.get(BlockRedstoneLamp.a); + boolean flag1 = (Boolean) iblockdata.get(BlockRedstoneLamp.a); - if (flag != world.isBlockIndirectlyPowered(blockposition)) { - if (flag) { + if (flag1 != world.isBlockIndirectlyPowered(blockposition)) { + if (flag1) { world.getBlockTickList().a(blockposition, this, 4); } else { // CraftBukkit start @@ -47,7 +51,8 @@ public class BlockRedstoneLamp extends Block { } } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!world.isClientSide) { if ((Boolean) iblockdata.get(BlockRedstoneLamp.a) && !world.isBlockIndirectlyPowered(blockposition)) { // CraftBukkit start @@ -61,6 +66,7 @@ public class BlockRedstoneLamp extends Block { } } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockRedstoneLamp.a); } diff --git a/src/main/java/net/minecraft/server/BlockRedstoneOre.java b/src/main/java/net/minecraft/server/BlockRedstoneOre.java index 929d4e903..08eea0fe5 100644 --- a/src/main/java/net/minecraft/server/BlockRedstoneOre.java +++ b/src/main/java/net/minecraft/server/BlockRedstoneOre.java @@ -13,18 +13,21 @@ public class BlockRedstoneOre extends Block { public BlockRedstoneOre(Block.Info block_info) { super(block_info); - this.v((IBlockData) this.getBlockData().set(BlockRedstoneOre.a, false)); + this.o((IBlockData) this.getBlockData().set(BlockRedstoneOre.a, false)); } - public int m(IBlockData iblockdata) { - return (Boolean) iblockdata.get(BlockRedstoneOre.a) ? super.m(iblockdata) : 0; + @Override + public int a(IBlockData iblockdata) { + return (Boolean) iblockdata.get(BlockRedstoneOre.a) ? super.a(iblockdata) : 0; } + @Override public void attack(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman) { interact(iblockdata, world, blockposition, entityhuman); // CraftBukkit - add entityhuman super.attack(iblockdata, world, blockposition, entityhuman); } + @Override public void stepOn(World world, BlockPosition blockposition, Entity entity) { // CraftBukkit start // interact(world.getType(blockposition), world, blockposition); @@ -36,7 +39,7 @@ public class BlockRedstoneOre extends Block { super.stepOn(world, blockposition, entity); } } else { - EntityInteractEvent event = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition)); // Akarin + EntityInteractEvent event = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); world.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { interact(world.getType(blockposition), world, blockposition, entity); // add entity @@ -46,9 +49,10 @@ public class BlockRedstoneOre extends Block { // CraftBukkit end } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { interact(iblockdata, world, blockposition, entityhuman); // CraftBukkit - add entityhuman - return super.interact(iblockdata, world, blockposition, entityhuman, enumhand, enumdirection, f, f1, f2); + return super.interact(iblockdata, world, blockposition, entityhuman, enumhand, movingobjectpositionblock); } private static void interact(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { // CraftBukkit - add Entity @@ -64,7 +68,8 @@ public class BlockRedstoneOre extends Block { } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if ((Boolean) iblockdata.get(BlockRedstoneOre.a)) { // CraftBukkit start if (CraftEventFactory.callBlockFadeEvent(world, blockposition, iblockdata.set(BlockRedstoneOre.a, false)).isCancelled()) { @@ -76,44 +81,31 @@ public class BlockRedstoneOre extends Block { } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.REDSTONE; - } - - public int getDropCount(IBlockData iblockdata, int i, World world, BlockPosition blockposition, Random random) { - return this.a(iblockdata, random) + random.nextInt(i + 1); - } - - public int a(IBlockData iblockdata, Random random) { - return 4 + random.nextInt(2); - } - - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - super.dropNaturally(iblockdata, world, blockposition, f, i); + @Override + public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { + super.dropNaturally(iblockdata, world, blockposition, itemstack); /* CraftBukkit start - Delegated to getExpDrop - if (this.getDropType(iblockdata, world, blockposition, i) != this) { - int j = 1 + world.random.nextInt(5); + if (EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) == 0) { + int i = 1 + world.random.nextInt(5); - this.dropExperience(world, blockposition, j); + this.dropExperience(world, blockposition, i); } // */ } @Override - public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, int enchantmentLevel) { - if (this.getDropType(iblockdata, world, blockposition, enchantmentLevel) != this) { - int j = 1 + world.random.nextInt(5); + public int getExpDrop(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { + if (EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) == 0) { + int i = 1 + world.random.nextInt(5); - return j; + return i; } return 0; // CraftBukkit end } private static void playEffect(World world, BlockPosition blockposition) { - // Akarin start - this handle by client - /* double d0 = 0.5625D; Random random = world.random; EnumDirection[] aenumdirection = EnumDirection.values(); @@ -123,7 +115,7 @@ public class BlockRedstoneOre extends Block { EnumDirection enumdirection = aenumdirection[j]; BlockPosition blockposition1 = blockposition.shift(enumdirection); - if (!world.getType(blockposition1).f(world, blockposition1)) { + if (!world.getType(blockposition1).g(world, blockposition1)) { EnumDirection.EnumAxis enumdirection_enumaxis = enumdirection.k(); double d1 = enumdirection_enumaxis == EnumDirection.EnumAxis.X ? 0.5D + 0.5625D * (double) enumdirection.getAdjacentX() : (double) random.nextFloat(); double d2 = enumdirection_enumaxis == EnumDirection.EnumAxis.Y ? 0.5D + 0.5625D * (double) enumdirection.getAdjacentY() : (double) random.nextFloat(); @@ -132,11 +124,10 @@ public class BlockRedstoneOre extends Block { world.addParticle(ParticleParamRedstone.a, (double) blockposition.getX() + d1, (double) blockposition.getY() + d2, (double) blockposition.getZ() + d3, 0.0D, 0.0D, 0.0D); } } - */ - // Akarin end } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockRedstoneOre.a); } diff --git a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java index b2b3b311f..919ba8a14 100644 --- a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java +++ b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java @@ -1,28 +1,30 @@ package net.minecraft.server; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.WeakHashMap; import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit public class BlockRedstoneTorch extends BlockTorch { - public static final BlockStateBoolean LIT = BlockProperties.o; - private static final Map> b = new java.util.WeakHashMap(); // Spigot + public static final BlockStateBoolean LIT = BlockProperties.r; + // Paper - Move the mapped list to World protected BlockRedstoneTorch(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockRedstoneTorch.LIT, true)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockRedstoneTorch.LIT, true)); } + @Override public int a(IWorldReader iworldreader) { return 2; } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { EnumDirection[] aenumdirection = EnumDirection.values(); int i = aenumdirection.length; @@ -34,6 +36,7 @@ public class BlockRedstoneTorch extends BlockTorch { } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (!flag) { EnumDirection[] aenumdirection = EnumDirection.values(); @@ -48,6 +51,7 @@ public class BlockRedstoneTorch extends BlockTorch { } } + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return (Boolean) iblockdata.get(BlockRedstoneTorch.LIT) && EnumDirection.UP != enumdirection ? 15 : 0; } @@ -56,28 +60,26 @@ public class BlockRedstoneTorch extends BlockTorch { return world.isBlockFacePowered(blockposition.down(), EnumDirection.DOWN); } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { a(iblockdata, world, blockposition, random, this.a(world, blockposition, iblockdata)); } public static void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random, boolean flag) { - List list = (List) BlockRedstoneTorch.b.get(world); - // Paper start - if (list != null) { - int index = 0; - while (index < list.size() && world.getTime() - ((BlockRedstoneTorch.RedstoneUpdateInfo) list.get(index)).getTime() > 60L) { - index++; - } - if (index > 0) { - list.subList(0, index).clear(); + java.util.ArrayDeque redstoneUpdateInfos = world.redstoneUpdateInfos; + + if (redstoneUpdateInfos != null) { + BlockRedstoneTorch.RedstoneUpdateInfo curr; + while ((curr = redstoneUpdateInfos.peek()) != null && world.getTime() - curr.getTime() > 60L) { + redstoneUpdateInfos.poll(); } } // Paper end // CraftBukkit start org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); - org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); int oldCurrent = ((Boolean) iblockdata.get(BlockRedstoneTorch.LIT)).booleanValue() ? 15 : 0; BlockRedstoneEvent event = new BlockRedstoneEvent(block, oldCurrent, oldCurrent); @@ -95,20 +97,7 @@ public class BlockRedstoneTorch extends BlockTorch { // CraftBukkit end world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockRedstoneTorch.LIT, false), 3); if (a(world, blockposition, true)) { - world.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_REDSTONE_TORCH_BURNOUT, SoundCategory.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); - - // Akarin start - this handle by client - /* - for (int i = 0; i < 5; ++i) { - double d0 = (double) blockposition.getX() + random.nextDouble() * 0.6D + 0.2D; - double d1 = (double) blockposition.getY() + random.nextDouble() * 0.6D + 0.2D; - double d2 = (double) blockposition.getZ() + random.nextDouble() * 0.6D + 0.2D; - - world.addParticle(Particles.M, d0, d1, d2, 0.0D, 0.0D, 0.0D); - } - */ - // Akarin end - + world.triggerEffect(1502, blockposition, 0); world.getBlockTickList().a(blockposition, world.getType(blockposition).getBlock(), 160); } } @@ -127,46 +116,51 @@ public class BlockRedstoneTorch extends BlockTorch { } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if ((Boolean) iblockdata.get(BlockRedstoneTorch.LIT) == this.a(world, blockposition, iblockdata) && !world.getBlockTickList().b(blockposition, this)) { world.getBlockTickList().a(blockposition, this, this.a((IWorldReader) world)); } } + @Override public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - return enumdirection == EnumDirection.DOWN ? iblockdata.a(iblockaccess, blockposition, enumdirection) : 0; + return enumdirection == EnumDirection.DOWN ? iblockdata.b(iblockaccess, blockposition, enumdirection) : 0; } + @Override public boolean isPowerSource(IBlockData iblockdata) { return true; } - public int m(IBlockData iblockdata) { - return (Boolean) iblockdata.get(BlockRedstoneTorch.LIT) ? super.m(iblockdata) : 0; + @Override + public int a(IBlockData iblockdata) { + return (Boolean) iblockdata.get(BlockRedstoneTorch.LIT) ? super.a(iblockdata) : 0; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockRedstoneTorch.LIT); } private static boolean a(World world, BlockPosition blockposition, boolean flag) { - List list = (List) BlockRedstoneTorch.b.get(world); - + // Paper start + java.util.ArrayDeque list = world.redstoneUpdateInfos; if (list == null) { - list = Lists.newArrayList(); - BlockRedstoneTorch.b.put(world, list); + list = world.redstoneUpdateInfos = new java.util.ArrayDeque<>(); } + if (flag) { - ((List) list).add(new BlockRedstoneTorch.RedstoneUpdateInfo(blockposition.h(), world.getTime())); + list.add(new BlockRedstoneTorch.RedstoneUpdateInfo(blockposition.immutableCopy(), world.getTime())); } int i = 0; - for (int j = 0; j < ((List) list).size(); ++j) { - BlockRedstoneTorch.RedstoneUpdateInfo blockredstonetorch_redstoneupdateinfo = (BlockRedstoneTorch.RedstoneUpdateInfo) ((List) list).get(j); - + for (java.util.Iterator iterator = list.iterator(); iterator.hasNext();) { + BlockRedstoneTorch.RedstoneUpdateInfo blockredstonetorch_redstoneupdateinfo = iterator.next(); + // Paper end if (blockredstonetorch_redstoneupdateinfo.a.equals(blockposition)) { ++i; if (i >= 8) { diff --git a/src/main/java/net/minecraft/server/BlockRedstoneWire.java b/src/main/java/net/minecraft/server/BlockRedstoneWire.java index b098a2816..337c03d1d 100644 --- a/src/main/java/net/minecraft/server/BlockRedstoneWire.java +++ b/src/main/java/net/minecraft/server/BlockRedstoneWire.java @@ -17,29 +17,27 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit public class BlockRedstoneWire extends Block { - public static final BlockStateEnum NORTH = BlockProperties.M; - public static final BlockStateEnum EAST = BlockProperties.L; - public static final BlockStateEnum SOUTH = BlockProperties.N; - public static final BlockStateEnum WEST = BlockProperties.O; - public static final BlockStateInteger POWER = BlockProperties.al; - public static final Map> q = Maps.newEnumMap(ImmutableMap.of(EnumDirection.NORTH, BlockRedstoneWire.NORTH, EnumDirection.EAST, BlockRedstoneWire.EAST, EnumDirection.SOUTH, BlockRedstoneWire.SOUTH, EnumDirection.WEST, BlockRedstoneWire.WEST)); - protected static final VoxelShape[] r = new VoxelShape[] { Block.a(3.0D, 0.0D, 3.0D, 13.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 3.0D, 13.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 3.0D, 13.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 3.0D, 13.0D, 1.0D, 16.0D), Block.a(3.0D, 0.0D, 0.0D, 13.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 0.0D, 13.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 13.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 0.0D, 13.0D, 1.0D, 16.0D), Block.a(3.0D, 0.0D, 3.0D, 16.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 3.0D, 16.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 3.0D, 16.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 3.0D, 16.0D, 1.0D, 16.0D), Block.a(3.0D, 0.0D, 0.0D, 16.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D)}; - public boolean canProvidePower() { return this.s; } // Paper - OBFHELPER - public void setCanProvidePower(boolean value) { this.s = value; } // Paper - OBFHELPER - private boolean s = true; - private Set getBlocksNeedingUpdate() { return this.t; } // Paper - OBFHELPER - private final Set t = Sets.newHashSet(); + public static final BlockStateEnum NORTH = BlockProperties.R; + public static final BlockStateEnum EAST = BlockProperties.Q; + public static final BlockStateEnum SOUTH = BlockProperties.S; + public static final BlockStateEnum WEST = BlockProperties.T; + public static final BlockStateInteger POWER = BlockProperties.as; + public static final Map> f = Maps.newEnumMap(ImmutableMap.of(EnumDirection.NORTH, BlockRedstoneWire.NORTH, EnumDirection.EAST, BlockRedstoneWire.EAST, EnumDirection.SOUTH, BlockRedstoneWire.SOUTH, EnumDirection.WEST, BlockRedstoneWire.WEST)); + protected static final VoxelShape[] g = new VoxelShape[]{Block.a(3.0D, 0.0D, 3.0D, 13.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 3.0D, 13.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 3.0D, 13.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 3.0D, 13.0D, 1.0D, 16.0D), Block.a(3.0D, 0.0D, 0.0D, 13.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 0.0D, 13.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 13.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 0.0D, 13.0D, 1.0D, 16.0D), Block.a(3.0D, 0.0D, 3.0D, 16.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 3.0D, 16.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 3.0D, 16.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 3.0D, 16.0D, 1.0D, 16.0D), Block.a(3.0D, 0.0D, 0.0D, 16.0D, 1.0D, 13.0D), Block.a(3.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 13.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D)}; + private boolean h = true; public final boolean canProvidePower() { return this.h; } public final void setCanProvidePower(boolean value) { this.h = value; } // Paper - OBFHELPER + private final Set i = Sets.newHashSet(); private Set getBlocksNeedingUpdate() { return this.i; } // Paper - OBFHELPER public BlockRedstoneWire(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockRedstoneWire.NORTH, BlockPropertyRedstoneSide.NONE)).set(BlockRedstoneWire.EAST, BlockPropertyRedstoneSide.NONE)).set(BlockRedstoneWire.SOUTH, BlockPropertyRedstoneSide.NONE)).set(BlockRedstoneWire.WEST, BlockPropertyRedstoneSide.NONE)).set(BlockRedstoneWire.POWER, 0)); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockRedstoneWire.NORTH, BlockPropertyRedstoneSide.NONE)).set(BlockRedstoneWire.EAST, BlockPropertyRedstoneSide.NONE)).set(BlockRedstoneWire.SOUTH, BlockPropertyRedstoneSide.NONE)).set(BlockRedstoneWire.WEST, BlockPropertyRedstoneSide.NONE)).set(BlockRedstoneWire.POWER, 0)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return BlockRedstoneWire.r[w(iblockdata)]; + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return BlockRedstoneWire.g[q(iblockdata)]; } - private static int w(IBlockData iblockdata) { + private static int q(IBlockData iblockdata) { int i = 0; boolean flag = iblockdata.get(BlockRedstoneWire.NORTH) != BlockPropertyRedstoneSide.NONE; boolean flag1 = iblockdata.get(BlockRedstoneWire.EAST) != BlockPropertyRedstoneSide.NONE; @@ -65,6 +63,7 @@ public class BlockRedstoneWire extends Block { return i; } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { World world = blockactioncontext.getWorld(); BlockPosition blockposition = blockactioncontext.getClickPosition(); @@ -72,10 +71,12 @@ public class BlockRedstoneWire extends Block { return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.getBlockData().set(BlockRedstoneWire.WEST, this.a((IBlockAccess) world, blockposition, EnumDirection.WEST))).set(BlockRedstoneWire.EAST, this.a((IBlockAccess) world, blockposition, EnumDirection.EAST))).set(BlockRedstoneWire.NORTH, this.a((IBlockAccess) world, blockposition, EnumDirection.NORTH))).set(BlockRedstoneWire.SOUTH, this.a((IBlockAccess) world, blockposition, EnumDirection.SOUTH)); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - return enumdirection == EnumDirection.DOWN ? iblockdata : (enumdirection == EnumDirection.UP ? (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.WEST, this.a((IBlockAccess) generatoraccess, blockposition, EnumDirection.WEST))).set(BlockRedstoneWire.EAST, this.a((IBlockAccess) generatoraccess, blockposition, EnumDirection.EAST))).set(BlockRedstoneWire.NORTH, this.a((IBlockAccess) generatoraccess, blockposition, EnumDirection.NORTH))).set(BlockRedstoneWire.SOUTH, this.a((IBlockAccess) generatoraccess, blockposition, EnumDirection.SOUTH)) : (IBlockData) iblockdata.set((IBlockState) BlockRedstoneWire.q.get(enumdirection), this.a((IBlockAccess) generatoraccess, blockposition, enumdirection))); + return enumdirection == EnumDirection.DOWN ? iblockdata : (enumdirection == EnumDirection.UP ? (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.WEST, this.a((IBlockAccess) generatoraccess, blockposition, EnumDirection.WEST))).set(BlockRedstoneWire.EAST, this.a((IBlockAccess) generatoraccess, blockposition, EnumDirection.EAST))).set(BlockRedstoneWire.NORTH, this.a((IBlockAccess) generatoraccess, blockposition, EnumDirection.NORTH))).set(BlockRedstoneWire.SOUTH, this.a((IBlockAccess) generatoraccess, blockposition, EnumDirection.SOUTH)) : (IBlockData) iblockdata.set((IBlockState) BlockRedstoneWire.f.get(enumdirection), this.a((IBlockAccess) generatoraccess, blockposition, enumdirection))); } + @Override public void b(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition, int i) { BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); Throwable throwable = null; @@ -85,7 +86,7 @@ public class BlockRedstoneWire extends Block { while (iterator.hasNext()) { EnumDirection enumdirection = (EnumDirection) iterator.next(); - BlockPropertyRedstoneSide blockpropertyredstoneside = (BlockPropertyRedstoneSide) iblockdata.get((IBlockState) BlockRedstoneWire.q.get(enumdirection)); + BlockPropertyRedstoneSide blockpropertyredstoneside = (BlockPropertyRedstoneSide) iblockdata.get((IBlockState) BlockRedstoneWire.f.get(enumdirection)); if (blockpropertyredstoneside != BlockPropertyRedstoneSide.NONE && generatoraccess.getType(blockposition_pooledblockposition.g(blockposition).c(enumdirection)).getBlock() != this) { blockposition_pooledblockposition.c(EnumDirection.DOWN); @@ -131,14 +132,15 @@ public class BlockRedstoneWire extends Block { private BlockPropertyRedstoneSide a(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { BlockPosition blockposition1 = blockposition.shift(enumdirection); - IBlockData iblockdata = iblockaccess.getType(blockposition.shift(enumdirection)); - IBlockData iblockdata1 = iblockaccess.getType(blockposition.up()); + IBlockData iblockdata = iblockaccess.getType(blockposition1); + BlockPosition blockposition2 = blockposition.up(); + IBlockData iblockdata1 = iblockaccess.getType(blockposition2); - if (!iblockdata1.isOccluding()) { - boolean flag = iblockaccess.getType(blockposition1).q() || iblockaccess.getType(blockposition1).getBlock() == Blocks.GLOWSTONE; + if (!iblockdata1.isOccluding(iblockaccess, blockposition2)) { + boolean flag = iblockdata.d(iblockaccess, blockposition1, EnumDirection.UP) || iblockdata.getBlock() == Blocks.HOPPER; - if (flag && k(iblockaccess.getType(blockposition1.up()))) { - if (iblockdata.k()) { + if (flag && j(iblockaccess.getType(blockposition1.up()))) { + if (iblockdata.o(iblockaccess, blockposition1)) { return BlockPropertyRedstoneSide.UP; } @@ -146,17 +148,15 @@ public class BlockRedstoneWire extends Block { } } - return !a(iblockaccess.getType(blockposition1), enumdirection) && (iblockdata.isOccluding() || !k(iblockaccess.getType(blockposition1.down()))) ? BlockPropertyRedstoneSide.NONE : BlockPropertyRedstoneSide.SIDE; - } - - public boolean a(IBlockData iblockdata) { - return false; + return !a(iblockdata, enumdirection) && (iblockdata.isOccluding(iblockaccess, blockposition1) || !j(iblockaccess.getType(blockposition1.down()))) ? BlockPropertyRedstoneSide.NONE : BlockPropertyRedstoneSide.SIDE; } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { - IBlockData iblockdata1 = iworldreader.getType(blockposition.down()); + BlockPosition blockposition1 = blockposition.down(); + IBlockData iblockdata1 = iworldreader.getType(blockposition1); - return iblockdata1.q() || iblockdata1.getBlock() == Blocks.GLOWSTONE; + return iblockdata1.d(iworldreader, blockposition1, EnumDirection.UP) || iblockdata1.getBlock() == Blocks.HOPPER; } // Paper start - Optimize redstone @@ -215,11 +215,11 @@ public class BlockRedstoneWire extends Block { l = this.getPower(l, worldIn.getType(blockpos)); } - if (worldIn.getType(blockpos).isOccluding() && !worldIn.getType(pos1.up()).isOccluding()) { + if (worldIn.getType(blockpos).isOccluding(worldIn, blockpos) && !worldIn.getType(pos1.up()).isOccluding(worldIn, pos1)) { if (flag && pos1.getY() >= pos2.getY()) { l = this.getPower(l, worldIn.getType(blockpos.up())); } - } else if (!worldIn.getType(blockpos).isOccluding() && flag && pos1.getY() <= pos2.getY()) { + } else if (!worldIn.getType(blockpos).isOccluding(worldIn, blockpos) && flag && pos1.getY() <= pos2.getY()) { l = this.getPower(l, worldIn.getType(blockpos.down())); } } @@ -272,9 +272,9 @@ public class BlockRedstoneWire extends Block { // Paper end private IBlockData a(World world, BlockPosition blockposition, IBlockData iblockdata) { iblockdata = this.b(world, blockposition, iblockdata); - List list = Lists.newArrayList(this.t); + List list = Lists.newArrayList(this.i); - this.t.clear(); + this.i.clear(); Iterator iterator = list.iterator(); while (iterator.hasNext()) { @@ -289,74 +289,61 @@ public class BlockRedstoneWire extends Block { private IBlockData b(World world, BlockPosition blockposition, IBlockData iblockdata) { IBlockData iblockdata1 = iblockdata; int i = (Integer) iblockdata.get(BlockRedstoneWire.POWER); - byte b0 = 0; - int j = this.getPower(b0, iblockdata); - this.s = false; - int k = world.u(blockposition); + this.h = false; + int j = world.q(blockposition); - this.s = true; - if (k > 0 && k > j - 1) { - j = k; - } + this.h = true; + int k = 0; - int l = 0; - Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + if (j < 15) { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); - while (iterator.hasNext()) { - EnumDirection enumdirection = (EnumDirection) iterator.next(); - BlockPosition blockposition1 = blockposition.shift(enumdirection); - boolean flag = blockposition1.getX() != blockposition.getX() || blockposition1.getZ() != blockposition.getZ(); - IBlockData iblockdata2 = world.getType(blockposition1); + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + IBlockData iblockdata2 = world.getType(blockposition1); - if (flag) { - l = this.getPower(l, iblockdata2); - } + k = this.getPower(k, iblockdata2); + BlockPosition blockposition2 = blockposition.up(); - if (iblockdata2.isOccluding() && !world.getType(blockposition.up()).isOccluding()) { - if (flag && blockposition.getY() >= blockposition.getY()) { - l = this.getPower(l, world.getType(blockposition1.up())); + if (iblockdata2.isOccluding(world, blockposition1) && !world.getType(blockposition2).isOccluding(world, blockposition2)) { + k = this.getPower(k, world.getType(blockposition1.up())); + } else if (!iblockdata2.isOccluding(world, blockposition1)) { + k = this.getPower(k, world.getType(blockposition1.down())); } - } else if (!iblockdata2.isOccluding() && flag && blockposition.getY() <= blockposition.getY()) { - l = this.getPower(l, world.getType(blockposition1.down())); } } - if (l > j) { - j = l - 1; - } else if (j > 0) { - --j; - } else { - j = 0; - } + int l = k - 1; - if (k > j - 1) { - j = k; + if (j > l) { + l = j; } // CraftBukkit start - if (i != j) { - BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(blockposition), i, j); // Akarin + if (i != l) { + BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), i, l); world.getServer().getPluginManager().callEvent(event); - j = event.getNewCurrent(); + l = event.getNewCurrent(); } // CraftBukkit end - if (i != j) { - iblockdata = (IBlockData) iblockdata.set(BlockRedstoneWire.POWER, j); + if (i != l) { + iblockdata = (IBlockData) iblockdata.set(BlockRedstoneWire.POWER, l); if (world.getType(blockposition) == iblockdata1) { world.setTypeAndData(blockposition, iblockdata, 2); } - this.t.add(blockposition); + this.i.add(blockposition); EnumDirection[] aenumdirection = EnumDirection.values(); int i1 = aenumdirection.length; for (int j1 = 0; j1 < i1; ++j1) { EnumDirection enumdirection1 = aenumdirection[j1]; - this.t.add(blockposition.shift(enumdirection1)); + this.i.add(blockposition.shift(enumdirection1)); } } @@ -378,7 +365,8 @@ public class BlockRedstoneWire extends Block { } } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata1.getBlock() != iblockdata.getBlock() && !world.isClientSide) { this.updateSurroundingRedstone(world, blockposition, iblockdata, null); // Paper - Optimize redstone Iterator iterator = EnumDirection.EnumDirectionLimit.VERTICAL.iterator(); @@ -403,7 +391,7 @@ public class BlockRedstoneWire extends Block { enumdirection = (EnumDirection) iterator.next(); BlockPosition blockposition1 = blockposition.shift(enumdirection); - if (world.getType(blockposition1).isOccluding()) { + if (world.getType(blockposition1).isOccluding(world, blockposition1)) { this.a(world, blockposition1.up()); } else { this.a(world, blockposition1.down()); @@ -413,6 +401,7 @@ public class BlockRedstoneWire extends Block { } } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (!flag && iblockdata.getBlock() != iblockdata1.getBlock()) { super.remove(iblockdata, world, blockposition, iblockdata1, flag); @@ -442,7 +431,7 @@ public class BlockRedstoneWire extends Block { enumdirection1 = (EnumDirection) iterator.next(); BlockPosition blockposition1 = blockposition.shift(enumdirection1); - if (world.getType(blockposition1).isOccluding()) { + if (world.getType(blockposition1).isOccluding(world, blockposition1)) { this.a(world, blockposition1.up()); } else { this.a(world, blockposition1.down()); @@ -463,24 +452,27 @@ public class BlockRedstoneWire extends Block { } } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if (!world.isClientSide) { if (iblockdata.canPlace(world, blockposition)) { this.updateSurroundingRedstone(world, blockposition, iblockdata, blockposition1); // Paper - Optimize redstone } else { - iblockdata.a(world, blockposition, 0); - world.setAir(blockposition); + c(iblockdata, world, blockposition); + world.a(blockposition, false); } } } + @Override public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - return !this.s ? 0 : iblockdata.a(iblockaccess, blockposition, enumdirection); + return !this.h ? 0 : iblockdata.b(iblockaccess, blockposition, enumdirection); } + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - if (!this.s) { + if (!this.h) { return 0; } else { int i = (Integer) iblockdata.get(BlockRedstoneWire.POWER); @@ -515,17 +507,18 @@ public class BlockRedstoneWire extends Block { private boolean b(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { BlockPosition blockposition1 = blockposition.shift(enumdirection); IBlockData iblockdata = iblockaccess.getType(blockposition1); - boolean flag = iblockdata.isOccluding(); - boolean flag1 = iblockaccess.getType(blockposition.up()).isOccluding(); + boolean flag = iblockdata.isOccluding(iblockaccess, blockposition1); + BlockPosition blockposition2 = blockposition.up(); + boolean flag1 = iblockaccess.getType(blockposition2).isOccluding(iblockaccess, blockposition2); return !flag1 && flag && a(iblockaccess, blockposition1.up()) ? true : (a(iblockdata, enumdirection) ? true : (iblockdata.getBlock() == Blocks.REPEATER && (Boolean) iblockdata.get(BlockDiodeAbstract.c) && iblockdata.get(BlockDiodeAbstract.FACING) == enumdirection ? true : !flag && a(iblockaccess, blockposition1.down()))); } protected static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) { - return k(iblockaccess.getType(blockposition)); + return j(iblockaccess.getType(blockposition)); } - protected static boolean k(IBlockData iblockdata) { + protected static boolean j(IBlockData iblockdata) { return a(iblockdata, (EnumDirection) null); } @@ -543,43 +536,44 @@ public class BlockRedstoneWire extends Block { } } + @Override public boolean isPowerSource(IBlockData iblockdata) { - return this.s; + return this.h; } + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { switch (enumblockrotation) { - case CLOCKWISE_180: - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.SOUTH))).set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.WEST))).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.NORTH))).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.EAST)); - case COUNTERCLOCKWISE_90: - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.EAST))).set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.SOUTH))).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.WEST))).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.NORTH)); - case CLOCKWISE_90: - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.WEST))).set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.NORTH))).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.EAST))).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.SOUTH)); - default: - return iblockdata; + case CLOCKWISE_180: + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.SOUTH))).set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.WEST))).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.NORTH))).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.EAST)); + case COUNTERCLOCKWISE_90: + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.EAST))).set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.SOUTH))).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.WEST))).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.NORTH)); + case CLOCKWISE_90: + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.WEST))).set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.NORTH))).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.EAST))).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.SOUTH)); + default: + return iblockdata; } } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { switch (enumblockmirror) { - case LEFT_RIGHT: - return (IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.SOUTH))).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.NORTH)); - case FRONT_BACK: - return (IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.WEST))).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.EAST)); - default: - return super.a(iblockdata, enumblockmirror); + case LEFT_RIGHT: + return (IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.SOUTH))).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.NORTH)); + case FRONT_BACK: + return (IBlockData) ((IBlockData) iblockdata.set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.WEST))).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.EAST)); + default: + return super.a(iblockdata, enumblockmirror); } } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockRedstoneWire.NORTH, BlockRedstoneWire.EAST, BlockRedstoneWire.SOUTH, BlockRedstoneWire.WEST, BlockRedstoneWire.POWER); } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockReed.java b/src/main/java/net/minecraft/server/BlockReed.java index c7017c58e..a4850c070 100644 --- a/src/main/java/net/minecraft/server/BlockReed.java +++ b/src/main/java/net/minecraft/server/BlockReed.java @@ -5,20 +5,25 @@ import java.util.Random; public class BlockReed extends Block { - public static final BlockStateInteger AGE = BlockProperties.X; + public static final BlockStateInteger AGE = BlockProperties.ad; protected static final VoxelShape b = Block.a(2.0D, 0.0D, 2.0D, 14.0D, 16.0D, 14.0D); protected BlockReed(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockReed.AGE, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockReed.AGE, 0)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockReed.b; } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { - if (iblockdata.canPlace(world, blockposition) && world.isEmpty(blockposition.up())) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + if (!iblockdata.canPlace(world, blockposition)) { + world.b(blockposition, true); + } else if (world.isEmpty(blockposition.up())) { + if (world.paperConfig.fixZeroTickInstantGrowFarms && !randomTick) return; // Paper - fix MC-113809 int i; for (i = 1; world.getType(blockposition.down(i)).getBlock() == this; ++i) { @@ -39,10 +44,16 @@ public class BlockReed extends Block { } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - return !iblockdata.canPlace(generatoraccess, blockposition) ? Blocks.AIR.getBlockData() : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); + if (!iblockdata.canPlace(generatoraccess, blockposition)) { + generatoraccess.getBlockTickList().a(blockposition, this, 1); + } + + return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { Block block = iworldreader.getType(blockposition.down()).getBlock(); @@ -68,19 +79,13 @@ public class BlockReed extends Block { } } - public boolean a(IBlockData iblockdata) { - return false; - } - + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockReed.AGE); } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockSapling.java b/src/main/java/net/minecraft/server/BlockSapling.java index 291cc9a39..28517b63f 100644 --- a/src/main/java/net/minecraft/server/BlockSapling.java +++ b/src/main/java/net/minecraft/server/BlockSapling.java @@ -13,7 +13,7 @@ import org.bukkit.event.world.StructureGrowEvent; public class BlockSapling extends BlockPlant implements IBlockFragilePlantElement { - public static final BlockStateInteger STAGE = BlockProperties.am; + public static final BlockStateInteger STAGE = BlockProperties.at; protected static final VoxelShape b = Block.a(2.0D, 0.0D, 2.0D, 14.0D, 12.0D, 14.0D); private final WorldGenTreeProvider c; public static TreeType treeType; // CraftBukkit @@ -21,16 +21,18 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen protected BlockSapling(WorldGenTreeProvider worldgentreeprovider, Block.Info block_info) { super(block_info); this.c = worldgentreeprovider; - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockSapling.STAGE, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockSapling.STAGE, 0)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockSapling.b; } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { - super.a(iblockdata, world, blockposition, random); - if (world.isLightLevel(blockposition.up(), 9) && random.nextInt(Math.max(2, (int) (((100.0F / world.spigotConfig.saplingModifier) * 7) + 0.5F))) == 0) { // Spigot // Paper + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + super.tick(iblockdata, world, blockposition, random); + if (world.getLightLevel(blockposition.up()) >= 9 && random.nextInt(Math.max(2, (int) (((100.0F / world.spigotConfig.saplingModifier) * 7) + 0.5F))) == 0) { // Spigot // CraftBukkit start world.captureTreeGeneration = true; // CraftBukkit end @@ -68,18 +70,22 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen } + @Override public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { return true; } + @Override public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { return (double) world.random.nextFloat() < 0.45D; } + @Override public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { this.grow(world, blockposition, iblockdata, random); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockSapling.STAGE); } diff --git a/src/main/java/net/minecraft/server/BlockShulkerBox.java b/src/main/java/net/minecraft/server/BlockShulkerBox.java deleted file mode 100644 index 997ed795b..000000000 --- a/src/main/java/net/minecraft/server/BlockShulkerBox.java +++ /dev/null @@ -1,242 +0,0 @@ -package net.minecraft.server; - -import javax.annotation.Nullable; - -public class BlockShulkerBox extends BlockTileEntity { - - public static final BlockStateEnum a = BlockDirectional.FACING; - @Nullable - public final EnumColor color; - - public BlockShulkerBox(@Nullable EnumColor enumcolor, Block.Info block_info) { - super(block_info); - this.color = enumcolor; - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockShulkerBox.a, EnumDirection.UP)); - } - - public TileEntity a(IBlockAccess iblockaccess) { - return new TileEntityShulkerBox(this.color); - } - - public boolean q(IBlockData iblockdata) { - return true; - } - - public boolean a(IBlockData iblockdata) { - return false; - } - - public EnumRenderType c(IBlockData iblockdata) { - return EnumRenderType.ENTITYBLOCK_ANIMATED; - } - - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { - if (world.isClientSide) { - return true; - } else if (entityhuman.isSpectator()) { - return true; - } else { - TileEntity tileentity = world.getTileEntity(blockposition); - - if (tileentity instanceof TileEntityShulkerBox) { - EnumDirection enumdirection1 = (EnumDirection) iblockdata.get(BlockShulkerBox.a); - boolean flag; - - if (((TileEntityShulkerBox) tileentity).r() == TileEntityShulkerBox.AnimationPhase.CLOSED) { - AxisAlignedBB axisalignedbb = VoxelShapes.b().getBoundingBox().b((double) (0.5F * (float) enumdirection1.getAdjacentX()), (double) (0.5F * (float) enumdirection1.getAdjacentY()), (double) (0.5F * (float) enumdirection1.getAdjacentZ())).a((double) enumdirection1.getAdjacentX(), (double) enumdirection1.getAdjacentY(), (double) enumdirection1.getAdjacentZ()); - - flag = world.getCubes((Entity) null, axisalignedbb.a(blockposition.shift(enumdirection1))); - } else { - flag = true; - } - - if (flag) { - entityhuman.a(StatisticList.OPEN_SHULKER_BOX); - entityhuman.openContainer((IInventory) tileentity); - } - - return true; - } else { - return false; - } - } - } - - public IBlockData getPlacedState(BlockActionContext blockactioncontext) { - return (IBlockData) this.getBlockData().set(BlockShulkerBox.a, blockactioncontext.getClickedFace()); - } - - protected void a(BlockStateList.a blockstatelist_a) { - blockstatelist_a.a(BlockShulkerBox.a); - } - - public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { - if (world.getTileEntity(blockposition) instanceof TileEntityShulkerBox) { - TileEntityShulkerBox tileentityshulkerbox = (TileEntityShulkerBox) world.getTileEntity(blockposition); - - tileentityshulkerbox.a(entityhuman.abilities.canInstantlyBuild); - tileentityshulkerbox.d(entityhuman); - } - - super.a(world, blockposition, iblockdata, entityhuman); - } - - // CraftBukkit start - override to prevent duplication when dropping - @Override - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - if (true) { - TileEntity tileentity = world.getTileEntity(blockposition); - - if (tileentity instanceof TileEntityShulkerBox) { - TileEntityShulkerBox tileentityshulkerbox = (TileEntityShulkerBox) tileentity; - - if (!tileentityshulkerbox.s() && tileentityshulkerbox.G()) { - ItemStack itemstack = new ItemStack(this); - - itemstack.getOrCreateTag().set("BlockEntityTag", ((TileEntityShulkerBox) tileentity).g(new NBTTagCompound())); - if (tileentityshulkerbox.hasCustomName()) { - itemstack.a(tileentityshulkerbox.getCustomName()); - tileentityshulkerbox.setCustomName((IChatBaseComponent) null); - } - - a(world, blockposition, itemstack); - tileentityshulkerbox.clear(); // Paper - This was intended to be called in Vanilla (is checked in the if statement above if has been called) - Fixes dupe issues - } - } - world.updateAdjacentComparators(blockposition, iblockdata.getBlock()); - } - } - // CraftBukkit end - - public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { - if (itemstack.hasName()) { - TileEntity tileentity = world.getTileEntity(blockposition); - - if (tileentity instanceof TileEntityShulkerBox) { - ((TileEntityShulkerBox) tileentity).setCustomName(itemstack.getName()); - } - } - - } - - public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { - if (iblockdata.getBlock() != iblockdata1.getBlock()) { - TileEntity tileentity = world.getTileEntity(blockposition); - - if (false && tileentity instanceof TileEntityShulkerBox) { // CraftBukkit - moved up - TileEntityShulkerBox tileentityshulkerbox = (TileEntityShulkerBox) tileentity; - - if (!tileentityshulkerbox.s() && tileentityshulkerbox.G()) { - ItemStack itemstack = new ItemStack(this); - - itemstack.getOrCreateTag().set("BlockEntityTag", ((TileEntityShulkerBox) tileentity).g(new NBTTagCompound())); - if (tileentityshulkerbox.hasCustomName()) { - itemstack.a(tileentityshulkerbox.getCustomName()); - tileentityshulkerbox.setCustomName((IChatBaseComponent) null); - } - - a(world, blockposition, itemstack); - } - - } - world.updateAdjacentComparators(blockposition, iblockdata.getBlock()); // CraftBukkit - moved down - - super.remove(iblockdata, world, blockposition, iblockdata1, flag); - } - } - - public EnumPistonReaction getPushReaction(IBlockData iblockdata) { - return EnumPistonReaction.DESTROY; - } - - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - TileEntity tileentity = iblockaccess.getTileEntity(blockposition); - - return tileentity instanceof TileEntityShulkerBox ? VoxelShapes.a(((TileEntityShulkerBox) tileentity).a(iblockdata)) : VoxelShapes.b(); - } - - public boolean f(IBlockData iblockdata) { - return false; - } - - public boolean isComplexRedstone(IBlockData iblockdata) { - return true; - } - - public int a(IBlockData iblockdata, World world, BlockPosition blockposition) { - return Container.b((IInventory) world.getTileEntity(blockposition)); - } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - ItemStack itemstack = super.a(iblockaccess, blockposition, iblockdata); - TileEntityShulkerBox tileentityshulkerbox = (TileEntityShulkerBox) iblockaccess.getTileEntity(blockposition); - NBTTagCompound nbttagcompound = tileentityshulkerbox.g(new NBTTagCompound()); - - if (!nbttagcompound.isEmpty()) { - itemstack.a("BlockEntityTag", (NBTBase) nbttagcompound); - } - - return itemstack; - } - - public static Block a(EnumColor enumcolor) { - if (enumcolor == null) { - return Blocks.SHULKER_BOX; - } else { - switch (enumcolor) { - case WHITE: - return Blocks.WHITE_SHULKER_BOX; - case ORANGE: - return Blocks.ORANGE_SHULKER_BOX; - case MAGENTA: - return Blocks.MAGENTA_SHULKER_BOX; - case LIGHT_BLUE: - return Blocks.LIGHT_BLUE_SHULKER_BOX; - case YELLOW: - return Blocks.YELLOW_SHULKER_BOX; - case LIME: - return Blocks.LIME_SHULKER_BOX; - case PINK: - return Blocks.PINK_SHULKER_BOX; - case GRAY: - return Blocks.GRAY_SHULKER_BOX; - case LIGHT_GRAY: - return Blocks.LIGHT_GRAY_SHULKER_BOX; - case CYAN: - return Blocks.CYAN_SHULKER_BOX; - case PURPLE: - default: - return Blocks.PURPLE_SHULKER_BOX; - case BLUE: - return Blocks.BLUE_SHULKER_BOX; - case BROWN: - return Blocks.BROWN_SHULKER_BOX; - case GREEN: - return Blocks.GREEN_SHULKER_BOX; - case RED: - return Blocks.RED_SHULKER_BOX; - case BLACK: - return Blocks.BLACK_SHULKER_BOX; - } - } - } - - public static ItemStack b(EnumColor enumcolor) { - return new ItemStack(a(enumcolor)); - } - - public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { - return (IBlockData) iblockdata.set(BlockShulkerBox.a, enumblockrotation.a((EnumDirection) iblockdata.get(BlockShulkerBox.a))); - } - - public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { - return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockShulkerBox.a))); - } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - EnumDirection enumdirection1 = (EnumDirection) iblockdata.get(BlockShulkerBox.a); - TileEntityShulkerBox.AnimationPhase tileentityshulkerbox_animationphase = ((TileEntityShulkerBox) iblockaccess.getTileEntity(blockposition)).r(); - - return tileentityshulkerbox_animationphase != TileEntityShulkerBox.AnimationPhase.CLOSED && (tileentityshulkerbox_animationphase != TileEntityShulkerBox.AnimationPhase.OPENED || enumdirection1 != enumdirection.opposite() && enumdirection1 != enumdirection) ? EnumBlockFaceShape.UNDEFINED : EnumBlockFaceShape.SOLID; - } -} diff --git a/src/main/java/net/minecraft/server/BlockSkullAbstract.java b/src/main/java/net/minecraft/server/BlockSkullAbstract.java deleted file mode 100644 index b82f68e2a..000000000 --- a/src/main/java/net/minecraft/server/BlockSkullAbstract.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.minecraft.server; - -public abstract class BlockSkullAbstract extends BlockTileEntity { - - private final BlockSkull.a a; - - public BlockSkullAbstract(BlockSkull.a blockskull_a, Block.Info block_info) { - super(block_info); - this.a = blockskull_a; - } - - public boolean a(IBlockData iblockdata) { - return false; - } - - public TileEntity a(IBlockAccess iblockaccess) { - return new TileEntitySkull(); - } - - // CraftBukkit start - Special case dropping so we can get info from the tile entity - @Override - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - if (world.random.nextFloat() < f) { - TileEntity tileentity = world.getTileEntity(blockposition); - - if (tileentity instanceof TileEntitySkull) { - TileEntitySkull tileentityskull = (TileEntitySkull) tileentity; - - if (tileentityskull.shouldDrop()) { - ItemStack itemstack = this.a((IBlockAccess) world, blockposition, iblockdata); - Block block = tileentityskull.getBlock().getBlock(); - - if ((block == Blocks.PLAYER_HEAD || block == Blocks.PLAYER_WALL_HEAD) && tileentityskull.getGameProfile() != null) { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - - GameProfileSerializer.serialize(nbttagcompound, tileentityskull.getGameProfile()); - itemstack.getOrCreateTag().set("SkullOwner", nbttagcompound); - } - - a(world, blockposition, itemstack); - } - } - } - } - // CraftBukkit end - - public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { - if (!world.isClientSide && entityhuman.abilities.canInstantlyBuild) { - TileEntitySkull.a(world, blockposition); - } - - super.a(world, blockposition, iblockdata, entityhuman); - } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } - - public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { - if (iblockdata.getBlock() != iblockdata1.getBlock() && !world.isClientSide) { - TileEntity tileentity = world.getTileEntity(blockposition); - - if (false && tileentity instanceof TileEntitySkull) { // CraftBukkit - Drop item in code above, not here - TileEntitySkull tileentityskull = (TileEntitySkull) tileentity; - - if (tileentityskull.shouldDrop()) { - ItemStack itemstack = this.a((IBlockAccess) world, blockposition, iblockdata); - Block block = tileentityskull.getBlock().getBlock(); - - if ((block == Blocks.PLAYER_HEAD || block == Blocks.PLAYER_WALL_HEAD) && tileentityskull.getGameProfile() != null) { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - - GameProfileSerializer.serialize(nbttagcompound, tileentityskull.getGameProfile()); - itemstack.getOrCreateTag().set("SkullOwner", nbttagcompound); - } - - a(world, blockposition, itemstack); - } - } - - super.remove(iblockdata, world, blockposition, iblockdata1, flag); - } - } -} diff --git a/src/main/java/net/minecraft/server/BlockSnow.java b/src/main/java/net/minecraft/server/BlockSnow.java index 9c22d2ec7..7fe58ef6e 100644 --- a/src/main/java/net/minecraft/server/BlockSnow.java +++ b/src/main/java/net/minecraft/server/BlockSnow.java @@ -5,97 +5,71 @@ import javax.annotation.Nullable; public class BlockSnow extends Block { - public static final BlockStateInteger LAYERS = BlockProperties.ae; - protected static final VoxelShape[] b = new VoxelShape[] { VoxelShapes.a(), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 4.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 6.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 10.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 12.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 14.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D)}; + public static final BlockStateInteger LAYERS = BlockProperties.ak; + protected static final VoxelShape[] b = new VoxelShape[]{VoxelShapes.a(), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 4.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 6.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 10.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 12.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 14.0D, 16.0D), Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D)}; protected BlockSnow(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockSnow.LAYERS, 1)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockSnow.LAYERS, 1)); } + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { switch (pathmode) { - case LAND: - return (Integer) iblockdata.get(BlockSnow.LAYERS) < 5; - case WATER: - return false; - case AIR: - return false; - default: - return false; + case LAND: + return (Integer) iblockdata.get(BlockSnow.LAYERS) < 5; + case WATER: + return false; + case AIR: + return false; + default: + return false; } } - public boolean a(IBlockData iblockdata) { - return (Integer) iblockdata.get(BlockSnow.LAYERS) == 8; - } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return enumdirection == EnumDirection.DOWN ? EnumBlockFaceShape.SOLID : EnumBlockFaceShape.UNDEFINED; - } - - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockSnow.b[(Integer) iblockdata.get(BlockSnow.LAYERS)]; } - public VoxelShape f(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockSnow.b[(Integer) iblockdata.get(BlockSnow.LAYERS) - 1]; } + @Override + public boolean n(IBlockData iblockdata) { + return true; + } + + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { IBlockData iblockdata1 = iworldreader.getType(blockposition.down()); Block block = iblockdata1.getBlock(); - if (block != Blocks.ICE && block != Blocks.PACKED_ICE && block != Blocks.BARRIER) { - EnumBlockFaceShape enumblockfaceshape = iblockdata1.c(iworldreader, blockposition.down(), EnumDirection.UP); - - return enumblockfaceshape == EnumBlockFaceShape.SOLID || iblockdata1.a(TagsBlock.LEAVES) || block == this && (Integer) iblockdata1.get(BlockSnow.LAYERS) == 8; - } else { - return false; - } + return block != Blocks.ICE && block != Blocks.PACKED_ICE && block != Blocks.BARRIER ? Block.a(iblockdata1.getCollisionShape(iworldreader, blockposition.down()), EnumDirection.UP) || block == this && (Integer) iblockdata1.get(BlockSnow.LAYERS) == 8 : false; } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { return !iblockdata.canPlace(generatoraccess, blockposition) ? Blocks.AIR.getBlockData() : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } - public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { - Integer integer = (Integer) iblockdata.get(BlockSnow.LAYERS); - - if (this.X_() && EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) > 0) { - if (integer == 8) { - a(world, blockposition, new ItemStack(Blocks.SNOW_BLOCK)); - } else { - for (int i = 0; i < integer; ++i) { - a(world, blockposition, this.t(iblockdata)); - } - } - } else { - a(world, blockposition, new ItemStack(Items.SNOWBALL, integer)); - } - - world.setAir(blockposition); - entityhuman.b(StatisticList.BLOCK_MINED.b(this)); - entityhuman.applyExhaustion(0.005F); - } - - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.AIR; - } - - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (world.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 11) { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { return; } // CraftBukkit end - iblockdata.a(world, blockposition, 0); - world.setAir(blockposition); + c(iblockdata, world, blockposition); + world.a(blockposition, false); } } + @Override public boolean a(IBlockData iblockdata, BlockActionContext blockactioncontext) { int i = (Integer) iblockdata.get(BlockSnow.LAYERS); @@ -103,6 +77,7 @@ public class BlockSnow extends Block { } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { IBlockData iblockdata = blockactioncontext.getWorld().getType(blockactioncontext.getClickPosition()); @@ -115,11 +90,8 @@ public class BlockSnow extends Block { } } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockSnow.LAYERS); } - - protected boolean X_() { - return true; - } } diff --git a/src/main/java/net/minecraft/server/BlockSnowBlock.java b/src/main/java/net/minecraft/server/BlockSnowBlock.java deleted file mode 100644 index 44ed65626..000000000 --- a/src/main/java/net/minecraft/server/BlockSnowBlock.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.minecraft.server; - -import java.util.Random; - -public class BlockSnowBlock extends Block { - - protected BlockSnowBlock(Block.Info block_info) { - super(block_info); - } - - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.SNOWBALL; - } - - public int a(IBlockData iblockdata, Random random) { - return 4; - } - - // Paper start - snow blocks don't need to tick - /* - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { - if (world.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 11) { - // CraftBukkit start - if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { - return; - } - // CraftBukkit end - iblockdata.a(world, blockposition, 0); - world.setAir(blockposition); - } - - } - */ - //Paper end -} diff --git a/src/main/java/net/minecraft/server/BlockSoil.java b/src/main/java/net/minecraft/server/BlockSoil.java index ba613d214..2fc6e210d 100644 --- a/src/main/java/net/minecraft/server/BlockSoil.java +++ b/src/main/java/net/minecraft/server/BlockSoil.java @@ -10,14 +10,15 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; public class BlockSoil extends Block { - public static final BlockStateInteger MOISTURE = BlockProperties.ai; + public static final BlockStateInteger MOISTURE = BlockProperties.ap; protected static final VoxelShape b = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 15.0D, 16.0D); protected BlockSoil(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockSoil.MOISTURE, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockSoil.MOISTURE, 0)); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (enumdirection == EnumDirection.UP && !iblockdata.canPlace(generatoraccess, blockposition)) { generatoraccess.getBlockTickList().a(blockposition, this, 1); @@ -26,31 +27,32 @@ public class BlockSoil extends Block { return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { IBlockData iblockdata1 = iworldreader.getType(blockposition.up()); return !iblockdata1.getMaterial().isBuildable() || iblockdata1.getBlock() instanceof BlockFenceGate; } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { return !this.getBlockData().canPlace(blockactioncontext.getWorld(), blockactioncontext.getClickPosition()) ? Blocks.DIRT.getBlockData() : super.getPlacedState(blockactioncontext); } - public int j(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return iblockaccess.K(); + @Override + public boolean n(IBlockData iblockdata) { + return true; } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockSoil.b; } - public boolean a(IBlockData iblockdata) { - return false; - } - - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!iblockdata.canPlace(world, blockposition)) { - b(iblockdata, world, blockposition); + fade(iblockdata, world, blockposition); } else { int i = (Integer) iblockdata.get(BlockSoil.MOISTURE); @@ -58,7 +60,7 @@ public class BlockSoil extends Block { if (i > 0) { org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(world, blockposition, (IBlockData) iblockdata.set(BlockSoil.MOISTURE, i - 1), 2); // CraftBukkit } else if (!a((IBlockAccess) world, blockposition)) { - b(iblockdata, world, blockposition); + fade(iblockdata, world, blockposition); } } else if (i < 7) { org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(world, blockposition, (IBlockData) iblockdata.set(BlockSoil.MOISTURE, 7), 2); // CraftBukkit @@ -67,15 +69,16 @@ public class BlockSoil extends Block { } } + @Override public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) { super.fallOn(world, blockposition, entity, f); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. - if (!world.isClientSide && world.random.nextFloat() < f - 0.5F && entity instanceof EntityLiving && (entity instanceof EntityHuman || world.getGameRules().getBoolean("mobGriefing")) && entity.width * entity.width * entity.length > 0.512F) { + if (!world.isClientSide && world.random.nextFloat() < f - 0.5F && entity instanceof EntityLiving && (entity instanceof EntityHuman || world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) && entity.getWidth() * entity.getWidth() * entity.getHeight() > 0.512F) { // CraftBukkit start - Interact soil org.bukkit.event.Cancellable cancellable; if (entity instanceof EntityHuman) { cancellable = CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null, null); } else { - cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition)); // Akarin + cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); world.getServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); } @@ -87,13 +90,13 @@ public class BlockSoil extends Block { return; } // CraftBukkit end - b(world.getType(blockposition), world, blockposition); + fade(world.getType(blockposition), world, blockposition); } // super.fallOn(world, blockposition, entity, f); // CraftBukkit - moved up } - public static void b(IBlockData iblockdata, World world, BlockPosition blockposition) { + public static void fade(IBlockData iblockdata, World world, BlockPosition blockposition) { // CraftBukkit start if (CraftEventFactory.callBlockFadeEvent(world, blockposition, Blocks.DIRT.getBlockData()).isCancelled()) { return; @@ -109,33 +112,27 @@ public class BlockSoil extends Block { } private static boolean a(IWorldReader iworldreader, BlockPosition blockposition) { - Iterator iterator = BlockPosition.b(blockposition.a(-4, 0, -4), blockposition.a(4, 1, 4)).iterator(); + Iterator iterator = BlockPosition.a(blockposition.b(-4, 0, -4), blockposition.b(4, 1, 4)).iterator(); - BlockPosition.MutableBlockPosition blockposition_mutableblockposition; + BlockPosition blockposition1; do { if (!iterator.hasNext()) { return false; } - blockposition_mutableblockposition = (BlockPosition.MutableBlockPosition) iterator.next(); - } while (!iworldreader.getFluid(blockposition_mutableblockposition).a(TagsFluid.WATER)); + blockposition1 = (BlockPosition) iterator.next(); + } while (!iworldreader.getFluid(blockposition1).a(TagsFluid.WATER)); return true; } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Blocks.DIRT; - } - + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockSoil.MOISTURE); } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return enumdirection == EnumDirection.DOWN ? EnumBlockFaceShape.SOLID : EnumBlockFaceShape.UNDEFINED; - } - + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { return false; } diff --git a/src/main/java/net/minecraft/server/BlockSponge.java b/src/main/java/net/minecraft/server/BlockSponge.java index 1f2d285d2..9edf937a6 100644 --- a/src/main/java/net/minecraft/server/BlockSponge.java +++ b/src/main/java/net/minecraft/server/BlockSponge.java @@ -15,15 +15,17 @@ public class BlockSponge extends Block { super(block_info); } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata1.getBlock() != iblockdata.getBlock()) { this.a(world, blockposition); } } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { this.a(world, blockposition); - super.doPhysics(iblockdata, world, blockposition, block, blockposition1); + super.doPhysics(iblockdata, world, blockposition, block, blockposition1, flag); } protected void a(World world, BlockPosition blockposition) { @@ -51,8 +53,10 @@ public class BlockSponge extends Block { for (int l = 0; l < k; ++l) { EnumDirection enumdirection = aenumdirection[l]; BlockPosition blockposition2 = blockposition1.shift(enumdirection); - IBlockData iblockdata = world.getType(blockposition2); - Fluid fluid = world.getFluid(blockposition2); + // CraftBukkit start + IBlockData iblockdata = blockList.getType(blockposition2); + Fluid fluid = blockList.getFluid(blockposition2); + // CraftBukkit end Material material = iblockdata.getMaterial(); if (fluid.a(TagsFluid.WATER)) { @@ -68,8 +72,12 @@ public class BlockSponge extends Block { queue.add(new Tuple<>(blockposition2, j + 1)); } } else if (material == Material.WATER_PLANT || material == Material.REPLACEABLE_WATER_PLANT) { - // iblockdata.a(world, blockposition2, 0); - blockList.setTypeAndData(blockposition2, Blocks.AIR.getBlockData(), 3); // CraftBukkit + // CraftBukkit start + // TileEntity tileentity = iblockdata.getBlock().isTileEntity() ? world.getTileEntity(blockposition2) : null; + + // a(iblockdata, world, blockposition2, tileentity); + blockList.setTypeAndData(blockposition2, Blocks.AIR.getBlockData(), 3); + // CraftBukkit end ++i; if (j < 6) { queue.add(new Tuple<>(blockposition2, j + 1)); @@ -85,7 +93,7 @@ public class BlockSponge extends Block { // CraftBukkit start List blocks = blockList.getList(); // Is a clone if (!blocks.isEmpty()) { - final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(blockposition); // Akarin + final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); SpongeAbsorbEvent event = new SpongeAbsorbEvent(bblock, (List) (List) blocks); world.getServer().getPluginManager().callEvent(event); @@ -106,9 +114,10 @@ public class BlockSponge extends Block { } else if (iblockdata.getBlock() instanceof BlockFluids) { // NOP } else if (material == Material.WATER_PLANT || material == Material.REPLACEABLE_WATER_PLANT) { + TileEntity tileentity = iblockdata.getBlock().isTileEntity() ? world.getTileEntity(blockposition2) : null; // Paper start if (block.getHandle().getMaterial() == Material.AIR) { - iblockdata.dropNaturally(world, blockposition2, 0); + dropNaturally(iblockdata, world, blockposition2, tileentity); } // Paper end } @@ -121,4 +130,3 @@ public class BlockSponge extends Block { return i > 0; } } - diff --git a/src/main/java/net/minecraft/server/BlockState.java b/src/main/java/net/minecraft/server/BlockState.java index ea0e0ff4f..00e67b567 100644 --- a/src/main/java/net/minecraft/server/BlockState.java +++ b/src/main/java/net/minecraft/server/BlockState.java @@ -13,26 +13,28 @@ public abstract class BlockState> implements IBlockState this.b = s; } + @Override public String a() { return this.b; } + @Override public Class b() { return this.a; } public String toString() { - return MoreObjects.toStringHelper(this).add("name", this.b).add("clazz", this.a).add("values", this.d()).toString(); + return MoreObjects.toStringHelper(this).add("name", this.b).add("clazz", this.a).add("values", this.getValues()).toString(); } public boolean equals(Object object) { return this == object; // Paper - only one instance per configuration } - private static java.util.concurrent.atomic.AtomicInteger hashId = new java.util.concurrent.atomic.AtomicInteger(1);// Paper - only one instance per configuration + private static final java.util.concurrent.atomic.AtomicInteger hashId = new java.util.concurrent.atomic.AtomicInteger(1); // Paper - only one instance per configuration private final int hashCode = 92821 * hashId.getAndIncrement(); // Paper - only one instance per configuration public final int hashCode() { - return hashCode; // Paper - only one instance per configuration + return this.hashCode; // Paper - only one instance per configuration } public int c() { diff --git a/src/main/java/net/minecraft/server/BlockStateBoolean.java b/src/main/java/net/minecraft/server/BlockStateBoolean.java index 71d2ad970..7ca302b52 100644 --- a/src/main/java/net/minecraft/server/BlockStateBoolean.java +++ b/src/main/java/net/minecraft/server/BlockStateBoolean.java @@ -12,7 +12,8 @@ public class BlockStateBoolean extends BlockState { super(s, Boolean.class); } - public Collection d() { + @Override + public Collection getValues() { return this.a; } @@ -20,6 +21,7 @@ public class BlockStateBoolean extends BlockState { return new BlockStateBoolean(s); } + @Override public Optional b(String s) { return !"true".equals(s) && !"false".equals(s) ? Optional.empty() : Optional.of(Boolean.valueOf(s)); } @@ -40,6 +42,7 @@ public class BlockStateBoolean extends BlockState { } } + @Override public int c() { return 31 * super.c() + this.a.hashCode(); } diff --git a/src/main/java/net/minecraft/server/BlockStateEnum.java b/src/main/java/net/minecraft/server/BlockStateEnum.java index facbf30b4..7cdadc6b6 100644 --- a/src/main/java/net/minecraft/server/BlockStateEnum.java +++ b/src/main/java/net/minecraft/server/BlockStateEnum.java @@ -35,10 +35,12 @@ public class BlockStateEnum & INamable> extends BlockState } - public Collection d() { + @Override + public Collection getValues() { return this.a; } + @Override public Optional b(String s) { return Optional.ofNullable(this.b.get(s)); } @@ -59,6 +61,7 @@ public class BlockStateEnum & INamable> extends BlockState } } + @Override public int c() { int i = super.c(); diff --git a/src/main/java/net/minecraft/server/BlockStateInteger.java b/src/main/java/net/minecraft/server/BlockStateInteger.java index 613cd0bce..0499a7170 100644 --- a/src/main/java/net/minecraft/server/BlockStateInteger.java +++ b/src/main/java/net/minecraft/server/BlockStateInteger.java @@ -33,7 +33,8 @@ public class BlockStateInteger extends BlockState { } } - public Collection d() { + @Override + public Collection getValues() { return this.a; } @@ -49,6 +50,7 @@ public class BlockStateInteger extends BlockState { } } + @Override public int c() { return 31 * super.c() + this.a.hashCode(); } @@ -57,6 +59,7 @@ public class BlockStateInteger extends BlockState { return new BlockStateInteger(s, i, j); } + @Override public Optional b(String s) { try { Integer integer = Integer.valueOf(s); diff --git a/src/main/java/net/minecraft/server/BlockStem.java b/src/main/java/net/minecraft/server/BlockStem.java index f8dda1b7a..f67b0c3ef 100644 --- a/src/main/java/net/minecraft/server/BlockStem.java +++ b/src/main/java/net/minecraft/server/BlockStem.java @@ -1,33 +1,35 @@ package net.minecraft.server; import java.util.Random; -import javax.annotation.Nullable; import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockStem extends BlockPlant implements IBlockFragilePlantElement { - public static final BlockStateInteger AGE = BlockProperties.W; - protected static final VoxelShape[] b = new VoxelShape[] { Block.a(7.0D, 0.0D, 7.0D, 9.0D, 2.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 4.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 6.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 8.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 10.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 12.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 14.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 16.0D, 9.0D)}; + public static final BlockStateInteger AGE = BlockProperties.ac; + protected static final VoxelShape[] b = new VoxelShape[]{Block.a(7.0D, 0.0D, 7.0D, 9.0D, 2.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 4.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 6.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 8.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 10.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 12.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 14.0D, 9.0D), Block.a(7.0D, 0.0D, 7.0D, 9.0D, 16.0D, 9.0D)}; private final BlockStemmed blockFruit; protected BlockStem(BlockStemmed blockstemmed, Block.Info block_info) { super(block_info); this.blockFruit = blockstemmed; - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockStem.AGE, 0)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockStem.AGE, 0)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockStem.b[(Integer) iblockdata.get(BlockStem.AGE)]; } - protected boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + protected boolean a_(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { return iblockdata.getBlock() == Blocks.FARMLAND; } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { - super.a(iblockdata, world, blockposition, random); - if (world.isLightLevel(blockposition.up(), 9)) { // Paper + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + super.tick(iblockdata, world, blockposition, random); + if (world.getLightLevel(blockposition, 0) >= 9) { float f = BlockCrops.a((Block) this, (IBlockAccess) world, blockposition); if (random.nextInt((int) ((100.0F / (this == Blocks.PUMPKIN_STEM ? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier)) * (25.0F / f)) + 1) == 0) { // Spigot @@ -55,47 +57,17 @@ public class BlockStem extends BlockPlant implements IBlockFragilePlantElement { } } - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - super.dropNaturally(iblockdata, world, blockposition, f, i); - if (!world.isClientSide) { - Item item = this.d(); - - if (item != null) { - int j = (Integer) iblockdata.get(BlockStem.AGE); - - for (int k = 0; k < 3; ++k) { - if (world.random.nextInt(15) <= j) { - a(world, blockposition, new ItemStack(item)); - } - } - - } - } - } - - @Nullable - protected Item d() { - return this.blockFruit == Blocks.PUMPKIN ? Items.PUMPKIN_SEEDS : (this.blockFruit == Blocks.MELON ? Items.MELON_SEEDS : null); - } - - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.AIR; - } - - public ItemStack a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - Item item = this.d(); - - return item == null ? ItemStack.a : new ItemStack(item); - } - + @Override public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { return (Integer) iblockdata.get(BlockStem.AGE) != 7; } + @Override public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { return true; } + @Override public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { int i = Math.min(7, (Integer) iblockdata.get(BlockStem.AGE) + MathHelper.nextInt(world.random, 2, 5)); IBlockData iblockdata1 = (IBlockData) iblockdata.set(BlockStem.AGE, i); @@ -107,6 +79,7 @@ public class BlockStem extends BlockPlant implements IBlockFragilePlantElement { } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockStem.AGE); } diff --git a/src/main/java/net/minecraft/server/BlockSweetBerryBush.java b/src/main/java/net/minecraft/server/BlockSweetBerryBush.java new file mode 100644 index 000000000..e16b477e8 --- /dev/null +++ b/src/main/java/net/minecraft/server/BlockSweetBerryBush.java @@ -0,0 +1,94 @@ +package net.minecraft.server; + +import java.util.Random; +// CraftBukkit start +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.event.CraftEventFactory; +// CraftBukkit end + +public class BlockSweetBerryBush extends BlockPlant implements IBlockFragilePlantElement { + + public static final BlockStateInteger a = BlockProperties.aa; + private static final VoxelShape b = Block.a(3.0D, 0.0D, 3.0D, 13.0D, 8.0D, 13.0D); + private static final VoxelShape c = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D); + + public BlockSweetBerryBush(Block.Info block_info) { + super(block_info); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockSweetBerryBush.a, 0)); + } + + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return (Integer) iblockdata.get(BlockSweetBerryBush.a) == 0 ? BlockSweetBerryBush.b : ((Integer) iblockdata.get(BlockSweetBerryBush.a) < 3 ? BlockSweetBerryBush.c : super.a(iblockdata, iblockaccess, blockposition, voxelshapecollision)); + } + + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + super.tick(iblockdata, world, blockposition, random); + int i = (Integer) iblockdata.get(BlockSweetBerryBush.a); + + if (i < 3 && world.random.nextInt(Math.max(1, (int) (100.0F / world.spigotConfig.sweetBerryModifier) * 5)) == 0 && world.getLightLevel(blockposition.up(), 0) >= 9) { // Spigot + CraftEventFactory.handleBlockGrowEvent(world, blockposition, (IBlockData) iblockdata.set(BlockSweetBerryBush.a, i + 1), 2); // CraftBukkit + } + + } + + @Override + public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { + if (entity instanceof EntityLiving && entity.getEntityType() != EntityTypes.FOX) { + entity.a(iblockdata, new Vec3D(0.800000011920929D, 0.75D, 0.800000011920929D)); + if (!world.isClientSide && (Integer) iblockdata.get(BlockSweetBerryBush.a) > 0 && (entity.H != entity.locX || entity.J != entity.locZ)) { + double d0 = Math.abs(entity.locX - entity.H); + double d1 = Math.abs(entity.locZ - entity.J); + + if (d0 >= 0.003000000026077032D || d1 >= 0.003000000026077032D) { + CraftEventFactory.blockDamage = CraftBlock.at(world, blockposition); // CraftBukkit + entity.damageEntity(DamageSource.SWEET_BERRY_BUSH, 1.0F); + CraftEventFactory.blockDamage = null; // CraftBukkit + } + } + + } + } + + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { + int i = (Integer) iblockdata.get(BlockSweetBerryBush.a); + boolean flag = i == 3; + + if (!flag && entityhuman.b(enumhand).getItem() == Items.BONE_MEAL) { + return false; + } else if (i > 1) { + int j = 1 + world.random.nextInt(2); + + a(world, blockposition, new ItemStack(Items.SWEET_BERRIES, j + (flag ? 1 : 0))); + world.playSound((EntityHuman) null, blockposition, SoundEffects.ITEM_SWEET_BERRIES_PICK_FROM_BUSH, SoundCategory.BLOCKS, 1.0F, 0.8F + world.random.nextFloat() * 0.4F); + world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockSweetBerryBush.a, 1), 2); + return true; + } else { + return super.interact(iblockdata, world, blockposition, entityhuman, enumhand, movingobjectpositionblock); + } + } + + @Override + protected void a(BlockStateList.a blockstatelist_a) { + blockstatelist_a.a(BlockSweetBerryBush.a); + } + + @Override + public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + return (Integer) iblockdata.get(BlockSweetBerryBush.a) < 3; + } + + @Override + public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + return true; + } + + @Override + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + int i = Math.min(3, (Integer) iblockdata.get(BlockSweetBerryBush.a) + 1); + + world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockSweetBerryBush.a, i), 2); + } +} diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java index c821e6b3b..b2689ee8b 100644 --- a/src/main/java/net/minecraft/server/BlockTNT.java +++ b/src/main/java/net/minecraft/server/BlockTNT.java @@ -5,14 +5,15 @@ import com.destroystokyo.paper.event.block.TNTPrimeEvent; // Paper - TNTPrimeEve public class BlockTNT extends Block { - public static final BlockStateBoolean a = BlockProperties.x; + public static final BlockStateBoolean a = BlockProperties.B; public BlockTNT(Block.Info block_info) { super(block_info); - this.v((IBlockData) this.getBlockData().set(BlockTNT.a, false)); + this.o((IBlockData) this.getBlockData().set(BlockTNT.a, false)); } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata1.getBlock() != iblockdata.getBlock()) { if (world.isBlockIndirectlyPowered(blockposition)) { // Paper start - TNTPrimeEvent @@ -20,45 +21,42 @@ public class BlockTNT extends Block { if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) return; // Paper end - this.a(world, blockposition); - world.setAir(blockposition); + a(world, blockposition); + world.a(blockposition, false); } } } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if (world.isBlockIndirectlyPowered(blockposition)) { // Paper start - TNTPrimeEvent org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition);; if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) return; // Paper end - this.a(world, blockposition); - world.setAir(blockposition); + a(world, blockposition); + world.a(blockposition, false); } } - public void dropNaturally(IBlockData iblockdata, World world, BlockPosition blockposition, float f, int i) { - if (!(Boolean) iblockdata.get(BlockTNT.a)) { - super.dropNaturally(iblockdata, world, blockposition, f, i); - } - } - + @Override public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { - if (!world.e() && !entityhuman.u() && (Boolean) iblockdata.get(BlockTNT.a)) { - this.a(world, blockposition); + if (!world.e() && !entityhuman.isCreative() && (Boolean) iblockdata.get(BlockTNT.a)) { + a(world, blockposition); } super.a(world, blockposition, iblockdata, entityhuman); } + @Override public void wasExploded(World world, BlockPosition blockposition, Explosion explosion) { if (!world.isClientSide) { // Paper start - TNTPrimeEvent org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition);; - org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.bukkitEntity : null; + org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.getBukkitEntity() : null; if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) return; // Paper end @@ -69,35 +67,38 @@ public class BlockTNT extends Block { } } - public void a(World world, BlockPosition blockposition) { - this.a(world, blockposition, (EntityLiving) null); + public static void a(World world, BlockPosition blockposition) { + a(world, blockposition, (EntityLiving) null); } - private void a(World world, BlockPosition blockposition, @Nullable EntityLiving entityliving) { + private static void a(World world, BlockPosition blockposition, @Nullable EntityLiving entityliving) { if (!world.isClientSide) { EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) blockposition.getX() + 0.5F), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + 0.5F), entityliving); world.addEntity(entitytntprimed); - world.a((EntityHuman) null, entitytntprimed.locX, entitytntprimed.locY, entitytntprimed.locZ, SoundEffects.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F); + world.playSound((EntityHuman) null, entitytntprimed.locX, entitytntprimed.locY, entitytntprimed.locZ, SoundEffects.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F); } } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { ItemStack itemstack = entityhuman.b(enumhand); Item item = itemstack.getItem(); if (item != Items.FLINT_AND_STEEL && item != Items.FIRE_CHARGE) { - return super.interact(iblockdata, world, blockposition, entityhuman, enumhand, enumdirection, f, f1, f2); + return super.interact(iblockdata, world, blockposition, entityhuman, enumhand, movingobjectpositionblock); } else { // Paper start - TNTPrimeEvent org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition); - if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.ITEM, entityhuman.bukkitEntity).callEvent()) + if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.ITEM, entityhuman.getBukkitEntity()).callEvent()) return true; // Paper end - this.a(world, blockposition, (EntityLiving) entityhuman); + a(world, blockposition, (EntityLiving) entityhuman); world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 11); if (item == Items.FLINT_AND_STEEL) { - itemstack.damage(1, entityhuman); + itemstack.damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(enumhand); + }); } else { itemstack.subtract(1); } @@ -106,34 +107,40 @@ public class BlockTNT extends Block { } } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { + @Override + public void a(World world, IBlockData iblockdata, MovingObjectPositionBlock movingobjectpositionblock, Entity entity) { if (!world.isClientSide && entity instanceof EntityArrow) { EntityArrow entityarrow = (EntityArrow) entity; Entity entity1 = entityarrow.getShooter(); if (entityarrow.isBurning()) { + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition(); // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityarrow, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { return; } // CraftBukkit end + // Paper start - TNTPrimeEvent org.bukkit.block.Block tntBlock = MCUtil.toBukkitBlock(world, blockposition); - if (!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.PROJECTILE, entityarrow.bukkitEntity).callEvent()) { + if (!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.PROJECTILE, entityarrow.getBukkitEntity()).callEvent()) { return; } // Paper end - this.a(world, blockposition, entity1 instanceof EntityLiving ? (EntityLiving) entity1 : null); - world.setAir(blockposition); + + a(world, blockposition, entity1 instanceof EntityLiving ? (EntityLiving) entity1 : null); + world.a(blockposition, false); } } } + @Override public boolean a(Explosion explosion) { return false; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockTNT.a); } diff --git a/src/main/java/net/minecraft/server/BlockTallPlant.java b/src/main/java/net/minecraft/server/BlockTallPlant.java index 39d449c28..227fe073f 100644 --- a/src/main/java/net/minecraft/server/BlockTallPlant.java +++ b/src/main/java/net/minecraft/server/BlockTallPlant.java @@ -4,13 +4,14 @@ import javax.annotation.Nullable; public class BlockTallPlant extends BlockPlant { - public static final BlockStateEnum HALF = BlockProperties.P; + public static final BlockStateEnum HALF = BlockProperties.U; public BlockTallPlant(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTallPlant.HALF, BlockPropertyDoubleBlockHalf.LOWER)); + this.o((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTallPlant.HALF, BlockPropertyDoubleBlockHalf.LOWER)); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { BlockPropertyDoubleBlockHalf blockpropertydoubleblockhalf = (BlockPropertyDoubleBlockHalf) iblockdata.get(BlockTallPlant.HALF); @@ -18,16 +19,19 @@ public class BlockTallPlant extends BlockPlant { } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { BlockPosition blockposition = blockactioncontext.getClickPosition(); return blockposition.getY() < 255 && blockactioncontext.getWorld().getType(blockposition.up()).a(blockactioncontext) ? super.getPlacedState(blockactioncontext) : null; } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { world.setTypeAndData(blockposition.up(), (IBlockData) this.getBlockData().set(BlockTallPlant.HALF, BlockPropertyDoubleBlockHalf.UPPER), 3); } + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { if (iblockdata.get(BlockTallPlant.HALF) != BlockPropertyDoubleBlockHalf.UPPER) { return super.canPlace(iblockdata, iworldreader, blockposition); @@ -43,10 +47,12 @@ public class BlockTallPlant extends BlockPlant { generatoraccess.setTypeAndData(blockposition.up(), (IBlockData) this.getBlockData().set(BlockTallPlant.HALF, BlockPropertyDoubleBlockHalf.UPPER), i); } + @Override public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { super.a(world, entityhuman, blockposition, Blocks.AIR.getBlockData(), tileentity, itemstack); } + @Override public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { // CraftBukkit start if (((WorldServer)world).hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, blockposition).isCancelled()) { // Paper @@ -54,38 +60,28 @@ public class BlockTallPlant extends BlockPlant { } // CraftBukkit end BlockPropertyDoubleBlockHalf blockpropertydoubleblockhalf = (BlockPropertyDoubleBlockHalf) iblockdata.get(BlockTallPlant.HALF); - boolean flag = blockpropertydoubleblockhalf == BlockPropertyDoubleBlockHalf.LOWER; - BlockPosition blockposition1 = flag ? blockposition.up() : blockposition.down(); + BlockPosition blockposition1 = blockpropertydoubleblockhalf == BlockPropertyDoubleBlockHalf.LOWER ? blockposition.up() : blockposition.down(); IBlockData iblockdata1 = world.getType(blockposition1); if (iblockdata1.getBlock() == this && iblockdata1.get(BlockTallPlant.HALF) != blockpropertydoubleblockhalf) { world.setTypeAndData(blockposition1, Blocks.AIR.getBlockData(), 35); world.a(entityhuman, 2001, blockposition1, Block.getCombinedId(iblockdata1)); - if (!world.isClientSide && !entityhuman.u()) { - if (flag) { - this.a(iblockdata, world, blockposition, entityhuman.getItemInMainHand()); - } else { - this.a(iblockdata1, world, blockposition1, entityhuman.getItemInMainHand()); - } + if (!world.isClientSide && !entityhuman.isCreative()) { + dropItems(iblockdata, world, blockposition, (TileEntity) null, entityhuman, entityhuman.getItemInMainHand()); + dropItems(iblockdata1, world, blockposition1, (TileEntity) null, entityhuman, entityhuman.getItemInMainHand()); } } super.a(world, blockposition, iblockdata, entityhuman); } - protected void a(IBlockData iblockdata, World world, BlockPosition blockposition, ItemStack itemstack) { - iblockdata.a(world, blockposition, 0); - } - - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return (IMaterial) (iblockdata.get(BlockTallPlant.HALF) == BlockPropertyDoubleBlockHalf.LOWER ? super.getDropType(iblockdata, world, blockposition, i) : Items.AIR); - } - + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockTallPlant.HALF); } - public Block.EnumRandomOffset q() { + @Override + public Block.EnumRandomOffset R_() { return Block.EnumRandomOffset.XZ; } } diff --git a/src/main/java/net/minecraft/server/BlockTrapdoor.java b/src/main/java/net/minecraft/server/BlockTrapdoor.java index 91f0a6205..015e8b6a1 100644 --- a/src/main/java/net/minecraft/server/BlockTrapdoor.java +++ b/src/main/java/net/minecraft/server/BlockTrapdoor.java @@ -1,70 +1,67 @@ package net.minecraft.server; import javax.annotation.Nullable; - -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit -public class BlockTrapdoor extends BlockFacingHorizontal implements IFluidSource, IFluidContainer { +public class BlockTrapdoor extends BlockFacingHorizontal implements IBlockWaterlogged { - public static final BlockStateBoolean OPEN = BlockProperties.r; - public static final BlockStateEnum HALF = BlockProperties.Q; - public static final BlockStateBoolean c = BlockProperties.t; - public static final BlockStateBoolean o = BlockProperties.y; - protected static final VoxelShape p = Block.a(0.0D, 0.0D, 0.0D, 3.0D, 16.0D, 16.0D); - protected static final VoxelShape q = Block.a(13.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); - protected static final VoxelShape r = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 3.0D); - protected static final VoxelShape s = Block.a(0.0D, 0.0D, 13.0D, 16.0D, 16.0D, 16.0D); - protected static final VoxelShape t = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 3.0D, 16.0D); - protected static final VoxelShape u = Block.a(0.0D, 13.0D, 0.0D, 16.0D, 16.0D, 16.0D); + public static final BlockStateBoolean OPEN = BlockProperties.u; + public static final BlockStateEnum HALF = BlockProperties.V; + public static final BlockStateBoolean c = BlockProperties.w; + public static final BlockStateBoolean d = BlockProperties.C; + protected static final VoxelShape e = Block.a(0.0D, 0.0D, 0.0D, 3.0D, 16.0D, 16.0D); + protected static final VoxelShape f = Block.a(13.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape g = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 3.0D); + protected static final VoxelShape h = Block.a(0.0D, 0.0D, 13.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape i = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 3.0D, 16.0D); + protected static final VoxelShape j = Block.a(0.0D, 13.0D, 0.0D, 16.0D, 16.0D, 16.0D); protected BlockTrapdoor(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTrapdoor.FACING, EnumDirection.NORTH)).set(BlockTrapdoor.OPEN, false)).set(BlockTrapdoor.HALF, BlockPropertyHalf.BOTTOM)).set(BlockTrapdoor.c, false)).set(BlockTrapdoor.o, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTrapdoor.FACING, EnumDirection.NORTH)).set(BlockTrapdoor.OPEN, false)).set(BlockTrapdoor.HALF, BlockPropertyHalf.BOTTOM)).set(BlockTrapdoor.c, false)).set(BlockTrapdoor.d, false)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { if (!(Boolean) iblockdata.get(BlockTrapdoor.OPEN)) { - return iblockdata.get(BlockTrapdoor.HALF) == BlockPropertyHalf.TOP ? BlockTrapdoor.u : BlockTrapdoor.t; + return iblockdata.get(BlockTrapdoor.HALF) == BlockPropertyHalf.TOP ? BlockTrapdoor.j : BlockTrapdoor.i; } else { switch ((EnumDirection) iblockdata.get(BlockTrapdoor.FACING)) { - case NORTH: - default: - return BlockTrapdoor.s; - case SOUTH: - return BlockTrapdoor.r; - case WEST: - return BlockTrapdoor.q; - case EAST: - return BlockTrapdoor.p; + case NORTH: + default: + return BlockTrapdoor.h; + case SOUTH: + return BlockTrapdoor.g; + case WEST: + return BlockTrapdoor.f; + case EAST: + return BlockTrapdoor.e; } } } - public boolean a(IBlockData iblockdata) { - return false; - } - + @Override public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { switch (pathmode) { - case LAND: - return (Boolean) iblockdata.get(BlockTrapdoor.OPEN); - case WATER: - return (Boolean) iblockdata.get(BlockTrapdoor.o); - case AIR: - return (Boolean) iblockdata.get(BlockTrapdoor.OPEN); - default: - return false; + case LAND: + return (Boolean) iblockdata.get(BlockTrapdoor.OPEN); + case WATER: + return (Boolean) iblockdata.get(BlockTrapdoor.d); + case AIR: + return (Boolean) iblockdata.get(BlockTrapdoor.OPEN); + default: + return false; } } - public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { + @Override + public boolean interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { if (this.material == Material.ORE) { return false; } else { iblockdata = (IBlockData) iblockdata.a((IBlockState) BlockTrapdoor.OPEN); world.setTypeAndData(blockposition, iblockdata, 2); - if ((Boolean) iblockdata.get(BlockTrapdoor.o)) { + if ((Boolean) iblockdata.get(BlockTrapdoor.d)) { world.getFluidTickList().a(blockposition, FluidTypes.WATER, FluidTypes.WATER.a((IWorldReader) world)); } @@ -86,14 +83,15 @@ public class BlockTrapdoor extends BlockFacingHorizontal implements IFluidSource } - public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { + @Override + public void doPhysics(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { if (!world.isClientSide) { - boolean flag = world.isBlockIndirectlyPowered(blockposition); + boolean flag1 = world.isBlockIndirectlyPowered(blockposition); - if (flag != (Boolean) iblockdata.get(BlockTrapdoor.c)) { + if (flag1 != (Boolean) iblockdata.get(BlockTrapdoor.c)) { // CraftBukkit start org.bukkit.World bworld = world.getWorld(); - org.bukkit.block.Block bblock = ((CraftWorld) bworld).getBlockAt(blockposition); // Akarin + org.bukkit.block.Block bblock = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); int power = bblock.getBlockPower(); int oldPower = (Boolean) iblockdata.get(OPEN) ? 15 : 0; @@ -101,16 +99,16 @@ public class BlockTrapdoor extends BlockFacingHorizontal implements IFluidSource if (oldPower == 0 ^ power == 0 || block.getBlockData().isPowerSource()) { BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bblock, oldPower, power); world.getServer().getPluginManager().callEvent(eventRedstone); - flag = eventRedstone.getNewCurrent() > 0; + flag1 = eventRedstone.getNewCurrent() > 0; } // CraftBukkit end - if ((Boolean) iblockdata.get(BlockTrapdoor.OPEN) != flag) { - iblockdata = (IBlockData) iblockdata.set(BlockTrapdoor.OPEN, flag); - this.a((EntityHuman) null, world, blockposition, flag); + if ((Boolean) iblockdata.get(BlockTrapdoor.OPEN) != flag1) { + iblockdata = (IBlockData) iblockdata.set(BlockTrapdoor.OPEN, flag1); + this.a((EntityHuman) null, world, blockposition, flag1); } - world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockTrapdoor.c, flag), 2); - if ((Boolean) iblockdata.get(BlockTrapdoor.o)) { + world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockTrapdoor.c, flag1), 2); + if ((Boolean) iblockdata.get(BlockTrapdoor.d)) { world.getFluidTickList().a(blockposition, FluidTypes.WATER, FluidTypes.WATER.a((IWorldReader) world)); } } @@ -118,13 +116,14 @@ public class BlockTrapdoor extends BlockFacingHorizontal implements IFluidSource } } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { IBlockData iblockdata = this.getBlockData(); Fluid fluid = blockactioncontext.getWorld().getFluid(blockactioncontext.getClickPosition()); EnumDirection enumdirection = blockactioncontext.getClickedFace(); if (!blockactioncontext.c() && enumdirection.k().c()) { - iblockdata = (IBlockData) ((IBlockData) iblockdata.set(BlockTrapdoor.FACING, enumdirection)).set(BlockTrapdoor.HALF, blockactioncontext.n() > 0.5F ? BlockPropertyHalf.TOP : BlockPropertyHalf.BOTTOM); + iblockdata = (IBlockData) ((IBlockData) iblockdata.set(BlockTrapdoor.FACING, enumdirection)).set(BlockTrapdoor.HALF, blockactioncontext.j().y - (double) blockactioncontext.getClickPosition().getY() > 0.5D ? BlockPropertyHalf.TOP : BlockPropertyHalf.BOTTOM); } else { iblockdata = (IBlockData) ((IBlockData) iblockdata.set(BlockTrapdoor.FACING, blockactioncontext.f().opposite())).set(BlockTrapdoor.HALF, enumdirection == EnumDirection.UP ? BlockPropertyHalf.BOTTOM : BlockPropertyHalf.TOP); } @@ -133,56 +132,35 @@ public class BlockTrapdoor extends BlockFacingHorizontal implements IFluidSource iblockdata = (IBlockData) ((IBlockData) iblockdata.set(BlockTrapdoor.OPEN, true)).set(BlockTrapdoor.c, true); } - return (IBlockData) iblockdata.set(BlockTrapdoor.o, fluid.c() == FluidTypes.WATER); + return (IBlockData) iblockdata.set(BlockTrapdoor.d, fluid.getType() == FluidTypes.WATER); } + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override protected void a(BlockStateList.a blockstatelist_a) { - blockstatelist_a.a(BlockTrapdoor.FACING, BlockTrapdoor.OPEN, BlockTrapdoor.HALF, BlockTrapdoor.c, BlockTrapdoor.o); + blockstatelist_a.a(BlockTrapdoor.FACING, BlockTrapdoor.OPEN, BlockTrapdoor.HALF, BlockTrapdoor.c, BlockTrapdoor.d); } - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return (enumdirection == EnumDirection.UP && iblockdata.get(BlockTrapdoor.HALF) == BlockPropertyHalf.TOP || enumdirection == EnumDirection.DOWN && iblockdata.get(BlockTrapdoor.HALF) == BlockPropertyHalf.BOTTOM) && !(Boolean) iblockdata.get(BlockTrapdoor.OPEN) ? EnumBlockFaceShape.SOLID : EnumBlockFaceShape.UNDEFINED; - } - - public FluidType removeFluid(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata) { - if ((Boolean) iblockdata.get(BlockTrapdoor.o)) { - generatoraccess.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockTrapdoor.o, false), 3); - return FluidTypes.WATER; - } else { - return FluidTypes.EMPTY; - } - } - - public Fluid h(IBlockData iblockdata) { - return (Boolean) iblockdata.get(BlockTrapdoor.o) ? FluidTypes.WATER.a(false) : super.h(iblockdata); - } - - public boolean canPlace(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, FluidType fluidtype) { - return !(Boolean) iblockdata.get(BlockTrapdoor.o) && fluidtype == FluidTypes.WATER; - } - - public boolean place(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid) { - if (!(Boolean) iblockdata.get(BlockTrapdoor.o) && fluid.c() == FluidTypes.WATER) { - if (!generatoraccess.e()) { - generatoraccess.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockTrapdoor.o, true), 3); - generatoraccess.getFluidTickList().a(blockposition, fluid.c(), fluid.c().a((IWorldReader) generatoraccess)); - } - - return true; - } else { - return false; - } + @Override + public Fluid g(IBlockData iblockdata) { + return (Boolean) iblockdata.get(BlockTrapdoor.d) ? FluidTypes.WATER.a(false) : super.g(iblockdata); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - if ((Boolean) iblockdata.get(BlockTrapdoor.o)) { + if ((Boolean) iblockdata.get(BlockTrapdoor.d)) { generatoraccess.getFluidTickList().a(blockposition, FluidTypes.WATER, FluidTypes.WATER.a((IWorldReader) generatoraccess)); } return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } + + @Override + public boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EntityTypes entitytypes) { + return false; + } } diff --git a/src/main/java/net/minecraft/server/BlockTripwire.java b/src/main/java/net/minecraft/server/BlockTripwire.java index bc5fca5a6..cc323a8f0 100644 --- a/src/main/java/net/minecraft/server/BlockTripwire.java +++ b/src/main/java/net/minecraft/server/BlockTripwire.java @@ -5,33 +5,34 @@ import java.util.List; import java.util.Map; import java.util.Random; -import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit public class BlockTripwire extends Block { - public static final BlockStateBoolean POWERED = BlockProperties.t; + public static final BlockStateBoolean POWERED = BlockProperties.w; public static final BlockStateBoolean ATTACHED = BlockProperties.a; - public static final BlockStateBoolean DISARMED = BlockProperties.c; + public static final BlockStateBoolean DISARMED = BlockProperties.d; public static final BlockStateBoolean NORTH = BlockSprawling.a; public static final BlockStateBoolean EAST = BlockSprawling.b; public static final BlockStateBoolean SOUTH = BlockSprawling.c; - public static final BlockStateBoolean WEST = BlockSprawling.o; - private static final Map u = BlockTall.q; - protected static final VoxelShape s = Block.a(0.0D, 1.0D, 0.0D, 16.0D, 2.5D, 16.0D); - protected static final VoxelShape t = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D); - private final BlockTripwireHook v; + public static final BlockStateBoolean WEST = BlockSprawling.d; + private static final Map j = BlockTall.f; + protected static final VoxelShape h = Block.a(0.0D, 1.0D, 0.0D, 16.0D, 2.5D, 16.0D); + protected static final VoxelShape i = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D); + private final BlockTripwireHook k; public BlockTripwire(BlockTripwireHook blocktripwirehook, Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTripwire.POWERED, false)).set(BlockTripwire.ATTACHED, false)).set(BlockTripwire.DISARMED, false)).set(BlockTripwire.NORTH, false)).set(BlockTripwire.EAST, false)).set(BlockTripwire.SOUTH, false)).set(BlockTripwire.WEST, false)); - this.v = blocktripwirehook; + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTripwire.POWERED, false)).set(BlockTripwire.ATTACHED, false)).set(BlockTripwire.DISARMED, false)).set(BlockTripwire.NORTH, false)).set(BlockTripwire.EAST, false)).set(BlockTripwire.SOUTH, false)).set(BlockTripwire.WEST, false)); + this.k = blocktripwirehook; } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return (Boolean) iblockdata.get(BlockTripwire.ATTACHED) ? BlockTripwire.s : BlockTripwire.t; + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return (Boolean) iblockdata.get(BlockTripwire.ATTACHED) ? BlockTripwire.h : BlockTripwire.i; } + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { World world = blockactioncontext.getWorld(); BlockPosition blockposition = blockactioncontext.getClickPosition(); @@ -39,30 +40,31 @@ public class BlockTripwire extends Block { return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.getBlockData().set(BlockTripwire.NORTH, this.a(world.getType(blockposition.north()), EnumDirection.NORTH))).set(BlockTripwire.EAST, this.a(world.getType(blockposition.east()), EnumDirection.EAST))).set(BlockTripwire.SOUTH, this.a(world.getType(blockposition.south()), EnumDirection.SOUTH))).set(BlockTripwire.WEST, this.a(world.getType(blockposition.west()), EnumDirection.WEST)); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - return enumdirection.k().c() ? (IBlockData) iblockdata.set((IBlockState) BlockTripwire.u.get(enumdirection), this.a(iblockdata1, enumdirection)) : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); - } - - public boolean a(IBlockData iblockdata) { - return false; + return enumdirection.k().c() ? (IBlockData) iblockdata.set((IBlockState) BlockTripwire.j.get(enumdirection), this.a(iblockdata1, enumdirection)) : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } + @Override public TextureType c() { return TextureType.TRANSLUCENT; } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (iblockdata1.getBlock() != iblockdata.getBlock()) { this.a(world, blockposition, iblockdata); } } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (!flag && iblockdata.getBlock() != iblockdata1.getBlock()) { this.a(world, blockposition, (IBlockData) iblockdata.set(BlockTripwire.POWERED, true)); } } + @Override public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { if (!world.isClientSide && !entityhuman.getItemInMainHand().isEmpty() && entityhuman.getItemInMainHand().getItem() == Items.SHEARS) { world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockTripwire.DISARMED, true), 4); @@ -72,7 +74,7 @@ public class BlockTripwire extends Block { } private void a(World world, BlockPosition blockposition, IBlockData iblockdata) { - EnumDirection[] aenumdirection = new EnumDirection[] { EnumDirection.SOUTH, EnumDirection.WEST}; + EnumDirection[] aenumdirection = new EnumDirection[]{EnumDirection.SOUTH, EnumDirection.WEST}; int i = aenumdirection.length; int j = 0; @@ -85,9 +87,9 @@ public class BlockTripwire extends Block { BlockPosition blockposition1 = blockposition.shift(enumdirection, k); IBlockData iblockdata1 = world.getType(blockposition1); - if (iblockdata1.getBlock() == this.v) { + if (iblockdata1.getBlock() == this.k) { if (iblockdata1.get(BlockTripwireHook.FACING) == enumdirection.opposite()) { - this.v.a(world, blockposition1, iblockdata1, false, true, k, iblockdata); + this.k.a(world, blockposition1, iblockdata1, false, true, k, iblockdata); } } else if (iblockdata1.getBlock() == this) { ++k; @@ -102,6 +104,7 @@ public class BlockTripwire extends Block { } + @Override public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { if (!world.isClientSide) { if (!(Boolean) iblockdata.get(BlockTripwire.POWERED)) { @@ -110,7 +113,8 @@ public class BlockTripwire extends Block { } } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!world.isClientSide) { if ((Boolean) world.getType(blockposition).get(BlockTripwire.POWERED)) { this.a(world, blockposition); @@ -141,7 +145,7 @@ public class BlockTripwire extends Block { if (flag != flag1 && flag1 && (Boolean)iblockdata.get(ATTACHED)) { org.bukkit.World bworld = world.getWorld(); org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); - org.bukkit.block.Block block = ((CraftWorld) bworld).getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); boolean allowed = false; // If all of the events are cancelled block the tripwire trigger, else allow @@ -186,38 +190,37 @@ public class BlockTripwire extends Block { public boolean a(IBlockData iblockdata, EnumDirection enumdirection) { Block block = iblockdata.getBlock(); - return block == this.v ? iblockdata.get(BlockTripwireHook.FACING) == enumdirection.opposite() : block == this; + return block == this.k ? iblockdata.get(BlockTripwireHook.FACING) == enumdirection.opposite() : block == this; } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { switch (enumblockrotation) { - case CLOCKWISE_180: - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.NORTH, iblockdata.get(BlockTripwire.SOUTH))).set(BlockTripwire.EAST, iblockdata.get(BlockTripwire.WEST))).set(BlockTripwire.SOUTH, iblockdata.get(BlockTripwire.NORTH))).set(BlockTripwire.WEST, iblockdata.get(BlockTripwire.EAST)); - case COUNTERCLOCKWISE_90: - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.NORTH, iblockdata.get(BlockTripwire.EAST))).set(BlockTripwire.EAST, iblockdata.get(BlockTripwire.SOUTH))).set(BlockTripwire.SOUTH, iblockdata.get(BlockTripwire.WEST))).set(BlockTripwire.WEST, iblockdata.get(BlockTripwire.NORTH)); - case CLOCKWISE_90: - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.NORTH, iblockdata.get(BlockTripwire.WEST))).set(BlockTripwire.EAST, iblockdata.get(BlockTripwire.NORTH))).set(BlockTripwire.SOUTH, iblockdata.get(BlockTripwire.EAST))).set(BlockTripwire.WEST, iblockdata.get(BlockTripwire.SOUTH)); - default: - return iblockdata; + case CLOCKWISE_180: + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.NORTH, iblockdata.get(BlockTripwire.SOUTH))).set(BlockTripwire.EAST, iblockdata.get(BlockTripwire.WEST))).set(BlockTripwire.SOUTH, iblockdata.get(BlockTripwire.NORTH))).set(BlockTripwire.WEST, iblockdata.get(BlockTripwire.EAST)); + case COUNTERCLOCKWISE_90: + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.NORTH, iblockdata.get(BlockTripwire.EAST))).set(BlockTripwire.EAST, iblockdata.get(BlockTripwire.SOUTH))).set(BlockTripwire.SOUTH, iblockdata.get(BlockTripwire.WEST))).set(BlockTripwire.WEST, iblockdata.get(BlockTripwire.NORTH)); + case CLOCKWISE_90: + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.NORTH, iblockdata.get(BlockTripwire.WEST))).set(BlockTripwire.EAST, iblockdata.get(BlockTripwire.NORTH))).set(BlockTripwire.SOUTH, iblockdata.get(BlockTripwire.EAST))).set(BlockTripwire.WEST, iblockdata.get(BlockTripwire.SOUTH)); + default: + return iblockdata; } } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { switch (enumblockmirror) { - case LEFT_RIGHT: - return (IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.NORTH, iblockdata.get(BlockTripwire.SOUTH))).set(BlockTripwire.SOUTH, iblockdata.get(BlockTripwire.NORTH)); - case FRONT_BACK: - return (IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.EAST, iblockdata.get(BlockTripwire.WEST))).set(BlockTripwire.WEST, iblockdata.get(BlockTripwire.EAST)); - default: - return super.a(iblockdata, enumblockmirror); + case LEFT_RIGHT: + return (IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.NORTH, iblockdata.get(BlockTripwire.SOUTH))).set(BlockTripwire.SOUTH, iblockdata.get(BlockTripwire.NORTH)); + case FRONT_BACK: + return (IBlockData) ((IBlockData) iblockdata.set(BlockTripwire.EAST, iblockdata.get(BlockTripwire.WEST))).set(BlockTripwire.WEST, iblockdata.get(BlockTripwire.EAST)); + default: + return super.a(iblockdata, enumblockmirror); } } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockTripwire.POWERED, BlockTripwire.ATTACHED, BlockTripwire.DISARMED, BlockTripwire.NORTH, BlockTripwire.EAST, BlockTripwire.WEST, BlockTripwire.SOUTH); } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockTripwireHook.java b/src/main/java/net/minecraft/server/BlockTripwireHook.java index 69bde3799..cc99708e8 100644 --- a/src/main/java/net/minecraft/server/BlockTripwireHook.java +++ b/src/main/java/net/minecraft/server/BlockTripwireHook.java @@ -9,50 +9,49 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit public class BlockTripwireHook extends Block { public static final BlockStateDirection FACING = BlockFacingHorizontal.FACING; - public static final BlockStateBoolean POWERED = BlockProperties.t; + public static final BlockStateBoolean POWERED = BlockProperties.w; public static final BlockStateBoolean ATTACHED = BlockProperties.a; - protected static final VoxelShape o = Block.a(5.0D, 0.0D, 10.0D, 11.0D, 10.0D, 16.0D); - protected static final VoxelShape p = Block.a(5.0D, 0.0D, 0.0D, 11.0D, 10.0D, 6.0D); - protected static final VoxelShape q = Block.a(10.0D, 0.0D, 5.0D, 16.0D, 10.0D, 11.0D); - protected static final VoxelShape r = Block.a(0.0D, 0.0D, 5.0D, 6.0D, 10.0D, 11.0D); + protected static final VoxelShape d = Block.a(5.0D, 0.0D, 10.0D, 11.0D, 10.0D, 16.0D); + protected static final VoxelShape e = Block.a(5.0D, 0.0D, 0.0D, 11.0D, 10.0D, 6.0D); + protected static final VoxelShape f = Block.a(10.0D, 0.0D, 5.0D, 16.0D, 10.0D, 11.0D); + protected static final VoxelShape g = Block.a(0.0D, 0.0D, 5.0D, 6.0D, 10.0D, 11.0D); public BlockTripwireHook(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTripwireHook.FACING, EnumDirection.NORTH)).set(BlockTripwireHook.POWERED, false)).set(BlockTripwireHook.ATTACHED, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTripwireHook.FACING, EnumDirection.NORTH)).set(BlockTripwireHook.POWERED, false)).set(BlockTripwireHook.ATTACHED, false)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { switch ((EnumDirection) iblockdata.get(BlockTripwireHook.FACING)) { - case EAST: - default: - return BlockTripwireHook.r; - case WEST: - return BlockTripwireHook.q; - case SOUTH: - return BlockTripwireHook.p; - case NORTH: - return BlockTripwireHook.o; + case EAST: + default: + return BlockTripwireHook.g; + case WEST: + return BlockTripwireHook.f; + case SOUTH: + return BlockTripwireHook.e; + case NORTH: + return BlockTripwireHook.d; } } - public boolean a(IBlockData iblockdata) { - return false; - } - + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockTripwireHook.FACING); BlockPosition blockposition1 = blockposition.shift(enumdirection.opposite()); IBlockData iblockdata1 = iworldreader.getType(blockposition1); - boolean flag = b(iblockdata1.getBlock()); - return !flag && enumdirection.k().c() && iblockdata1.c(iworldreader, blockposition1, enumdirection) == EnumBlockFaceShape.SOLID && !iblockdata1.isPowerSource(); + return enumdirection.k().c() && iblockdata1.d(iworldreader, blockposition1, enumdirection) && !iblockdata1.isPowerSource(); } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { return enumdirection.opposite() == iblockdata.get(BlockTripwireHook.FACING) && !iblockdata.canPlace(generatoraccess, blockposition) ? Blocks.AIR.getBlockData() : super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { IBlockData iblockdata = (IBlockData) ((IBlockData) this.getBlockData().set(BlockTripwireHook.POWERED, false)).set(BlockTripwireHook.ATTACHED, false); World world = blockactioncontext.getWorld(); @@ -77,6 +76,7 @@ public class BlockTripwireHook extends Block { return null; } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { this.a(world, blockposition, iblockdata, false, false, -1, (IBlockData) null); } @@ -137,7 +137,7 @@ public class BlockTripwireHook extends Block { } // CraftBukkit start - org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); world.getServer().getPluginManager().callEvent(eventRedstone); @@ -171,19 +171,20 @@ public class BlockTripwireHook extends Block { } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { this.a(world, blockposition, iblockdata, false, true, -1, (IBlockData) null); } private void a(World world, BlockPosition blockposition, boolean flag, boolean flag1, boolean flag2, boolean flag3) { if (flag1 && !flag3) { - world.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_TRIPWIRE_CLICK_ON, SoundCategory.BLOCKS, 0.4F, 0.6F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_TRIPWIRE_CLICK_ON, SoundCategory.BLOCKS, 0.4F, 0.6F); } else if (!flag1 && flag3) { - world.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_TRIPWIRE_CLICK_OFF, SoundCategory.BLOCKS, 0.4F, 0.5F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_TRIPWIRE_CLICK_OFF, SoundCategory.BLOCKS, 0.4F, 0.5F); } else if (flag && !flag2) { - world.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_TRIPWIRE_ATTACH, SoundCategory.BLOCKS, 0.4F, 0.7F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_TRIPWIRE_ATTACH, SoundCategory.BLOCKS, 0.4F, 0.7F); } else if (!flag && flag2) { - world.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_TRIPWIRE_DETACH, SoundCategory.BLOCKS, 0.4F, 1.2F / (world.random.nextFloat() * 0.2F + 0.9F)); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_TRIPWIRE_DETACH, SoundCategory.BLOCKS, 0.4F, 1.2F / (world.random.nextFloat() * 0.2F + 0.9F)); } } @@ -193,6 +194,7 @@ public class BlockTripwireHook extends Block { world.applyPhysics(blockposition.shift(enumdirection.opposite()), this); } + @Override public void remove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (!flag && iblockdata.getBlock() != iblockdata1.getBlock()) { boolean flag1 = (Boolean) iblockdata.get(BlockTripwireHook.ATTACHED); @@ -211,35 +213,38 @@ public class BlockTripwireHook extends Block { } } + @Override public int a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return (Boolean) iblockdata.get(BlockTripwireHook.POWERED) ? 15 : 0; } + @Override public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { return !(Boolean) iblockdata.get(BlockTripwireHook.POWERED) ? 0 : (iblockdata.get(BlockTripwireHook.FACING) == enumdirection ? 15 : 0); } + @Override public boolean isPowerSource(IBlockData iblockdata) { return true; } + @Override public TextureType c() { return TextureType.CUTOUT_MIPPED; } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { return (IBlockData) iblockdata.set(BlockTripwireHook.FACING, enumblockrotation.a((EnumDirection) iblockdata.get(BlockTripwireHook.FACING))); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { return iblockdata.a(enumblockmirror.a((EnumDirection) iblockdata.get(BlockTripwireHook.FACING))); } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockTripwireHook.FACING, BlockTripwireHook.POWERED, BlockTripwireHook.ATTACHED); } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; - } } diff --git a/src/main/java/net/minecraft/server/BlockTurtleEgg.java b/src/main/java/net/minecraft/server/BlockTurtleEgg.java index 1c1bf85a0..0118a8451 100644 --- a/src/main/java/net/minecraft/server/BlockTurtleEgg.java +++ b/src/main/java/net/minecraft/server/BlockTurtleEgg.java @@ -12,20 +12,22 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; public class BlockTurtleEgg extends Block { private static final VoxelShape c = Block.a(3.0D, 0.0D, 3.0D, 12.0D, 7.0D, 12.0D); - private static final VoxelShape o = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 7.0D, 15.0D); - public static final BlockStateInteger a = BlockProperties.ad; - public static final BlockStateInteger b = BlockProperties.ac; + private static final VoxelShape d = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 7.0D, 15.0D); + public static final BlockStateInteger a = BlockProperties.aj; + public static final BlockStateInteger b = BlockProperties.ai; public BlockTurtleEgg(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTurtleEgg.a, 0)).set(BlockTurtleEgg.b, 1)); + this.o((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockTurtleEgg.a, 0)).set(BlockTurtleEgg.b, 1)); } + @Override public void stepOn(World world, BlockPosition blockposition, Entity entity) { this.a(world, blockposition, entity, 100); super.stepOn(world, blockposition, entity); } + @Override public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) { if (!(entity instanceof EntityZombie)) { this.a(world, blockposition, entity, 3); @@ -59,11 +61,11 @@ public class BlockTurtleEgg extends Block { } private void a(World world, BlockPosition blockposition, IBlockData iblockdata) { - world.a((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_EGG_BREAK, SoundCategory.BLOCKS, 0.7F, 0.9F + world.random.nextFloat() * 0.2F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_EGG_BREAK, SoundCategory.BLOCKS, 0.7F, 0.9F + world.random.nextFloat() * 0.2F); int i = (Integer) iblockdata.get(BlockTurtleEgg.b); if (i <= 1) { - world.setAir(blockposition, false); + world.b(blockposition, false); } else { world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockTurtleEgg.b, i - 1), 2); world.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); @@ -71,7 +73,8 @@ public class BlockTurtleEgg extends Block { } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (this.a(world) && this.a((IBlockAccess) world, blockposition)) { int i = (Integer) iblockdata.get(BlockTurtleEgg.a); @@ -81,7 +84,7 @@ public class BlockTurtleEgg extends Block { return; } // CraftBukkit end - world.a((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_EGG_CRACK, SoundCategory.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_EGG_CRACK, SoundCategory.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); // world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockTurtleEgg.a, i + 1), 2); // CraftBukkit - handled above } else { // CraftBukkit start - Call BlockFadeEvent @@ -89,12 +92,12 @@ public class BlockTurtleEgg extends Block { return; } // CraftBukkit end - world.a((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_EGG_HATCH, SoundCategory.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); - world.setAir(blockposition); + world.playSound((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_EGG_HATCH, SoundCategory.BLOCKS, 0.7F, 0.9F + random.nextFloat() * 0.2F); + world.a(blockposition, false); if (!world.isClientSide) { for (int j = 0; j < (Integer) iblockdata.get(BlockTurtleEgg.b); ++j) { world.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); - EntityTurtle entityturtle = EntityTypes.TURTLE.create(world); // Paper + EntityTurtle entityturtle = (EntityTurtle) EntityTypes.TURTLE.a(world); entityturtle.setAgeRaw(-24000); entityturtle.g(blockposition); @@ -111,7 +114,8 @@ public class BlockTurtleEgg extends Block { return iblockaccess.getType(blockposition.down()).getBlock() == Blocks.SAND; } - public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1) { + @Override + public void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) { if (this.a((IBlockAccess) world, blockposition) && !world.isClientSide) { world.triggerEffect(2005, blockposition, 0); } @@ -119,56 +123,46 @@ public class BlockTurtleEgg extends Block { } private boolean a(World world) { - float f = world.k(1.0F); + float f = world.j(1.0F); return (double) f < 0.69D && (double) f > 0.65D ? true : world.random.nextInt(500) == 0; } - protected boolean X_() { - return true; - } - + @Override public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { super.a(world, entityhuman, blockposition, iblockdata, tileentity, itemstack); this.a(world, blockposition, iblockdata); } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.AIR; - } - + @Override public boolean a(IBlockData iblockdata, BlockActionContext blockactioncontext) { return blockactioncontext.getItemStack().getItem() == this.getItem() && (Integer) iblockdata.get(BlockTurtleEgg.b) < 4 ? true : super.a(iblockdata, blockactioncontext); } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { IBlockData iblockdata = blockactioncontext.getWorld().getType(blockactioncontext.getClickPosition()); return iblockdata.getBlock() == this ? (IBlockData) iblockdata.set(BlockTurtleEgg.b, Math.min(4, (Integer) iblockdata.get(BlockTurtleEgg.b) + 1)) : super.getPlacedState(blockactioncontext); } + @Override public TextureType c() { return TextureType.CUTOUT; } - public boolean a(IBlockData iblockdata) { - return false; - } - - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { - return (Integer) iblockdata.get(BlockTurtleEgg.b) > 1 ? BlockTurtleEgg.o : BlockTurtleEgg.c; - } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return (Integer) iblockdata.get(BlockTurtleEgg.b) > 1 ? BlockTurtleEgg.d : BlockTurtleEgg.c; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockTurtleEgg.a, BlockTurtleEgg.b); } private boolean a(World world, Entity entity) { - return entity instanceof EntityTurtle ? false : (entity instanceof EntityLiving && !(entity instanceof EntityHuman) ? world.getGameRules().getBoolean("mobGriefing") : true); + return entity instanceof EntityTurtle ? false : (entity instanceof EntityLiving && !(entity instanceof EntityHuman) ? world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) : true); } } diff --git a/src/main/java/net/minecraft/server/BlockVine.java b/src/main/java/net/minecraft/server/BlockVine.java index 7006619b2..455dae92a 100644 --- a/src/main/java/net/minecraft/server/BlockVine.java +++ b/src/main/java/net/minecraft/server/BlockVine.java @@ -10,66 +10,64 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class BlockVine extends Block { - public static final BlockStateBoolean UP = BlockSprawling.p; + public static final BlockStateBoolean UP = BlockSprawling.e; public static final BlockStateBoolean NORTH = BlockSprawling.a; public static final BlockStateBoolean EAST = BlockSprawling.b; public static final BlockStateBoolean SOUTH = BlockSprawling.c; - public static final BlockStateBoolean WEST = BlockSprawling.o; - public static final Map q = (Map) BlockSprawling.r.entrySet().stream().filter((entry) -> { + public static final BlockStateBoolean WEST = BlockSprawling.d; + public static final Map f = (Map) BlockSprawling.g.entrySet().stream().filter((entry) -> { return entry.getKey() != EnumDirection.DOWN; }).collect(SystemUtils.a()); - protected static final VoxelShape r = Block.a(0.0D, 15.0D, 0.0D, 16.0D, 16.0D, 16.0D); - protected static final VoxelShape s = Block.a(0.0D, 0.0D, 0.0D, 1.0D, 16.0D, 16.0D); - protected static final VoxelShape t = Block.a(15.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); - protected static final VoxelShape u = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 1.0D); - protected static final VoxelShape v = Block.a(0.0D, 0.0D, 15.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape g = Block.a(0.0D, 15.0D, 0.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape h = Block.a(0.0D, 0.0D, 0.0D, 1.0D, 16.0D, 16.0D); + protected static final VoxelShape i = Block.a(15.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); + protected static final VoxelShape j = Block.a(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 1.0D); + protected static final VoxelShape k = Block.a(0.0D, 0.0D, 15.0D, 16.0D, 16.0D, 16.0D); public BlockVine(Block.Info block_info) { super(block_info); - this.v((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockVine.UP, false)).set(BlockVine.NORTH, false)).set(BlockVine.EAST, false)).set(BlockVine.SOUTH, false)).set(BlockVine.WEST, false)); + this.o((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) this.blockStateList.getBlockData()).set(BlockVine.UP, false)).set(BlockVine.NORTH, false)).set(BlockVine.EAST, false)).set(BlockVine.SOUTH, false)).set(BlockVine.WEST, false)); } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { VoxelShape voxelshape = VoxelShapes.a(); if ((Boolean) iblockdata.get(BlockVine.UP)) { - voxelshape = VoxelShapes.a(voxelshape, BlockVine.r); + voxelshape = VoxelShapes.a(voxelshape, BlockVine.g); } if ((Boolean) iblockdata.get(BlockVine.NORTH)) { - voxelshape = VoxelShapes.a(voxelshape, BlockVine.u); + voxelshape = VoxelShapes.a(voxelshape, BlockVine.j); } if ((Boolean) iblockdata.get(BlockVine.EAST)) { - voxelshape = VoxelShapes.a(voxelshape, BlockVine.t); + voxelshape = VoxelShapes.a(voxelshape, BlockVine.i); } if ((Boolean) iblockdata.get(BlockVine.SOUTH)) { - voxelshape = VoxelShapes.a(voxelshape, BlockVine.v); + voxelshape = VoxelShapes.a(voxelshape, BlockVine.k); } if ((Boolean) iblockdata.get(BlockVine.WEST)) { - voxelshape = VoxelShapes.a(voxelshape, BlockVine.s); + voxelshape = VoxelShapes.a(voxelshape, BlockVine.h); } return voxelshape; } - public boolean a(IBlockData iblockdata) { - return false; - } - + @Override public boolean canPlace(IBlockData iblockdata, IWorldReader iworldreader, BlockPosition blockposition) { - return this.k(this.m(iblockdata, iworldreader, blockposition)); + return this.j(this.m(iblockdata, iworldreader, blockposition)); } - private boolean k(IBlockData iblockdata) { - return this.w(iblockdata) > 0; + private boolean j(IBlockData iblockdata) { + return this.q(iblockdata) > 0; } - private int w(IBlockData iblockdata) { + private int q(IBlockData iblockdata) { int i = 0; - Iterator iterator = BlockVine.q.values().iterator(); + Iterator iterator = BlockVine.f.values().iterator(); while (iterator.hasNext()) { BlockStateBoolean blockstateboolean = (BlockStateBoolean) iterator.next(); @@ -82,18 +80,18 @@ public class BlockVine extends Block { return i; } - private boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + private boolean b(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { if (enumdirection == EnumDirection.DOWN) { return false; } else { BlockPosition blockposition1 = blockposition.shift(enumdirection); - if (this.b(iblockaccess, blockposition1, enumdirection)) { + if (a(iblockaccess, blockposition1, enumdirection)) { return true; } else if (enumdirection.k() == EnumDirection.EnumAxis.Y) { return false; } else { - BlockStateBoolean blockstateboolean = (BlockStateBoolean) BlockVine.q.get(enumdirection); + BlockStateBoolean blockstateboolean = (BlockStateBoolean) BlockVine.f.get(enumdirection); IBlockData iblockdata = iblockaccess.getType(blockposition.up()); return iblockdata.getBlock() == this && (Boolean) iblockdata.get(blockstateboolean); @@ -101,21 +99,17 @@ public class BlockVine extends Block { } } - private boolean b(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + public static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { IBlockData iblockdata = iblockaccess.getType(blockposition); - return iblockdata.c(iblockaccess, blockposition, enumdirection.opposite()) == EnumBlockFaceShape.SOLID && !f(iblockdata.getBlock()); - } - - protected static boolean f(Block block) { - return block instanceof BlockShulkerBox || block instanceof BlockStainedGlass || block == Blocks.BEACON || block == Blocks.CAULDRON || block == Blocks.GLASS || block == Blocks.PISTON || block == Blocks.STICKY_PISTON || block == Blocks.PISTON_HEAD || block.a(TagsBlock.WOODEN_TRAPDOORS); + return Block.a(iblockdata.getCollisionShape(iblockaccess, blockposition), enumdirection.opposite()); } private IBlockData m(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { BlockPosition blockposition1 = blockposition.up(); if ((Boolean) iblockdata.get(BlockVine.UP)) { - iblockdata = (IBlockData) iblockdata.set(BlockVine.UP, this.b(iblockaccess, blockposition1, EnumDirection.DOWN)); + iblockdata = (IBlockData) iblockdata.set(BlockVine.UP, a(iblockaccess, blockposition1, EnumDirection.DOWN)); } IBlockData iblockdata1 = null; @@ -126,7 +120,7 @@ public class BlockVine extends Block { BlockStateBoolean blockstateboolean = getDirection(enumdirection); if ((Boolean) iblockdata.get(blockstateboolean)) { - boolean flag = this.a(iblockaccess, blockposition, enumdirection); + boolean flag = this.b(iblockaccess, blockposition, enumdirection); if (!flag) { if (iblockdata1 == null) { @@ -143,26 +137,28 @@ public class BlockVine extends Block { return iblockdata; } + @Override public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { if (enumdirection == EnumDirection.DOWN) { return super.updateState(iblockdata, enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); } else { IBlockData iblockdata2 = this.m(iblockdata, generatoraccess, blockposition); - return !this.k(iblockdata2) ? Blocks.AIR.getBlockData() : iblockdata2; + return !this.j(iblockdata2) ? Blocks.AIR.getBlockData() : iblockdata2; } } - public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { + @Override + public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (!world.isClientSide) { IBlockData iblockdata1 = this.m(iblockdata, world, blockposition); if (iblockdata1 != iblockdata) { - if (this.k(iblockdata1)) { + if (this.j(iblockdata1)) { world.setTypeAndData(blockposition, iblockdata1, 2); } else { - iblockdata.a(world, blockposition, 0); - world.setAir(blockposition); + c(iblockdata, world, blockposition); + world.a(blockposition, false); } } else if (world.random.nextInt(Math.max(1, (int) (100.0F / world.spigotConfig.vineModifier) * 4)) == 0) { // Spigot @@ -187,30 +183,30 @@ public class BlockVine extends Block { // CraftBukkit start - Call BlockSpreadEvent BlockPosition source = blockposition; - if (flag && this.b((IBlockAccess) world, blockposition3, enumdirection1)) { + if (flag && a((IBlockAccess) world, blockposition3, enumdirection1)) { CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition2, (IBlockData) this.getBlockData().set(getDirection(enumdirection1), true), 2); - } else if (flag1 && this.b((IBlockAccess) world, blockposition4, enumdirection2)) { + } else if (flag1 && a((IBlockAccess) world, blockposition4, enumdirection2)) { CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition2, (IBlockData) this.getBlockData().set(getDirection(enumdirection2), true), 2); } else { EnumDirection enumdirection3 = enumdirection.opposite(); - if (flag && world.isEmpty(blockposition3) && this.b((IBlockAccess) world, blockposition.shift(enumdirection1), enumdirection3)) { + if (flag && world.isEmpty(blockposition3) && a((IBlockAccess) world, blockposition.shift(enumdirection1), enumdirection3)) { CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition3, (IBlockData) this.getBlockData().set(getDirection(enumdirection3), true), 2); - } else if (flag1 && world.isEmpty(blockposition4) && this.b((IBlockAccess) world, blockposition.shift(enumdirection2), enumdirection3)) { + } else if (flag1 && world.isEmpty(blockposition4) && a((IBlockAccess) world, blockposition.shift(enumdirection2), enumdirection3)) { CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition4, (IBlockData) this.getBlockData().set(getDirection(enumdirection3), true), 2); - } else if ((double) world.random.nextFloat() < 0.05D && this.b((IBlockAccess) world, blockposition2.up(), EnumDirection.UP)) { + } else if ((double) world.random.nextFloat() < 0.05D && a((IBlockAccess) world, blockposition2.up(), EnumDirection.UP)) { CraftEventFactory.handleBlockSpreadEvent(world, source, blockposition2, (IBlockData) this.getBlockData().set(BlockVine.UP, true), 2); } // CraftBukkit end } - } else if (this.b((IBlockAccess) world, blockposition2, enumdirection)) { + } else if (a((IBlockAccess) world, blockposition2, enumdirection)) { world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(getDirection(enumdirection), true), 2); } } } else { if (enumdirection == EnumDirection.UP && blockposition.getY() < 255) { - if (this.a((IBlockAccess) world, blockposition, enumdirection)) { + if (this.b((IBlockAccess) world, blockposition, enumdirection)) { world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockVine.UP, true), 2); return; } @@ -225,12 +221,12 @@ public class BlockVine extends Block { while (iterator.hasNext()) { enumdirection1 = (EnumDirection) iterator.next(); - if (random.nextBoolean() || !this.b((IBlockAccess) world, blockposition1.shift(enumdirection1), EnumDirection.UP)) { + if (random.nextBoolean() || !a((IBlockAccess) world, blockposition1.shift(enumdirection1), EnumDirection.UP)) { iblockdata3 = (IBlockData) iblockdata3.set(getDirection(enumdirection1), false); } } - if (this.x(iblockdata3)) { + if (this.canSpread(iblockdata3)) { CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition1, iblockdata3, 2); // CraftBukkit } @@ -245,7 +241,7 @@ public class BlockVine extends Block { IBlockData iblockdata4 = iblockdata2.isAir() ? this.getBlockData() : iblockdata2; IBlockData iblockdata5 = this.a(iblockdata, iblockdata4, random); - if (iblockdata4 != iblockdata5 && this.x(iblockdata5)) { + if (iblockdata4 != iblockdata5 && this.canSpread(iblockdata5)) { CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition2, iblockdata5, 2); // CraftBukkit } } @@ -274,13 +270,13 @@ public class BlockVine extends Block { return iblockdata1; } - private boolean x(IBlockData iblockdata) { + private boolean canSpread(IBlockData iblockdata) { return (Boolean) iblockdata.get(BlockVine.NORTH) || (Boolean) iblockdata.get(BlockVine.EAST) || (Boolean) iblockdata.get(BlockVine.SOUTH) || (Boolean) iblockdata.get(BlockVine.WEST); } private boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) { boolean flag = true; - Iterable iterable = BlockPosition.MutableBlockPosition.b(blockposition.getX() - 4, blockposition.getY() - 1, blockposition.getZ() - 4, blockposition.getX() + 4, blockposition.getY() + 1, blockposition.getZ() + 4); + Iterable iterable = BlockPosition.b(blockposition.getX() - 4, blockposition.getY() - 1, blockposition.getZ() - 4, blockposition.getX() + 4, blockposition.getY() + 1, blockposition.getZ() + 4); int i = 5; Iterator iterator = iterable.iterator(); @@ -298,13 +294,15 @@ public class BlockVine extends Block { return true; } + @Override public boolean a(IBlockData iblockdata, BlockActionContext blockactioncontext) { IBlockData iblockdata1 = blockactioncontext.getWorld().getType(blockactioncontext.getClickPosition()); - return iblockdata1.getBlock() == this ? this.w(iblockdata1) < BlockVine.q.size() : super.a(iblockdata, blockactioncontext); + return iblockdata1.getBlock() == this ? this.q(iblockdata1) < BlockVine.f.size() : super.a(iblockdata, blockactioncontext); } @Nullable + @Override public IBlockData getPlacedState(BlockActionContext blockactioncontext) { IBlockData iblockdata = blockactioncontext.getWorld().getType(blockactioncontext.getClickPosition()); boolean flag = iblockdata.getBlock() == this; @@ -319,7 +317,7 @@ public class BlockVine extends Block { BlockStateBoolean blockstateboolean = getDirection(enumdirection); boolean flag1 = flag && (Boolean) iblockdata.get(blockstateboolean); - if (!flag1 && this.a((IBlockAccess) blockactioncontext.getWorld(), blockactioncontext.getClickPosition(), enumdirection)) { + if (!flag1 && this.b((IBlockAccess) blockactioncontext.getWorld(), blockactioncontext.getClickPosition(), enumdirection)) { return (IBlockData) iblockdata1.set(blockstateboolean, true); } } @@ -328,58 +326,43 @@ public class BlockVine extends Block { return flag ? iblockdata1 : null; } - public IMaterial getDropType(IBlockData iblockdata, World world, BlockPosition blockposition, int i) { - return Items.AIR; - } - - public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) { - if (!world.isClientSide && itemstack.getItem() == Items.SHEARS) { - entityhuman.b(StatisticList.BLOCK_MINED.b(this)); - entityhuman.applyExhaustion(0.005F); - a(world, blockposition, new ItemStack(Blocks.VINE)); - } else { - super.a(world, entityhuman, blockposition, iblockdata, tileentity, itemstack); - } - - } - + @Override public TextureType c() { return TextureType.CUTOUT; } + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(BlockVine.UP, BlockVine.NORTH, BlockVine.EAST, BlockVine.SOUTH, BlockVine.WEST); } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) { switch (enumblockrotation) { - case CLOCKWISE_180: - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockVine.NORTH, iblockdata.get(BlockVine.SOUTH))).set(BlockVine.EAST, iblockdata.get(BlockVine.WEST))).set(BlockVine.SOUTH, iblockdata.get(BlockVine.NORTH))).set(BlockVine.WEST, iblockdata.get(BlockVine.EAST)); - case COUNTERCLOCKWISE_90: - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockVine.NORTH, iblockdata.get(BlockVine.EAST))).set(BlockVine.EAST, iblockdata.get(BlockVine.SOUTH))).set(BlockVine.SOUTH, iblockdata.get(BlockVine.WEST))).set(BlockVine.WEST, iblockdata.get(BlockVine.NORTH)); - case CLOCKWISE_90: - return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockVine.NORTH, iblockdata.get(BlockVine.WEST))).set(BlockVine.EAST, iblockdata.get(BlockVine.NORTH))).set(BlockVine.SOUTH, iblockdata.get(BlockVine.EAST))).set(BlockVine.WEST, iblockdata.get(BlockVine.SOUTH)); - default: - return iblockdata; + case CLOCKWISE_180: + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockVine.NORTH, iblockdata.get(BlockVine.SOUTH))).set(BlockVine.EAST, iblockdata.get(BlockVine.WEST))).set(BlockVine.SOUTH, iblockdata.get(BlockVine.NORTH))).set(BlockVine.WEST, iblockdata.get(BlockVine.EAST)); + case COUNTERCLOCKWISE_90: + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockVine.NORTH, iblockdata.get(BlockVine.EAST))).set(BlockVine.EAST, iblockdata.get(BlockVine.SOUTH))).set(BlockVine.SOUTH, iblockdata.get(BlockVine.WEST))).set(BlockVine.WEST, iblockdata.get(BlockVine.NORTH)); + case CLOCKWISE_90: + return (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata.set(BlockVine.NORTH, iblockdata.get(BlockVine.WEST))).set(BlockVine.EAST, iblockdata.get(BlockVine.NORTH))).set(BlockVine.SOUTH, iblockdata.get(BlockVine.EAST))).set(BlockVine.WEST, iblockdata.get(BlockVine.SOUTH)); + default: + return iblockdata; } } + @Override public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) { switch (enumblockmirror) { - case LEFT_RIGHT: - return (IBlockData) ((IBlockData) iblockdata.set(BlockVine.NORTH, iblockdata.get(BlockVine.SOUTH))).set(BlockVine.SOUTH, iblockdata.get(BlockVine.NORTH)); - case FRONT_BACK: - return (IBlockData) ((IBlockData) iblockdata.set(BlockVine.EAST, iblockdata.get(BlockVine.WEST))).set(BlockVine.WEST, iblockdata.get(BlockVine.EAST)); - default: - return super.a(iblockdata, enumblockmirror); + case LEFT_RIGHT: + return (IBlockData) ((IBlockData) iblockdata.set(BlockVine.NORTH, iblockdata.get(BlockVine.SOUTH))).set(BlockVine.SOUTH, iblockdata.get(BlockVine.NORTH)); + case FRONT_BACK: + return (IBlockData) ((IBlockData) iblockdata.set(BlockVine.EAST, iblockdata.get(BlockVine.WEST))).set(BlockVine.WEST, iblockdata.get(BlockVine.EAST)); + default: + return super.a(iblockdata, enumblockmirror); } } public static BlockStateBoolean getDirection(EnumDirection enumdirection) { - return (BlockStateBoolean) BlockVine.q.get(enumdirection); - } - - public EnumBlockFaceShape a(IBlockAccess iblockaccess, IBlockData iblockdata, BlockPosition blockposition, EnumDirection enumdirection) { - return EnumBlockFaceShape.UNDEFINED; + return (BlockStateBoolean) BlockVine.f.get(enumdirection); } } diff --git a/src/main/java/net/minecraft/server/BlockWaterLily.java b/src/main/java/net/minecraft/server/BlockWaterLily.java index 8ec343f57..7dc4fd0e2 100644 --- a/src/main/java/net/minecraft/server/BlockWaterLily.java +++ b/src/main/java/net/minecraft/server/BlockWaterLily.java @@ -8,21 +8,24 @@ public class BlockWaterLily extends BlockPlant { super(block_info); } + @Override public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Entity entity) { super.a(iblockdata, world, blockposition, entity); if (entity instanceof EntityBoat && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { // CraftBukkit - world.setAir(new BlockPosition(blockposition), true); + world.b(new BlockPosition(blockposition), true); } } - public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return BlockWaterLily.a; } - protected boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + @Override + protected boolean a_(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { Fluid fluid = iblockaccess.getFluid(blockposition); - return fluid.c() == FluidTypes.WATER || iblockdata.getMaterial() == Material.ICE; + return fluid.getType() == FluidTypes.WATER || iblockdata.getMaterial() == Material.ICE; } } diff --git a/src/main/java/net/minecraft/server/BlockWitherSkull.java b/src/main/java/net/minecraft/server/BlockWitherSkull.java index eab8106e2..e38afada4 100644 --- a/src/main/java/net/minecraft/server/BlockWitherSkull.java +++ b/src/main/java/net/minecraft/server/BlockWitherSkull.java @@ -10,13 +10,16 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; public class BlockWitherSkull extends BlockSkull { + @Nullable private static ShapeDetector c; - private static ShapeDetector o; + @Nullable + private static ShapeDetector d; protected BlockWitherSkull(Block.Info block_info) { super(BlockSkull.Type.WITHER_SKELETON, block_info); } + @Override public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, @Nullable EntityLiving entityliving, ItemStack itemstack) { super.postPlace(world, blockposition, iblockdata, entityliving, itemstack); TileEntity tileentity = world.getTileEntity(blockposition); @@ -29,71 +32,58 @@ public class BlockWitherSkull extends BlockSkull { public static void a(World world, BlockPosition blockposition, TileEntitySkull tileentityskull) { if (world.captureBlockStates) return; // CraftBukkit - Block block = tileentityskull.getBlock().getBlock(); - boolean flag = block == Blocks.WITHER_SKELETON_SKULL || block == Blocks.WITHER_SKELETON_WALL_SKULL; + if (!world.isClientSide) { + Block block = tileentityskull.getBlock().getBlock(); + boolean flag = block == Blocks.WITHER_SKELETON_SKULL || block == Blocks.WITHER_SKELETON_WALL_SKULL; - if (flag && blockposition.getY() >= 2 && world.getDifficulty() != EnumDifficulty.PEACEFUL && !world.isClientSide) { - ShapeDetector shapedetector = d(); - ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = shapedetector.a(world, blockposition); + if (flag && blockposition.getY() >= 2 && world.getDifficulty() != EnumDifficulty.PEACEFUL) { + ShapeDetector shapedetector = d(); + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = shapedetector.a(world, blockposition); - if (shapedetector_shapedetectorcollection != null) { - // CraftBukkit start - Use BlockStateListPopulator - BlockStateListPopulator blockList = new BlockStateListPopulator(world); - int i; + if (shapedetector_shapedetectorcollection != null) { + // CraftBukkit start - Use BlockStateListPopulator + BlockStateListPopulator blockList = new BlockStateListPopulator(world); + for (int i = 0; i < shapedetector.c(); ++i) { + for (int j = 0; j < shapedetector.b(); ++j) { + ShapeDetectorBlock shapedetectorblock = shapedetector_shapedetectorcollection.a(i, j, 0); - for (i = 0; i < 3; ++i) { - TileEntitySkull.a(world, shapedetector_shapedetectorcollection.a(i, 0, 0).getPosition()); - } - - for (i = 0; i < shapedetector.c(); ++i) { - for (int j = 0; j < shapedetector.b(); ++j) { - blockList.setTypeAndData(shapedetector_shapedetectorcollection.a(i, j, 0).getPosition(), Blocks.AIR.getBlockData(), 2); // CraftBukkit + blockList.setTypeAndData(shapedetectorblock.getPosition(), Blocks.AIR.getBlockData(), 2); // CraftBukkit + // world.triggerEffect(2001, shapedetectorblock.getPosition(), Block.getCombinedId(shapedetectorblock.a())); // CraftBukkit + } } - } - BlockPosition blockposition1 = shapedetector_shapedetectorcollection.a(1, 0, 0).getPosition(); - EntityWither entitywither = EntityTypes.WITHER.create(world); // Paper - BlockPosition blockposition2 = shapedetector_shapedetectorcollection.a(1, 2, 0).getPosition(); + EntityWither entitywither = (EntityWither) EntityTypes.WITHER.a(world); + BlockPosition blockposition1 = shapedetector_shapedetectorcollection.a(1, 2, 0).getPosition(); - entitywither.setPositionRotation((double) blockposition2.getX() + 0.5D, (double) blockposition2.getY() + 0.55D, (double) blockposition2.getZ() + 0.5D, shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? 0.0F : 90.0F, 0.0F); - entitywither.aQ = shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? 0.0F : 90.0F; - entitywither.l(); - // CraftBukkit start - if (!world.addEntity(entitywither, SpawnReason.BUILD_WITHER)) { - // Restore drop status from above - for (i = 0; i < 3; ++i) { - TileEntitySkull.setShouldDrop(world, shapedetector_shapedetectorcollection.a(i, 0, 0).getPosition(), true); + entitywither.setPositionRotation((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.55D, (double) blockposition1.getZ() + 0.5D, shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? 0.0F : 90.0F, 0.0F); + entitywither.aK = shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? 0.0F : 90.0F; + entitywither.l(); + // CraftBukkit start + if (!world.addEntity(entitywither, SpawnReason.BUILD_WITHER)) { + return; } - return; - } - blockList.updateList(); - // CraftBukkit end - Iterator iterator = world.a(EntityPlayer.class, entitywither.getBoundingBox().g(50.0D)).iterator(); - - while (iterator.hasNext()) { - EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - - CriterionTriggers.n.a(entityplayer, (Entity) entitywither); - } - - // world.addEntity(entitywither); // CraftBukkit - moved up - - int k; - - // Akarin start - this handle by client - /* - for (k = 0; k < 120; ++k) { - world.addParticle(Particles.E, (double) blockposition1.getX() + world.random.nextDouble(), (double) (blockposition1.getY() - 2) + world.random.nextDouble() * 3.9D, (double) blockposition1.getZ() + world.random.nextDouble(), 0.0D, 0.0D, 0.0D); - } - */ - // Akarin end - - for (k = 0; k < shapedetector.c(); ++k) { - for (int l = 0; l < shapedetector.b(); ++l) { - world.update(shapedetector_shapedetectorcollection.a(k, l, 0).getPosition(), Blocks.AIR); + for (BlockPosition pos : blockList.getBlocks()) { + world.triggerEffect(2001, pos, Block.getCombinedId(world.getType(pos))); } - } + blockList.updateList(); + // CraftBukkit end + Iterator iterator = world.a(EntityPlayer.class, entitywither.getBoundingBox().g(50.0D)).iterator(); + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + CriterionTriggers.n.a(entityplayer, (Entity) entitywither); + } + + // world.addEntity(entitywither); // CraftBukkit - moved up + + for (int k = 0; k < shapedetector.c(); ++k) { + for (int l = 0; l < shapedetector.b(); ++l) { + world.update(shapedetector_shapedetectorcollection.a(k, l, 0).getPosition(), Blocks.AIR); + } + } + + } } } } @@ -102,7 +92,7 @@ public class BlockWitherSkull extends BlockSkull { return itemstack.getItem() == Items.WITHER_SKELETON_SKULL && blockposition.getY() >= 2 && world.getDifficulty() != EnumDifficulty.PEACEFUL && !world.isClientSide ? e().a(world, blockposition) != null : false; } - protected static ShapeDetector d() { + private static ShapeDetector d() { if (BlockWitherSkull.c == null) { BlockWitherSkull.c = ShapeDetectorBuilder.a().a("^^^", "###", "~#~").a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SOUL_SAND))).a('^', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.WITHER_SKELETON_SKULL).or(BlockStatePredicate.a(Blocks.WITHER_SKELETON_WALL_SKULL)))).a('~', ShapeDetectorBlock.a(MaterialPredicate.a(Material.AIR))).b(); } @@ -110,11 +100,11 @@ public class BlockWitherSkull extends BlockSkull { return BlockWitherSkull.c; } - protected static ShapeDetector e() { - if (BlockWitherSkull.o == null) { - BlockWitherSkull.o = ShapeDetectorBuilder.a().a(" ", "###", "~#~").a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SOUL_SAND))).a('~', ShapeDetectorBlock.a(MaterialPredicate.a(Material.AIR))).b(); + private static ShapeDetector e() { + if (BlockWitherSkull.d == null) { + BlockWitherSkull.d = ShapeDetectorBuilder.a().a(" ", "###", "~#~").a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SOUL_SAND))).a('~', ShapeDetectorBlock.a(MaterialPredicate.a(Material.AIR))).b(); } - return BlockWitherSkull.o; + return BlockWitherSkull.d; } } diff --git a/src/main/java/net/minecraft/server/BossBattleCustom.java b/src/main/java/net/minecraft/server/BossBattleCustom.java index bc460f8ef..218b97057 100644 --- a/src/main/java/net/minecraft/server/BossBattleCustom.java +++ b/src/main/java/net/minecraft/server/BossBattleCustom.java @@ -38,6 +38,7 @@ public class BossBattleCustom extends BossBattleServer { return this.h; } + @Override public void addPlayer(EntityPlayer entityplayer) { super.addPlayer(entityplayer); this.i.add(entityplayer.getUniqueID()); @@ -47,11 +48,13 @@ public class BossBattleCustom extends BossBattleServer { this.i.add(uuid); } + @Override public void removePlayer(EntityPlayer entityplayer) { super.removePlayer(entityplayer); this.i.remove(entityplayer.getUniqueID()); } + @Override public void b() { super.b(); this.i.clear(); @@ -190,7 +193,7 @@ public class BossBattleCustom extends BossBattleServer { while (iterator.hasNext()) { UUID uuid = (UUID) iterator.next(); - nbttaglist.add((NBTBase) GameProfileSerializer.a(uuid)); + nbttaglist.add(GameProfileSerializer.a(uuid)); } nbttagcompound.set("Players", nbttaglist); diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java index 6efc156de..67dc837f4 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -1,86 +1,61 @@ package net.minecraft.server; -// Paper start -import com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.UUID; -// Paper end import com.destroystokyo.paper.exception.ServerInternalException; import com.google.common.collect.Maps; -import com.google.common.collect.Queues; import com.google.common.collect.Sets; -import com.koloboke.collect.map.hash.HashObjObjMaps; - -import io.akarin.server.core.AkarinAsyncExecutor; -import io.akarin.server.core.AkarinCreatureSpanwner; -import io.akarin.server.core.AkarinGlobalConfig; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; import it.unimi.dsi.fastutil.shorts.ShortList; import it.unimi.dsi.fastutil.shorts.ShortListIterator; -import java.util.BitSet; import java.util.Collection; -import java.util.HashSet; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.Map.Entry; +import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -// CraftBukkit start -import com.google.common.collect.Lists; -import java.util.LinkedList; -import org.bukkit.craftbukkit.event.CraftEventFactory; -import org.bukkit.event.entity.CreatureSpawnEvent; -// CraftBukkit end - public class Chunk implements IChunkAccess { - private static final Logger d = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public static final ChunkSection a = null; public static final ChunkSection EMPTY_CHUNK_SECTION = Chunk.a; // Paper - OBFHELPER - private volatile ChunkSection[] sections; // Akarin - volatile - private final BiomeBase[] f; - private final BitSet g; // Akarin - private final Map h; - private boolean i;public boolean isLoaded() { return i; } // Paper - OBFHELPER + private final ChunkSection[] sections; + private final BiomeBase[] d; + private final Map e; + public boolean loaded; public boolean isLoaded() { return loaded; } // Paper - OBFHELPER public final World world; public final Map heightMap; - public Long scheduledForUnload; // Paper - delay chunk unloads - private static final Logger logger = LogManager.getLogger(); // Paper - public final int locX; - public final int locZ; - private volatile boolean l; // Akarin - private final ChunkConverter m; + private final ChunkConverter i; public final Map tileEntities; public final List[] entitySlices; // Spigot - private final Map p; - private final Map q; - private final ShortList[] r; - private final TickList s; - private final TickList t; - private boolean u; - private boolean v;public boolean hasEntities() { return v; } // Paper - OBFHELPER - private long lastSaved; - private volatile boolean x; public boolean isModified() { return x; } // Paper - OBFHELPER // Akarin - volatile - private int y; - private long z; - private int A; - private final ConcurrentLinkedQueue B; - private ChunkStatus C; - private int D; - private final AtomicInteger E; - private final ChunkCoordIntPair F; + private final Map l; + private final Map m; + private final ShortList[] n; + private TickList o; + private TickList p; + private boolean q; + public long lastSaved; // Paper + private volatile boolean s; + private long t; + @Nullable + private Supplier u; + @Nullable + private Consumer v; + private final ChunkCoordIntPair loc; + private volatile boolean x; + + public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeBase[] abiomebase) { + this(world, chunkcoordintpair, abiomebase, ChunkConverter.a, TickListEmpty.b(), TickListEmpty.b(), 0L, (ChunkSection[]) null, (Consumer) null); + } - // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking - private volatile int neighbors = 0x1 << 12; // Akarin - volatile - public long chunkKey; // Paper start public final co.aikar.util.Counter entityCounts = new co.aikar.util.Counter<>(); public final co.aikar.util.Counter tileEntityCounts = new co.aikar.util.Counter<>(); @@ -109,104 +84,79 @@ public class Chunk implements IChunkAccess { return removed; } } - final PaperLightingQueue.LightingQueue lightingQueue = new PaperLightingQueue.LightingQueue(this); // Track the number of minecarts and items // Keep this synced with entitySlices.add() and entitySlices.remove() private final int[] itemCounts = new int[16]; private final int[] inventoryEntityCounts = new int[16]; // Paper end - public boolean areNeighborsLoaded(final int radius) { - switch (radius) { - case 2: - return this.neighbors == Integer.MAX_VALUE >> 6; - case 1: - final int mask = - // x z offset x z offset x z offset - (0x1 << (1 * 5 + 1 + 12)) | (0x1 << (0 * 5 + 1 + 12)) | (0x1 << (-1 * 5 + 1 + 12)) | - (0x1 << (1 * 5 + 0 + 12)) | (0x1 << (0 * 5 + 0 + 12)) | (0x1 << (-1 * 5 + 0 + 12)) | - (0x1 << (1 * 5 + -1 + 12)) | (0x1 << (0 * 5 + -1 + 12)) | (0x1 << (-1 * 5 + -1 + 12)); - return (this.neighbors & mask) == mask; - default: - throw new UnsupportedOperationException(String.valueOf(radius)); - } - } - public void setNeighborLoaded(final int x, final int z) { - this.neighbors |= 0x1 << (x * 5 + 12 + z); - } - - public void setNeighborUnloaded(final int x, final int z) { - this.neighbors &= ~(0x1 << (x * 5 + 12 + z)); - } - // CraftBukkit end - - public Chunk(World world, int i, int j, BiomeBase[] abiomebase, ChunkConverter chunkconverter, TickList ticklist, TickList ticklist1, long k) { + public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeBase[] abiomebase, ChunkConverter chunkconverter, TickList ticklist, TickList ticklist1, long i, @Nullable ChunkSection[] achunksection, @Nullable Consumer consumer) { this.sections = new ChunkSection[16]; - this.g = new BitSet(256); // Akarin - this.h = Maps.newHashMap(); + this.e = Maps.newHashMap(); this.heightMap = Maps.newEnumMap(HeightMap.Type.class); this.tileEntities = new TileEntityHashMap(); // Paper - this.p = Maps.newHashMap(); - this.q = Maps.newHashMap(); - this.r = new ShortList[16]; - this.A = 4096; - this.B = Queues.newConcurrentLinkedQueue(); - this.C = ChunkStatus.EMPTY; - this.E = new AtomicInteger(); + this.l = Maps.newHashMap(); + this.m = Maps.newHashMap(); + this.n = new ShortList[16]; this.entitySlices = (List[]) (new List[16]); // Spigot this.world = world; - this.locX = i; - this.locZ = j; - this.F = new ChunkCoordIntPair(i, j); - this.m = chunkconverter; + this.loc = chunkcoordintpair; + this.i = chunkconverter; HeightMap.Type[] aheightmap_type = HeightMap.Type.values(); - int l = aheightmap_type.length; + int j = aheightmap_type.length; - for (int i1 = 0; i1 < l; ++i1) { - HeightMap.Type heightmap_type = aheightmap_type[i1]; + for (int k = 0; k < j; ++k) { + HeightMap.Type heightmap_type = aheightmap_type[k]; - if (heightmap_type.c() == HeightMap.Use.LIVE_WORLD) { + if (ChunkStatus.FULL.h().contains(heightmap_type)) { this.heightMap.put(heightmap_type, new HeightMap(this, heightmap_type)); } } - for (int j1 = 0; j1 < this.entitySlices.length; ++j1) { - this.entitySlices[j1] = new org.bukkit.craftbukkit.util.UnsafeList(); // Spigot + for (int l = 0; l < this.entitySlices.length; ++l) { + this.entitySlices[l] = new org.bukkit.craftbukkit.util.UnsafeList(); // Spigot + } + + this.d = abiomebase; + this.o = ticklist; + this.p = ticklist1; + this.t = i; + this.v = consumer; + if (achunksection != null) { + if (this.sections.length == achunksection.length) { + System.arraycopy(achunksection, 0, this.sections, 0, this.sections.length); + } else { + Chunk.LOGGER.warn("Could not set level chunk sections, array length is {} instead of {}", achunksection.length, this.sections.length); + } } - this.f = abiomebase; - this.s = ticklist; - this.t = ticklist1; - this.z = k; // CraftBukkit start this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); - this.chunkKey = ChunkCoordIntPair.a(this.locX, this.locZ); } public org.bukkit.Chunk bukkitChunk; - public boolean mustSave; - private boolean needsDecoration; + public org.bukkit.Chunk getBukkitChunk() { + return bukkitChunk; + } + + public boolean mustNotSave; + public boolean needsDecoration; // CraftBukkit end - public Chunk(World world, ProtoChunk protochunk, int i, int j) { - this(world, i, j, protochunk.getBiomeIndex(), protochunk.v(), protochunk.k(), protochunk.l(), protochunk.m()); - - int k; - - for (k = 0; k < this.sections.length; ++k) { - this.sections[k] = protochunk.getSections()[k]; - if (this.sections[k] != null) this.sections[k].disableLocks(); // Paper - Async Chunks - disable locks used during world gen - } - - Iterator iterator = protochunk.s().iterator(); + public Chunk(World world, ProtoChunk protochunk) { + this(world, protochunk.getPos(), protochunk.getBiomeIndex(), protochunk.p(), protochunk.n(), protochunk.o(), protochunk.q(), protochunk.getSections(), (Consumer) null); + Iterator iterator = protochunk.y().iterator(); while (iterator.hasNext()) { NBTTagCompound nbttagcompound = (NBTTagCompound) iterator.next(); - ChunkRegionLoader.a(nbttagcompound, world, this); + EntityTypes.a(nbttagcompound, world, (entity) -> { + this.a(entity); + return entity; + }); } - iterator = protochunk.r().values().iterator(); + iterator = protochunk.x().values().iterator(); while (iterator.hasNext()) { TileEntity tileentity = (TileEntity) iterator.next(); @@ -214,252 +164,52 @@ public class Chunk implements IChunkAccess { this.a(tileentity); } - this.h.putAll(protochunk.w()); + this.e.putAll(protochunk.z()); - for (k = 0; k < protochunk.u().length; ++k) { - this.r[k] = protochunk.u()[k]; + for (int i = 0; i < protochunk.l().length; ++i) { + this.n[i] = protochunk.l()[i]; } - this.a(protochunk.e()); - this.b(protochunk.f()); - iterator = protochunk.t().iterator(); + this.a(protochunk.h()); + this.b(protochunk.v()); + iterator = protochunk.f().iterator(); while (iterator.hasNext()) { - HeightMap.Type heightmap_type = (HeightMap.Type) iterator.next(); + Entry entry = (Entry) iterator.next(); - if (heightmap_type.c() == HeightMap.Use.LIVE_WORLD) { - ((HeightMap) this.heightMap.computeIfAbsent(heightmap_type, (heightmap_type1) -> { - return new HeightMap(this, heightmap_type1); - })).a(protochunk.b(heightmap_type).b()); + if (ChunkStatus.FULL.h().contains(entry.getKey())) { + this.b((HeightMap.Type) entry.getKey()).a(((HeightMap) entry.getValue()).a()); } } - this.x = true; - this.a(ChunkStatus.FULLCHUNK); + this.b(protochunk.r()); + this.s = true; this.needsDecoration = true; // CraftBukkit } - public Set t() { - Set set = Sets.newHashSet(this.h.keySet()); + @Override + public HeightMap b(HeightMap.Type heightmap_type) { + return (HeightMap) this.heightMap.computeIfAbsent(heightmap_type, (heightmap_type1) -> { + return new HeightMap(this, heightmap_type1); + }); + } + + @Override + public Set c() { + Set set = Sets.newHashSet(this.e.keySet()); set.addAll(this.tileEntities.keySet()); return set; } - public boolean a(int i, int j) { - return i == this.locX && j == this.locZ; - } - + @Override public ChunkSection[] getSections() { return this.sections; } - public void initLighting() { - Runnable runnable = () -> { // Akarin - int i = this.b(); - - this.y = Integer.MAX_VALUE; - Iterator iterator = this.heightMap.values().iterator(); - - while (iterator.hasNext()) { - HeightMap heightmap = (HeightMap) iterator.next(); - - heightmap.a(); - } - - for (int j = 0; j < 16; ++j) { - for (int k = 0; k < 16; ++k) { - if (this.world.worldProvider.g()) { - int l = 15; - int i1 = i + 16 - 1; - - do { - int j1 = this.d(j, i1, k); - - if (j1 == 0 && l != 15) { - j1 = 1; - } - - l -= j1; - if (l > 0) { - ChunkSection chunksection = this.sections[i1 >> 4]; - - if (chunksection != Chunk.a) { - chunksection.a(j, i1 & 15, k, l); - //this.world.m(new BlockPosition((this.locX << 4) + j, i1, (this.locZ << 4) + k)); // Akarin - } - } - - --i1; - } while (i1 > 0 && l > 0); - } - } - } - - this.x = true; - // Akarin start - }; - if (AkarinGlobalConfig.enableAsyncLighting) - AkarinAsyncExecutor.scheduleAsyncTask(runnable); - else - runnable.run(); - // Akarin end - } - - private void c(int i, int j) { - synchronized (this) { // Akarin - synchronized - this.g.set(i + j * 16); - } // Akarin - synchronized - this.l = true; - } - - private void g(boolean flag) { - //this.world.methodProfiler.enter("recheckGaps"); // Akarin - remove caller - if (this.areNeighborsLoaded(1)) { // Paper - for (int i = 0; i < 16; ++i) { - for (int j = 0; j < 16; ++j) { - // Akarin start - int index = i + j * 16; - boolean has; - synchronized (this) { - if (has = this.g.get(index)) - this.g.set(index); - } - if (has) { - // Akarin end - int k = this.a(HeightMap.Type.LIGHT_BLOCKING, i, j); - int l = this.locX * 16 + i; - int i1 = this.locZ * 16 + j; - int j1 = Integer.MAX_VALUE; - - EnumDirection enumdirection; - Iterator iterator; - - for (iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); iterator.hasNext(); j1 = Math.min(j1, this.world.d(l + enumdirection.getAdjacentX(), i1 + enumdirection.getAdjacentZ()))) { - enumdirection = (EnumDirection) iterator.next(); - } - - this.c(l, i1, j1); - iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); - - while (iterator.hasNext()) { - enumdirection = (EnumDirection) iterator.next(); - this.c(l + enumdirection.getAdjacentX(), i1 + enumdirection.getAdjacentZ(), k); - } - - if (flag) { - //this.world.methodProfiler.exit(); // Akarin - remove caller - return; - } - } - } - } - - this.l = false; - } - - //this.world.methodProfiler.exit(); // Akarin - remove caller - } - - private void c(int i, int j, int k) { - int l = this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(i, 0, j)).getY(); - - if (l > k) { - this.a(i, j, k, l + 1); - } else if (l < k) { - this.a(i, j, l, k + 1); - } - - } - - private void a(int i, int j, int k, int l) { - if (l > k && this.areNeighborsLoaded(1)) { // Paper - for (int i1 = k; i1 < l; ++i1) { - this.world.updateBrightness(EnumSkyBlock.SKY, new BlockPosition(i, i1, j), this); // Paper - } - - this.x = true; - } - - } - - private void a(int i, int j, int k, IBlockData iblockdata) { - HeightMap heightmap = (HeightMap) this.heightMap.get(HeightMap.Type.LIGHT_BLOCKING); - int l = heightmap.a(i & 15, k & 15) & 255; - - if (heightmap.a(i, j, k, iblockdata)) { - int i1 = heightmap.a(i & 15, k & 15); - int j1 = this.locX * 16 + i; - int k1 = this.locZ * 16 + k; - - this.world.a(j1, k1, i1, l); - int l1; - int i2; - int j2; - - if (this.world.worldProvider.g()) { - l1 = Math.min(l, i1); - i2 = Math.max(l, i1); - j2 = i1 < l ? 15 : 0; - - int k2; - - for (k2 = l1; k2 < i2; ++k2) { - ChunkSection chunksection = this.sections[k2 >> 4]; - - if (chunksection != Chunk.a) { - chunksection.a(i, k2 & 15, k, j2); - //this.world.m(new BlockPosition((this.locX << 4) + i, k2, (this.locZ << 4) + k)); // Akarin - } - } - - k2 = 15; - - while (i1 > 0 && k2 > 0) { - --i1; - int l2 = this.d(i, i1, k); - - l2 = l2 == 0 ? 1 : l2; - k2 -= l2; - k2 = Math.max(0, k2); - ChunkSection chunksection1 = this.sections[i1 >> 4]; - - if (chunksection1 != Chunk.a) { - chunksection1.a(i, i1 & 15, k, k2); - } - } - } - - if (i1 < this.y) { - this.y = i1; - } - - if (this.world.worldProvider.g()) { - l1 = heightmap.a(i & 15, k & 15); - i2 = Math.min(l, l1); - j2 = Math.max(l, l1); - Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); - - while (iterator.hasNext()) { - EnumDirection enumdirection = (EnumDirection) iterator.next(); - - this.a(j1 + enumdirection.getAdjacentX(), k1 + enumdirection.getAdjacentZ(), i2, j2); - } - - this.a(j1, k1, i2, j2); - } - - this.x = true; - } - } - - private int d(int i, int j, int k) { - return this.getBlockData(i, j, k).b(this.world, new BlockPosition(i, j, k)); - } - // Paper start - Optimize getBlockData to reduce instructions public final IBlockData getBlockData(BlockPosition pos) { return getBlockData(pos.getX(), pos.getY(), pos.getZ()); } // Paper - public final IBlockData getType(BlockPosition blockposition) { + public IBlockData getType(BlockPosition blockposition) { return this.getBlockData(blockposition.getX(), blockposition.getY(), blockposition.getZ()); } @@ -475,7 +225,7 @@ public class Chunk implements IChunkAccess { public IBlockData getBlockData_unused(int i, int j, int k) { // Paper end - if (this.world.S() == WorldType.DEBUG_ALL_BLOCK_STATES) { + if (this.world.P() == WorldType.DEBUG_ALL_BLOCK_STATES) { IBlockData iblockdata = null; if (j == 60) { @@ -483,7 +233,7 @@ public class Chunk implements IChunkAccess { } if (j == 70) { - iblockdata = ChunkProviderDebug.b(i, k); + iblockdata = ChunkProviderDebug.a(i, k); } return iblockdata == null ? Blocks.AIR.getBlockData() : iblockdata; @@ -492,7 +242,7 @@ public class Chunk implements IChunkAccess { if (j >= 0 && j >> 4 < this.sections.length) { ChunkSection chunksection = this.sections[j >> 4]; - if (chunksection != Chunk.a) { + if (!ChunkSection.a(chunksection)) { return chunksection.getType(i & 15, j & 15, k & 15); } } @@ -510,16 +260,29 @@ public class Chunk implements IChunkAccess { } } - public Fluid getFluid(BlockPosition blockposition) { - return this.b(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + // Paper start - If loaded util + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + return this.getFluid(blockposition); } - public Fluid b(int i, int j, int k) { + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + return this.getType(blockposition); + } + // Paper end + + @Override + public Fluid getFluid(BlockPosition blockposition) { + return this.a(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + } + + public Fluid a(int i, int j, int k) { try { if (j >= 0 && j >> 4 < this.sections.length) { ChunkSection chunksection = this.sections[j >> 4]; - if (chunksection != Chunk.a) { + if (!ChunkSection.a(chunksection)) { return chunksection.b(i & 15, j & 15, k & 15); } } @@ -538,6 +301,7 @@ public class Chunk implements IChunkAccess { // CraftBukkit start @Nullable + @Override public IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag) { return this.setType(blockposition, iblockdata, flag, true); } @@ -548,55 +312,45 @@ public class Chunk implements IChunkAccess { int i = blockposition.getX() & 15; int j = blockposition.getY(); int k = blockposition.getZ() & 15; - int l = ((HeightMap) this.heightMap.get(HeightMap.Type.LIGHT_BLOCKING)).a(i, k); - IBlockData iblockdata1 = this.getType(blockposition); + ChunkSection chunksection = this.sections[j >> 4]; + + if (chunksection == Chunk.a) { + if (iblockdata.isAir()) { + return null; + } + + chunksection = new ChunkSection(j >> 4 << 4, this, this.world, true); // Paper - Anti-Xray + this.sections[j >> 4] = chunksection; + } + + boolean flag1 = chunksection.c(); + IBlockData iblockdata1 = chunksection.setType(i, j & 15, k, iblockdata); if (iblockdata1 == iblockdata) { return null; } else { Block block = iblockdata.getBlock(); Block block1 = iblockdata1.getBlock(); - ChunkSection chunksection = this.sections[j >> 4]; - boolean flag1 = false; - if (chunksection == Chunk.a) { - if (iblockdata.isAir()) { - return null; - } - - chunksection = new ChunkSection(j >> 4 << 4, this.world.worldProvider.g(), this, this.world, true); // Paper - Anti-Xray - this.sections[j >> 4] = chunksection; - flag1 = j >= l; - } - - chunksection.setType(i, j & 15, k, iblockdata); ((HeightMap) this.heightMap.get(HeightMap.Type.MOTION_BLOCKING)).a(i, j, k, iblockdata); ((HeightMap) this.heightMap.get(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES)).a(i, j, k, iblockdata); ((HeightMap) this.heightMap.get(HeightMap.Type.OCEAN_FLOOR)).a(i, j, k, iblockdata); ((HeightMap) this.heightMap.get(HeightMap.Type.WORLD_SURFACE)).a(i, j, k, iblockdata); + boolean flag2 = chunksection.c(); + + if (flag1 != flag2) { + this.world.getChunkProvider().getLightEngine().a(blockposition, flag2); + } + if (!this.world.isClientSide) { iblockdata1.remove(this.world, blockposition, iblockdata, flag); } else if (block1 != block && block1 instanceof ITileEntity) { - this.world.n(blockposition); + this.world.removeTileEntity(blockposition); } - if (false && chunksection.getType(i, j & 15, k).getBlock() != block) { // Paper - don't need to recheck this - this would only fail due to non main thread writes which are not supported + if (chunksection.getType(i, j & 15, k).getBlock() != block) { return null; } else { - if (flag1) { - this.initLighting(); - } else { - this.runOrQueueLightUpdate(() -> { // Paper - Queue light update - int i1 = iblockdata.b(this.world, blockposition); - int j1 = iblockdata1.b(this.world, blockposition); - - this.a(i, j, k, iblockdata); - if (i1 != j1 && (i1 < j1 || this.getBrightness(EnumSkyBlock.SKY, blockposition) > 0 || this.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 0)) { - this.c(i, k); - } - }); // Paper - } - TileEntity tileentity; if (block1 instanceof ITileEntity) { @@ -608,120 +362,45 @@ public class Chunk implements IChunkAccess { // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled. if (!this.world.isClientSide && doPlace && (!this.world.captureBlockStates || block instanceof BlockTileEntity)) { - iblockdata.onPlace(this.world, blockposition, iblockdata1); + iblockdata.onPlace(this.world, blockposition, iblockdata1, flag); } if (block instanceof ITileEntity) { tileentity = this.a(blockposition, Chunk.EnumTileEntityState.CHECK); if (tileentity == null) { - tileentity = ((ITileEntity) block).a(this.world); + tileentity = ((ITileEntity) block).createTile(this.world); this.world.setTileEntity(blockposition, tileentity); } else { tileentity.invalidateBlockCache(); } } - this.x = true; + this.s = true; return iblockdata1; } } } - public int getBrightness(EnumSkyBlock enumskyblock, BlockPosition blockposition) { - return this.a(enumskyblock, blockposition, this.world.o().g()); - } - - public int a(EnumSkyBlock enumskyblock, BlockPosition blockposition, boolean flag) { - int i = blockposition.getX() & 15; - int j = blockposition.getY(); - int k = blockposition.getZ() & 15; - int l = j >> 4; - - if (l >= 0 && l <= this.sections.length - 1) { - ChunkSection chunksection = this.sections[l]; - - return chunksection == Chunk.a ? (this.c(blockposition) ? enumskyblock.c : 0) : (enumskyblock == EnumSkyBlock.SKY ? (!flag ? 0 : chunksection.c(i, j & 15, k)) : (enumskyblock == EnumSkyBlock.BLOCK ? chunksection.d(i, j & 15, k) : enumskyblock.c)); - } else { - return (enumskyblock != EnumSkyBlock.SKY || !flag) && enumskyblock != EnumSkyBlock.BLOCK ? 0 : enumskyblock.c; - } - } - - public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { - this.a(enumskyblock, this.world.o().g(), blockposition, i); - } - - public void a(EnumSkyBlock enumskyblock, boolean flag, BlockPosition blockposition, int i) { - int j = blockposition.getX() & 15; - int k = blockposition.getY(); - int l = blockposition.getZ() & 15; - int i1 = k >> 4; - - if (i1 < 16 && i1 >= 0) { - ChunkSection chunksection = this.sections[i1]; - - if (chunksection == Chunk.a) { - if (i == enumskyblock.c) { - return; - } - - chunksection = new ChunkSection(i1 << 4, flag, this, this.world, true); // Paper - Anti-Xray - this.sections[i1] = chunksection; - this.initLighting(); - } - - if (enumskyblock == EnumSkyBlock.SKY) { - if (this.world.worldProvider.g()) { - chunksection.a(j, k & 15, l, i); - } - } else if (enumskyblock == EnumSkyBlock.BLOCK) { - chunksection.b(j, k & 15, l, i); - } - - this.x = true; - } + @Nullable + @Override + public LightEngine e() { + return this.world.getChunkProvider().getLightEngine(); } public final int getLightSubtracted(BlockPosition blockposition, int i) { return this.a(blockposition, i); } // Paper - OBFHELPER public int a(BlockPosition blockposition, int i) { - return this.a(blockposition, i, this.world.o().g()); - } - - public int a(BlockPosition blockposition, int i, boolean flag) { - int j = blockposition.getX() & 15; - int k = blockposition.getY(); - int l = blockposition.getZ() & 15; - int i1 = k >> 4; - - if (i1 >= 0 && i1 <= this.sections.length - 1) { - ChunkSection chunksection = this.sections[i1]; - - if (chunksection == Chunk.a) { - return flag && i < EnumSkyBlock.SKY.c ? EnumSkyBlock.SKY.c - i : 0; - } else { - int j1 = flag ? chunksection.c(j, k & 15, l) : 0; - - j1 -= i; - int k1 = chunksection.d(j, k & 15, l); - - if (k1 > j1) { - j1 = k1; - } - - return j1; - } - } else { - return 0; - } + return this.a(blockposition, i, this.world.getWorldProvider().g()); } + @Override public void a(Entity entity) { - this.v = true; + this.q = true; int i = MathHelper.floor(entity.locX / 16.0D); int j = MathHelper.floor(entity.locZ / 16.0D); - if (i != this.locX || j != this.locZ) { - Chunk.d.warn("Wrong location! ({}, {}) should be ({}, {}), {}", i, j, this.locX, this.locZ, entity); - entity.die(); + if (i != this.loc.x || j != this.loc.z) { + Chunk.LOGGER.warn("Wrong location! ({}, {}) should be ({}, {}), {}", i, j, this.loc.x, this.loc.z, entity); + entity.dead = true; return; // Paper } @@ -757,27 +436,22 @@ public class Chunk implements IChunkAccess { if (!entity.inChunk || entity.getCurrentChunk() != this) entityCounts.increment(entity.getMinecraftKeyString()); // Paper entity.inChunk = true; entity.setCurrentChunk(this); // Paper - entity.chunkX = this.locX; + entity.chunkX = this.loc.x; entity.chunkY = k; - entity.chunkZ = this.locZ; + entity.chunkZ = this.loc.z; this.entitySlices[k].add(entity); // Paper start - entity.entitySlice = this.entitySlices[k]; // Paper - this.markDirty(); if (entity instanceof EntityItem) { itemCounts[k]++; } else if (entity instanceof IInventory) { inventoryEntityCounts[k]++; - // Akarin start - } else if (entity instanceof IAnimal) { - for (EnumCreatureType type : EnumCreatureType.values()) - if (type.matches(entity)) - AkarinCreatureSpanwner.increment(this.getPos(), type); - // Akarin end } // Paper end + entity.entitySlice = this.entitySlices[k]; // Paper + this.markDirty(); // Paper } + @Override public void a(HeightMap.Type heightmap_type, long[] along) { ((HeightMap) this.heightMap.get(heightmap_type)).a(along); } @@ -803,44 +477,31 @@ public class Chunk implements IChunkAccess { if (!this.entitySlices[i].remove(entity)) { return; } - this.markDirty(); if (entity instanceof EntityItem) { itemCounts[i]--; } else if (entity instanceof IInventory) { inventoryEntityCounts[i]--; - // Akarin start - } else if (entity instanceof IAnimal) { - for (EnumCreatureType type : EnumCreatureType.values()) - if (type.matches(entity)) { - AkarinCreatureSpanwner.decrement(this.getPos(), type); - } - // Akarin end } entityCounts.decrement(entity.getMinecraftKeyString()); + this.markDirty(); // Paper // Paper end } - public boolean c(BlockPosition blockposition) { - int i = blockposition.getX() & 15; - int j = blockposition.getY(); - int k = blockposition.getZ() & 15; - - return j >= ((HeightMap) this.heightMap.get(HeightMap.Type.LIGHT_BLOCKING)).a(i, k); - } - + @Override public int a(HeightMap.Type heightmap_type, int i, int j) { return ((HeightMap) this.heightMap.get(heightmap_type)).a(i & 15, j & 15) - 1; } @Nullable - private TileEntity j(BlockPosition blockposition) { + private TileEntity k(BlockPosition blockposition) { IBlockData iblockdata = this.getType(blockposition); Block block = iblockdata.getBlock(); - return !block.isTileEntity() ? null : ((ITileEntity) block).a(this.world); + return !block.isTileEntity() ? null : ((ITileEntity) block).createTile(this.world); } @Nullable + @Override public TileEntity getTileEntity(BlockPosition blockposition) { return this.a(blockposition, Chunk.EnumTileEntityState.CHECK); } @@ -856,7 +517,7 @@ public class Chunk implements IChunkAccess { // CraftBukkit end if (tileentity == null) { - NBTTagCompound nbttagcompound = (NBTTagCompound) this.h.remove(blockposition); + NBTTagCompound nbttagcompound = (NBTTagCompound) this.e.remove(blockposition); if (nbttagcompound != null) { TileEntity tileentity1 = this.a(blockposition, nbttagcompound); @@ -869,12 +530,10 @@ public class Chunk implements IChunkAccess { if (tileentity == null) { if (chunk_enumtileentitystate == Chunk.EnumTileEntityState.IMMEDIATE) { - tileentity = this.j(blockposition); + tileentity = this.k(blockposition); this.world.setTileEntity(blockposition, tileentity); - } else if (chunk_enumtileentitystate == Chunk.EnumTileEntityState.QUEUED) { - this.B.add(blockposition); } - } else if (tileentity.x()) { + } else if (tileentity.isRemoved()) { this.tileEntities.remove(blockposition); return null; } @@ -883,23 +542,25 @@ public class Chunk implements IChunkAccess { } public void a(TileEntity tileentity) { - this.a(tileentity.getPosition(), tileentity); - if (this.i) { - this.world.a(tileentity); + this.setTileEntity(tileentity.getPosition(), tileentity); + if (this.loaded || this.world.e()) { + this.world.setTileEntity(tileentity.getPosition(), tileentity); } } - public void a(BlockPosition blockposition, TileEntity tileentity) { - tileentity.setWorld(this.world); - tileentity.setPosition(blockposition); + @Override + public void setTileEntity(BlockPosition blockposition, TileEntity tileentity) { if (this.getType(blockposition).getBlock() instanceof ITileEntity) { - if (this.tileEntities.containsKey(blockposition)) { - ((TileEntity) this.tileEntities.get(blockposition)).y(); + tileentity.setWorld(this.world); + tileentity.setPosition(blockposition); + tileentity.n(); + TileEntity tileentity1 = (TileEntity) this.tileEntities.put(blockposition.immutableCopy(), tileentity); + + if (tileentity1 != null && tileentity1 != tileentity) { + tileentity1.V_(); } - tileentity.z(); - this.tileEntities.put(blockposition.h(), tileentity); // CraftBukkit start // Paper start - Remove invalid mob spawner tile entities } else if (tileentity instanceof TileEntityMobSpawner && !(getBlockData(blockposition.getX(), blockposition.getY(), blockposition.getZ()).getBlock() instanceof BlockMobSpawner)) { @@ -910,8 +571,8 @@ public class Chunk implements IChunkAccess { ServerInternalException e = new ServerInternalException( "Attempted to place a tile entity (" + tileentity + ") at " + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ() - + " (" + getBlockData(blockposition) + ") where there was no entity tile!\n" + - "Chunk coordinates: " + (this.locX * 16) + "," + (this.locZ * 16)); + + " (" + getType(blockposition) + ") where there was no entity tile!\n" + + "Chunk coordinates: " + (this.loc.x * 16) + "," + (this.loc.z * 16)); e.printStackTrace(); ServerInternalException.reportInternalException(e); @@ -925,90 +586,54 @@ public class Chunk implements IChunkAccess { } } + @Override public void a(NBTTagCompound nbttagcompound) { - this.h.put(new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")), nbttagcompound); + this.e.put(new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")), nbttagcompound); } - public void removeTileEntity(BlockPosition blockposition) { this.d(blockposition); } // Paper - OBFHELPER - public void d(BlockPosition blockposition) { - if (this.i) { + @Nullable + @Override + public NBTTagCompound j(BlockPosition blockposition) { + TileEntity tileentity = this.getTileEntity(blockposition); + NBTTagCompound nbttagcompound; + + if (tileentity != null && !tileentity.isRemoved()) { + nbttagcompound = tileentity.save(new NBTTagCompound()); + nbttagcompound.setBoolean("keepPacked", false); + return nbttagcompound; + } else { + nbttagcompound = (NBTTagCompound) this.e.get(blockposition); + if (nbttagcompound != null) { + nbttagcompound = nbttagcompound.clone(); + nbttagcompound.setBoolean("keepPacked", true); + } + + return nbttagcompound; + } + } + + @Override + public void removeTileEntity(BlockPosition blockposition) { + if (this.loaded || this.world.e()) { TileEntity tileentity = (TileEntity) this.tileEntities.remove(blockposition); if (tileentity != null) { - tileentity.y(); + tileentity.V_(); } } } public void addEntities() { - this.i = true; - this.world.a(this.tileEntities.values()); - List[] aentityslice = this.entitySlices; // Spigot - int i = aentityslice.length; - - for (int j = 0; j < i; ++j) { - List entityslice = aentityslice[j]; // Spigot - // Paper start - DuplicateUUIDMode mode = world.paperConfig.duplicateUUIDMode; - if (mode == DuplicateUUIDMode.WARN || mode == DuplicateUUIDMode.DELETE || mode == DuplicateUUIDMode.SAFE_REGEN) { - Map thisChunk = HashObjObjMaps.newMutableMap(); // Akarin - for (Iterator iterator = ((List) entityslice).iterator(); iterator.hasNext(); ) { - Entity entity = iterator.next(); - if (entity.dead || entity.valid) continue; - Entity other = ((WorldServer) world).entitiesByUUID.get(entity.uniqueID); - if (other == null || other.dead || world.getEntityUnloadQueue().contains(other)) { - other = thisChunk.get(entity.uniqueID); - } - - if (mode == DuplicateUUIDMode.SAFE_REGEN && other != null && !other.dead && - !world.getEntityUnloadQueue().contains(other) - && java.util.Objects.equals(other.getSaveID(), entity.getSaveID()) - && entity.getBukkitEntity().getLocation().distance(other.getBukkitEntity().getLocation()) < world.paperConfig.duplicateUUIDDeleteRange - ) { - if (World.DEBUG_ENTITIES) logger.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + " because it was near the duplicate and likely an actual duplicate. See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); - entity.die(); - iterator.remove(); - continue; - } - if (other != null && !other.dead) { - switch (mode) { - case SAFE_REGEN: { - entity.setUUID(UUID.randomUUID()); - if (World.DEBUG_ENTITIES) logger.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", regenerated UUID for " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); - break; - } - case DELETE: { - if (World.DEBUG_ENTITIES) logger.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); - entity.die(); - iterator.remove(); - break; - } - default: - if (World.DEBUG_ENTITIES) logger.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", doing nothing to " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); - break; - } - } - thisChunk.put(entity.uniqueID, entity); - } - } - // Paper end - - // CraftBukkit start - this.world.addChunkEntities(entityslice.stream() // Paper - add all at same time to avoid entities adding to world modifying slice state, skip already added entities (not normal, but can happen) - // Paper start - Inline event into stream - .filter((entity) -> { - if (!this.needsDecoration) { - return true; - } - return CraftEventFactory.doEntityAddEventCalling(this.world, entity, CreatureSpawnEvent.SpawnReason.CHUNK_GEN); - }) - // Paper end - Inline event into stream - .filter((entity) -> !(entity instanceof EntityHuman || entity.valid))); // Paper - add all at same time to avoid entities adding to world modifying slice state, skip already added entities (not normal, but can happen) - // CraftBukkit end + if (this.v != null) { + this.v.accept(this); + this.v = null; } - // CraftBukkit start + } + + // CraftBukkit start + public void loadCallback() { org.bukkit.Server server = this.world.getServer(); if (server != null) { /* @@ -1019,13 +644,13 @@ public class Chunk implements IChunkAccess { server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(this.bukkitChunk, this.needsDecoration)); if (this.needsDecoration) { - this.world.timings.syncChunkLoadPopulateTimer.startTimingUnsafe(); // Paper - BlockSand.instaFall = true; + try (co.aikar.timings.Timing ignored = this.world.timings.syncChunkLoadPopulateTimer.startTiming()) { // Paper + this.needsDecoration = false; java.util.Random random = new java.util.Random(); random.setSeed(world.getSeed()); long xRand = random.nextLong() / 2L * 2L + 1L; long zRand = random.nextLong() / 2L * 2L + 1L; - random.setSeed((long) locX * xRand + (long) locZ * zRand ^ world.getSeed()); + random.setSeed((long) this.loc.x * xRand + (long) this.loc.z * zRand ^ world.getSeed()); org.bukkit.World world = this.world.getWorld(); if (world != null) { @@ -1038,76 +663,26 @@ public class Chunk implements IChunkAccess { this.world.populating = false; } } - BlockSand.instaFall = false; server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); - this.world.timings.syncChunkLoadPopulateTimer.stopTimingUnsafe(); // Paper + } // Paper } } - // CraftBukkit end } - public void removeEntities() { - this.i = false; - Iterator iterator = this.tileEntities.values().iterator(); - - while (iterator.hasNext()) { - TileEntity tileentity = (TileEntity) iterator.next(); - // Spigot Start - if ( tileentity instanceof IInventory ) - { - for ( org.bukkit.entity.HumanEntity h : Lists.newArrayList((List) ( (IInventory) tileentity ).getViewers() ) ) - { - if ( h instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity ) - { - ( (org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - } - } - } - // Spigot End - - this.world.b(tileentity); - } - - List[] aentityslice = this.entitySlices; // Spigot - int i = aentityslice.length; - - for (int j = 0; j < i; ++j) { - // CraftBukkit start - List newList = Lists.newArrayList(aentityslice[j]); - java.util.Iterator iter = newList.iterator(); - while (iter.hasNext()) { - Entity entity = iter.next(); - // Spigot Start - if ( entity instanceof IInventory ) - { - for ( org.bukkit.entity.HumanEntity h : Lists.newArrayList( (List) ( (IInventory) entity ).getViewers() ) ) - { - if ( h instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity ) - { - ( (org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - } - } - } - // Spigot End - - // Do not pass along players, as doing so can get them stuck outside of time. - // (which for example disables inventory icon updates and prevents block breaking) - if (entity instanceof EntityPlayer) { - iter.remove(); - } - } - - this.world.b((Collection) newList); - // CraftBukkit end - } - + public void unloadCallback() { + org.bukkit.Server server = this.world.getServer(); + org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(this.bukkitChunk, this.isNeedsSaving()); + server.getPluginManager().callEvent(unloadEvent); + // note: saving can be prevented, but not forced if no saving is actually required + this.mustNotSave = !unloadEvent.isSaveChunk(); } + // CraftBukkit end public void markDirty() { - this.x = true; + this.s = true; } - public void a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List list, Predicate predicate) { + public void a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); int j = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); @@ -1118,34 +693,24 @@ public class Chunk implements IChunkAccess { if (!this.entitySlices[k].isEmpty()) { Iterator iterator = this.entitySlices[k].iterator(); - // Paper start - Don't search for inventories if we have none, and that is all we want - /* - * We check if they want inventories by seeing if it is the static `IEntitySelector.c` - * - * Make sure the inventory selector stays in sync. - * It should be the one that checks `var1 instanceof IInventory && var1.isAlive()` - */ - if (predicate == IEntitySelector.isInventory() && inventoryEntityCounts[k] <= 0) continue; - // Paper end while (iterator.hasNext()) { Entity entity1 = (Entity) iterator.next(); + if (entity1.shouldBeRemoved) continue; // Paper if (entity1.getBoundingBox().c(axisalignedbb) && entity1 != entity) { if (predicate == null || predicate.test(entity1)) { list.add(entity1); } - Entity[] aentity = entity1.bi(); - - if (aentity != null) { - Entity[] aentity1 = aentity; - int l = aentity.length; + if (entity1 instanceof EntityEnderDragon) { + EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity1).dT(); + int l = aentitycomplexpart.length; for (int i1 = 0; i1 < l; ++i1) { - Entity entity2 = aentity1[i1]; + EntityComplexPart entitycomplexpart = aentitycomplexpart[i1]; - if (entity2 != entity && entity2.getBoundingBox().c(axisalignedbb) && (predicate == null || predicate.test(entity2))) { - list.add(entity2); + if (entitycomplexpart != entity && entitycomplexpart.getBoundingBox().c(axisalignedbb) && (predicate == null || predicate.test(entitycomplexpart))) { + list.add(entitycomplexpart); } } } @@ -1156,6 +721,37 @@ public class Chunk implements IChunkAccess { } + public void a(@Nullable EntityTypes entitytypes, AxisAlignedBB axisalignedbb, List list, Predicate predicate) { + int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); + int j = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); + + i = MathHelper.clamp(i, 0, this.entitySlices.length - 1); + j = MathHelper.clamp(j, 0, this.entitySlices.length - 1); + + for (int k = i; k <= j; ++k) { + Iterator iterator = this.entitySlices[k].iterator(); // Spigot + + // Paper start - Don't search for inventories if we have none, and that is all we want + /* + * We check if they want inventories by seeing if it is the static `IEntitySelector.c` + * + * Make sure the inventory selector stays in sync. + * It should be the one that checks `var1 instanceof IInventory && var1.isAlive()` + */ + if (predicate == IEntitySelector.isInventory() && inventoryEntityCounts[k] <= 0) continue; + // Paper end + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + if (entity.shouldBeRemoved) continue; // Paper + + if ((entitytypes == null || entity.getEntityType() == entitytypes) && entity.getBoundingBox().c(axisalignedbb) && predicate.test(entity)) { + list.add(entity); + } + } + } + + } + public void a(Class oclass, AxisAlignedBB axisalignedbb, List list, @Nullable Predicate predicate) { int i = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D); int j = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D); @@ -1179,6 +775,7 @@ public class Chunk implements IChunkAccess { while (iterator.hasNext()) { T t0 = (T) iterator.next(); // CraftBukkit - decompile error + if (t0.shouldBeRemoved) continue; // Paper if (oclass.isInstance(t0) && t0.getBoundingBox().c(axisalignedbb) && (predicate == null || predicate.test(t0))) { // Spigot - instance check list.add(t0); @@ -1188,147 +785,31 @@ public class Chunk implements IChunkAccess { } - public boolean c(boolean flag) { - if (flag) { - if (this.v && this.world.getTime() != this.lastSaved || this.x) { - return true; - } - } - // Paper start - Make world configurable and incremental - // This !flag section should say if isModified or hasEntities, then check auto save - return ((isModified() || hasEntities()) && this.world.getTime() >= this.lastSaved + world.paperConfig.autoSavePeriod); - // Paper end - } - public boolean isEmpty() { return false; } - public void d(boolean flag) { - if (this.l && this.world.worldProvider.g() && !flag) { - this.g(this.world.isClientSide); - } - - this.u = true; - - while (!this.B.isEmpty()) { - BlockPosition blockposition = (BlockPosition) this.B.poll(); - - if (this.a(blockposition, Chunk.EnumTileEntityState.CHECK) == null && this.getType(blockposition).getBlock().isTileEntity()) { - TileEntity tileentity = this.j(blockposition); - - this.world.setTileEntity(blockposition, tileentity); - //this.world.a(blockposition, blockposition); // Akarin - } - } - - } - - public boolean isReady() { - return true; // Paper - Always send chunks - } - - public boolean v() { - return this.u; - } - + @Override public ChunkCoordIntPair getPos() { - return this.F; - } - - public boolean b(int i, int j) { - if (i < 0) { - i = 0; - } - - if (j >= 256) { - j = 255; - } - - for (int k = i; k <= j; k += 16) { - ChunkSection chunksection = this.sections[k >> 4]; - - if (chunksection != Chunk.a && !chunksection.a()) { - return false; - } - } - - return true; - } - - public void a(ChunkSection[] achunksection) { - if (this.sections.length != achunksection.length) { - Chunk.d.warn("Could not set level chunk sections, array length is {} instead of {}", achunksection.length, this.sections.length); - } else { - System.arraycopy(achunksection, 0, this.sections, 0, this.sections.length); - } - } - - public BiomeBase getBiome(BlockPosition blockposition) { - int i = blockposition.getX() & 15; - int j = blockposition.getZ() & 15; - - return this.f[j << 4 | i]; + return this.loc; } + @Override public BiomeBase[] getBiomeIndex() { - return this.f; + return this.d; } - public void x() { - if (this.A < 4096) { - BlockPosition blockposition = new BlockPosition(this.locX << 4, 0, this.locZ << 4); - - for (int i = 0; i < 8; ++i) { - if (this.A >= 4096) { - return; - } - - int j = this.A % 16; - int k = this.A / 16 % 16; - int l = this.A / 256; - - ++this.A; - - for (int i1 = 0; i1 < 16; ++i1) { - BlockPosition blockposition1 = blockposition.a(k, (j << 4) + i1, l); - boolean flag = i1 == 0 || i1 == 15 || k == 0 || k == 15 || l == 0 || l == 15; - - if (this.sections[j] == Chunk.a && flag || this.sections[j] != Chunk.a && this.sections[j].getType(k, i1, l).isAir()) { - EnumDirection[] aenumdirection = EnumDirection.values(); - int j1 = aenumdirection.length; - - for (int k1 = 0; k1 < j1; ++k1) { - EnumDirection enumdirection = aenumdirection[k1]; - BlockPosition blockposition2 = blockposition1.shift(enumdirection); - - if (this.world.getType(blockposition2).e() > 0) { - this.world.r(blockposition2); - } - } - - this.world.r(blockposition1); - } - } - } - - } - } - - public boolean y() { - return this.i; + public void setLoaded(boolean flag) { + this.loaded = flag; } public World getWorld() { return this.world; } - public Set A() { - return this.heightMap.keySet(); - } - - public HeightMap b(HeightMap.Type heightmap_type) { - return (HeightMap) this.heightMap.get(heightmap_type); + @Override + public Collection> f() { + return Collections.unmodifiableSet(this.heightMap.entrySet()); } public Map getTileEntities() { @@ -1339,138 +820,135 @@ public class Chunk implements IChunkAccess { return this.entitySlices; } - public NBTTagCompound g(BlockPosition blockposition) { - return (NBTTagCompound) this.h.get(blockposition); + @Override + public NBTTagCompound i(BlockPosition blockposition) { + return (NBTTagCompound) this.e.get(blockposition); } - public TickList k() { - return this.s; + @Override + public Stream m() { + return StreamSupport.stream(BlockPosition.b(this.loc.d(), 0, this.loc.e(), this.loc.f(), 255, this.loc.g()).spliterator(), false).filter((blockposition) -> { + return this.getType(blockposition).h() != 0; + }); } - public TickList l() { - return this.t; + @Override + public TickList n() { + return this.o; } - public BitSet a(WorldGenStage.Features worldgenstage_features) { - throw new RuntimeException("Not yet implemented"); + @Override + public TickList o() { + return this.p; } - public void a(boolean flag) { - this.x = flag; + @Override + public void setNeedsSaving(boolean flag) { + this.s = flag; } - public void f(boolean flag) { - this.v = flag; + @Override + public boolean isNeedsSaving() { + return (this.s || this.q && this.world.getTime() != this.lastSaved) && !this.mustNotSave; // CraftBukkit } + public void d(boolean flag) { + this.q = flag; + } + + @Override public void setLastSaved(long i) { this.lastSaved = i; } @Nullable + @Override public StructureStart a(String s) { - return (StructureStart) this.p.get(s); + return (StructureStart) this.l.get(s); } + @Override public void a(String s, StructureStart structurestart) { - this.p.put(s, structurestart); + this.l.put(s, structurestart); } - public Map e() { - return this.p; + @Override + public Map h() { + return this.l; } + @Override public void a(Map map) { - this.p.clear(); - this.p.putAll(map); + this.l.clear(); + this.l.putAll(map); } - @Nullable + @Override public LongSet b(String s) { - return (LongSet) this.q.computeIfAbsent(s, (s1) -> { + return (LongSet) this.m.computeIfAbsent(s, (s1) -> { return new LongOpenHashSet(); }); } + @Override public void a(String s, long i) { - ((LongSet) this.q.computeIfAbsent(s, (s1) -> { + ((LongSet) this.m.computeIfAbsent(s, (s1) -> { return new LongOpenHashSet(); })).add(i); } - public Map f() { - return this.q; + @Override + public Map v() { + return this.m; } + @Override public void b(Map map) { - this.q.clear(); - this.q.putAll(map); + this.m.clear(); + this.m.putAll(map); } - public int D() { - return this.y; - } - - public long m() { - return world.paperConfig.fixedInhabitedTime < 0 ? this.z : world.paperConfig.fixedInhabitedTime; // Paper + @Override + public long q() { + return world.paperConfig.fixedInhabitedTime < 0 ? this.t : world.paperConfig.fixedInhabitedTime; // Paper } + @Override public void b(long i) { - this.z = i; + this.t = i; } - public void E() { - if (!this.C.a(ChunkStatus.POSTPROCESSED) && this.D == 8) { - ChunkCoordIntPair chunkcoordintpair = this.getPos(); + public void A() { + ChunkCoordIntPair chunkcoordintpair = this.getPos(); - for (int i = 0; i < this.r.length; ++i) { - if (this.r[i] != null) { - ShortListIterator shortlistiterator = this.r[i].iterator(); + for (int i = 0; i < this.n.length; ++i) { + if (this.n[i] != null) { + ShortListIterator shortlistiterator = this.n[i].iterator(); - while (shortlistiterator.hasNext()) { - Short oshort = (Short) shortlistiterator.next(); - BlockPosition blockposition = ProtoChunk.a(oshort, i, chunkcoordintpair); - IBlockData iblockdata = this.world.getType(blockposition); - IBlockData iblockdata1 = Block.b(iblockdata, this.world, blockposition); + while (shortlistiterator.hasNext()) { + Short oshort = (Short) shortlistiterator.next(); + BlockPosition blockposition = ProtoChunk.a(oshort, i, chunkcoordintpair); + IBlockData iblockdata = this.getType(blockposition); + IBlockData iblockdata1 = Block.b(iblockdata, (GeneratorAccess) this.world, blockposition); - this.world.setTypeAndData(blockposition, iblockdata1, 20); - } - - this.r[i].clear(); + this.world.setTypeAndData(blockposition, iblockdata1, 20); } + + this.n[i].clear(); } - - if (this.s instanceof ProtoChunkTickList) { - ((ProtoChunkTickList) this.s).a(this.world.getBlockTickList(), (blockposition1) -> { // CraftBukkit - decompile error - return this.world.getType(blockposition1).getBlock(); - }); - } - - if (this.t instanceof ProtoChunkTickList) { - ((ProtoChunkTickList) this.t).a(this.world.getFluidTickList(), (blockposition1) -> { // CraftBukkit - decompile error - return this.world.getFluid(blockposition1).c(); - }); - } - - Iterator iterator = (new HashSet(this.h.keySet())).iterator(); - - while (iterator.hasNext()) { - BlockPosition blockposition1 = (BlockPosition) iterator.next(); - - this.getTileEntity(blockposition1); - } - - this.h.clear(); - this.a(ChunkStatus.POSTPROCESSED); - this.m.a(this); - // Paper start - resend chunk after post process - PlayerChunk playerChunk = ((WorldServer) world).getPlayerChunkMap().getChunk(locX, locZ); - if (playerChunk != null) { - playerChunk.done = false; - playerChunk.sendAll(); - } - // Paper end } + + this.B(); + Iterator iterator = Sets.newHashSet(this.e.keySet()).iterator(); + + while (iterator.hasNext()) { + BlockPosition blockposition1 = (BlockPosition) iterator.next(); + + this.getTileEntity(blockposition1); + } + + this.e.clear(); + this.i.a(this); } @Nullable @@ -1481,10 +959,10 @@ public class Chunk implements IChunkAccess { Block block = this.getType(blockposition).getBlock(); if (block instanceof ITileEntity) { - tileentity = ((ITileEntity) block).a(this.world); + tileentity = ((ITileEntity) block).createTile(this.world); } else { tileentity = null; - Chunk.d.warn("Tried to load a DUMMY block entity @ {} but found not block entity block {} at location", blockposition, this.getType(blockposition)); + Chunk.LOGGER.warn("Tried to load a DUMMY block entity @ {} but found not block entity block {} at location", blockposition, this.getType(blockposition)); } } else { tileentity = TileEntity.create(nbttagcompound); @@ -1494,74 +972,84 @@ public class Chunk implements IChunkAccess { tileentity.setPosition(blockposition); this.a(tileentity); } else { - Chunk.d.warn("Tried to load a block entity for block {} but failed at location {}", this.getType(blockposition), blockposition); + Chunk.LOGGER.warn("Tried to load a block entity for block {} but failed at location {}", this.getType(blockposition), blockposition); } return tileentity; } - public ChunkConverter F() { - return this.m; + @Override + public ChunkConverter p() { + return this.i; } - public ShortList[] G() { - return this.r; + @Override + public ShortList[] l() { + return this.n; } - public void a(short short0, int i) { - ProtoChunk.a(this.r, i).add(short0); - } - - public ChunkStatus i() { - return this.C; - } - - public void a(ChunkStatus chunkstatus) { - this.C = chunkstatus; - } - - public void c(String s) { - this.a(ChunkStatus.a(s)); - } - - public void H() { - ++this.D; - if (this.D > 8) { - throw new RuntimeException("Error while adding chunk to cache. Too many neighbors"); - } else { - if (this.J()) { - ((IAsyncTaskHandler) this.world).postToMainThread(this::E); - } - + public void B() { + if (this.o instanceof ProtoChunkTickList) { + ((ProtoChunkTickList) this.o).a(this.world.getBlockTickList(), (blockposition) -> { // CraftBukkit - decompile error + return this.getType(blockposition).getBlock(); + }); + this.o = TickListEmpty.b(); + } else if (this.o instanceof TickListChunk) { + this.world.getBlockTickList().a(((TickListChunk) this.o).b()); + this.o = TickListEmpty.b(); } + + if (this.p instanceof ProtoChunkTickList) { + ((ProtoChunkTickList) this.p).a(this.world.getFluidTickList(), (blockposition) -> { // CraftBukkit - decompile error + return this.getFluid(blockposition).getType(); + }); + this.p = TickListEmpty.b(); + } else if (this.p instanceof TickListChunk) { + this.world.getFluidTickList().a(((TickListChunk) this.p).b()); + this.p = TickListEmpty.b(); + } + } - public void I() { - --this.D; - if (this.D < 0) { - throw new RuntimeException("Error while removing chunk from cache. Not enough neighbors"); + public void a(WorldServer worldserver) { + if (this.o == TickListEmpty.b()) { // CraftBukkit - decompile error + this.o = new TickListChunk<>(IRegistry.BLOCK::getKey, worldserver.getBlockTickList().a(this.loc, true, false)); + this.setNeedsSaving(true); } + + if (this.p == TickListEmpty.b()) { // CraftBukkit - decompile error + this.p = new TickListChunk<>(IRegistry.FLUID::getKey, worldserver.getFluidTickList().a(this.loc, true, false)); + this.setNeedsSaving(true); + } + } - public boolean J() { - return this.D == 8; + @Override + public ChunkStatus getChunkStatus() { + return ChunkStatus.FULL; } - // Paper start - public void runOrQueueLightUpdate(Runnable runnable) { - // Akarin start - if (AkarinGlobalConfig.enableAsyncLighting) { - AkarinAsyncExecutor.scheduleAsyncTask(runnable); - return; - } - // Akarin end - if (this.world.paperConfig.queueLightUpdates) { - lightingQueue.add(runnable); - } else { - runnable.run(); - } + public PlayerChunk.State getState() { + return this.u == null ? PlayerChunk.State.BORDER : (PlayerChunk.State) this.u.get(); + } + + public void a(Supplier supplier) { + this.u = supplier; + } + + @Override + public void a(LightEngine lightengine) {} + + @Override + public boolean r() { + return this.x; + } + + @Override + public void b(boolean flag) { + this.x = flag; + this.setNeedsSaving(true); } - // Paper end public static enum EnumTileEntityState { diff --git a/src/main/java/net/minecraft/server/ChunkCache.java b/src/main/java/net/minecraft/server/ChunkCache.java index eef3ab73f..beb50d206 100644 --- a/src/main/java/net/minecraft/server/ChunkCache.java +++ b/src/main/java/net/minecraft/server/ChunkCache.java @@ -1,220 +1,178 @@ package net.minecraft.server; -import java.util.function.Predicate; import javax.annotation.Nullable; -public class ChunkCache implements IIBlockAccess { +public class ChunkCache implements IWorldReader { - protected int a; - protected int b; - protected Chunk[][] c; + protected final int a; + protected final int b; + protected final IChunkAccess[][] c; protected boolean d; - protected World e; + protected final World e; - public ChunkCache(World world, BlockPosition blockposition, BlockPosition blockposition1, int i) { + public ChunkCache(World world, BlockPosition blockposition, BlockPosition blockposition1) { this.e = world; - this.a = blockposition.getX() - i >> 4; - this.b = blockposition.getZ() - i >> 4; - int j = blockposition1.getX() + i >> 4; - int k = blockposition1.getZ() + i >> 4; + this.a = blockposition.getX() >> 4; + this.b = blockposition.getZ() >> 4; + int i = blockposition1.getX() >> 4; + int j = blockposition1.getZ() >> 4; - this.c = new Chunk[j - this.a + 1][k - this.b + 1]; + this.c = new IChunkAccess[i - this.a + 1][j - this.b + 1]; this.d = true; + int k; int l; - int i1; - for (l = this.a; l <= j; ++l) { - for (i1 = this.b; i1 <= k; ++i1) { - this.c[l - this.a][i1 - this.b] = world.getChunkIfLoaded(l, i1); // Paper + for (k = this.a; k <= i; ++k) { + for (l = this.b; l <= j; ++l) { + this.c[k - this.a][l - this.b] = world.getChunkIfLoadedImmediately(k, l); // Paper } } - for (l = blockposition.getX() >> 4; l <= blockposition1.getX() >> 4; ++l) { - for (i1 = blockposition.getZ() >> 4; i1 <= blockposition1.getZ() >> 4; ++i1) { - Chunk chunk = this.c[l - this.a][i1 - this.b]; + for (k = blockposition.getX() >> 4; k <= blockposition1.getX() >> 4; ++k) { + for (l = blockposition.getZ() >> 4; l <= blockposition1.getZ() >> 4; ++l) { + IChunkAccess ichunkaccess = this.c[k - this.a][l - this.b]; - if (chunk != null && !chunk.b(blockposition.getY(), blockposition1.getY())) { + if (ichunkaccess != null && !ichunkaccess.a(blockposition.getY(), blockposition1.getY())) { this.d = false; + return; } } } } - @Nullable - public TileEntity getTileEntity(BlockPosition blockposition) { - return this.a(blockposition, Chunk.EnumTileEntityState.IMMEDIATE); - } - - @Nullable - public TileEntity a(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) { - int i = (blockposition.getX() >> 4) - this.a; - int j = (blockposition.getZ() >> 4) - this.b; - - return this.c[i][j].a(blockposition, chunk_enumtileentitystate); - } - - public float A(BlockPosition blockposition) { - return this.e.worldProvider.i()[this.getLightLevel(blockposition)]; - } - - public int d(BlockPosition blockposition, int i) { - if (this.getType(blockposition).c(this, blockposition)) { - int j = 0; - EnumDirection[] aenumdirection = EnumDirection.values(); - int k = aenumdirection.length; - - for (int l = 0; l < k; ++l) { - EnumDirection enumdirection = aenumdirection[l]; - int i1 = this.getLightLevel(blockposition.shift(enumdirection), i); - - if (i1 > j) { - j = i1; - } - - if (j >= 15) { - return j; - } - } - - return j; - } else { - return this.getLightLevel(blockposition, i); - } - } - - public WorldProvider o() { - return this.e.o(); - } - + @Override public int getLightLevel(BlockPosition blockposition, int i) { - if (blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() <= 30000000) { - if (blockposition.getY() < 0) { - return 0; - } else { - int j; + return this.e.getLightLevel(blockposition, i); + } - if (blockposition.getY() >= 256) { - j = 15 - i; - if (j < 0) { - j = 0; - } - - return j; - } else { - j = (blockposition.getX() >> 4) - this.a; - int k = (blockposition.getZ() >> 4) - this.b; - - return this.c[j][k].a(blockposition, i); - } - } - } else { - return 15; + // Paper start - if loaded util + @Nullable + @Override + public IChunkAccess getChunkIfLoadedImmediately(int x, int z) { + IChunkAccess chunk = this.getChunkAt(x, z, ChunkStatus.FULL, false); + if (chunk instanceof ChunkEmpty) { + return null; } + return chunk; } - public boolean isChunkLoaded(int i, int j, boolean flag) { - return this.a(i, j); + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + return chunk == null ? null : chunk.getFluid(blockposition); } - public boolean e(BlockPosition blockposition) { - return false; + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + return chunk == null ? null : chunk.getType(blockposition); } + // Paper end - public boolean a(int i, int j) { + @Nullable + @Override + public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { int k = i - this.a; int l = j - this.b; - return k >= 0 && k < this.c.length && l >= 0 && l < this.c[k].length; + if (k >= 0 && k < this.c.length && l >= 0 && l < this.c[k].length) { + IChunkAccess ichunkaccess = this.c[k][l]; + + return (IChunkAccess) (ichunkaccess != null ? ichunkaccess : new ChunkEmpty(this.e, new ChunkCoordIntPair(i, j))); + } else { + return new ChunkEmpty(this.e, new ChunkCoordIntPair(i, j)); + } } + @Override + public boolean isChunkLoaded(int i, int j) { + int k = i - this.a; + int l = j - this.b; + + return k >= 0 && k < this.c.length && l >= 0 && l < this.c[k].length && this.c[k][l] != null; // Paper - We don't always load chunks + } + + @Override + public BlockPosition getHighestBlockYAt(HeightMap.Type heightmap_type, BlockPosition blockposition) { + return this.e.getHighestBlockYAt(heightmap_type, blockposition); + } + + @Override public int a(HeightMap.Type heightmap_type, int i, int j) { - throw new RuntimeException("NOT IMPLEMENTED!"); + return this.e.a(heightmap_type, i, j); } + @Override + public int c() { + return this.e.c(); + } + + @Override public WorldBorder getWorldBorder() { return this.e.getWorldBorder(); } + @Override public boolean a(@Nullable Entity entity, VoxelShape voxelshape) { - throw new RuntimeException("This method should never be called here. No entity logic inside Region"); + return true; + } + + @Override + public boolean e() { + return false; + } + + @Override + public int getSeaLevel() { + return this.e.getSeaLevel(); + } + + @Override + public WorldProvider getWorldProvider() { + return this.e.getWorldProvider(); } @Nullable - public EntityHuman a(double d0, double d1, double d2, double d3, Predicate predicate) { - throw new RuntimeException("This method should never be called here. No entity logic inside Region"); + @Override + public TileEntity getTileEntity(BlockPosition blockposition) { + IChunkAccess ichunkaccess = this.w(blockposition); + + return ichunkaccess.getTileEntity(blockposition); } + @Override public IBlockData getType(BlockPosition blockposition) { - if (blockposition.getY() >= 0 && blockposition.getY() < 256) { - int i = (blockposition.getX() >> 4) - this.a; - int j = (blockposition.getZ() >> 4) - this.b; - - if (i >= 0 && i < this.c.length && j >= 0 && j < this.c[i].length) { - Chunk chunk = this.c[i][j]; - - if (chunk != null) { - return chunk.getType(blockposition); - } - } - } - - return Blocks.AIR.getBlockData(); - } - - public Fluid getFluid(BlockPosition blockposition) { - if (blockposition.getY() >= 0 && blockposition.getY() < 256) { - int i = (blockposition.getX() >> 4) - this.a; - int j = (blockposition.getZ() >> 4) - this.b; - - if (i >= 0 && i < this.c.length && j >= 0 && j < this.c[i].length) { - Chunk chunk = this.c[i][j]; - - if (chunk != null) { - return chunk.getFluid(blockposition); - } - } - } - - return FluidTypes.EMPTY.i(); - } - - public int c() { - return 0; - } - - public BiomeBase getBiome(BlockPosition blockposition) { - int i = (blockposition.getX() >> 4) - this.a; - int j = (blockposition.getZ() >> 4) - this.b; - - return this.c[i][j].getBiome(blockposition); - } - - public boolean isEmpty(BlockPosition blockposition) { - return this.getType(blockposition).isAir(); - } - - public int getBrightness(EnumSkyBlock enumskyblock, BlockPosition blockposition) { - if (blockposition.getY() >= 0 && blockposition.getY() < 256) { - int i = (blockposition.getX() >> 4) - this.a; - int j = (blockposition.getZ() >> 4) - this.b; - - return this.c[i][j].getBrightness(enumskyblock, blockposition); + if (World.isOutsideWorld(blockposition)) { + return Blocks.AIR.getBlockData(); } else { - return enumskyblock.c; + IChunkAccess ichunkaccess = this.w(blockposition); + + return ichunkaccess.getType(blockposition); } } - public int a(BlockPosition blockposition, EnumDirection enumdirection) { - return this.getType(blockposition).b((IBlockAccess) this, blockposition, enumdirection); + @Override + public Fluid getFluid(BlockPosition blockposition) { + if (World.isOutsideWorld(blockposition)) { + return FluidTypes.EMPTY.i(); + } else { + IChunkAccess ichunkaccess = this.w(blockposition); + + return ichunkaccess.getFluid(blockposition); + } } - public boolean e() { - throw new RuntimeException("Not yet implemented"); + @Override + public BiomeBase getBiome(BlockPosition blockposition) { + IChunkAccess ichunkaccess = this.w(blockposition); + + return ichunkaccess.getBiome(blockposition); } - public int getSeaLevel() { - throw new RuntimeException("Not yet implemented"); + @Override + public int getBrightness(EnumSkyBlock enumskyblock, BlockPosition blockposition) { + return this.e.getBrightness(enumskyblock, blockposition); } } diff --git a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java index d2cece265..bbf136614 100644 --- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java +++ b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java @@ -1,7 +1,14 @@ package net.minecraft.server; +import java.util.Spliterators.AbstractSpliterator; +import java.util.function.Consumer; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import javax.annotation.Nullable; + public class ChunkCoordIntPair { + public static final long a = pair(1875016, 1875016); public final int x; public final int z; @@ -20,22 +27,21 @@ public class ChunkCoordIntPair { this.z = (int) (i >> 32); } - public long asLong() { return a(); } // Paper - public long a() { - return a(this.x, this.z); + public long pair() { + return pair(this.x, this.z); } - public static long asLong(final BlockPosition pos) { return a(pos.getX() >> 4, pos.getZ() >> 4); } // Paper - OBFHELPER - public static long asLong(int x, int z) { return a(x, z); } // Paper - OBFHELPER - public static long a(int i, int j) { + public static long asLong(final BlockPosition pos) { return pair(pos.getX() >> 4, pos.getZ() >> 4); } // Paper - OBFHELPER + public static long asLong(int x, int z) { return pair(x, z); } // Paper - OBFHELPER + public static long pair(int i, int j) { return (long) i & 4294967295L | ((long) j & 4294967295L) << 32; } - public static int a(long i) { + public static int getX(long i) { return (int) (i & 4294967295L); } - public static int b(long i) { + public static int getZ(long i) { return (int) (i >>> 32 & 4294967295L); } @@ -58,15 +64,6 @@ public class ChunkCoordIntPair { } } - public double a(Entity entity) { - double d0 = (double) (this.x * 16 + 8); - double d1 = (double) (this.z * 16 + 8); - double d2 = d0 - entity.locX; - double d3 = d1 - entity.locZ; - - return d2 * d2 + d3 * d3; - } - public int d() { return this.x << 4; } @@ -83,6 +80,22 @@ public class ChunkCoordIntPair { return (this.z << 4) + 15; } + public int getRegionX() { + return this.x >> 5; + } + + public int getRegionZ() { + return this.z >> 5; + } + + public int j() { + return this.x & 31; + } + + public int k() { + return this.z & 31; + } + public BlockPosition a(int i, int j, int k) { return new BlockPosition((this.x << 4) + i, j, (this.z << 4) + k); } @@ -91,7 +104,45 @@ public class ChunkCoordIntPair { return "[" + this.x + ", " + this.z + "]"; } - public BlockPosition h() { + public BlockPosition l() { return new BlockPosition(this.x << 4, 0, this.z << 4); } + + public static Stream a(ChunkCoordIntPair chunkcoordintpair, int i) { + return a(new ChunkCoordIntPair(chunkcoordintpair.x - i, chunkcoordintpair.z - i), new ChunkCoordIntPair(chunkcoordintpair.x + i, chunkcoordintpair.z + i)); + } + + public static Stream a(final ChunkCoordIntPair chunkcoordintpair, final ChunkCoordIntPair chunkcoordintpair1) { + int i = Math.abs(chunkcoordintpair.x - chunkcoordintpair1.x) + 1; + int j = Math.abs(chunkcoordintpair.z - chunkcoordintpair1.z) + 1; + final int k = chunkcoordintpair.x < chunkcoordintpair1.x ? 1 : -1; + final int l = chunkcoordintpair.z < chunkcoordintpair1.z ? 1 : -1; + + return StreamSupport.stream(new AbstractSpliterator((long) (i * j), 64) { + @Nullable + private ChunkCoordIntPair e; + + public boolean tryAdvance(Consumer consumer) { + if (this.e == null) { + this.e = chunkcoordintpair; + } else { + int i1 = this.e.x; + int j1 = this.e.z; + + if (i1 == chunkcoordintpair1.x) { + if (j1 == chunkcoordintpair1.z) { + return false; + } + + this.e = new ChunkCoordIntPair(chunkcoordintpair.x, j1 + l); + } else { + this.e = new ChunkCoordIntPair(i1 + k, j1); + } + } + + consumer.accept(this.e); + return true; + } + }, false); + } } diff --git a/src/main/java/net/minecraft/server/ChunkGenerator.java b/src/main/java/net/minecraft/server/ChunkGenerator.java index 0c9583834..701b214bf 100644 --- a/src/main/java/net/minecraft/server/ChunkGenerator.java +++ b/src/main/java/net/minecraft/server/ChunkGenerator.java @@ -1,45 +1,225 @@ package net.minecraft.server; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.LongSet; +import java.util.BitSet; +import java.util.Iterator; import java.util.List; +import java.util.ListIterator; +import java.util.Locale; +import java.util.Map.Entry; import javax.annotation.Nullable; -public interface ChunkGenerator { +public abstract class ChunkGenerator { - void createChunk(IChunkAccess ichunkaccess); + protected final GeneratorAccess a; + protected final long seed; + protected final WorldChunkManager c; + protected final C settings; - void addFeatures(RegionLimitedWorldAccess regionlimitedworldaccess, WorldGenStage.Features worldgenstage_features); + public ChunkGenerator(GeneratorAccess generatoraccess, WorldChunkManager worldchunkmanager, C c0) { + this.a = generatoraccess; + this.seed = generatoraccess.getSeed(); + this.c = worldchunkmanager; + this.settings = c0; + } - void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess); + public void createBiomes(IChunkAccess ichunkaccess) { + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + int i = chunkcoordintpair.x; + int j = chunkcoordintpair.z; + BiomeBase[] abiomebase = this.c.getBiomeBlock(i * 16, j * 16, 16, 16); - void addMobs(RegionLimitedWorldAccess regionlimitedworldaccess); + ichunkaccess.a(abiomebase); + } - List getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition); + protected BiomeBase getCarvingBiome(IChunkAccess ichunkaccess) { + return ichunkaccess.getBiome(BlockPosition.ZERO); + } + + protected BiomeBase getDecoratingBiome(RegionLimitedWorldAccess regionlimitedworldaccess, BlockPosition blockposition) { + return this.c.getBiome(blockposition); + } + + public void doCarving(IChunkAccess ichunkaccess, WorldGenStage.Features worldgenstage_features) { + SeededRandom seededrandom = new SeededRandom(); + boolean flag = true; + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + int i = chunkcoordintpair.x; + int j = chunkcoordintpair.z; + BitSet bitset = ichunkaccess.a(worldgenstage_features); + + for (int k = i - 8; k <= i + 8; ++k) { + for (int l = j - 8; l <= j + 8; ++l) { + List> list = this.getCarvingBiome(ichunkaccess).a(worldgenstage_features); + ListIterator listiterator = list.listIterator(); + + while (listiterator.hasNext()) { + int i1 = listiterator.nextIndex(); + WorldGenCarverWrapper worldgencarverwrapper = (WorldGenCarverWrapper) listiterator.next(); + + seededrandom.c(this.seed + (long) i1, k, l); + if (worldgencarverwrapper.a(seededrandom, k, l)) { + worldgencarverwrapper.a(ichunkaccess, seededrandom, this.getSeaLevel(), k, l, i, j, bitset); + } + } + } + } + + } @Nullable - BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockposition, int i, boolean flag); + public BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockposition, int i, boolean flag) { + StructureGenerator structuregenerator = (StructureGenerator) WorldGenerator.aP.get(s.toLowerCase(Locale.ROOT)); - C getSettings(); + return structuregenerator != null ? structuregenerator.getNearestGeneratedFeature(world, this, blockposition, i, flag) : null; + } - int a(World world, boolean flag, boolean flag1); + public void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess) { + int i = regionlimitedworldaccess.a(); + int j = regionlimitedworldaccess.b(); + int k = i * 16; + int l = j * 16; + BlockPosition blockposition = new BlockPosition(k, 0, l); + BiomeBase biomebase = this.getDecoratingBiome(regionlimitedworldaccess, blockposition.b(8, 8, 8)); + SeededRandom seededrandom = new SeededRandom(); + long i1 = seededrandom.a(regionlimitedworldaccess.getSeed(), k, l); + WorldGenStage.Decoration[] aworldgenstage_decoration = WorldGenStage.Decoration.values(); + int j1 = aworldgenstage_decoration.length; - boolean canSpawnStructure(BiomeBase biomebase, StructureGenerator structuregenerator); + for (int k1 = 0; k1 < j1; ++k1) { + WorldGenStage.Decoration worldgenstage_decoration = aworldgenstage_decoration[k1]; + + try { + biomebase.a(worldgenstage_decoration, this, regionlimitedworldaccess, i1, seededrandom, blockposition); + } catch (Exception exception) { + CrashReport crashreport = CrashReport.a(exception, "Biome decoration"); + + crashreport.a("Generation").a("CenterX", (Object) i).a("CenterZ", (Object) j).a("Step", (Object) worldgenstage_decoration).a("Seed", (Object) i1).a("Biome", (Object) IRegistry.BIOME.getKey(biomebase)); + throw new ReportedException(crashreport); + } + } + + } + + public abstract void buildBase(IChunkAccess ichunkaccess); + + public void addMobs(RegionLimitedWorldAccess regionlimitedworldaccess) {} + + public C getSettings() { + return this.settings; + } + + public abstract int getSpawnHeight(); + + public void doMobSpawning(WorldServer worldserver, boolean flag, boolean flag1) {} + + public boolean canSpawnStructure(BiomeBase biomebase, StructureGenerator structuregenerator) { + return biomebase.a(structuregenerator); + } @Nullable - WorldGenFeatureConfiguration getFeatureConfiguration(BiomeBase biomebase, StructureGenerator structuregenerator); + public C getFeatureConfiguration(BiomeBase biomebase, StructureGenerator structuregenerator) { + return biomebase.b(structuregenerator); + } - Long2ObjectMap getStructureStartCache(StructureGenerator structuregenerator); + public WorldChunkManager getWorldChunkManager() { + return this.c; + } - Long2ObjectMap getStructureCache(StructureGenerator structuregenerator); + public long getSeed() { + return this.seed; + } - WorldChunkManager getWorldChunkManager(); + public int getGenerationDepth() { + return 256; + } - long getSeed(); + public List getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { + return this.a.getBiome(blockposition).getMobs(enumcreaturetype); + } - int getSpawnHeight(); + public void createStructures(IChunkAccess ichunkaccess, ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager) { + Iterator iterator = WorldGenerator.aP.values().iterator(); - int getGenerationDepth(); + while (iterator.hasNext()) { + StructureGenerator structuregenerator = (StructureGenerator) iterator.next(); - World getWorld(); // Spigot + if (chunkgenerator.getWorldChunkManager().a(structuregenerator)) { + SeededRandom seededrandom = new SeededRandom(); + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + StructureStart structurestart = StructureStart.a; + + // CraftBukkit start + if (structuregenerator == WorldGenerator.STRONGHOLD) { + synchronized (structuregenerator) { + if (structuregenerator.a(chunkgenerator, seededrandom, chunkcoordintpair.x, chunkcoordintpair.z)) { + BiomeBase biomebase = this.getWorldChunkManager().getBiome(new BlockPosition(chunkcoordintpair.d() + 9, 0, chunkcoordintpair.e() + 9)); + StructureStart structurestart1 = structuregenerator.a().create(structuregenerator, chunkcoordintpair.x, chunkcoordintpair.z, biomebase, StructureBoundingBox.a(), 0, chunkgenerator.getSeed()); + + structurestart1.a(this, definedstructuremanager, chunkcoordintpair.x, chunkcoordintpair.z, biomebase); + structurestart = structurestart1.e() ? structurestart1 : StructureStart.a; + } + } + } else + // CraftBukkit end + if (structuregenerator.a(chunkgenerator, seededrandom, chunkcoordintpair.x, chunkcoordintpair.z)) { + BiomeBase biomebase = this.getWorldChunkManager().getBiome(new BlockPosition(chunkcoordintpair.d() + 9, 0, chunkcoordintpair.e() + 9)); + StructureStart structurestart1 = structuregenerator.a().create(structuregenerator, chunkcoordintpair.x, chunkcoordintpair.z, biomebase, StructureBoundingBox.a(), 0, chunkgenerator.getSeed()); + + structurestart1.a(this, definedstructuremanager, chunkcoordintpair.x, chunkcoordintpair.z, biomebase); + structurestart = structurestart1.e() ? structurestart1 : StructureStart.a; + } + + ichunkaccess.a(structuregenerator.b(), structurestart); + } + } + + } + + public void storeStructures(GeneratorAccess generatoraccess, IChunkAccess ichunkaccess) { + boolean flag = true; + int i = ichunkaccess.getPos().x; + int j = ichunkaccess.getPos().z; + int k = i << 4; + int l = j << 4; + + for (int i1 = i - 8; i1 <= i + 8; ++i1) { + for (int j1 = j - 8; j1 <= j + 8; ++j1) { + long k1 = ChunkCoordIntPair.pair(i1, j1); + Iterator iterator = generatoraccess.getChunkAt(i1, j1).h().entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + StructureStart structurestart = (StructureStart) entry.getValue(); + + if (structurestart != StructureStart.a && structurestart.c().a(k, l, k + 15, l + 15)) { + ichunkaccess.a((String) entry.getKey(), k1); + PacketDebug.a(generatoraccess, structurestart); + } + } + } + } + + } + + public abstract void buildNoise(GeneratorAccess generatoraccess, IChunkAccess ichunkaccess); + + public int getSeaLevel() { + return 63; + } + + public abstract int getBaseHeight(int i, int j, HeightMap.Type heightmap_type); + + public int b(int i, int j, HeightMap.Type heightmap_type) { + return this.getBaseHeight(i, j, heightmap_type); + } + + public int c(int i, int j, HeightMap.Type heightmap_type) { + return this.getBaseHeight(i, j, heightmap_type) - 1; + } + + // Spigot start + public World getWorld() { + return this.a.getMinecraftWorld(); + } + // Spigot end } diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java index 835a2aae4..338b67c3c 100644 --- a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java +++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java @@ -1,51 +1,223 @@ package net.minecraft.server; -import com.google.common.collect.Maps; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; -import it.unimi.dsi.fastutil.longs.LongSet; -import java.util.BitSet; +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectList; +import it.unimi.dsi.fastutil.objects.ObjectListIterator; import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Locale; -import java.util.Map; import java.util.Random; -import javax.annotation.Nullable; -public abstract class ChunkGeneratorAbstract implements ChunkGenerator { +public abstract class ChunkGeneratorAbstract extends ChunkGenerator { - protected final GeneratorAccess a; - protected final long b; - protected final WorldChunkManager c; - protected final Map, Long2ObjectMap> d = Maps.newHashMap(); - protected final Map, Long2ObjectMap> e = Maps.newHashMap(); + private static final float[] h = (float[]) SystemUtils.a((new float[13824]), (afloat) -> { + for (int i = 0; i < 24; ++i) { + for (int j = 0; j < 24; ++j) { + for (int k = 0; k < 24; ++k) { + afloat[i * 24 * 24 + j * 24 + k] = (float) b(j - 12, k - 12, i - 12); + } + } + } - public ChunkGeneratorAbstract(GeneratorAccess generatoraccess, WorldChunkManager worldchunkmanager) { - this.a = generatoraccess; - this.b = generatoraccess.getSeed(); - this.c = worldchunkmanager; + }); + private static final IBlockData i = Blocks.AIR.getBlockData(); + private final int j; + private final int k; + private final int l; + private final int m; + private final int n; + protected final SeededRandom e; + private final NoiseGeneratorOctaves o; + private final NoiseGeneratorOctaves p; + private final NoiseGeneratorOctaves q; + private final NoiseGenerator r; + protected final IBlockData f; + protected final IBlockData g; + + public ChunkGeneratorAbstract(GeneratorAccess generatoraccess, WorldChunkManager worldchunkmanager, int i, int j, int k, T t0, boolean flag) { + super(generatoraccess, worldchunkmanager, t0); + this.j = j; + this.k = i; + this.f = t0.r(); + this.g = t0.s(); + this.l = 16 / this.k; + this.m = k / this.j; + this.n = 16 / this.k; + this.e = new SeededRandom(this.seed); + this.o = new NoiseGeneratorOctaves(this.e, 16); + this.p = new NoiseGeneratorOctaves(this.e, 16); + this.q = new NoiseGeneratorOctaves(this.e, 8); + this.r = (NoiseGenerator) (flag ? new NoiseGenerator3(this.e, 4) : new NoiseGeneratorOctaves(this.e, 4)); } - public void addFeatures(RegionLimitedWorldAccess regionlimitedworldaccess, WorldGenStage.Features worldgenstage_features) { - SeededRandom seededrandom = new SeededRandom(this.b); - boolean flag = true; - int i = regionlimitedworldaccess.a(); - int j = regionlimitedworldaccess.b(); - BitSet bitset = regionlimitedworldaccess.getChunkAt(i, j).a(worldgenstage_features); + private double a(int i, int j, int k, double d0, double d1, double d2, double d3) { + double d4 = 0.0D; + double d5 = 0.0D; + double d6 = 0.0D; + double d7 = 1.0D; - for (int k = i - 8; k <= i + 8; ++k) { - for (int l = j - 8; l <= j + 8; ++l) { - List> list = regionlimitedworldaccess.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(new BlockPosition(k * 16, 0, l * 16), (BiomeBase) null).a(worldgenstage_features); - ListIterator listiterator = list.listIterator(); + for (int l = 0; l < 16; ++l) { + double d8 = NoiseGeneratorOctaves.a((double) i * d0 * d7); + double d9 = NoiseGeneratorOctaves.a((double) j * d1 * d7); + double d10 = NoiseGeneratorOctaves.a((double) k * d0 * d7); + double d11 = d1 * d7; - while (listiterator.hasNext()) { - int i1 = listiterator.nextIndex(); - WorldGenCarverWrapper worldgencarverwrapper = (WorldGenCarverWrapper) listiterator.next(); + d4 += this.o.a(l).a(d8, d9, d10, d11, (double) j * d11) / d7; + d5 += this.p.a(l).a(d8, d9, d10, d11, (double) j * d11) / d7; + if (l < 8) { + d6 += this.q.a(l).a(NoiseGeneratorOctaves.a((double) i * d2 * d7), NoiseGeneratorOctaves.a((double) j * d3 * d7), NoiseGeneratorOctaves.a((double) k * d2 * d7), d3 * d7, (double) j * d3 * d7) / d7; + } - seededrandom.c(regionlimitedworldaccess.getMinecraftWorld().getSeed() + (long) i1, k, l); - if (worldgencarverwrapper.a(regionlimitedworldaccess, seededrandom, k, l, WorldGenFeatureConfiguration.e)) { - worldgencarverwrapper.a(regionlimitedworldaccess, seededrandom, k, l, i, j, bitset, WorldGenFeatureConfiguration.e); + d7 /= 2.0D; + } + + return MathHelper.b(d4 / 512.0D, d5 / 512.0D, (d6 / 10.0D + 1.0D) / 2.0D); + } + + protected double[] b(int i, int j) { + double[] adouble = new double[this.m + 1]; + + this.a(adouble, i, j); + return adouble; + } + + protected void a(double[] adouble, int i, int j, double d0, double d1, double d2, double d3, int k, int l) { + double[] adouble1 = this.a(i, j); + double d4 = adouble1[0]; + double d5 = adouble1[1]; + double d6 = this.g(); + double d7 = this.h(); + + for (int i1 = 0; i1 < this.i(); ++i1) { + double d8 = this.a(i, i1, j, d0, d1, d2, d3); + + d8 -= this.a(d4, d5, i1); + if ((double) i1 > d6) { + d8 = MathHelper.b(d8, (double) l, ((double) i1 - d6) / (double) k); + } else if ((double) i1 < d7) { + d8 = MathHelper.b(d8, -30.0D, (d7 - (double) i1) / (d7 - 1.0D)); + } + + adouble[i1] = d8; + } + + } + + protected abstract double[] a(int i, int j); + + protected abstract double a(double d0, double d1, int i); + + protected double g() { + return (double) (this.i() - 4); + } + + protected double h() { + return 0.0D; + } + + @Override + public int getBaseHeight(int i, int j, HeightMap.Type heightmap_type) { + int k = Math.floorDiv(i, this.k); + int l = Math.floorDiv(j, this.k); + int i1 = Math.floorMod(i, this.k); + int j1 = Math.floorMod(j, this.k); + double d0 = (double) i1 / (double) this.k; + double d1 = (double) j1 / (double) this.k; + double[][] adouble = new double[][]{this.b(k, l), this.b(k, l + 1), this.b(k + 1, l), this.b(k + 1, l + 1)}; + int k1 = this.getSeaLevel(); + + for (int l1 = this.m - 1; l1 >= 0; --l1) { + double d2 = adouble[0][l1]; + double d3 = adouble[1][l1]; + double d4 = adouble[2][l1]; + double d5 = adouble[3][l1]; + double d6 = adouble[0][l1 + 1]; + double d7 = adouble[1][l1 + 1]; + double d8 = adouble[2][l1 + 1]; + double d9 = adouble[3][l1 + 1]; + + for (int i2 = this.j - 1; i2 >= 0; --i2) { + double d10 = (double) i2 / (double) this.j; + double d11 = MathHelper.a(d10, d0, d1, d2, d6, d4, d8, d3, d7, d5, d9); + int j2 = l1 * this.j + i2; + + if (d11 > 0.0D || j2 < k1) { + IBlockData iblockdata; + + if (d11 > 0.0D) { + iblockdata = this.f; + } else { + iblockdata = this.g; + } + + if (heightmap_type.d().test(iblockdata)) { + return j2 + 1; + } + } + } + } + + return 0; + } + + protected abstract void a(double[] adouble, int i, int j); + + public int i() { + return this.m + 1; + } + + @Override + public void buildBase(IChunkAccess ichunkaccess) { + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + int i = chunkcoordintpair.x; + int j = chunkcoordintpair.z; + SeededRandom seededrandom = new SeededRandom(); + + seededrandom.a(i, j); + ChunkCoordIntPair chunkcoordintpair1 = ichunkaccess.getPos(); + int k = chunkcoordintpair1.d(); + int l = chunkcoordintpair1.e(); + double d0 = 0.0625D; + BiomeBase[] abiomebase = ichunkaccess.getBiomeIndex(); + + for (int i1 = 0; i1 < 16; ++i1) { + for (int j1 = 0; j1 < 16; ++j1) { + int k1 = k + i1; + int l1 = l + j1; + int i2 = ichunkaccess.a(HeightMap.Type.WORLD_SURFACE_WG, i1, j1) + 1; + double d1 = this.r.a((double) k1 * 0.0625D, (double) l1 * 0.0625D, 0.0625D, (double) i1 * 0.0625D); + + abiomebase[j1 * 16 + i1].a(seededrandom, ichunkaccess, k1, l1, i2, d1, this.getSettings().r(), this.getSettings().s(), this.getSeaLevel(), this.a.getSeed()); + } + } + + this.a(ichunkaccess, seededrandom); + } + + protected void a(IChunkAccess ichunkaccess, Random random) { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + int i = ichunkaccess.getPos().d(); + int j = ichunkaccess.getPos().e(); + T t0 = this.getSettings(); + int k = t0.u(); final int floorHeight = k; // Paper + int l = t0.t(); final int roofHeight = l; // Paper + Iterator iterator = BlockPosition.b(i, 0, j, i + 15, 0, j + 15).iterator(); + + while (iterator.hasNext()) { + BlockPosition blockposition = (BlockPosition) iterator.next(); + int i1; + + if (l > 0) { + for (i1 = l; i1 >= l - 4; --i1) { + if (i1 >= (getWorld().paperConfig.generateFlatBedrock ? roofHeight : l - random.nextInt(5))) { // Paper - Configurable flat bedrock roof + ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false); + } + } + } + + if (k < 256) { + for (i1 = k + 4; i1 >= k; --i1) { + if (i1 <= (getWorld().paperConfig.generateFlatBedrock ? floorHeight : k + random.nextInt(5))) { // Paper - Configurable flat bedrock floor + ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false); } } } @@ -53,113 +225,204 @@ public abstract class ChunkGeneratorAbstract implem } - @Nullable - public BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockposition, int i, boolean flag) { - StructureGenerator structuregenerator = (StructureGenerator) WorldGenerator.aF.get(s.toLowerCase(Locale.ROOT)); - - return structuregenerator != null ? structuregenerator.getNearestGeneratedFeature(world, this, blockposition, i, flag) : null; - } - - protected void a(IChunkAccess ichunkaccess, Random random) { - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - int i = ichunkaccess.getPos().d(); - int j = ichunkaccess.getPos().e(); - Iterator iterator = BlockPosition.a(i, 0, j, i + 16, 0, j + 16).iterator(); + @Override + public void buildNoise(GeneratorAccess generatoraccess, IChunkAccess ichunkaccess) { + int i = this.getSeaLevel(); + ObjectList objectlist = new ObjectArrayList(10); + ObjectList objectlist1 = new ObjectArrayList(32); + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + int j = chunkcoordintpair.x; + int k = chunkcoordintpair.z; + int l = j << 4; + int i1 = k << 4; + Iterator iterator = WorldGenerator.aQ.iterator(); while (iterator.hasNext()) { - BlockPosition blockposition = (BlockPosition) iterator.next(); + StructureGenerator structuregenerator = (StructureGenerator) iterator.next(); + String s = structuregenerator.b(); + LongIterator longiterator = ichunkaccess.b(s).iterator(); - for (int k = 4; k >= 0; --k) { - if (k <= random.nextInt(5)) { - ichunkaccess.setType(blockposition_mutableblockposition.c(blockposition.getX(), k, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false); + while (longiterator.hasNext()) { + long j1 = longiterator.nextLong(); + ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(j1); + IChunkAccess ichunkaccess1 = generatoraccess.getChunkAt(chunkcoordintpair1.x, chunkcoordintpair1.z); + StructureStart structurestart = ichunkaccess1.a(s); + + if (structurestart != null && structurestart.e()) { + Iterator iterator1 = structurestart.d().iterator(); + + while (iterator1.hasNext()) { + StructurePiece structurepiece = (StructurePiece) iterator1.next(); + + if (structurepiece.a(chunkcoordintpair, 12) && structurepiece instanceof WorldGenFeaturePillagerOutpostPoolPiece) { + WorldGenFeaturePillagerOutpostPoolPiece worldgenfeaturepillageroutpostpoolpiece = (WorldGenFeaturePillagerOutpostPoolPiece) structurepiece; + WorldGenFeatureDefinedStructurePoolTemplate.Matching worldgenfeaturedefinedstructurepooltemplate_matching = worldgenfeaturepillageroutpostpoolpiece.b().c(); + + if (worldgenfeaturedefinedstructurepooltemplate_matching == WorldGenFeatureDefinedStructurePoolTemplate.Matching.RIGID) { + objectlist.add(worldgenfeaturepillageroutpostpoolpiece); + } + + Iterator iterator2 = worldgenfeaturepillageroutpostpoolpiece.e().iterator(); + + while (iterator2.hasNext()) { + WorldGenFeatureDefinedStructureJigsawJunction worldgenfeaturedefinedstructurejigsawjunction = (WorldGenFeatureDefinedStructureJigsawJunction) iterator2.next(); + int k1 = worldgenfeaturedefinedstructurejigsawjunction.a(); + int l1 = worldgenfeaturedefinedstructurejigsawjunction.c(); + + if (k1 > l - 12 && l1 > i1 - 12 && k1 < l + 15 + 12 && l1 < i1 + 15 + 12) { + objectlist1.add(worldgenfeaturedefinedstructurejigsawjunction); + } + } + } + } } } } - } + double[][][] adouble = new double[2][this.n + 1][this.m + 1]; - public void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess) { - BlockFalling.instaFall = true; - int i = regionlimitedworldaccess.a(); - int j = regionlimitedworldaccess.b(); - int k = i * 16; - int l = j * 16; - BlockPosition blockposition = new BlockPosition(k, 0, l); - BiomeBase biomebase = regionlimitedworldaccess.getChunkAt(i + 1, j + 1).getBiomeIndex()[0]; - SeededRandom seededrandom = new SeededRandom(); - long i1 = seededrandom.a(regionlimitedworldaccess.getSeed(), k, l); - WorldGenStage.Decoration[] aworldgenstage_decoration = WorldGenStage.Decoration.values(); - int j1 = aworldgenstage_decoration.length; - - for (int k1 = 0; k1 < j1; ++k1) { - WorldGenStage.Decoration worldgenstage_decoration = aworldgenstage_decoration[k1]; - - biomebase.a(worldgenstage_decoration, this, regionlimitedworldaccess, i1, seededrandom, blockposition); + for (int i2 = 0; i2 < this.n + 1; ++i2) { + adouble[0][i2] = new double[this.m + 1]; + this.a(adouble[0][i2], j * this.l, k * this.n + i2); + adouble[1][i2] = new double[this.m + 1]; } - BlockFalling.instaFall = false; - } + ProtoChunk protochunk = (ProtoChunk) ichunkaccess; + HeightMap heightmap = protochunk.b(HeightMap.Type.OCEAN_FLOOR_WG); + HeightMap heightmap1 = protochunk.b(HeightMap.Type.WORLD_SURFACE_WG); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + ObjectListIterator objectlistiterator = objectlist.iterator(); + ObjectListIterator objectlistiterator1 = objectlist1.iterator(); - public void a(IChunkAccess ichunkaccess, BiomeBase[] abiomebase, SeededRandom seededrandom, int i) { - double d0 = 0.03125D; - ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); - int j = chunkcoordintpair.d(); - int k = chunkcoordintpair.e(); - double[] adouble = this.a(chunkcoordintpair.x, chunkcoordintpair.z); + for (int j2 = 0; j2 < this.l; ++j2) { + int k2; - for (int l = 0; l < 16; ++l) { - for (int i1 = 0; i1 < 16; ++i1) { - int j1 = j + l; - int k1 = k + i1; - int l1 = ichunkaccess.a(HeightMap.Type.WORLD_SURFACE_WG, l, i1) + 1; - - abiomebase[i1 * 16 + l].a(seededrandom, ichunkaccess, j1, k1, l1, adouble[i1 * 16 + l], this.getSettings().r(), this.getSettings().s(), i, this.a.getSeed()); + for (k2 = 0; k2 < this.n + 1; ++k2) { + this.a(adouble[1][k2], j * this.l + j2 + 1, k * this.n + k2); } + + for (k2 = 0; k2 < this.n; ++k2) { + ChunkSection chunksection = protochunk.a(15); + + chunksection.a(); + + for (int l2 = this.m - 1; l2 >= 0; --l2) { + double d0 = adouble[0][k2][l2]; + double d1 = adouble[0][k2 + 1][l2]; + double d2 = adouble[1][k2][l2]; + double d3 = adouble[1][k2 + 1][l2]; + double d4 = adouble[0][k2][l2 + 1]; + double d5 = adouble[0][k2 + 1][l2 + 1]; + double d6 = adouble[1][k2][l2 + 1]; + double d7 = adouble[1][k2 + 1][l2 + 1]; + + for (int i3 = this.j - 1; i3 >= 0; --i3) { + int j3 = l2 * this.j + i3; + int k3 = j3 & 15; + int l3 = j3 >> 4; + + if (chunksection.getYPosition() >> 4 != l3) { + chunksection.b(); + chunksection = protochunk.a(l3); + chunksection.a(); + } + + double d8 = (double) i3 / (double) this.j; + double d9 = MathHelper.d(d8, d0, d4); + double d10 = MathHelper.d(d8, d2, d6); + double d11 = MathHelper.d(d8, d1, d5); + double d12 = MathHelper.d(d8, d3, d7); + + for (int i4 = 0; i4 < this.k; ++i4) { + int j4 = l + j2 * this.k + i4; + int k4 = j4 & 15; + double d13 = (double) i4 / (double) this.k; + double d14 = MathHelper.d(d13, d9, d10); + double d15 = MathHelper.d(d13, d11, d12); + + for (int l4 = 0; l4 < this.k; ++l4) { + int i5 = i1 + k2 * this.k + l4; + int j5 = i5 & 15; + double d16 = (double) l4 / (double) this.k; + double d17 = MathHelper.d(d16, d14, d15); + double d18 = MathHelper.a(d17 / 200.0D, -1.0D, 1.0D); + + int k5; + int l5; + int i6; + + for (d18 = d18 / 2.0D - d18 * d18 * d18 / 24.0D; objectlistiterator.hasNext(); d18 += a(k5, l5, i6) * 0.8D) { + WorldGenFeaturePillagerOutpostPoolPiece worldgenfeaturepillageroutpostpoolpiece1 = (WorldGenFeaturePillagerOutpostPoolPiece) objectlistiterator.next(); + StructureBoundingBox structureboundingbox = worldgenfeaturepillageroutpostpoolpiece1.g(); + + k5 = Math.max(0, Math.max(structureboundingbox.a - j4, j4 - structureboundingbox.d)); + l5 = j3 - (structureboundingbox.b + worldgenfeaturepillageroutpostpoolpiece1.d()); + i6 = Math.max(0, Math.max(structureboundingbox.c - i5, i5 - structureboundingbox.f)); + } + + objectlistiterator.back(objectlist.size()); + + while (objectlistiterator1.hasNext()) { + WorldGenFeatureDefinedStructureJigsawJunction worldgenfeaturedefinedstructurejigsawjunction1 = (WorldGenFeatureDefinedStructureJigsawJunction) objectlistiterator1.next(); + int j6 = j4 - worldgenfeaturedefinedstructurejigsawjunction1.a(); + + k5 = j3 - worldgenfeaturedefinedstructurejigsawjunction1.b(); + l5 = i5 - worldgenfeaturedefinedstructurejigsawjunction1.c(); + d18 += a(j6, k5, l5) * 0.4D; + } + + objectlistiterator1.back(objectlist1.size()); + IBlockData iblockdata; + + if (d18 > 0.0D) { + iblockdata = this.f; + } else if (j3 < i) { + iblockdata = this.g; + } else { + iblockdata = ChunkGeneratorAbstract.i; + } + + if (iblockdata != ChunkGeneratorAbstract.i) { + if (iblockdata.h() != 0) { + blockposition_mutableblockposition.d(j4, j3, i5); + protochunk.k(blockposition_mutableblockposition); + } + + chunksection.setType(k4, k3, j5, iblockdata, false); + heightmap.a(k4, j3, j5, iblockdata); + heightmap1.a(k4, j3, j5, iblockdata); + } + } + } + } + } + + chunksection.b(); + } + + double[][] adouble1 = adouble[0]; + + adouble[0] = adouble[1]; + adouble[1] = adouble1; } } - public abstract C getSettings(); + private static double a(int i, int j, int k) { + int l = i + 12; + int i1 = j + 12; + int j1 = k + 12; - public abstract double[] a(int i, int j); - - public boolean canSpawnStructure(BiomeBase biomebase, StructureGenerator structuregenerator) { - return biomebase.a(structuregenerator); + return l >= 0 && l < 24 ? (i1 >= 0 && i1 < 24 ? (j1 >= 0 && j1 < 24 ? (double) ChunkGeneratorAbstract.h[j1 * 24 * 24 + l * 24 + i1] : 0.0D) : 0.0D) : 0.0D; } - @Nullable - public WorldGenFeatureConfiguration getFeatureConfiguration(BiomeBase biomebase, StructureGenerator structuregenerator) { - return biomebase.b(structuregenerator); - } + private static double b(int i, int j, int k) { + double d0 = (double) (i * i + k * k); + double d1 = (double) j + 0.5D; + double d2 = d1 * d1; + double d3 = Math.pow(2.718281828459045D, -(d2 / 16.0D + d0 / 16.0D)); + double d4 = -d1 * MathHelper.i(d2 / 2.0D + d0 / 2.0D) / 2.0D; - public WorldChunkManager getWorldChunkManager() { - return this.c; + return d4 * d3; } - - public long getSeed() { - return this.b; - } - - public Long2ObjectMap getStructureStartCache(StructureGenerator structuregenerator) { - return (Long2ObjectMap) this.d.computeIfAbsent(structuregenerator, (structuregenerator1) -> { - return new ExpiringMap<>(8192, 10000); // Paper - already synchronized - }); - } - - public Long2ObjectMap getStructureCache(StructureGenerator structuregenerator) { - return (Long2ObjectMap) this.e.computeIfAbsent(structuregenerator, (structuregenerator1) -> { - return new ExpiringMap<>(8192, 10000); // Paper - already synchronized - }); - } - - public int getGenerationDepth() { - return 256; - } - - // Spigot start - @Override - public World getWorld() { - return this.a.getMinecraftWorld(); - } - // Spigot end } diff --git a/src/main/java/net/minecraft/server/ChunkMap.java b/src/main/java/net/minecraft/server/ChunkMap.java deleted file mode 100644 index b6cbfee4a..000000000 --- a/src/main/java/net/minecraft/server/ChunkMap.java +++ /dev/null @@ -1,142 +0,0 @@ -package net.minecraft.server; - -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.util.Map; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class ChunkMap extends Long2ObjectOpenHashMap { - - private static final Logger a = LogManager.getLogger(); - - public ChunkMap(int i) { - super(i); - } - - public Chunk put(long i, Chunk chunk) { - chunk.world.timings.syncChunkLoadPostTimer.startTiming(); // Paper - //org.spigotmc.AsyncCatcher.catchOp("Async Chunk put"); // Paper // Akarin - comment - lastChunkByPos = chunk; // Paper - // Paper start - Chunk chunk1; - synchronized (this) { - // synchronize so any async gets are safe - chunk1 = (Chunk) super.put(i, chunk); - } - if (chunk1 == null) { // Paper - we should never be overwriting chunks - // Paper end - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i); - - for (int j = chunkcoordintpair.x - 1; j <= chunkcoordintpair.x + 1; ++j) { - for (int k = chunkcoordintpair.z - 1; k <= chunkcoordintpair.z + 1; ++k) { - if (j != chunkcoordintpair.x || k != chunkcoordintpair.z) { - long l = ChunkCoordIntPair.a(j, k); - Chunk chunk2 = (Chunk) super.get(l); // Paper - use super to avoid polluting last access cache - - if (chunk2 != null) { - chunk.H(); - chunk2.H(); - } - } - } - } - - // CraftBukkit start - // Update neighbor counts - for (int x = -2; x < 3; x++) { - for (int z = -2; z < 3; z++) { - if (x == 0 && z == 0) { - continue; - } - - Chunk neighbor = super.get(ChunkCoordIntPair.a(chunkcoordintpair.x + x, chunkcoordintpair.z + z)); // Paper - use super to avoid polluting last access cache - if (neighbor != null) { - neighbor.setNeighborLoaded(-x, -z); - chunk.setNeighborLoaded(x, z); - } - } - // Paper start - } } else { - a.error("Overwrote existing chunk! (" + chunk.world.getWorld().getName() + ":" + chunk.locX+"," + chunk.locZ + ")", new IllegalStateException()); - } - // Paper end - // Paper start - if this is a spare chunk (not part of any players view distance), go ahead and queue it for unload. - if (!((WorldServer)chunk.world).getPlayerChunkMap().isChunkInUse(chunk.locX, chunk.locZ)) { - if (chunk.world.paperConfig.delayChunkUnloadsBy > 0) { - chunk.scheduledForUnload = System.currentTimeMillis(); - } else { - ((WorldServer) chunk.world).getChunkProvider().unload(chunk); - } - } - // Paper end - chunk.world.timings.syncChunkLoadPostTimer.stopTiming(); // Paper - // CraftBukkit end - - return chunk1; - } - - public Chunk put(Long olong, Chunk chunk) { - return MCUtil.ensureMain("Chunk Put", () -> this.put(olong.longValue(), chunk)); // Paper - } - - public Chunk remove(long i) { - // Paper start - //org.spigotmc.AsyncCatcher.catchOp("Async Chunk remove"); // Akarin - comment - Chunk chunk; - synchronized (this) { - // synchronize so any async gets are safe - chunk = super.remove(i); - } - if (chunk != null) { // Paper - don't decrement if we didn't remove anything - // Paper end - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i); - - for (int j = chunkcoordintpair.x - 1; j <= chunkcoordintpair.x + 1; ++j) { - for (int k = chunkcoordintpair.z - 1; k <= chunkcoordintpair.z + 1; ++k) { - if (j != chunkcoordintpair.x || k != chunkcoordintpair.z) { - Chunk chunk1 = (Chunk) super.get(ChunkCoordIntPair.a(j, k)); // Paper - use super to avoid polluting last access cache - - if (chunk1 != null) { - chunk1.I(); - } - } - } - } - - // Paper start - } // close if (chunk != null) - if (lastChunkByPos != null && i == lastChunkByPos.chunkKey) { - lastChunkByPos = null; - } - return chunk; - } - private Chunk lastChunkByPos = null; - - @Override - public Chunk get(long l) { - if (MCUtil.isMainThread()) { - if (lastChunkByPos != null && l == lastChunkByPos.chunkKey) { - return lastChunkByPos; - } - final Chunk chunk = super.get(l); - return chunk != null ? (lastChunkByPos = chunk) : null; - } else { - synchronized (this) { - return super.get(l); - } - } - } - // Paper end - - public Chunk remove(Object object) { - return MCUtil.ensureMain("Chunk Remove", () -> this.remove(((Long) object).longValue())); // Paper - } - - public void putAll(Map map) { - throw new RuntimeException("Not yet implemented"); - } - - public boolean remove(Object object, Object object1) { - throw new RuntimeException("Not yet implemented"); - } -} diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java new file mode 100644 index 000000000..63a688725 --- /dev/null +++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java @@ -0,0 +1,493 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Sets; +import com.mojang.datafixers.util.Either; +import it.unimi.dsi.fastutil.longs.Long2ByteMap; +import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap; +import it.unimi.dsi.fastutil.longs.Long2IntMap; +import it.unimi.dsi.fastutil.longs.Long2IntMaps; +import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry; +import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet; +import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator; +import it.unimi.dsi.fastutil.objects.ObjectIterator; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import it.unimi.dsi.fastutil.objects.ObjectSet; +import it.unimi.dsi.fastutil.objects.ObjectSortedSet; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import javax.annotation.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public abstract class ChunkMapDistance { + + private static final Logger LOGGER = LogManager.getLogger(); + private static final int b = 33 + ChunkStatus.a(ChunkStatus.FULL) - 2; + private final Long2ObjectMap> c = new Long2ObjectOpenHashMap(); + public final Long2ObjectOpenHashMap>> tickets = new Long2ObjectOpenHashMap(); // CraftBukkit - private -> public + private final ChunkMapDistance.a e = new ChunkMapDistance.a(); + private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); + private final ChunkMapDistance.c g = new ChunkMapDistance.c(33); + private final java.util.Queue pendingChunkUpdates = new java.util.LinkedList<>(); // PAIL pendingChunkUpdates // Paper - use a queue + private final ChunkTaskQueueSorter i; + private final Mailbox> j; + private final Mailbox k; + private final LongSet l = new LongOpenHashSet(); + private final Executor m; + private long currentTick; + + protected ChunkMapDistance(Executor executor, Executor executor1) { + executor1.getClass(); + Mailbox mailbox = Mailbox.a("player ticket throttler", executor1::execute); + ChunkTaskQueueSorter chunktaskqueuesorter = new ChunkTaskQueueSorter(ImmutableList.of(mailbox), executor, 4); + + this.i = chunktaskqueuesorter; + this.j = chunktaskqueuesorter.a(mailbox, true); + this.k = chunktaskqueuesorter.a(mailbox); + this.m = executor1; + } + + protected void purgeTickets() { + ++this.currentTick; + ObjectIterator objectiterator = this.tickets.long2ObjectEntrySet().fastIterator(); + + while (objectiterator.hasNext()) { + Entry>> entry = (Entry) objectiterator.next(); + + if ((entry.getValue()).removeIf((ticket) -> { // Craftbukkit - decompile error + return ticket.a(this.currentTick); + })) { + this.e.b(entry.getLongKey(), this.a((ObjectSortedSet) entry.getValue()), false); + } + + if (((ObjectSortedSet) entry.getValue()).isEmpty()) { + objectiterator.remove(); + } + } + + } + + private int a(ObjectSortedSet> objectsortedset) { + ObjectBidirectionalIterator> objectbidirectionaliterator = objectsortedset.iterator(); + + return objectbidirectionaliterator.hasNext() ? ((Ticket) objectbidirectionaliterator.next()).b() : PlayerChunkMap.GOLDEN_TICKET + 1; + } + + protected abstract boolean a(long i); + + @Nullable + protected abstract PlayerChunk b(long i); + + @Nullable + protected abstract PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k); + + public boolean a(PlayerChunkMap playerchunkmap) { + this.f.a(); + this.g.a(); + int i = Integer.MAX_VALUE - this.e.a(Integer.MAX_VALUE); + boolean flag = i != 0; + + if (flag) { + ; + } + + // Paper start + if (!this.pendingChunkUpdates.isEmpty()) { + while(!this.pendingChunkUpdates.isEmpty()) { + this.pendingChunkUpdates.remove().a(playerchunkmap); + } + // Paper end + return true; + } else { + if (!this.l.isEmpty()) { + LongIterator longiterator = this.l.iterator(); + + while (longiterator.hasNext()) { + long j = longiterator.nextLong(); + + if (this.e(j).stream().anyMatch((ticket) -> { + return ticket.getTicketType() == TicketType.PLAYER; + })) { + PlayerChunk playerchunk = playerchunkmap.getUpdatingChunk(j); + + if (playerchunk == null) { + throw new IllegalStateException(); + } + + CompletableFuture> completablefuture = playerchunk.b(); + + completablefuture.thenAccept((either) -> { + this.m.execute(() -> { + this.k.a(ChunkTaskQueueSorter.a(() -> { // Craftbukkit - decompile error + }, j, false)); + }); + }); + } + } + + this.l.clear(); + } + + return flag; + } + } + + private boolean addTicket(long i, Ticket ticket) { // CraftBukkit - void -> boolean + ObjectSortedSet> objectsortedset = this.e(i); + ObjectBidirectionalIterator> objectbidirectionaliterator = objectsortedset.iterator(); + int j; + + if (objectbidirectionaliterator.hasNext()) { + j = ((Ticket) objectbidirectionaliterator.next()).b(); + } else { + j = PlayerChunkMap.GOLDEN_TICKET + 1; + } + + boolean ret = false; // CraftBukkit + if (objectsortedset.add(ticket)) { + ret = true; // CraftBukkit + } + + if (ticket.b() < j) { + this.e.b(i, ticket.b(), true); + } + + return ret; // CraftBukkit + } + + private boolean removeTicket(long i, Ticket ticket) { // CraftBukkit - void -> boolean + ObjectSortedSet> objectsortedset = this.e(i); + + boolean removed = false; // CraftBukkit + if (objectsortedset.remove(ticket)) { + removed = true; // CraftBukkit + } + + if (objectsortedset.isEmpty()) { + this.tickets.remove(i); + } + + this.e.b(i, this.a(objectsortedset), false); + return removed; // CraftBukkit + } + + public void a(TicketType tickettype, ChunkCoordIntPair chunkcoordintpair, int i, T t0) { + // CraftBukkit start + this.addTicketAtLevel(tickettype, chunkcoordintpair, i, t0); + } + + public boolean addTicketAtLevel(TicketType ticketType, ChunkCoordIntPair chunkcoordintpair, int level, T identifier) { + return this.addTicket(chunkcoordintpair.pair(), new Ticket<>(ticketType, level, identifier, this.currentTick)); + // CraftBukkit end + } + + public void b(TicketType tickettype, ChunkCoordIntPair chunkcoordintpair, int i, T t0) { + // CraftBukkit start + this.removeTicketAtLevel(tickettype, chunkcoordintpair, i, t0); + } + + public boolean removeTicketAtLevel(TicketType ticketType, ChunkCoordIntPair chunkcoordintpair, int level, T identifier) { + Ticket ticket = new Ticket<>(ticketType, level, identifier, this.currentTick); + + return this.removeTicket(chunkcoordintpair.pair(), ticket); + // CraftBukkit end + } + + public void addTicket(TicketType tickettype, ChunkCoordIntPair chunkcoordintpair, int i, T t0) { + this.addTicket(chunkcoordintpair.pair(), new Ticket<>(tickettype, 33 - i, t0, this.currentTick)); + } + + public void removeTicket(TicketType tickettype, ChunkCoordIntPair chunkcoordintpair, int i, T t0) { + Ticket ticket = new Ticket<>(tickettype, 33 - i, t0, this.currentTick); + + this.removeTicket(chunkcoordintpair.pair(), ticket); + } + + private ObjectSortedSet> e(long i) { + return (ObjectSortedSet) this.tickets.computeIfAbsent(i, (j) -> { + return new ObjectAVLTreeSet(); + }); + } + + protected void a(ChunkCoordIntPair chunkcoordintpair, boolean flag) { + Ticket ticket = new Ticket<>(TicketType.FORCED, 31, chunkcoordintpair, this.currentTick); + + if (flag) { + this.addTicket(chunkcoordintpair.pair(), ticket); + } else { + this.removeTicket(chunkcoordintpair.pair(), ticket); + } + + } + + public void a(SectionPosition sectionposition, EntityPlayer entityplayer) { + long i = sectionposition.u().pair(); + + ((ObjectSet) this.c.computeIfAbsent(i, (j) -> { + return new ObjectOpenHashSet(); + })).add(entityplayer); + this.f.b(i, 0, true); + this.g.b(i, 0, true); + } + + public void b(SectionPosition sectionposition, EntityPlayer entityplayer) { + long i = sectionposition.u().pair(); + ObjectSet objectset = (ObjectSet) this.c.get(i); + + objectset.remove(entityplayer); + if (objectset.isEmpty()) { + this.c.remove(i); + this.f.b(i, Integer.MAX_VALUE, false); + this.g.b(i, Integer.MAX_VALUE, false); + } + + } + + protected String c(long i) { + ObjectSortedSet> objectsortedset = (ObjectSortedSet) this.tickets.get(i); + String s; + + if (objectsortedset != null && !objectsortedset.isEmpty()) { + s = ((Ticket) objectsortedset.first()).toString(); + } else { + s = "no_ticket"; + } + + return s; + } + + protected void a(int i) { + this.g.a(i); + } + + public int b() { + this.f.a(); + return this.f.a.size(); + } + + public boolean d(long i) { + this.f.a(); + return this.f.a.containsKey(i); + } + + public String c() { + return this.i.a(); + } + + // CraftBukkit start + public void removeAllTicketsFor(TicketType ticketType, int ticketLevel, T ticketIdentifier) { + Ticket target = new Ticket<>(ticketType, ticketLevel, ticketIdentifier, this.currentTick); + + for (java.util.Iterator>> iterator = this.tickets.values().iterator(); iterator.hasNext();) { + ObjectSortedSet> tickets = iterator.next(); + tickets.remove(target); + + if (tickets.isEmpty()) { + iterator.remove(); + } + } + } + // CraftBukkit end + + class a extends ChunkMap { + + public a() { + super(PlayerChunkMap.GOLDEN_TICKET + 2, 16, 256); + } + + @Override + protected int b(long i) { + ObjectSortedSet> objectsortedset = (ObjectSortedSet) ChunkMapDistance.this.tickets.get(i); + + if (objectsortedset == null) { + return Integer.MAX_VALUE; + } else { + ObjectBidirectionalIterator> objectbidirectionaliterator = objectsortedset.iterator(); + + return !objectbidirectionaliterator.hasNext() ? Integer.MAX_VALUE : ((Ticket) objectbidirectionaliterator.next()).b(); + } + } + + @Override + protected int c(long i) { + if (!ChunkMapDistance.this.a(i)) { + PlayerChunk playerchunk = ChunkMapDistance.this.b(i); + + if (playerchunk != null) { + return playerchunk.getTicketLevel(); + } + } + + return PlayerChunkMap.GOLDEN_TICKET + 1; + } + + @Override + protected void a(long i, int j) { + PlayerChunk playerchunk = ChunkMapDistance.this.b(i); + int k = playerchunk == null ? PlayerChunkMap.GOLDEN_TICKET + 1 : playerchunk.getTicketLevel(); + + if (k != j) { + playerchunk = ChunkMapDistance.this.a(i, j, playerchunk, k); + if (playerchunk != null) { + ChunkMapDistance.this.pendingChunkUpdates.add(playerchunk); + } + + } + } + + public int a(int i) { + return this.b(i); + } + } + + class c extends ChunkMapDistance.b { + + private int e = 0; + private final Long2IntMap f = Long2IntMaps.synchronize(new Long2IntOpenHashMap()); + private final LongSet g = new LongOpenHashSet(); + + protected c(int i) { + super(i); + this.f.defaultReturnValue(i + 2); + } + + @Override + protected void a(long i, int j, int k) { + this.g.add(i); + } + + public void a(int i) { + ObjectIterator objectiterator = this.a.long2ByteEntrySet().iterator(); + + while (objectiterator.hasNext()) { + it.unimi.dsi.fastutil.longs.Long2ByteMap.Entry it_unimi_dsi_fastutil_longs_long2bytemap_entry = (it.unimi.dsi.fastutil.longs.Long2ByteMap.Entry) objectiterator.next(); + byte b0 = it_unimi_dsi_fastutil_longs_long2bytemap_entry.getByteValue(); + long j = it_unimi_dsi_fastutil_longs_long2bytemap_entry.getLongKey(); + + this.a(j, b0, this.c(b0), b0 <= i - 2); + } + + this.e = i; + } + + private void a(long i, int j, boolean flag, boolean flag1) { + if (flag != flag1) { + Ticket ticket = new Ticket<>(TicketType.PLAYER, ChunkMapDistance.b, new ChunkCoordIntPair(i), ChunkMapDistance.this.currentTick); + + if (flag1) { + ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // Craftbukkit - decompile error + ChunkMapDistance.this.m.execute(() -> { + if (this.c(this.c(i))) { + ChunkMapDistance.this.addTicket(i, ticket); + ChunkMapDistance.this.l.add(i); + } else { + ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // Craftbukkit - decompile error + }, i, false)); + } + + }); + }, i, () -> { + return j; + })); + } else { + ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // Craftbukkit - decompile error + ChunkMapDistance.this.m.execute(() -> { + ChunkMapDistance.this.removeTicket(i, ticket); + }); + }, i, true)); + } + } + + } + + @Override + public void a() { + super.a(); + if (!this.g.isEmpty()) { + LongIterator longiterator = this.g.iterator(); + + while (longiterator.hasNext()) { + long i = longiterator.nextLong(); + int j = this.f.get(i); + int k = this.c(i); + + if (j != k) { + ChunkMapDistance.this.i.a(new ChunkCoordIntPair(i), () -> { + return this.f.get(i); + }, k, (l) -> { + if (l >= this.f.defaultReturnValue()) { + this.f.remove(i); + } else { + this.f.put(i, l); + } + + }); + this.a(i, k, this.c(j), this.c(k)); + } + } + + this.g.clear(); + } + + } + + private boolean c(int i) { + return i <= this.e - 2; + } + } + + class b extends ChunkMap { + + protected final Long2ByteMap a = new Long2ByteOpenHashMap(); + protected final int b; + + protected b(int i) { + super(i + 2, 16, 256); + this.b = i; + this.a.defaultReturnValue((byte) (i + 2)); + } + + @Override + protected int c(long i) { + return this.a.get(i); + } + + @Override + protected void a(long i, int j) { + byte b0; + + if (j > this.b) { + b0 = this.a.remove(i); + } else { + b0 = this.a.put(i, (byte) j); + } + + this.a(i, b0, j); + } + + protected void a(long i, int j, int k) {} + + @Override + protected int b(long i) { + return this.d(i) ? 0 : Integer.MAX_VALUE; + } + + private boolean d(long i) { + ObjectSet objectset = (ObjectSet) ChunkMapDistance.this.c.get(i); + + return objectset != null && !objectset.isEmpty(); + } + + public void a() { + this.b(Integer.MAX_VALUE); + } + } +} diff --git a/src/main/java/net/minecraft/server/ChunkProviderGenerate.java b/src/main/java/net/minecraft/server/ChunkProviderGenerate.java index 275e6a177..b794a39d3 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderGenerate.java +++ b/src/main/java/net/minecraft/server/ChunkProviderGenerate.java @@ -1,69 +1,34 @@ package net.minecraft.server; import java.util.List; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; public class ChunkProviderGenerate extends ChunkGeneratorAbstract { - private static final Logger f = LogManager.getLogger(); - private final NoiseGeneratorOctaves g; - private final NoiseGeneratorOctaves h; - private final NoiseGeneratorOctaves i; - private final NoiseGenerator3 j; - private final GeneratorSettingsOverworld k; - private final NoiseGeneratorOctaves l; - private final NoiseGeneratorOctaves m; - private final WorldType n; - private final float[] o; - private final MobSpawnerPhantom p = new MobSpawnerPhantom(); - private final IBlockData q; - private final IBlockData r; - - public ChunkProviderGenerate(GeneratorAccess generatoraccess, WorldChunkManager worldchunkmanager, GeneratorSettingsOverworld generatorsettingsoverworld) { - super(generatoraccess, worldchunkmanager); - this.n = generatoraccess.getWorldData().getType(); - SeededRandom seededrandom = new SeededRandom(this.b); - - this.g = new NoiseGeneratorOctaves(seededrandom, 16); - this.h = new NoiseGeneratorOctaves(seededrandom, 16); - this.i = new NoiseGeneratorOctaves(seededrandom, 8); - this.j = new NoiseGenerator3(seededrandom, 4); - this.l = new NoiseGeneratorOctaves(seededrandom, 10); - this.m = new NoiseGeneratorOctaves(seededrandom, 16); - this.o = new float[25]; - + private static final float[] h = (float[]) SystemUtils.a((new float[25]), (afloat) -> { // CraftBukkit - decompile error for (int i = -2; i <= 2; ++i) { for (int j = -2; j <= 2; ++j) { float f = 10.0F / MathHelper.c((float) (i * i + j * j) + 0.2F); - this.o[i + 2 + (j + 2) * 5] = f; + afloat[i + 2 + (j + 2) * 5] = f; } } - this.k = generatorsettingsoverworld; - this.q = this.k.r(); - this.r = this.k.s(); - } - - public void createChunk(IChunkAccess ichunkaccess) { - ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); - int i = chunkcoordintpair.x; - int j = chunkcoordintpair.z; - SeededRandom seededrandom = new SeededRandom(); - - seededrandom.a(i, j); - BiomeBase[] abiomebase = this.c.getBiomeBlock(i * 16, j * 16, 16, 16); - - ichunkaccess.a(abiomebase); - this.a(i, j, ichunkaccess); - ichunkaccess.a(HeightMap.Type.WORLD_SURFACE_WG, HeightMap.Type.OCEAN_FLOOR_WG); - this.a(ichunkaccess, abiomebase, seededrandom, this.a.getSeaLevel()); - this.a(ichunkaccess, seededrandom); - ichunkaccess.a(HeightMap.Type.WORLD_SURFACE_WG, HeightMap.Type.OCEAN_FLOOR_WG); - ichunkaccess.a(ChunkStatus.BASE); + }); + private final NoiseGeneratorOctaves i; + private final boolean j; + private final MobSpawnerPhantom k = new MobSpawnerPhantom(); + private final MobSpawnerPatrol l = new MobSpawnerPatrol(); + private final MobSpawnerCat m = new MobSpawnerCat(); + private final VillageSiege n = new VillageSiege(); + + public ChunkProviderGenerate(GeneratorAccess generatoraccess, WorldChunkManager worldchunkmanager, GeneratorSettingsOverworld generatorsettingsoverworld) { + super(generatoraccess, worldchunkmanager, 4, 8, 256, generatorsettingsoverworld, true); + this.e.a(2620); + this.i = new NoiseGeneratorOctaves(this.e, 16); + this.j = generatoraccess.getWorldData().getType() == WorldType.AMPLIFIED; } + @Override public void addMobs(RegionLimitedWorldAccess regionlimitedworldaccess) { int i = regionlimitedworldaccess.a(); int j = regionlimitedworldaccess.b(); @@ -74,201 +39,135 @@ public class ChunkProviderGenerate extends ChunkGeneratorAbstract 0.0D) { - ichunkaccess.setType(blockposition_mutableblockposition, this.q, false); - } else if (k2 * 8 + l2 < this.k.w()) { - ichunkaccess.setType(blockposition_mutableblockposition, this.r, false); - } - } - - d10 += d12; - d11 += d13; - } - - d1 += d5; - d2 += d6; - d3 += d7; - d4 += d8; - } + if (this.j && f4 > 0.0F) { + f4 = 1.0F + f4 * 2.0F; + f5 = 1.0F + f5 * 4.0F; } + // CraftBukkit start - fix MC-54738 + if (f4 < -1.8F) { + f4 = -1.8F; + } + // CraftBukkit end + + float f6 = ChunkProviderGenerate.h[k + 2 + (l + 2) * 5] / (f4 + 2.0F); + + if (biomebase.g() > f3) { + f6 /= 2.0F; + } + + f += f5 * f6; + f1 += f4 * f6; + f2 += f6; } } + f /= f2; + f1 /= f2; + f = f * 0.9F + 0.1F; + f1 = (f1 * 4.0F - 1.0F) / 8.0F; + adouble[0] = (double) f1 + this.c(i, j); + adouble[1] = (double) f; + return adouble; } - private void a(BiomeBase[] abiomebase, int i, int j, int k, double[] adouble) { - double[] adouble1 = this.m.a(i, k, 5, 5, this.k.x(), this.k.y(), this.k.z()); - float f = this.k.A(); - float f1 = this.k.B(); - double[] adouble2 = this.i.a(i, j, k, 5, 33, 5, (double) (f / this.k.C()), (double) (f1 / this.k.D()), (double) (f / this.k.E())); - double[] adouble3 = this.g.a(i, j, k, 5, 33, 5, (double) f, (double) f1, (double) f); - double[] adouble4 = this.h.a(i, j, k, 5, 33, 5, (double) f, (double) f1, (double) f); - int l = 0; - int i1 = 0; + private double c(int i, int j) { + double d0 = this.i.a((double) (i * 200), 10.0D, (double) (j * 200), 1.0D, 0.0D, true) / 8000.0D; - for (int j1 = 0; j1 < 5; ++j1) { - for (int k1 = 0; k1 < 5; ++k1) { - float f2 = 0.0F; - float f3 = 0.0F; - float f4 = 0.0F; - boolean flag = true; - BiomeBase biomebase = abiomebase[j1 + 2 + (k1 + 2) * 10]; - - for (int l1 = -2; l1 <= 2; ++l1) { - for (int i2 = -2; i2 <= 2; ++i2) { - BiomeBase biomebase1 = abiomebase[j1 + l1 + 2 + (k1 + i2 + 2) * 10]; - float f5 = this.k.F() + biomebase1.h() * this.k.G(); - float f6 = this.k.H() + biomebase1.l() * this.k.I(); - - if (this.n == WorldType.AMPLIFIED && f5 > 0.0F) { - f5 = 1.0F + f5 * 2.0F; - f6 = 1.0F + f6 * 4.0F; - } - // CraftBukkit start - fix MC-54738 - if (f5 < -1.8F) { - f5 = -1.8F; - } - // CraftBukkit end - - float f7 = this.o[l1 + 2 + (i2 + 2) * 5] / (f5 + 2.0F); - - if (biomebase1.h() > biomebase.h()) { - f7 /= 2.0F; - } - - f2 += f6 * f7; - f3 += f5 * f7; - f4 += f7; - } - } - - f2 /= f4; - f3 /= f4; - f2 = f2 * 0.9F + 0.1F; - f3 = (f3 * 4.0F - 1.0F) / 8.0F; - double d0 = adouble1[i1] / 8000.0D; - - if (d0 < 0.0D) { - d0 = -d0 * 0.3D; - } - - d0 = d0 * 3.0D - 2.0D; - if (d0 < 0.0D) { - d0 /= 2.0D; - if (d0 < -1.0D) { - d0 = -1.0D; - } - - d0 /= 1.4D; - d0 /= 2.0D; - } else { - if (d0 > 1.0D) { - d0 = 1.0D; - } - - d0 /= 8.0D; - } - - ++i1; - double d1 = (double) f3; - double d2 = (double) f2; - - d1 += d0 * 0.2D; - d1 = d1 * this.k.J() / 8.0D; - double d3 = this.k.J() + d1 * 4.0D; - - for (int j2 = 0; j2 < 33; ++j2) { - double d4 = ((double) j2 - d3) * this.k.K() * 128.0D / 256.0D / d2; - - if (d4 < 0.0D) { - d4 *= 4.0D; - } - - double d5 = adouble3[l] / this.k.L(); - double d6 = adouble4[l] / this.k.M(); - double d7 = (adouble2[l] / 10.0D + 1.0D) / 2.0D; - double d8 = MathHelper.b(d5, d6, d7) - d4; - - if (j2 > 29) { - double d9 = (double) ((float) (j2 - 29) / 3.0F); - - d8 = d8 * (1.0D - d9) - 10.0D * d9; - } - - adouble[l] = d8; - ++l; - } - } + if (d0 < 0.0D) { + d0 = -d0 * 0.3D; } + d0 = d0 * 3.0D - 2.0D; + if (d0 < 0.0D) { + d0 /= 28.0D; + } else { + if (d0 > 1.0D) { + d0 = 1.0D; + } + + d0 /= 40.0D; + } + + return d0; } + @Override public List getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { - BiomeBase biomebase = this.a.getBiome(blockposition); + if (WorldGenerator.SWAMP_HUT.c(this.a, blockposition)) { + if (enumcreaturetype == EnumCreatureType.MONSTER) { + return WorldGenerator.SWAMP_HUT.e(); + } - return enumcreaturetype == EnumCreatureType.MONSTER && ((WorldGenFeatureSwampHut) WorldGenerator.l).d(this.a, blockposition) ? WorldGenerator.l.d() : (enumcreaturetype == EnumCreatureType.MONSTER && WorldGenerator.n.b(this.a, blockposition) ? WorldGenerator.n.d() : biomebase.getMobs(enumcreaturetype)); + if (enumcreaturetype == EnumCreatureType.CREATURE) { + return WorldGenerator.SWAMP_HUT.f(); + } + } else if (enumcreaturetype == EnumCreatureType.MONSTER) { + if (WorldGenerator.PILLAGER_OUTPOST.a(this.a, blockposition)) { + return WorldGenerator.PILLAGER_OUTPOST.e(); + } + + if (WorldGenerator.OCEAN_MONUMENT.a(this.a, blockposition)) { + return WorldGenerator.OCEAN_MONUMENT.e(); + } + } + + return super.getMobsFor(enumcreaturetype, blockposition); } - public int a(World world, boolean flag, boolean flag1) { - byte b0 = 0; - int i = b0 + this.p.a(world, flag, flag1); - - return i; - } - - public GeneratorSettingsOverworld getSettings() { - return this.k; - } - - public double[] a(int i, int j) { - double d0 = 0.03125D; - - return this.j.a((double) (i << 4), (double) (j << 4), 16, 16, 0.0625D, 0.0625D, 1.0D); + @Override + public void doMobSpawning(WorldServer worldserver, boolean flag, boolean flag1) { + this.k.a(worldserver, flag, flag1); + this.l.a(worldserver, flag, flag1); + this.m.a(worldserver, flag, flag1); + this.n.a(worldserver, flag, flag1); } + @Override public int getSpawnHeight() { return this.a.getSeaLevel() + 1; } + + @Override + public int getSeaLevel() { + return 63; + } } diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java index ad81e469f..e7539dd79 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -1,507 +1,819 @@ package net.minecraft.server; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import it.unimi.dsi.fastutil.longs.LongSet; -import it.unimi.dsi.fastutil.objects.ObjectIterator; +import com.google.common.annotations.VisibleForTesting; +import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.util.Either; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import java.io.File; import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; +import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; import java.util.function.BooleanSupplier; -import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; import javax.annotation.Nullable; import com.destroystokyo.paper.exception.ServerInternalException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -// CraftBukkit start -import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; -import org.bukkit.event.world.ChunkUnloadEvent; -// CraftBukkit end +public class ChunkProviderServer extends IChunkProvider { -public class ChunkProviderServer implements IChunkProvider { - - private static final Logger a = LogManager.getLogger(); - public final LongSet unloadQueue = new LongOpenHashSet(); + private static final int b = (int) Math.pow(17.0D, 2.0D); + private static final List c = ChunkStatus.a(); static final List getPossibleChunkStatuses() { return ChunkProviderServer.c; } // Paper - OBFHELPER + private final ChunkMapDistance chunkMapDistance; public final ChunkGenerator chunkGenerator; - public final IChunkLoader chunkLoader; - // Paper start - chunk save stats - private long lastQueuedSaves = 0L; // Paper - private long lastProcessedSaves = 0L; // Paper - private long lastSaveStatPrinted = System.currentTimeMillis(); - // Paper end - public final Long2ObjectMap chunks = new ChunkMap(8192); // Paper - remove synchronize - we keep everything on main for manip - private Chunk lastChunk; - private final ChunkTaskScheduler chunkScheduler; - final SchedulerBatch batchScheduler; // Paper - public final WorldServer world; - final IAsyncTaskHandler asyncTaskHandler; // Paper + private final WorldServer world; + private final Thread serverThread; + private final LightEngineThreaded lightEngine; + public final ChunkProviderServer.a serverThreadQueue; // Paper private -> public + public final PlayerChunkMap playerChunkMap; + private final WorldPersistentData worldPersistentData; + private long lastTickTime; + public boolean allowMonsters = true; + public boolean allowAnimals = true; + private final long[] cachePos = new long[4]; + private final ChunkStatus[] cacheStatus = new ChunkStatus[4]; + private final IChunkAccess[] cacheChunk = new IChunkAccess[4]; - public ChunkProviderServer(WorldServer worldserver, IChunkLoader ichunkloader, ChunkGenerator chunkgenerator, IAsyncTaskHandler iasynctaskhandler) { + public ChunkProviderServer(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, WorldLoadListener worldloadlistener, Supplier supplier) { this.world = worldserver; - this.chunkLoader = ichunkloader; + this.serverThreadQueue = new ChunkProviderServer.a(worldserver); this.chunkGenerator = chunkgenerator; - this.asyncTaskHandler = iasynctaskhandler; - this.chunkScheduler = new ChunkTaskScheduler(0, worldserver, chunkgenerator, ichunkloader, iasynctaskhandler); // CraftBukkit - very buggy, broken in lots of __subtle__ ways. Same goes for async chunk loading. Also Bukkit API / plugins can't handle async events at all anyway. - this.batchScheduler = new SchedulerBatch<>(this.chunkScheduler); + this.serverThread = Thread.currentThread(); + File file1 = worldserver.getWorldProvider().getDimensionManager().a(file); + File file2 = new File(file1, "data"); + + file2.mkdirs(); + this.worldPersistentData = new WorldPersistentData(file2, datafixer); + this.playerChunkMap = new PlayerChunkMap(worldserver, file, datafixer, definedstructuremanager, executor, this.serverThreadQueue, this, this.getChunkGenerator(), worldloadlistener, supplier, i); + this.lightEngine = this.playerChunkMap.a(); + this.chunkMapDistance = this.playerChunkMap.e(); + this.clearCache(); } - public Collection a() { - return this.chunks.values(); + @Override + public LightEngineThreaded getLightEngine() { + return this.lightEngine; } - public void unload(Chunk chunk) { - if (this.world.worldProvider.a(chunk.locX, chunk.locZ)) { - this.unloadQueue.add(ChunkCoordIntPair.a(chunk.locX, chunk.locZ)); - } - - } - - public void b() { - ObjectIterator objectiterator = this.chunks.values().iterator(); - - while (objectiterator.hasNext()) { - Chunk chunk = (Chunk) objectiterator.next(); - - this.unload(chunk); - } - - } - - public void a(int i, int j) { - this.unloadQueue.remove(ChunkCoordIntPair.a(i, j)); - } - - // Paper start - defaults if Async Chunks is not enabled - boolean chunkGoingToExists(int x, int z) { - final long k = ChunkCoordIntPair.asLong(x, z); - return chunkScheduler.progressCache.containsKey(k); - } - public void bumpPriority(ChunkCoordIntPair coords) { - // do nothing, override in async - } - - public List getSpiralOutChunks(BlockPosition blockposition, int radius) { - List list = com.google.common.collect.Lists.newArrayList(); - - list.add(new ChunkCoordIntPair(blockposition.getX() >> 4, blockposition.getZ() >> 4)); - for (int r = 1; r <= radius; r++) { - int x = -r; - int z = r; - - // Iterates the edge of half of the box; then negates for other half. - while (x <= r && z > -r) { - list.add(new ChunkCoordIntPair((blockposition.getX() + (x << 4)) >> 4, (blockposition.getZ() + (z << 4)) >> 4)); - list.add(new ChunkCoordIntPair((blockposition.getX() - (x << 4)) >> 4, (blockposition.getZ() - (z << 4)) >> 4)); - - if (x < r) { - x++; - } else { - z--; - } - } - } - return list; - } - - public Chunk getChunkAt(int x, int z, boolean load, boolean gen, Consumer consumer) { - return getChunkAt(x, z, load, gen, false, consumer); - } - public Chunk getChunkAt(int x, int z, boolean load, boolean gen, boolean priority, Consumer consumer) { - Chunk chunk = getChunkAt(x, z, load, gen); - if (consumer != null) { - consumer.accept(chunk); - } - return chunk; - } - - PaperAsyncChunkProvider.CancellableChunkRequest requestChunk(int x, int z, boolean gen, boolean priority, Consumer consumer) { - Chunk chunk = getChunkAt(x, z, gen, priority, consumer); - return new PaperAsyncChunkProvider.CancellableChunkRequest() { - @Override - public void cancel() { - - } - - @Override - public Chunk getChunk() { - return chunk; - } - }; - } - // Paper end - @Nullable - public Chunk getChunkAt(int i, int j, boolean flag, boolean flag1) { - IChunkLoader ichunkloader = this.chunkLoader; - Chunk chunk; - // Paper start - do already loaded checks before synchronize - long k = ChunkCoordIntPair.a(i, j); - chunk = (Chunk) this.chunks.get(k); - if (chunk != null) { - //this.lastChunk = chunk; // Paper remove vanilla lastChunk - return chunk; - } - // Paper end + private PlayerChunk getChunk(long i) { + return this.playerChunkMap.getVisibleChunk(i); + } - synchronized (this.chunkLoader) { - // Paper start - remove vanilla lastChunk, we do it more accurately - /* if (this.lastChunk != null && this.lastChunk.locX == i && this.lastChunk.locZ == j) { - return this.lastChunk; - }*/ // Paper end + public int b() { + return this.playerChunkMap.c(); + } - // Paper start - move up - //long k = ChunkCoordIntPair.a(i, j); - - /*chunk = (Chunk) this.chunks.get(k); - if (chunk != null) { - //this.lastChunk = chunk; // Paper remove vanilla lastChunk - return chunk; - }*/ - // Paper end - - if (flag) { - try (co.aikar.timings.Timing timing = world.timings.syncChunkLoadTimer.startTiming()) { // Paper - chunk = this.chunkLoader.a(this.world, i, j, (chunk1) -> { - chunk1.setLastSaved(this.world.getTime()); - this.chunks.put(ChunkCoordIntPair.a(i, j), chunk1); - }); - } catch (Exception exception) { - ChunkProviderServer.a.error("Couldn't load chunk", exception); - } - } + private void a(long i, IChunkAccess ichunkaccess, ChunkStatus chunkstatus) { + for (int j = 3; j > 0; --j) { + this.cachePos[j] = this.cachePos[j - 1]; + this.cacheStatus[j] = this.cacheStatus[j - 1]; + this.cacheChunk[j] = this.cacheChunk[j - 1]; } - if (chunk != null) { - this.asyncTaskHandler.postToMainThread(chunk::addEntities); - return chunk; - } else if (flag1) { - try (co.aikar.timings.Timing timing = world.timings.chunkGeneration.startTiming(true)) { // Paper // Akarin - this.batchScheduler.b(); - this.batchScheduler.a(new ChunkCoordIntPair(i, j)); - CompletableFuture completablefuture = this.batchScheduler.c(); + this.cachePos[0] = i; + this.cacheStatus[0] = chunkstatus; + this.cacheChunk[0] = ichunkaccess; + } - return (Chunk) completablefuture.thenApply(this::a).join(); - } catch (RuntimeException runtimeexception) { - throw this.a(i, j, (Throwable) runtimeexception); - } - // finally { world.timings.syncChunkLoadTimer.stopTiming(); } // Spigot // Paper - } else { + // Paper start - "real" get chunk if loaded + // Note: Partially copied from the getChunkAt method below + @Nullable + public Chunk getChunkAtIfCachedImmediately(int x, int z) { + long k = ChunkCoordIntPair.pair(x, z); + + // Note: Bypass cache to make this MT-Safe + + PlayerChunk playerChunk = this.getChunk(k); + if (playerChunk == null) { return null; } - } - // CraftBukkit start - public Chunk generateChunk(int x, int z) { - try { - this.batchScheduler.b(); - ChunkCoordIntPair pos = new ChunkCoordIntPair(x, z); - this.chunkScheduler.forcePolluteCache(pos); - ((ChunkRegionLoader) this.chunkLoader).blacklist.add(pos.a()); - this.batchScheduler.a(pos); - CompletableFuture completablefuture = this.batchScheduler.c(); - - Chunk chunk = (Chunk) completablefuture.thenApply(this::a).join(); - ((ChunkRegionLoader) this.chunkLoader).blacklist.remove(pos.a()); - return chunk; - } catch (RuntimeException runtimeexception) { - throw this.a(x, z, (Throwable) runtimeexception); - } - } - // CraftBukkit end - - public IChunkAccess a(int i, int j, boolean flag) { - Chunk chunk = this.getChunkAt(i, j, true, false); - - return (IChunkAccess) (chunk != null ? chunk : (IChunkAccess) this.chunkScheduler.b(new ChunkCoordIntPair(i, j), flag)); - } - - public CompletableFuture loadAllChunks(Iterable iterable, Consumer consumer) { return a(iterable, consumer).thenCompose(protoChunk -> null); } // Paper - overriden in async chunk provider - private CompletableFuture a(Iterable iterable, Consumer consumer) { // Paper - mark private, use above method - this.batchScheduler.b(); - Iterator iterator = iterable.iterator(); - - while (iterator.hasNext()) { - ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next(); - Chunk chunk = this.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, true, false); - - if (chunk != null) { - consumer.accept(chunk); - } else { - this.batchScheduler.a(chunkcoordintpair).thenApply(this::a).thenAccept(consumer); - } - } - - return this.batchScheduler.c(); - } - - ReportedException generateChunkError(int i, int j, Throwable throwable) { return a(i, j, throwable); } // Paper - OBFHELPER - private ReportedException a(int i, int j, Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Exception generating new chunk"); - CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Chunk to be generated"); - - crashreportsystemdetails.a("Location", (Object) String.format("%d,%d", i, j)); - crashreportsystemdetails.a("Position hash", (Object) ChunkCoordIntPair.a(i, j)); - crashreportsystemdetails.a("Generator", (Object) this.chunkGenerator); - return new ReportedException(crashreport); - } - - private Chunk a(IChunkAccess ichunkaccess) { - ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); - int i = chunkcoordintpair.x; - int j = chunkcoordintpair.z; - long k = ChunkCoordIntPair.a(i, j); - Long2ObjectMap long2objectmap = this.chunks; - Chunk chunk; - - synchronized (this.chunks) { - Chunk chunk1 = (Chunk) this.chunks.get(k); - - if (chunk1 != null) { - return chunk1; - } - - if (ichunkaccess instanceof Chunk) { - chunk = (Chunk) ichunkaccess; - } else { - if (!(ichunkaccess instanceof ProtoChunk)) { - throw new IllegalStateException(); - } - - chunk = new Chunk(this.world, (ProtoChunk) ichunkaccess, i, j); - } - - this.chunks.put(k, chunk); - //this.lastChunk = chunk; // Paper - } - - this.asyncTaskHandler.postToMainThread(chunk::addEntities); - return chunk; - } - - public void saveChunk(IChunkAccess ichunkaccess, boolean unloaded) { // Spigot - try (co.aikar.timings.Timing timed = world.timings.chunkSaveData.startTimingUnsafe()) { // Paper - Timings - ichunkaccess.setLastSaved(this.world.getTime()); - this.chunkLoader.saveChunk(this.world, ichunkaccess, unloaded); // Spigot - } catch (IOException ioexception) { - // Paper start - String msg = "Couldn\'t save chunk"; - ChunkProviderServer.a.error(msg, ioexception); - ServerInternalException.reportInternalException(ioexception); - } catch (ExceptionWorldConflict exceptionworldconflict) { - ChunkProviderServer.a.error("Couldn\'t save chunk; already in use by another instance of Minecraft?", exceptionworldconflict); - String msg = "Couldn\'t save chunk; already in use by another instance of Minecraft?"; - ChunkProviderServer.a.error(msg, exceptionworldconflict); - ServerInternalException.reportInternalException(exceptionworldconflict); - // Paper end - } - - } - - public boolean a(boolean flag) { - int i = 0; - - this.chunkScheduler.a(() -> { - return true; - }); - IChunkLoader ichunkloader = this.chunkLoader; - - synchronized (this.chunkLoader) { - ObjectIterator objectiterator = this.chunks.values().iterator(); - - // Paper start - final ChunkRegionLoader chunkLoader = (ChunkRegionLoader) world.getChunkProvider().chunkLoader; - final int queueSize = chunkLoader.getQueueSize(); - - final long now = System.currentTimeMillis(); - final long timeSince = (now - lastSaveStatPrinted) / 1000; - final Integer printRateSecs = Integer.getInteger("printSaveStats"); - if (printRateSecs != null && timeSince >= printRateSecs) { - final String timeStr = "/" + timeSince +"s"; - final long queuedSaves = chunkLoader.getQueuedSaves(); - long queuedDiff = queuedSaves - lastQueuedSaves; - lastQueuedSaves = queuedSaves; - - final long processedSaves = chunkLoader.getProcessedSaves(); - long processedDiff = processedSaves - lastProcessedSaves; - lastProcessedSaves = processedSaves; - - lastSaveStatPrinted = now; - if (processedDiff > 0 || queueSize > 0 || queuedDiff > 0) { - System.out.println("[Chunk Save Stats] " + world.worldData.getName() + - " - Current: " + queueSize + - " - Queued: " + queuedDiff + timeStr + - " - Processed: " +processedDiff + timeStr - ); - } - } - if (!flag && queueSize > world.paperConfig.queueSizeAutoSaveThreshold){ - return false; - } - // Paper end - while (objectiterator.hasNext()) { - Chunk chunk = (Chunk) objectiterator.next(); - - if (chunk.c(flag)) { - this.saveChunk(chunk, false); // Spigot - chunk.a(false); - ++i; - if (!flag && i >= world.paperConfig.maxAutoSaveChunksPerTick) { // Spigot - // Paper - Incremental Auto Save - cap max - return false; - } - } - } - - return true; - } - } - - public void close() { - // Paper start - we do not need to wait for chunk generations to finish on close - /*try { - this.batchScheduler.a(); - } catch (InterruptedException interruptedexception) { - ChunkProviderServer.a.error("Couldn't stop taskManager", interruptedexception); - }*/ - // Paper end - - } - - public void c() { - IChunkLoader ichunkloader = this.chunkLoader; - - synchronized (this.chunkLoader) { - this.chunkLoader.b(); - } - } - - private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.96; // Spigot - - public boolean unloadChunks(BooleanSupplier booleansupplier) { - if (!this.world.savingDisabled) { - if (!this.unloadQueue.isEmpty()) { - // Spigot start - org.spigotmc.SlackActivityAccountant activityAccountant = this.world.getMinecraftServer().slackActivityAccountant; - activityAccountant.startActivity(0.5); - int targetSize = Math.min(this.unloadQueue.size() - 100, (int) (this.unloadQueue.size() * UNLOAD_QUEUE_RESIZE_FACTOR)); // Paper - Make more aggressive - // Spigot end - Iterator iterator = this.unloadQueue.iterator(); - - while (iterator.hasNext()) { // Spigot - Long olong = (Long) iterator.next(); - iterator.remove(); // Spigot - IChunkLoader ichunkloader = this.chunkLoader; - - synchronized (this.chunkLoader) { - Chunk chunk = (Chunk) this.chunks.get(olong); - - if (chunk != null) { - // CraftBukkit start - move unload logic to own method - if (!unloadChunk(chunk, true)) { - continue; - } - // CraftBukkit end - - // Spigot start - if (!booleansupplier.getAsBoolean() && this.unloadQueue.size() <= targetSize && activityAccountant.activityTimeIsExhausted()) { - break; - } - // Spigot end - } - } - } - activityAccountant.endActivity(); // Spigot - } - // Paper start - delayed chunk unloads - long now = System.currentTimeMillis(); - long unloadAfter = world.paperConfig.delayChunkUnloadsBy; - if (unloadAfter > 0) { - //noinspection Convert2streamapi - for (Chunk chunk : chunks.values()) { - if (chunk.scheduledForUnload != null && now - chunk.scheduledForUnload > unloadAfter) { - chunk.scheduledForUnload = null; - unload(chunk); - } - } - } - // Paper end - - this.chunkScheduler.a(booleansupplier); - } - - return false; - } - - // CraftBukkit start - public boolean unloadChunk(Chunk chunk, boolean save) { - ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk, save); - this.world.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return false; - } - save = event.isSaveChunk(); - chunk.lightingQueue.processUnload(); // Paper - - // Update neighbor counts - for (int x = -2; x < 3; x++) { - for (int z = -2; z < 3; z++) { - if (x == 0 && z == 0) { - continue; - } - - Chunk neighbor = this.chunks.get(chunk.chunkKey); // Paper - if (neighbor != null) { - neighbor.setNeighborUnloaded(-x, -z); - chunk.setNeighborUnloaded(x, z); - } - } - } - // Moved from unloadChunks above - synchronized (this.chunkLoader) { - chunk.removeEntities(); - if (save) { - this.saveChunk(chunk, true); // Spigot - } - this.chunks.remove(chunk.chunkKey); - // this.lastChunk = null; // Paper - } - return true; - } - // CraftBukkit end - - public boolean d() { - return !this.world.savingDisabled; - } - - public String getName() { - return "ServerChunkCache: " + this.chunks.size() + " Drop: " + this.unloadQueue.size(); - } - - public List a(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { - return this.chunkGenerator.getMobsFor(enumcreaturetype, blockposition); - } - - public int a(World world, boolean flag, boolean flag1) { - return this.chunkGenerator.a(world, flag, flag1); + return playerChunk.getFullChunkIfCached(); } @Nullable - public BlockPosition a(World world, String s, BlockPosition blockposition, int i, boolean flag) { - return this.chunkGenerator.findNearestMapFeature(world, s, blockposition, i, flag); + public Chunk getChunkAtIfLoadedImmediately(int x, int z) { + long k = ChunkCoordIntPair.pair(x, z); + + // Note: Bypass cache since we need to check ticket level, and to make this MT-Safe + + PlayerChunk playerChunk = this.getChunk(k); + if (playerChunk == null) { + return null; + } + + return playerChunk.getFullChunk(); } + @Nullable + public IChunkAccess getChunkAtImmediately(int x, int z) { + long k = ChunkCoordIntPair.pair(x, z); + + // Note: Bypass cache to make this MT-Safe + + PlayerChunk playerChunk = this.getChunk(k); + if (playerChunk == null) { + return null; + } + + return playerChunk.getAvailableChunkNow(); + + } + + private long asyncLoadSeqCounter; + + public void getChunkAtAsynchronously(int x, int z, boolean gen, java.util.function.Consumer onComplete) { + if (Thread.currentThread() != this.serverThread) { + this.serverThreadQueue.execute(() -> { + this.getChunkAtAsynchronously(x, z, gen, onComplete); + }); + return; + } + + long k = ChunkCoordIntPair.pair(x, z); + ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(x, z); + + IChunkAccess ichunkaccess; + + // try cache + for (int l = 0; l < 4; ++l) { + if (k == this.cachePos[l] && ChunkStatus.FULL == this.cacheStatus[l]) { + ichunkaccess = this.cacheChunk[l]; + if (ichunkaccess != null) { // CraftBukkit - the chunk can become accessible in the meantime TODO for non-null chunks it might also make sense to check that the chunk's state hasn't changed in the meantime + + // move to first in cache + + for (int i1 = 3; i1 > 0; --i1) { + this.cachePos[i1] = this.cachePos[i1 - 1]; + this.cacheStatus[i1] = this.cacheStatus[i1 - 1]; + this.cacheChunk[i1] = this.cacheChunk[i1 - 1]; + } + + this.cachePos[0] = k; + this.cacheStatus[0] = ChunkStatus.FULL; + this.cacheChunk[0] = ichunkaccess; + + onComplete.accept((Chunk)ichunkaccess); + + return; + } + } + } + + if (gen) { + this.bringToFullStatusAsync(x, z, chunkPos, onComplete); + return; + } + + IChunkAccess current = this.getChunkAtImmediately(x, z); // we want to bypass ticket restrictions + if (current != null) { + if (!(current instanceof ProtoChunkExtension) && !(current instanceof net.minecraft.server.Chunk)) { + onComplete.accept(null); // the chunk is not gen'd + return; + } + // we know the chunk is at full status here (either in read-only mode or the real thing) + this.bringToFullStatusAsync(x, z, chunkPos, onComplete); + return; + } + + ChunkStatus status = world.getChunkProvider().playerChunkMap.getStatusOnDiskNoLoad(x, z); + + if (status != null && status != ChunkStatus.FULL) { + // does not exist on disk + onComplete.accept(null); + return; + } + + if (status == ChunkStatus.FULL) { + this.bringToFullStatusAsync(x, z, chunkPos, onComplete); + return; + } + + // status is null here + + // here we don't know what status it is and we're not supposed to generate + // so we asynchronously load empty status + + this.bringToStatusAsync(x, z, chunkPos, ChunkStatus.EMPTY, (IChunkAccess chunk) -> { + if (!(chunk instanceof ProtoChunkExtension) && !(chunk instanceof net.minecraft.server.Chunk)) { + // the chunk on disk was not a full status chunk + onComplete.accept(null); + return; + } + this.bringToFullStatusAsync(x, z, chunkPos, onComplete); // bring to full status if required + }); + } + + private void bringToFullStatusAsync(int x, int z, ChunkCoordIntPair chunkPos, java.util.function.Consumer onComplete) { + this.bringToStatusAsync(x, z, chunkPos, ChunkStatus.FULL, (java.util.function.Consumer)onComplete); + } + + private void bringToStatusAsync(int x, int z, ChunkCoordIntPair chunkPos, ChunkStatus status, java.util.function.Consumer onComplete) { + CompletableFuture> future = this.getChunkFutureMainThread(x, z, status, true); + Long identifier = Long.valueOf(this.asyncLoadSeqCounter++); + int ticketLevel = MCUtil.getTicketLevelFor(status); + this.addTicketAtLevel(TicketType.ASYNC_LOAD, chunkPos, ticketLevel, identifier); + + future.whenCompleteAsync((Either either, Throwable throwable) -> { + // either left -> success + // either right -> failure + + if (throwable != null) { + throw new RuntimeException(throwable); + } + + this.removeTicketAtLevel(TicketType.ASYNC_LOAD, chunkPos, ticketLevel, identifier); + this.addTicketAtLevel(TicketType.UNKNOWN, chunkPos, ticketLevel, chunkPos); // allow unloading + + Optional failure = either.right(); + + if (failure.isPresent()) { + // failure + throw new IllegalStateException("Chunk failed to load: " + failure.get().toString()); + } + + onComplete.accept(either.left().get()); + + }, this.serverThreadQueue); + } + + public void addTicketAtLevel(TicketType ticketType, ChunkCoordIntPair chunkPos, int ticketLevel, T identifier) { + this.chunkMapDistance.addTicketAtLevel(ticketType, chunkPos, ticketLevel, identifier); + } + + public void removeTicketAtLevel(TicketType ticketType, ChunkCoordIntPair chunkPos, int ticketLevel, T identifier) { + this.chunkMapDistance.removeTicketAtLevel(ticketType, chunkPos, ticketLevel, identifier); + } + // Paper end + + @Nullable + @Override + public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { + final int x = i; final int z = j; // Paper - conflict on variable change + if (Thread.currentThread() != this.serverThread) { + return (IChunkAccess) CompletableFuture.supplyAsync(() -> { + return this.getChunkAt(i, j, chunkstatus, flag); + }, this.serverThreadQueue).join(); + } else { + long k = ChunkCoordIntPair.pair(i, j); + + IChunkAccess ichunkaccess; + + for (int l = 0; l < 4; ++l) { + if (k == this.cachePos[l] && chunkstatus == this.cacheStatus[l]) { + ichunkaccess = this.cacheChunk[l]; + if (ichunkaccess != null) { // CraftBukkit - the chunk can become accessible in the meantime TODO for non-null chunks it might also make sense to check that the chunk's state hasn't changed in the meantime + return ichunkaccess; + } + } + } + + CompletableFuture> completablefuture = this.getChunkFutureMainThread(i, j, chunkstatus, flag); + + if (!completablefuture.isDone()) { // Paper + // Paper start - async chunk io/loading + this.world.asyncChunkTaskManager.raisePriority(x, z, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY); + com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.world, x, z); + // Paper end + com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.world, x, z); // Paper - sync load info + this.world.timings.chunkAwait.startTiming(); // Paper + this.serverThreadQueue.awaitTasks(completablefuture::isDone); + com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug + this.world.timings.chunkAwait.stopTiming(); // Paper + } // Paper + ichunkaccess = (IChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { + return ichunkaccess1; + }, (playerchunk_failure) -> { + if (flag) { + throw new IllegalStateException("Chunk not there when requested: " + playerchunk_failure); + } else { + return null; + } + }); + this.a(k, ichunkaccess, chunkstatus); + return ichunkaccess; + } + } + + @Nullable + @Override + public Chunk a(int i, int j) { + if (Thread.currentThread() != this.serverThread) { + return null; + } else { + long k = ChunkCoordIntPair.pair(i, j); + + for (int l = 0; l < 4; ++l) { + if (k == this.cachePos[l] && this.cacheStatus[l] == ChunkStatus.FULL) { + IChunkAccess ichunkaccess = this.cacheChunk[l]; + + return ichunkaccess instanceof Chunk ? (Chunk) ichunkaccess : null; + } + } + + PlayerChunk playerchunk = this.getChunk(k); + + if (playerchunk == null) { + return null; + } else { + Either either = (Either) playerchunk.b(ChunkStatus.FULL).getNow(null); // Craftbukkit - decompile error + + if (either == null) { + return null; + } else { + IChunkAccess ichunkaccess1 = (IChunkAccess) either.left().orElse(null); // Craftbukkit - decompile error + + if (ichunkaccess1 != null) { + this.a(k, ichunkaccess1, ChunkStatus.FULL); + if (ichunkaccess1 instanceof Chunk) { + return (Chunk) ichunkaccess1; + } + } + + return null; + } + } + } + } + + private void clearCache() { + Arrays.fill(this.cachePos, ChunkCoordIntPair.a); + Arrays.fill(this.cacheStatus, (Object) null); + Arrays.fill(this.cacheChunk, (Object) null); + } + + private CompletableFuture> getChunkFutureMainThread(int i, int j, ChunkStatus chunkstatus, boolean flag) { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + long k = chunkcoordintpair.pair(); + int l = 33 + ChunkStatus.a(chunkstatus); + PlayerChunk playerchunk = this.getChunk(k); + + // CraftBukkit start - don't add new ticket for currently unloading chunk + boolean currentlyUnloading = false; + if (playerchunk != null) { + PlayerChunk.State oldChunkState = PlayerChunk.getChunkState(playerchunk.oldTicketLevel); + PlayerChunk.State currentChunkState = PlayerChunk.getChunkState(playerchunk.getTicketLevel()); + currentlyUnloading = (oldChunkState.isAtLeast(PlayerChunk.State.BORDER) && !currentChunkState.isAtLeast(PlayerChunk.State.BORDER)); + } + if (flag && !currentlyUnloading) { + // CraftBukkit end + this.chunkMapDistance.a(TicketType.UNKNOWN, chunkcoordintpair, l, chunkcoordintpair); + if (this.a(playerchunk, l)) { + GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler(); + + gameprofilerfiller.enter("chunkLoad"); + this.tickDistanceManager(); + playerchunk = this.getChunk(k); + gameprofilerfiller.exit(); + if (this.a(playerchunk, l)) { + throw new IllegalStateException("No chunk holder after ticket has been added"); + } + } + } + + return this.a(playerchunk, l) ? PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE : playerchunk.a(chunkstatus, this.playerChunkMap); + } + + private boolean a(@Nullable PlayerChunk playerchunk, int i) { + return playerchunk == null || playerchunk.oldTicketLevel > i; // CraftBukkit using oldTicketLevel for isLoaded checks + } + + public boolean isLoaded(int i, int j) { + PlayerChunk playerchunk = this.getChunk((new ChunkCoordIntPair(i, j)).pair()); + int k = 33 + ChunkStatus.a(ChunkStatus.FULL); + + return !this.a(playerchunk, k); + } + + @Override + public IBlockAccess c(int i, int j) { + long k = ChunkCoordIntPair.pair(i, j); + PlayerChunk playerchunk = this.getChunk(k); + + if (playerchunk == null) { + return null; + } else { + int l = ChunkProviderServer.c.size() - 1; + + while (true) { + ChunkStatus chunkstatus = (ChunkStatus) ChunkProviderServer.c.get(l); + Optional optional = ((Either) playerchunk.getStatusFutureUnchecked(chunkstatus).getNow(PlayerChunk.UNLOADED_CHUNK_ACCESS)).left(); + + if (optional.isPresent()) { + return (IBlockAccess) optional.get(); + } + + if (chunkstatus == ChunkStatus.LIGHT.e()) { + return null; + } + + --l; + } + } + } + + @Override + public World getWorld() { + return this.world; + } + + public boolean runTasks() { + return this.serverThreadQueue.executeNext(); + } + + private boolean tickDistanceManager() { + boolean flag = this.chunkMapDistance.a(this.playerChunkMap); + boolean flag1 = this.playerChunkMap.b(); + + if (!flag && !flag1) { + return false; + } else { + this.clearCache(); + return true; + } + } + + @Override + public boolean a(Entity entity) { + long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4); + + return this.a(i, PlayerChunk::b); + } + + @Override + public boolean a(ChunkCoordIntPair chunkcoordintpair) { + return this.a(chunkcoordintpair.pair(), PlayerChunk::b); + } + + @Override + public boolean a(BlockPosition blockposition) { + long i = ChunkCoordIntPair.pair(blockposition.getX() >> 4, blockposition.getZ() >> 4); + + return this.a(i, PlayerChunk::a); + } + + public boolean b(Entity entity) { + long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4); + + return this.a(i, PlayerChunk::c); + } + + private boolean a(long i, Function>> function) { + PlayerChunk playerchunk = this.getChunk(i); + + if (playerchunk == null) { + return false; + } else { + Either either = (Either) ((CompletableFuture) function.apply(playerchunk)).getNow(PlayerChunk.UNLOADED_CHUNK); + + return either.left().isPresent(); + } + } + + public void save(boolean flag) { + this.tickDistanceManager(); + try (co.aikar.timings.Timing timed = world.timings.chunkSaveData.startTiming()) { // Paper - Timings + this.playerChunkMap.save(flag); + } // Paper - Timings + } + + // Paper start - duplicate save, but call incremental + public void saveIncrementally() { + this.tickDistanceManager(); + try (co.aikar.timings.Timing timed = world.timings.chunkSaveData.startTiming()) { // Paper - Timings + this.playerChunkMap.saveIncrementally(); + } // Paper - Timings + } + // Paper end + + @Override + public void close() throws IOException { + // CraftBukkit start + close(true); + } + + public void close(boolean save) throws IOException { + if (save) { + this.save(true); + } + // CraftBukkit end + this.lightEngine.close(); + this.playerChunkMap.close(); + } + + // CraftBukkit start - modelled on below + public void purgeUnload() { + this.world.getMethodProfiler().enter("purge"); + this.chunkMapDistance.purgeTickets(); + this.tickDistanceManager(); + this.world.getMethodProfiler().exitEnter("unload"); + this.playerChunkMap.unloadChunks(() -> true); + this.world.getMethodProfiler().exit(); + this.clearCache(); + } + // CraftBukkit end + + public void tick(BooleanSupplier booleansupplier) { + this.world.getMethodProfiler().enter("purge"); + this.world.timings.doChunkMap.startTiming(); // Spigot + this.chunkMapDistance.purgeTickets(); + this.tickDistanceManager(); + this.world.timings.doChunkMap.stopTiming(); // Spigot + this.world.getMethodProfiler().exitEnter("chunks"); + this.world.timings.chunks.startTiming(); // Paper - timings + this.tickChunks(); + this.world.timings.chunks.stopTiming(); // Paper - timings + this.world.timings.doChunkUnload.startTiming(); // Spigot + this.world.getMethodProfiler().exitEnter("unload"); + this.playerChunkMap.unloadChunks(booleansupplier); + this.world.timings.doChunkUnload.stopTiming(); // Spigot + this.world.getMethodProfiler().exit(); + this.clearCache(); + } + + private void tickChunks() { + long i = this.world.getTime(); + long j = i - this.lastTickTime; + + this.lastTickTime = i; + WorldData worlddata = this.world.getWorldData(); + boolean flag = worlddata.getType() == WorldType.DEBUG_ALL_BLOCK_STATES; + boolean flag1 = this.world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && !world.getPlayers().isEmpty(); // CraftBukkit + + if (!flag) { + this.world.getMethodProfiler().enter("pollingChunks"); + int k = this.world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED); + BlockPosition blockposition = this.world.getSpawn(); + boolean flag2 = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; // CraftBukkit // PAIL: TODO monster ticks + + this.world.getMethodProfiler().enter("naturalSpawnCount"); + this.world.timings.countNaturalMobs.startTiming(); // Paper - timings + int l = this.chunkMapDistance.b(); + EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values(); + // Paper start - per player mob spawning + int[] worldMobCount; + if (this.playerChunkMap.playerMobDistanceMap != null) { + // update distance map + this.world.timings.playerMobDistanceMapUpdate.startTiming(); + this.playerChunkMap.playerMobDistanceMap.update(this.world.players, this.playerChunkMap.viewDistance); + this.world.timings.playerMobDistanceMapUpdate.stopTiming(); + // re-set mob counts + for (EntityPlayer player : this.world.players) { + Arrays.fill(player.mobCounts, 0); + } + worldMobCount = this.world.countMobs(true); + } else { + worldMobCount = this.world.countMobs(false); + } + // Paper end + + this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings + this.world.getMethodProfiler().exit(); + this.playerChunkMap.f().forEach((playerchunk) -> { + Optional optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); + + if (optional.isPresent()) { + Chunk chunk = (Chunk) optional.get(); + + this.world.getMethodProfiler().enter("broadcast"); + this.world.timings.broadcastChunkUpdates.startTiming(); // Paper - timings + playerchunk.a(chunk); + this.world.timings.broadcastChunkUpdates.stopTiming(); // Paper - timings + this.world.getMethodProfiler().exit(); + ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + + // Paper start - timings + this.world.timings.chunkRangeCheckBig.startTiming(); + // note: this is just a copy of the expression in the if + boolean bigRadiusOutsideRange = !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair); + this.world.timings.chunkRangeCheckBig.stopTiming(); + if (bigRadiusOutsideRange) { + // Paper end + chunk.b(chunk.q() + j); + // Paper start - timings + this.world.timings.chunkRangeCheckSmall.startTiming(); + // note: this is just a copy of the expression in the if + boolean smallRadiusOutsideRange = flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair, true); + this.world.timings.chunkRangeCheckSmall.stopTiming(); + if (smallRadiusOutsideRange) { // Spigot + // Paper end + this.world.getMethodProfiler().enter("spawner"); + this.world.timings.mobSpawn.startTiming(); // Spigot + EnumCreatureType[] aenumcreaturetype1 = aenumcreaturetype; + int i1 = aenumcreaturetype.length; + + for (int j1 = 0; j1 < i1; ++j1) { + EnumCreatureType enumcreaturetype = aenumcreaturetype1[j1]; + + // CraftBukkit start - Use per-world spawn limits + int limit = enumcreaturetype.b(); + switch (enumcreaturetype) { + case MONSTER: + limit = world.getWorld().getMonsterSpawnLimit(); + break; + case CREATURE: + limit = world.getWorld().getAnimalSpawnLimit(); + break; + case WATER_CREATURE: + limit = world.getWorld().getWaterAnimalSpawnLimit(); + break; + case AMBIENT: + limit = world.getWorld().getAmbientSpawnLimit(); + break; + } + + if (limit == 0) { + continue; + } + // CraftBukkit end + + if (enumcreaturetype != EnumCreatureType.MISC && (!enumcreaturetype.c() || this.allowAnimals) && (enumcreaturetype.c() || this.allowMonsters) && (!enumcreaturetype.d() || flag2)) { + int k1 = limit * l / ChunkProviderServer.b; // CraftBukkit - use per-world limits + + // Paper start - only allow spawns upto the limit per chunk and update count afterwards + int currEntityCount = worldMobCount[enumcreaturetype.ordinal()]; + int difference = k1 - currEntityCount; + + if (this.world.paperConfig.perPlayerMobSpawns) { + int minDiff = Integer.MAX_VALUE; + for (EntityPlayer entityplayer : this.playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) { + minDiff = Math.min(limit - this.playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff); + } + difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; + } + + if (difference > 0) { + int spawnCount = SpawnerCreature.spawnMobs(enumcreaturetype, this.world, chunk, blockposition, difference, + this.world.paperConfig.perPlayerMobSpawns ? this.playerChunkMap::updatePlayerMobTypeMap : null); + worldMobCount[enumcreaturetype.ordinal()] += spawnCount; + // Paper end + } + } + } + + this.world.timings.mobSpawn.stopTiming(); // Spigot + this.world.getMethodProfiler().exit(); + } + + this.world.timings.chunkTicks.startTiming(); // Spigot // Paper + this.world.a(chunk, k); + this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper + } + } + }); + this.world.getMethodProfiler().enter("customSpawners"); + if (flag1) { + try (co.aikar.timings.Timing ignored = this.world.timings.miscMobSpawning.startTiming()) { // Paper - timings + this.chunkGenerator.doMobSpawning(this.world, this.allowMonsters, this.allowAnimals); + } // Paper - timings + } + + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().exit(); + } + + this.playerChunkMap.g(); + } + + @Override + public String getName() { + return "ServerChunkCache: " + this.h(); + } + + @VisibleForTesting + public int f() { + return this.serverThreadQueue.be(); + } + + @Override public ChunkGenerator getChunkGenerator() { return this.chunkGenerator; } - public int g() { - return this.chunks.size(); + public int h() { + return this.playerChunkMap.d(); } - public boolean isLoaded(int i, int j) { - return this.chunks.get(ChunkCoordIntPair.asLong(i, j)) != null; // Paper - use get for last access + public void flagDirty(BlockPosition blockposition) { + int i = blockposition.getX() >> 4; + int j = blockposition.getZ() >> 4; + PlayerChunk playerchunk = this.getChunk(ChunkCoordIntPair.pair(i, j)); + + if (playerchunk != null) { + playerchunk.a(blockposition.getX() & 15, blockposition.getY(), blockposition.getZ() & 15); + } + + } + + @Override + public void a(EnumSkyBlock enumskyblock, SectionPosition sectionposition) { + this.serverThreadQueue.execute(() -> { + PlayerChunk playerchunk = this.getChunk(sectionposition.u().pair()); + + if (playerchunk != null) { + playerchunk.a(enumskyblock, sectionposition.b()); + } + + }); + } + + public void addTicket(TicketType tickettype, ChunkCoordIntPair chunkcoordintpair, int i, T t0) { + this.chunkMapDistance.addTicket(tickettype, chunkcoordintpair, i, t0); + } + + public void removeTicket(TicketType tickettype, ChunkCoordIntPair chunkcoordintpair, int i, T t0) { + this.chunkMapDistance.removeTicket(tickettype, chunkcoordintpair, i, t0); + } + + @Override + public void a(ChunkCoordIntPair chunkcoordintpair, boolean flag) { + this.chunkMapDistance.a(chunkcoordintpair, flag); + } + + public void movePlayer(EntityPlayer entityplayer) { + this.playerChunkMap.movePlayer(entityplayer); + } + + public void removeEntity(Entity entity) { + this.playerChunkMap.removeEntity(entity); + } + + public void addEntity(Entity entity) { + this.playerChunkMap.addEntity(entity); + } + + public void broadcastIncludingSelf(Entity entity, Packet packet) { + this.playerChunkMap.broadcastIncludingSelf(entity, packet); + } + + public void broadcast(Entity entity, Packet packet) { + this.playerChunkMap.broadcast(entity, packet); + } + + public void setViewDistance(int i) { + this.playerChunkMap.setViewDistance(i); + } + + @Override + public void a(boolean flag, boolean flag1) { + this.allowMonsters = flag; + this.allowAnimals = flag1; + } + + public WorldPersistentData getWorldPersistentData() { + return this.worldPersistentData; + } + + public VillagePlace j() { + return this.playerChunkMap.h(); + } + + final class a extends IAsyncTaskHandler { + + private a(World world) { + super("Chunk source main thread executor for " + IRegistry.DIMENSION_TYPE.getKey(world.getWorldProvider().getDimensionManager())); + } + + @Override + protected Runnable postToMainThread(Runnable runnable) { + return runnable; + } + + @Override + protected boolean canExecute(Runnable runnable) { + return true; + } + + @Override + protected boolean isNotMainThread() { + return true; + } + + @Override + protected Thread getThread() { + return ChunkProviderServer.this.serverThread; + } + + @Override + protected boolean executeNext() { + // CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task + try { + boolean execChunkTask = com.destroystokyo.paper.io.chunk.ChunkTaskManager.pollChunkWaitQueue() || ChunkProviderServer.this.world.asyncChunkTaskManager.pollNextChunkTask(); // Paper + if (ChunkProviderServer.this.tickDistanceManager()) { + return true; + } else { + ChunkProviderServer.this.lightEngine.queueUpdate(); + return super.executeNext() || execChunkTask; // Paper + } + } finally { + playerChunkMap.callbackExecutor.run(); + } + // CraftBukkit end + } } } diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java index dce52ac0f..98cc4efcf 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java @@ -2,796 +2,565 @@ package net.minecraft.server; import co.aikar.timings.Timings; import com.google.common.collect.Maps; -import com.mojang.datafixers.DataFixTypes; -import com.mojang.datafixers.DataFixer; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; import it.unimi.dsi.fastutil.shorts.ShortList; import it.unimi.dsi.fastutil.shorts.ShortListIterator; -import java.io.DataInputStream; -import java.io.DataOutput; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; +import java.util.ArrayDeque; // Paper +import java.util.Arrays; import java.util.BitSet; +import java.util.EnumSet; import java.util.Iterator; import java.util.Map; +import java.util.Objects; import java.util.Map.Entry; -import java.util.function.Consumer; import java.util.function.Function; import javax.annotation.Nullable; -import java.util.concurrent.ConcurrentLinkedQueue; // Paper import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -// Spigot start -import java.util.function.Supplier; -import org.spigotmc.SupplierUtils; -// Spigot end -public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { +public class ChunkRegionLoader { - // Paper start - Chunk queue improvements - private static class QueuedChunk { - public ChunkCoordIntPair coords; - public Supplier compoundSupplier; - public Runnable onSave; + private static final Logger LOGGER = LogManager.getLogger(); - public QueuedChunk(Runnable run) { - this.coords = null; - this.compoundSupplier = null; - this.onSave = run; - } + // Paper start + public static final class InProgressChunkHolder { - public QueuedChunk(ChunkCoordIntPair coords, Supplier compoundSupplier) { - this.coords = coords; - this.compoundSupplier = compoundSupplier; + public final ProtoChunk protoChunk; + public final ArrayDeque tasks; + + public NBTTagCompound poiData; + + public InProgressChunkHolder(final ProtoChunk protoChunk, final ArrayDeque tasks) { + this.protoChunk = protoChunk; + this.tasks = tasks; } } - final private ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); - // Paper end - private static final Logger a = LogManager.getLogger(); - private final it.unimi.dsi.fastutil.longs.Long2ObjectMap> saveMap = it.unimi.dsi.fastutil.longs.Long2ObjectMaps.synchronize(new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>()); // Paper - private final File c; - private final DataFixer d; - private PersistentStructureLegacy e; - // private boolean f; // CraftBukkit - public final LongSet blacklist = new LongOpenHashSet(); - private static final double SAVE_QUEUE_TARGET_SIZE = 625; // Spigot - // Paper start - support saving to an alternate directory - private final File templateWorld; - private final File actualWorld; - private final boolean useAltWorld; + public static ProtoChunk loadChunk(WorldServer worldserver, DefinedStructureManager definedstructuremanager, VillagePlace villageplace, ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) { + InProgressChunkHolder holder = loadChunk(worldserver, definedstructuremanager, villageplace, chunkcoordintpair, nbttagcompound, true); + holder.tasks.forEach(Runnable::run); + return holder.protoChunk; + } - private void copyIfNeeded(int x, int z) { - if (!useAltWorld) { - return; + public static InProgressChunkHolder loadChunk(WorldServer worldserver, DefinedStructureManager definedstructuremanager, VillagePlace villageplace, ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound, boolean distinguish) { + ArrayDeque tasksToExecuteOnMain = new ArrayDeque<>(); + // Paper end + ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator(); + WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager(); + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level"); + ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos")); + + if (!Objects.equals(chunkcoordintpair, chunkcoordintpair1)) { + ChunkRegionLoader.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", chunkcoordintpair, chunkcoordintpair, chunkcoordintpair1); } - synchronized (RegionFileCache.class) { - if (RegionFileCache.hasRegionFile(this.actualWorld, x, z)) { - return; - } - File actual = RegionFileCache.getRegionFileName(this.actualWorld, x, z); - File template = RegionFileCache.getRegionFileName(this.templateWorld, x, z); - if (!actual.exists() && template.exists()) { - try { - //a.info("Copying" + template + " to " + actual); - java.nio.file.Files.copy(template.toPath(), actual.toPath(), java.nio.file.StandardCopyOption.COPY_ATTRIBUTES); - } catch (IOException e1) { - LogManager.getLogger().error("Error copying " + template + " to " + actual, e1); - MinecraftServer.getServer().safeShutdown(); - com.destroystokyo.paper.util.SneakyThrow.sneaky(e1); + + BiomeBase[] abiomebase = new BiomeBase[256]; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + if (nbttagcompound1.hasKeyOfType("Biomes", 11)) { + int[] aint = nbttagcompound1.getIntArray("Biomes"); + + for (int i = 0; i < aint.length; ++i) { + abiomebase[i] = (BiomeBase) IRegistry.BIOME.fromId(aint[i]); + if (abiomebase[i] == null) { + abiomebase[i] = worldchunkmanager.getBiome(blockposition_mutableblockposition.d((i & 15) + chunkcoordintpair.d(), 0, (i >> 4 & 15) + chunkcoordintpair.e())); } } - } - } - // Paper end - - public ChunkRegionLoader(File file, DataFixer datafixer) { - // Paper start - this.actualWorld = file; - if (com.destroystokyo.paper.PaperConfig.useVersionedWorld) { - this.useAltWorld = true; - String name = file.getName(); - File container = file.getParentFile().getParentFile(); - if (name.equals("DIM-1") || name.equals("DIM1")) { - container = container.getParentFile(); - } - this.templateWorld = new File(container, name); - File region = new File(file, "region"); - if (!region.exists()) { - region.mkdirs(); - } } else { - this.useAltWorld = false; - this.templateWorld = file; - } - // Paper end - this.c = file; - this.d = datafixer; - } - - @Nullable - private NBTTagCompound a(GeneratorAccess generatoraccess, int i, int j) throws IOException { - return this.a(generatoraccess.o().getDimensionManager(), generatoraccess.h(), i, j, generatoraccess); // CraftBukkit - } - - // CraftBukkit start - private boolean check(ChunkProviderServer cps, int x, int z) throws IOException { - if (cps != null) { - //com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread"); // Paper - this is safe - if (cps.isLoaded(x, z)) { - return true; + for (int j = 0; j < abiomebase.length; ++j) { + abiomebase[j] = worldchunkmanager.getBiome(blockposition_mutableblockposition.d((j & 15) + chunkcoordintpair.d(), 0, (j >> 4 & 15) + chunkcoordintpair.e())); } } - if (this.chunkExists(x, z)) { - NBTTagCompound nbt = RegionFileCache.read(this.c, x, z); - if (nbt != null) { - NBTTagCompound level = nbt.getCompound("Level"); - if (level.getBoolean("TerrainPopulated")) { - return true; + ChunkConverter chunkconverter = nbttagcompound1.hasKeyOfType("UpgradeData", 10) ? new ChunkConverter(nbttagcompound1.getCompound("UpgradeData")) : ChunkConverter.a; + ProtoChunkTickList protochunkticklist = new ProtoChunkTickList<>((block) -> { + return block == null || block.getBlockData().isAir(); + }, chunkcoordintpair, nbttagcompound1.getList("ToBeTicked", 9)); + ProtoChunkTickList protochunkticklist1 = new ProtoChunkTickList<>((fluidtype) -> { + return fluidtype == null || fluidtype == FluidTypes.EMPTY; + }, chunkcoordintpair, nbttagcompound1.getList("LiquidsToBeTicked", 9)); + boolean flag = nbttagcompound1.getBoolean("isLightOn"); + NBTTagList nbttaglist = nbttagcompound1.getList("Sections", 10); + boolean flag1 = true; + ChunkSection[] achunksection = new ChunkSection[16]; + boolean flag2 = worldserver.getWorldProvider().g(); + ChunkProviderServer chunkproviderserver = worldserver.getChunkProvider(); + LightEngine lightengine = chunkproviderserver.getLightEngine(); + + if (flag) { + tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main + lightengine.b(chunkcoordintpair, true); + }); // Paper - delay this task since we're executing off-main + } + + for (int k = 0; k < nbttaglist.size(); ++k) { + NBTTagCompound nbttagcompound2 = nbttaglist.getCompound(k); + byte b0 = nbttagcompound2.getByte("Y"); + + if (nbttagcompound2.hasKeyOfType("Palette", 9) && nbttagcompound2.hasKeyOfType("BlockStates", 12)) { + ChunkSection chunksection = new ChunkSection(b0 << 4, null, worldserver, false); // Paper - Anti-Xray + + chunksection.getBlocks().a(nbttagcompound2.getList("Palette", 10), nbttagcompound2.getLongArray("BlockStates")); + chunksection.recalcBlockCounts(); + if (!chunksection.c()) { + achunksection[b0] = chunksection; } - ChunkStatus status = ChunkStatus.a(level.getString("Status")); - if (status != null && status.a(ChunkStatus.DECORATED)) { - return true; + tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main + villageplace.a(chunkcoordintpair, chunksection); + }); // Paper - delay this task since we're executing off-main + } + + if (flag) { + if (nbttagcompound2.hasKeyOfType("BlockLight", 7)) { + // Paper start - delay this task since we're executing off-main + NibbleArray blockLight = new NibbleArray(nbttagcompound2.getByteArray("BlockLight")); + // Note: We move the block light nibble array creation here for perf & in case the compound is modified + tasksToExecuteOnMain.add(() -> { + lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), blockLight); + }); + // Paper end + } + + if (flag2 && nbttagcompound2.hasKeyOfType("SkyLight", 7)) { + // Paper start - delay this task since we're executing off-main + NibbleArray skyLight = new NibbleArray(nbttagcompound2.getByteArray("SkyLight")); + // Note: We move the block light nibble array creation here for perf & in case the compound is modified + tasksToExecuteOnMain.add(() -> { + lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), skyLight); + }); + // Paper end } } } - return false; - } + long l = nbttagcompound1.getLong("InhabitedTime"); + ChunkStatus.Type chunkstatus_type = a(nbttagcompound); + Object object; - public boolean chunkExists(int x, int z) { - // Paper start - if (this.saveMap.containsKey(ChunkCoordIntPair.asLong(x, z))) { - return true; - } - copyIfNeeded(x, z); - return RegionFileCache.chunkExists(this.actualWorld, x, z); - // Paper end - } + if (chunkstatus_type == ChunkStatus.Type.LEVELCHUNK) { + NBTTagList nbttaglist1; + Function function; + RegistryBlocks registryblocks; + Object object1; - @Nullable - private NBTTagCompound a(DimensionManager dimensionmanager, @Nullable PersistentCollection persistentcollection, int i, int j, @Nullable GeneratorAccess generatoraccess) throws IOException { - // CraftBukkit start - if (blacklist.contains(ChunkCoordIntPair.a(i, j))) { - return null; - } - // CraftBukkit end - copyIfNeeded(i, j); // Paper - - NBTTagCompound nbttagcompound = SupplierUtils.getIfExists(this.saveMap.get(ChunkCoordIntPair.asLong(i, j))); // Spigot // Paper - - if (nbttagcompound != null) { - return nbttagcompound; - } else { - NBTTagCompound nbttagcompound1 = RegionFileCache.read(this.c, i, j); - - if (nbttagcompound1 == null) { - return null; + if (nbttagcompound1.hasKeyOfType("TileTicks", 9)) { + nbttaglist1 = nbttagcompound1.getList("TileTicks", 10); + // function = IRegistry.BLOCK::getKey; + registryblocks = IRegistry.BLOCK; + registryblocks.getClass(); + object1 = TickListChunk.a(nbttaglist1, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get); } else { - int k = nbttagcompound1.hasKeyOfType("DataVersion", 99) ? nbttagcompound1.getInt("DataVersion") : -1; - // CraftBukkit start - if (k < 1466) { - NBTTagCompound level = nbttagcompound1.getCompound("Level"); - if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) { - ChunkProviderServer cps = (generatoraccess == null) ? null : ((WorldServer) generatoraccess).getChunkProvider(); - if (check(cps, i - 1, j) && check(cps, i - 1, j - 1) && check(cps, i, j - 1)) { - level.setBoolean("LightPopulated", true); - } - } - } - // CraftBukkit end - - if (k < 1493) { - nbttagcompound1 = GameProfileSerializer.a(this.d, DataFixTypes.CHUNK, nbttagcompound1, k, 1493); - if (nbttagcompound1.getCompound("Level").getBoolean("hasLegacyStructureData")) { - this.a(dimensionmanager, persistentcollection); - nbttagcompound1 = this.e.a(nbttagcompound1); - } - } - - nbttagcompound1 = GameProfileSerializer.a(this.d, DataFixTypes.CHUNK, nbttagcompound1, Math.max(1493, k)); - if (k < 1631) { - nbttagcompound1.setInt("DataVersion", 1631); - this.a(new ChunkCoordIntPair(i, j), new SupplierUtils.ValueSupplier<>(nbttagcompound1)); // Spigot - } - - return nbttagcompound1; + object1 = protochunkticklist; } + + Object object2; + + if (nbttagcompound1.hasKeyOfType("LiquidTicks", 9)) { + nbttaglist1 = nbttagcompound1.getList("LiquidTicks", 10); + // function = IRegistry.FLUID::getKey; + registryblocks = IRegistry.FLUID; + registryblocks.getClass(); + object2 = TickListChunk.a(nbttaglist1, IRegistry.FLUID::getKey, IRegistry.FLUID::get); + } else { + object2 = protochunkticklist1; + } + + object = new Chunk(worldserver.getMinecraftWorld(), chunkcoordintpair, abiomebase, chunkconverter, (TickList) object1, (TickList) object2, l, achunksection, (chunk) -> { + loadEntities(nbttagcompound1, chunk); + }); + } else { + ProtoChunk protochunk = new ProtoChunk(chunkcoordintpair, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, worldserver); // Paper - Anti-Xray + + object = protochunk; + protochunk.a(abiomebase); + protochunk.b(l); + protochunk.a(ChunkStatus.a(nbttagcompound1.getString("Status"))); + if (protochunk.getChunkStatus().b(ChunkStatus.FEATURES)) { + protochunk.a(lightengine); + } + + if (!flag && protochunk.getChunkStatus().b(ChunkStatus.LIGHT)) { + Iterator iterator = BlockPosition.b(chunkcoordintpair.d(), 0, chunkcoordintpair.e(), chunkcoordintpair.f(), 255, chunkcoordintpair.g()).iterator(); + + while (iterator.hasNext()) { + BlockPosition blockposition = (BlockPosition) iterator.next(); + + if (((IChunkAccess) object).getType(blockposition).h() != 0) { + protochunk.k(blockposition); + } + } + } + } + + ((IChunkAccess) object).b(flag); + NBTTagCompound nbttagcompound3 = nbttagcompound1.getCompound("Heightmaps"); + EnumSet enumset = EnumSet.noneOf(HeightMap.Type.class); + Iterator iterator1 = ((IChunkAccess) object).getChunkStatus().h().iterator(); + + while (iterator1.hasNext()) { + HeightMap.Type heightmap_type = (HeightMap.Type) iterator1.next(); + String s = heightmap_type.a(); + + if (nbttagcompound3.hasKeyOfType(s, 12)) { + ((IChunkAccess) object).a(heightmap_type, nbttagcompound3.getLongArray(s)); + } else { + enumset.add(heightmap_type); + } + } + + HeightMap.a((IChunkAccess) object, enumset); + NBTTagCompound nbttagcompound4 = nbttagcompound1.getCompound("Structures"); + + ((IChunkAccess) object).a(a(chunkgenerator, definedstructuremanager, worldchunkmanager, nbttagcompound4)); + ((IChunkAccess) object).b(b(nbttagcompound4)); + if (nbttagcompound1.getBoolean("shouldSave")) { + ((IChunkAccess) object).setNeedsSaving(true); + } + + NBTTagList nbttaglist2 = nbttagcompound1.getList("PostProcessing", 9); + + NBTTagList nbttaglist3; + int i1; + + for (int j1 = 0; j1 < nbttaglist2.size(); ++j1) { + nbttaglist3 = nbttaglist2.b(j1); + + for (i1 = 0; i1 < nbttaglist3.size(); ++i1) { + ((IChunkAccess) object).a(nbttaglist3.d(i1), j1); + } + } + + if (chunkstatus_type == ChunkStatus.Type.LEVELCHUNK) { + return new InProgressChunkHolder(new ProtoChunkExtension((Chunk) object), tasksToExecuteOnMain); // Paper - Async chunk loading + } else { + ProtoChunk protochunk1 = (ProtoChunk) object; + + nbttaglist3 = nbttagcompound1.getList("Entities", 10); + + for (i1 = 0; i1 < nbttaglist3.size(); ++i1) { + protochunk1.b(nbttaglist3.getCompound(i1)); + } + + NBTTagList nbttaglist4 = nbttagcompound1.getList("TileEntities", 10); + + NBTTagCompound nbttagcompound5; + + for (int k1 = 0; k1 < nbttaglist4.size(); ++k1) { + nbttagcompound5 = nbttaglist4.getCompound(k1); + ((IChunkAccess) object).a(nbttagcompound5); + } + + NBTTagList nbttaglist5 = nbttagcompound1.getList("Lights", 9); + + for (int l1 = 0; l1 < nbttaglist5.size(); ++l1) { + NBTTagList nbttaglist6 = nbttaglist5.b(l1); + + for (int i2 = 0; i2 < nbttaglist6.size(); ++i2) { + protochunk1.b(nbttaglist6.d(i2), l1); + } + } + + nbttagcompound5 = nbttagcompound1.getCompound("CarvingMasks"); + Iterator iterator2 = nbttagcompound5.getKeys().iterator(); + + while (iterator2.hasNext()) { + String s1 = (String) iterator2.next(); + WorldGenStage.Features worldgenstage_features = WorldGenStage.Features.valueOf(s1); + + protochunk1.a(worldgenstage_features, BitSet.valueOf(nbttagcompound5.getByteArray(s1))); + } + + return new InProgressChunkHolder(protochunk1, tasksToExecuteOnMain); // Paper - Async chunk loading } } - private final Object legacyStructureLock = new Object(); // Paper - public void getPersistentStructureLegacy(DimensionManager dimensionmanager, @Nullable PersistentCollection persistentcollection) { this.a(dimensionmanager, persistentcollection); } // Paper - public void a(DimensionManager dimensionmanager, @Nullable PersistentCollection persistentcollection) { - if (this.e == null) { - synchronized (legacyStructureLock){ if (this.e == null) { // Paper - this.e = PersistentStructureLegacy.a(dimensionmanager, persistentcollection); - } } } // Paper + // Paper start - async chunk save for unload + public static final class AsyncSaveData { + public final NibbleArray[] blockLight; // null or size of 17 (for indices -1 through 15) + public final NibbleArray[] skyLight; + public final NBTTagList blockTickList; // non-null if we had to go to the server's tick list + public final NBTTagList fluidTickList; // non-null if we had to go to the server's tick list + + public final long worldTime; + + public AsyncSaveData(NibbleArray[] blockLight, NibbleArray[] skyLight, NBTTagList blockTickList, NBTTagList fluidTickList, + long worldTime) { + this.blockLight = blockLight; + this.skyLight = skyLight; + this.blockTickList = blockTickList; + this.fluidTickList = fluidTickList; + this.worldTime = worldTime; + } + } + + // must be called sync + public static AsyncSaveData getAsyncSaveData(WorldServer world, IChunkAccess chunk) { + org.spigotmc.AsyncCatcher.catchOp("preparation of chunk data for async save"); + ChunkCoordIntPair chunkPos = chunk.getPos(); + + LightEngineThreaded lightenginethreaded = world.getChunkProvider().getLightEngine(); + + NibbleArray[] blockLight = new NibbleArray[17 - (-1)]; + NibbleArray[] skyLight = new NibbleArray[17 - (-1)]; + + for (int i = -1; i < 17; ++i) { + NibbleArray blockArray = lightenginethreaded.a(EnumSkyBlock.BLOCK).a(SectionPosition.a(chunkPos, i)); + NibbleArray skyArray = lightenginethreaded.a(EnumSkyBlock.SKY).a(SectionPosition.a(chunkPos, i)); + + // copy data for safety + if (blockArray != null) { + blockArray = blockArray.copy(); + } + if (skyArray != null) { + skyArray = skyArray.copy(); + } + + // apply offset of 1 for -1 starting index + blockLight[i + 1] = blockArray; + skyLight[i + 1] = skyArray; + } + + TickList blockTickList = chunk.n(); + + NBTTagList blockTickListSerialized; + if (blockTickList instanceof ProtoChunkTickList || blockTickList instanceof TickListChunk) { + blockTickListSerialized = null; + } else { + blockTickListSerialized = world.getBlockTickList().a(chunkPos); + } + + TickList fluidTickList = chunk.o(); + + NBTTagList fluidTickListSerialized; + if (fluidTickList instanceof ProtoChunkTickList || fluidTickList instanceof TickListChunk) { + fluidTickListSerialized = null; + } else { + fluidTickListSerialized = world.getFluidTickList().a(chunkPos); + } + + return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, world.getTime()); + } + + public static NBTTagCompound saveChunk(WorldServer worldserver, IChunkAccess ichunkaccess) { + return saveChunk(worldserver, ichunkaccess, null); + } + public static NBTTagCompound saveChunk(WorldServer worldserver, IChunkAccess ichunkaccess, AsyncSaveData asyncsavedata) { + // Paper end + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound.setInt("DataVersion", SharedConstants.a().getWorldVersion()); + nbttagcompound.set("Level", nbttagcompound1); + nbttagcompound1.setInt("xPos", chunkcoordintpair.x); + nbttagcompound1.setInt("zPos", chunkcoordintpair.z); + nbttagcompound1.setLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime()); // Paper - async chunk unloading + nbttagcompound1.setLong("InhabitedTime", ichunkaccess.q()); + nbttagcompound1.setString("Status", ichunkaccess.getChunkStatus().d()); + ChunkConverter chunkconverter = ichunkaccess.p(); + + if (!chunkconverter.a()) { + nbttagcompound1.set("UpgradeData", chunkconverter.b()); + } + + ChunkSection[] achunksection = ichunkaccess.getSections(); + NBTTagList nbttaglist = new NBTTagList(); + LightEngineThreaded lightenginethreaded = worldserver.getChunkProvider().getLightEngine(); + boolean flag = ichunkaccess.r(); + + NBTTagCompound nbttagcompound2; + + for (int i = -1; i < 17; ++i) { // Paper - conflict on loop parameter change + int finalI = i; + ChunkSection chunksection = (ChunkSection) Arrays.stream(achunksection).filter((chunksection1) -> { + return chunksection1 != null && chunksection1.getYPosition() >> 4 == finalI; + }).findFirst().orElse(Chunk.a); + // Paper start - async chunk save for unload + NibbleArray nibblearray; // block light + NibbleArray nibblearray1; // sky light + if (asyncsavedata == null) { + nibblearray = lightenginethreaded.a(EnumSkyBlock.BLOCK).a(SectionPosition.a(chunkcoordintpair, i)); /// Paper - diff on method change (see getAsyncSaveData) + nibblearray1 = lightenginethreaded.a(EnumSkyBlock.SKY).a(SectionPosition.a(chunkcoordintpair, i)); // Paper - diff on method change (see getAsyncSaveData) + } else { + nibblearray = asyncsavedata.blockLight[i + 1]; // +1 to offset the -1 starting index + nibblearray1 = asyncsavedata.skyLight[i + 1]; // +1 to offset the -1 starting index + } + // Paper end + if (chunksection != Chunk.a || nibblearray != null || nibblearray1 != null) { + nbttagcompound2 = new NBTTagCompound(); + nbttagcompound2.setByte("Y", (byte) (i & 255)); + if (chunksection != Chunk.a) { + chunksection.getBlocks().a(nbttagcompound2, "Palette", "BlockStates"); + } + + if (nibblearray != null && !nibblearray.c()) { + nbttagcompound2.setByteArray("BlockLight", nibblearray.asBytes()); + } + + if (nibblearray1 != null && !nibblearray1.c()) { + nbttagcompound2.setByteArray("SkyLight", nibblearray1.asBytes()); + } + + nbttaglist.add(nbttagcompound2); + } + } + + nbttagcompound1.set("Sections", nbttaglist); + if (flag) { + nbttagcompound1.setBoolean("isLightOn", true); + } + + BiomeBase[] abiomebase = ichunkaccess.getBiomeIndex(); + int[] aint = abiomebase != null ? new int[abiomebase.length] : new int[0]; + + if (abiomebase != null) { + for (int j = 0; j < abiomebase.length; ++j) { + aint[j] = IRegistry.BIOME.a(abiomebase[j]); + } + } + + nbttagcompound1.setIntArray("Biomes", aint); + NBTTagList nbttaglist1 = new NBTTagList(); + Iterator iterator = ichunkaccess.c().iterator(); + + while (iterator.hasNext()) { + BlockPosition blockposition = (BlockPosition) iterator.next(); + + nbttagcompound2 = ichunkaccess.j(blockposition); + if (nbttagcompound2 != null) { + nbttaglist1.add(nbttagcompound2); + } + } + + nbttagcompound1.set("TileEntities", nbttaglist1); + NBTTagList nbttaglist2 = new NBTTagList(); + + java.util.List toUpdate = new java.util.ArrayList<>(); // Paper + if (ichunkaccess.getChunkStatus().getType() == ChunkStatus.Type.LEVELCHUNK) { + Chunk chunk = (Chunk) ichunkaccess; + + chunk.d(false); + + for (int k = 0; k < chunk.getEntitySlices().length; ++k) { + Iterator iterator1 = chunk.getEntitySlices()[k].iterator(); + + while (iterator1.hasNext()) { + Entity entity = (Entity) iterator1.next(); + NBTTagCompound nbttagcompound3 = new NBTTagCompound(); + // Paper start + if ((int)Math.floor(entity.locX) >> 4 != chunk.getPos().x || (int)Math.floor(entity.locZ) >> 4 != chunk.getPos().z) { + LogManager.getLogger().warn(entity + " is not in this chunk, skipping save. This a bug fix to a vanilla bug. Do not report this to PaperMC please."); + if (asyncsavedata == null) toUpdate.add(entity); // todo fix this broken code, entityJoinedWorld wont work in this case! + continue; + } + if (asyncsavedata == null && entity.dead) { // todo + continue; + } + // Paper end + if (entity.d(nbttagcompound3)) { + chunk.d(true); + nbttaglist2.add(nbttagcompound3); + } + } + } + + // Paper start - move entities to the correct chunk + for (Entity entity : toUpdate) { + worldserver.entityJoinedWorld(entity); + } + // Paper end + + } else { + ProtoChunk protochunk = (ProtoChunk) ichunkaccess; + + nbttaglist2.addAll(protochunk.y()); + nbttagcompound1.set("Lights", a(protochunk.w())); + nbttagcompound2 = new NBTTagCompound(); + WorldGenStage.Features[] aworldgenstage_features = WorldGenStage.Features.values(); + int l = aworldgenstage_features.length; + + for (int i1 = 0; i1 < l; ++i1) { + WorldGenStage.Features worldgenstage_features = aworldgenstage_features[i1]; + + nbttagcompound2.setByteArray(worldgenstage_features.toString(), ichunkaccess.a(worldgenstage_features).toByteArray()); + } + + nbttagcompound1.set("CarvingMasks", nbttagcompound2); + } + + nbttagcompound1.set("Entities", nbttaglist2); + TickList ticklist = ichunkaccess.n(); // Paper - diff on method change (see getAsyncSaveData) + + if (ticklist instanceof ProtoChunkTickList) { + nbttagcompound1.set("ToBeTicked", ((ProtoChunkTickList) ticklist).b()); + } else if (ticklist instanceof TickListChunk) { + nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).a(asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime())); // Paper - async chunk unloading + // Paper start - async chunk save for unload + } else if (asyncsavedata != null) { + nbttagcompound1.set("TileTicks", asyncsavedata.blockTickList); + // Paper end + } else { + nbttagcompound1.set("TileTicks", worldserver.getBlockTickList().a(chunkcoordintpair)); // Paper - diff on method change (see getAsyncSaveData) + } + + TickList ticklist1 = ichunkaccess.o(); // Paper - diff on method change (see getAsyncSaveData) + + if (ticklist1 instanceof ProtoChunkTickList) { + nbttagcompound1.set("LiquidsToBeTicked", ((ProtoChunkTickList) ticklist1).b()); + } else if (ticklist1 instanceof TickListChunk) { + nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).a(asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime())); // Paper - async chunk unloading + // Paper start - async chunk save for unload + } else if (asyncsavedata != null) { + nbttagcompound1.set("LiquidTicks", asyncsavedata.fluidTickList); + // Paper end + } else { + nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair)); // Paper - diff on method change (see getAsyncSaveData) + } + + nbttagcompound1.set("PostProcessing", a(ichunkaccess.l())); + NBTTagCompound nbttagcompound4 = new NBTTagCompound(); + Iterator iterator2 = ichunkaccess.f().iterator(); + + while (iterator2.hasNext()) { + Entry entry = (Entry) iterator2.next(); + + if (ichunkaccess.getChunkStatus().h().contains(entry.getKey())) { + nbttagcompound4.set(((HeightMap.Type) entry.getKey()).a(), new NBTTagLongArray(((HeightMap) entry.getValue()).a())); + } + } + + nbttagcompound1.set("Heightmaps", nbttagcompound4); + nbttagcompound1.set("Structures", a(chunkcoordintpair, ichunkaccess.h(), ichunkaccess.v())); + return nbttagcompound; } // Paper start - private long queuedSaves = 0; - private final java.util.concurrent.atomic.AtomicLong processedSaves = new java.util.concurrent.atomic.AtomicLong(0L); - public int getQueueSize() { return queue.size(); } - public long getQueuedSaves() { return queuedSaves; } - public long getProcessedSaves() { return processedSaves.longValue(); } + public static ChunkStatus getStatus(NBTTagCompound compound) { + if (compound == null) { + return null; + } + + // Note: Copied from below + return ChunkStatus.getStatus(compound.getCompound("Level").getString("Status")); + } // Paper end - // CraftBukkit start - Add async variant, provide compatibility - @Nullable - public Chunk a(GeneratorAccess generatoraccess, int i, int j, Consumer consumer) throws IOException { - generatoraccess.getMinecraftWorld().timings.syncChunkLoadDataTimer.startTiming(); // Spigot - Object[] data = loadChunk(generatoraccess, i, j, consumer); - generatoraccess.getMinecraftWorld().timings.syncChunkLoadDataTimer.stopTiming(); // Spigot - if (data != null) { - Chunk chunk = (Chunk) data[0]; - NBTTagCompound nbttagcompound = (NBTTagCompound) data[1]; - consumer.accept(chunk); - this.loadEntities(nbttagcompound.getCompound("Level"), chunk); - return chunk; - } - - return null; - } - - public Object[] loadChunk(GeneratorAccess generatoraccess, int i, int j, Consumer consumer) throws IOException { - // CraftBukkit end - NBTTagCompound nbttagcompound = this.a(generatoraccess, i, j); - - if (nbttagcompound == null) { - return null; - } else { - /* - Chunk chunk = this.a(generatoraccess, i, j, nbttagcompound); - - if (chunk != null) { - consumer.accept(chunk); - this.loadEntities(nbttagcompound.getCompound("Level"), chunk); - } - - return chunk; - */ - - return this.a(generatoraccess, i, j, nbttagcompound); - } - } - - @Nullable - public ProtoChunk b(GeneratorAccess generatoraccess, int i, int j, Consumer consumer) throws IOException { - NBTTagCompound nbttagcompound; - - try { - nbttagcompound = this.a(generatoraccess, i, j); - } catch (ReportedException reportedexception) { - if (reportedexception.getCause() instanceof IOException) { - throw (IOException) reportedexception.getCause(); - } - - throw reportedexception; - } - - if (nbttagcompound == null) { - return null; - } else { - ProtoChunk protochunk = this.b(generatoraccess, i, j, nbttagcompound); - - if (protochunk != null) { - consumer.accept(protochunk); - } - - return protochunk; - } - } - - @Nullable - protected Object[] a(GeneratorAccess generatoraccess, int i, int j, NBTTagCompound nbttagcompound) { // CraftBukkit - return Chunk -> Object[] - if (nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8)) { - ChunkStatus.Type chunkstatus_type = this.a(nbttagcompound); - - if (chunkstatus_type != ChunkStatus.Type.LEVELCHUNK) { - return null; - } else { - NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level"); - - if (!nbttagcompound1.hasKeyOfType("Sections", 9)) { - ChunkRegionLoader.a.error("Chunk file at {},{} is missing block data, skipping", i, j); - return null; - } else { - Chunk chunk = this.a(generatoraccess, nbttagcompound1); - - if (!chunk.a(i, j)) { - ChunkRegionLoader.a.error("Chunk file at {},{} is in the wrong location; relocating. (Expected {}, {}, got {}, {})", i, j, i, j, chunk.locX, chunk.locZ); - nbttagcompound1.setInt("xPos", i); - nbttagcompound1.setInt("zPos", j); - - // CraftBukkit start - Have to move tile entities since we don't load them at this stage - NBTTagList tileEntities = nbttagcompound.getCompound("Level").getList("TileEntities", 10); - if (tileEntities != null) { - for (int te = 0; te < tileEntities.size(); te++) { - NBTTagCompound tileEntity = (NBTTagCompound) tileEntities.get(te); - int x = tileEntity.getInt("x") - chunk.locX * 16; - int z = tileEntity.getInt("z") - chunk.locZ * 16; - tileEntity.setInt("x", i * 16 + x); - tileEntity.setInt("z", j * 16 + z); - } - } - // CraftBukkit end - chunk = this.a(generatoraccess, nbttagcompound1); - } - - // CraftBukkit start - Object[] data = new Object[2]; - data[0] = chunk; - data[1] = nbttagcompound; - return data; - // CraftBukkit end - } - } - } else { - ChunkRegionLoader.a.error("Chunk file at {},{} is missing level data, skipping", i, j); - return null; - } - } - - @Nullable - protected ProtoChunk b(GeneratorAccess generatoraccess, int i, int j, NBTTagCompound nbttagcompound) { - if (nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8)) { - ChunkStatus.Type chunkstatus_type = this.a(nbttagcompound); - - if (chunkstatus_type == ChunkStatus.Type.LEVELCHUNK) { - return new ProtoChunkExtension((IChunkAccess) this.a(generatoraccess, i, j, nbttagcompound)[0]); // CraftBukkit - fix up access - } else { - NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level"); - - return this.b(generatoraccess, nbttagcompound1); - } - } else { - ChunkRegionLoader.a.error("Chunk file at {},{} is missing level data, skipping", i, j); - return null; - } - } - - // Spigot start - public void saveChunk(World world, IChunkAccess ichunkaccess) throws IOException, ExceptionWorldConflict { - saveChunk(world, ichunkaccess, false); // Ideally we shouldn't use this, but easier than decompile errors - } - - public void saveChunk(World world, IChunkAccess ichunkaccess, boolean unloaded) throws IOException, ExceptionWorldConflict { - if (ichunkaccess.i().d() == ChunkStatus.Type.PROTOCHUNK) { return; } // Paper - don't save proto chunks - // Spigot end - world.checkSession(); - - try { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - - nbttagcompound.setInt("DataVersion", 1631); - ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); - - nbttagcompound.set("Level", nbttagcompound1); - // Spigot start - Supplier completion; - final long worldTime = world.getTime(); - final boolean worldHasSkyLight = world.worldProvider.g(); - if (ichunkaccess.i().d() == ChunkStatus.Type.LEVELCHUNK) { - final Chunk chunk = (Chunk) ichunkaccess; - saveEntities(nbttagcompound1, chunk, world); - completion = new Supplier() { - public NBTTagCompound get() { - saveBody(chunk, world, nbttagcompound1, worldTime, worldHasSkyLight); - return nbttagcompound; - } - }; - } else { - /* // Paper start - we will never invoke this in an unsafe way - NBTTagCompound nbttagcompound2 = this.a(world, chunkcoordintpair.x, chunkcoordintpair.z); - - if (nbttagcompound2 != null && this.a(nbttagcompound2) == ChunkStatus.Type.LEVELCHUNK) { - return; - }*/ // Paper end - - completion = new Supplier() { - public NBTTagCompound get() { - a((ProtoChunk) ichunkaccess, world, nbttagcompound1, worldTime, worldHasSkyLight); - return nbttagcompound; - } - }; - } - - this.a(chunkcoordintpair, SupplierUtils.createUnivaluedSupplier(completion, unloaded)); // Paper - Remove save queue target size - // Spigot end - } catch (Exception exception) { - ChunkRegionLoader.a.error("Failed to save chunk", exception); - } - - } - - protected void a(ChunkCoordIntPair chunkcoordintpair, Supplier nbttagcompound) { // Spigot - this.saveMap.put(chunkcoordintpair.asLong(), nbttagcompound); // Paper - queue.add(new QueuedChunk(chunkcoordintpair, nbttagcompound)); // Paper - Chunk queue improvements - queuedSaves++; // Paper - FileIOThread.a().a(this); - } - - public boolean a() { - // CraftBukkit start - return this.processSaveQueueEntry(false); - } - - private boolean processSaveQueueEntry(boolean logCompletion) { - // Paper start - Chunk queue improvements - QueuedChunk chunk = queue.poll(); - if (chunk == null) { - // Paper - end - if (logCompletion) { // CraftBukkit - ChunkRegionLoader.a.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.c.getName()); - } - - return false; - } else { - // Paper start - if (chunk.onSave != null) { - chunk.onSave.run(); - return true; - } - // Paper end - ChunkCoordIntPair chunkcoordintpair = chunk.coords; // Paper - Chunk queue improvements - Supplier nbttagcompound = chunk.compoundSupplier; // Spigot // Paper - processedSaves.incrementAndGet(); // Paper - - if (nbttagcompound == null) { - return true; - } else { - try { - // CraftBukkit start - RegionFileCache.write(this.c, chunkcoordintpair.x, chunkcoordintpair.z, SupplierUtils.getIfExists(nbttagcompound)); // Spigot - - // Paper start remove from map only if this was the latest version of the chunk - synchronized (this.saveMap) { - long k = chunkcoordintpair.asLong(); - // This will not equal if a newer version is still pending - wait until newest is saved to remove - if (this.saveMap.get(k) == chunk.compoundSupplier) { - this.saveMap.remove(k); - } - } - // Paper end - /* - NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream); - dataoutputstream.close(); - */ - // CraftBukkit end - if (this.e != null) { - this.e.a(chunkcoordintpair.a()); - } - } catch (Exception exception) { - ChunkRegionLoader.a.error("Failed to save chunk", exception); - } - - return true; - } - } - } - - private ChunkStatus.Type a(@Nullable NBTTagCompound nbttagcompound) { + public static ChunkStatus.Type a(@Nullable NBTTagCompound nbttagcompound) { if (nbttagcompound != null) { ChunkStatus chunkstatus = ChunkStatus.a(nbttagcompound.getCompound("Level").getString("Status")); if (chunkstatus != null) { - return chunkstatus.d(); + return chunkstatus.getType(); } } return ChunkStatus.Type.PROTOCHUNK; } - public void b() { - try { - // this.f = true; // CraftBukkit - - while (true) { - if (this.processSaveQueueEntry(true)) { // CraftBukkit - continue; - } - break; // CraftBukkit - Fix infinite loop when saving chunks - } - } finally { - // this.f = false; // CraftBukkit - } - - } - - private void a(ProtoChunk protochunk, World world, NBTTagCompound nbttagcompound, long worldTime, boolean worldHasSkyLight) { // Spigot - int i = protochunk.getPos().x; - int j = protochunk.getPos().z; - - nbttagcompound.setInt("xPos", i); - nbttagcompound.setInt("zPos", j); - nbttagcompound.setLong("LastUpdate", worldTime); // Spigot - nbttagcompound.setLong("InhabitedTime", protochunk.m()); - nbttagcompound.setString("Status", protochunk.i().b()); - ChunkConverter chunkconverter = protochunk.v(); - - if (!chunkconverter.a()) { - nbttagcompound.set("UpgradeData", chunkconverter.b()); - } - - ChunkSection[] achunksection = protochunk.getSections(); - NBTTagList nbttaglist = this.a(world, achunksection, worldHasSkyLight); // Spigot - - nbttagcompound.set("Sections", nbttaglist); - BiomeBase[] abiomebase = protochunk.getBiomeIndex(); - int[] aint = abiomebase != null ? new int[abiomebase.length] : new int[0]; - - if (abiomebase != null) { - for (int k = 0; k < abiomebase.length; ++k) { - aint[k] = IRegistry.BIOME.a(abiomebase[k]); // CraftBukkit - decompile error - } - } - - nbttagcompound.setIntArray("Biomes", aint); - NBTTagList nbttaglist1 = new NBTTagList(); - Iterator iterator = protochunk.s().iterator(); - - NBTTagCompound nbttagcompound1; - - while (iterator.hasNext()) { - nbttagcompound1 = (NBTTagCompound) iterator.next(); - nbttaglist1.add((NBTBase) nbttagcompound1); - } - - nbttagcompound.set("Entities", nbttaglist1); - NBTTagList nbttaglist2 = new NBTTagList(); - Iterator iterator1 = protochunk.q().iterator(); - - while (iterator1.hasNext()) { - BlockPosition blockposition = (BlockPosition) iterator1.next(); - TileEntity tileentity = protochunk.getTileEntity(blockposition); - - if (tileentity != null) { - NBTTagCompound nbttagcompound2 = new NBTTagCompound(); - - tileentity.save(nbttagcompound2); - nbttaglist2.add((NBTBase) nbttagcompound2); - } else { - nbttaglist2.add((NBTBase) protochunk.g(blockposition)); - } - } - - nbttagcompound.set("TileEntities", nbttaglist2); - nbttagcompound.set("Lights", a(protochunk.p())); - nbttagcompound.set("PostProcessing", a(protochunk.u())); - nbttagcompound.set("ToBeTicked", protochunk.k().a()); - nbttagcompound.set("LiquidsToBeTicked", protochunk.l().a()); - nbttagcompound1 = new NBTTagCompound(); - Iterator iterator2 = protochunk.t().iterator(); - - while (iterator2.hasNext()) { - HeightMap.Type heightmap_type = (HeightMap.Type) iterator2.next(); - - nbttagcompound1.set(heightmap_type.b(), new NBTTagLongArray(protochunk.b(heightmap_type).b())); - } - - nbttagcompound.set("Heightmaps", nbttagcompound1); - NBTTagCompound nbttagcompound3 = new NBTTagCompound(); - WorldGenStage.Features[] aworldgenstage_features = WorldGenStage.Features.values(); - int l = aworldgenstage_features.length; - - for (int i1 = 0; i1 < l; ++i1) { - WorldGenStage.Features worldgenstage_features = aworldgenstage_features[i1]; - - nbttagcompound3.setByteArray(worldgenstage_features.toString(), protochunk.a(worldgenstage_features).toByteArray()); - } - - nbttagcompound.set("CarvingMasks", nbttagcompound3); - nbttagcompound.set("Structures", this.a(i, j, protochunk.e(), protochunk.f())); - } - - private void saveBody(Chunk chunk, World world, NBTTagCompound nbttagcompound, long worldTime, boolean worldHasSkyLight) { // Spigot - nbttagcompound.setInt("xPos", chunk.locX); - nbttagcompound.setInt("zPos", chunk.locZ); - nbttagcompound.setLong("LastUpdate", worldTime); // Spigot - nbttagcompound.setLong("InhabitedTime", chunk.m()); - nbttagcompound.setString("Status", chunk.i().b()); - ChunkConverter chunkconverter = chunk.F(); - - if (!chunkconverter.a()) { - nbttagcompound.set("UpgradeData", chunkconverter.b()); - } - - ChunkSection[] achunksection = chunk.getSections(); - NBTTagList nbttaglist = this.a(world, achunksection, worldHasSkyLight); // Spigot - - nbttagcompound.set("Sections", nbttaglist); - BiomeBase[] abiomebase = chunk.getBiomeIndex(); - int[] aint = new int[abiomebase.length]; - - for (int i = 0; i < abiomebase.length; ++i) { - aint[i] = IRegistry.BIOME.a(abiomebase[i]); // CraftBukkit - decompile error - } - - nbttagcompound.setIntArray("Biomes", aint); - - // Spigot start - End this method here and split off entity saving to another method - } - - private void saveEntities(NBTTagCompound nbttagcompound, Chunk chunk, World world) { - // Spigot end - chunk.f(false); - NBTTagList nbttaglist1 = new NBTTagList(); - - Iterator iterator; - - java.util.List toUpdate = new java.util.ArrayList<>(); // Paper - for (int j = 0; j < chunk.getEntitySlices().length; ++j) { - iterator = chunk.getEntitySlices()[j].iterator(); - - while (iterator.hasNext()) { - Entity entity = (Entity) iterator.next(); - // Paper start - if ((int)Math.floor(entity.locX) >> 4 != chunk.locX || (int)Math.floor(entity.locZ) >> 4 != chunk.locZ) { - LogManager.getLogger().warn(entity + " is not in this chunk, skipping save. This a bug fix to a vanilla bug. Do not report this to PaperMC please."); - toUpdate.add(entity); - continue; - } - if (entity.dead) { - continue; - } - // Paper end - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - - if (entity.d(nbttagcompound1)) { - chunk.f(true); - nbttaglist1.add((NBTBase) nbttagcompound1); - } - } - } - // Paper start - move entities to the correct chunk - for (Entity entity : toUpdate) { - world.entityJoinedWorld(entity, false); - } - // Paper end - - nbttagcompound.set("Entities", nbttaglist1); - NBTTagList nbttaglist2 = new NBTTagList(); - - iterator = chunk.t().iterator(); - - while (iterator.hasNext()) { - BlockPosition blockposition = (BlockPosition) iterator.next(); - TileEntity tileentity = chunk.getTileEntity(blockposition); - NBTTagCompound nbttagcompound2; - - if (tileentity != null) { - nbttagcompound2 = new NBTTagCompound(); - tileentity.save(nbttagcompound2); - nbttagcompound2.setBoolean("keepPacked", false); - nbttaglist2.add((NBTBase) nbttagcompound2); - } else { - nbttagcompound2 = chunk.g(blockposition); - if (nbttagcompound2 != null) { - nbttagcompound2.setBoolean("keepPacked", true); - nbttaglist2.add((NBTBase) nbttagcompound2); - } - } - } - - nbttagcompound.set("TileEntities", nbttaglist2); - if (world.getBlockTickList() instanceof TickListServer) { - nbttagcompound.set("TileTicks", ((TickListServer) world.getBlockTickList()).a(chunk)); - } - - if (world.getFluidTickList() instanceof TickListServer) { - nbttagcompound.set("LiquidTicks", ((TickListServer) world.getFluidTickList()).a(chunk)); - } - - nbttagcompound.set("PostProcessing", a(chunk.G())); - if (chunk.k() instanceof ProtoChunkTickList) { - nbttagcompound.set("ToBeTicked", ((ProtoChunkTickList) chunk.k()).a()); - } - - if (chunk.l() instanceof ProtoChunkTickList) { - nbttagcompound.set("LiquidsToBeTicked", ((ProtoChunkTickList) chunk.l()).a()); - } - - NBTTagCompound nbttagcompound3 = new NBTTagCompound(); - Iterator iterator1 = chunk.A().iterator(); - - while (iterator1.hasNext()) { - HeightMap.Type heightmap_type = (HeightMap.Type) iterator1.next(); - - if (heightmap_type.c() == HeightMap.Use.LIVE_WORLD) { - nbttagcompound3.set(heightmap_type.b(), new NBTTagLongArray(chunk.b(heightmap_type).b())); - } - } - - nbttagcompound.set("Heightmaps", nbttagcompound3); - nbttagcompound.set("Structures", this.a(chunk.locX, chunk.locZ, chunk.e(), chunk.f())); - } - - private Chunk a(GeneratorAccess generatoraccess, NBTTagCompound nbttagcompound) { - int i = nbttagcompound.getInt("xPos"); - int j = nbttagcompound.getInt("zPos"); - BiomeBase[] abiomebase = new BiomeBase[256]; - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - - if (nbttagcompound.hasKeyOfType("Biomes", 11)) { - int[] aint = nbttagcompound.getIntArray("Biomes"); - - for (int k = 0; k < aint.length; ++k) { - abiomebase[k] = (BiomeBase) IRegistry.BIOME.fromId(aint[k]); - if (abiomebase[k] == null) { - abiomebase[k] = generatoraccess.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(blockposition_mutableblockposition.c((k & 15) + (i << 4), 0, (k >> 4 & 15) + (j << 4)), Biomes.PLAINS); - } - } - } else { - for (int l = 0; l < abiomebase.length; ++l) { - abiomebase[l] = generatoraccess.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(blockposition_mutableblockposition.c((l & 15) + (i << 4), 0, (l >> 4 & 15) + (j << 4)), Biomes.PLAINS); - } - } - - ChunkConverter chunkconverter = nbttagcompound.hasKeyOfType("UpgradeData", 10) ? new ChunkConverter(nbttagcompound.getCompound("UpgradeData")) : ChunkConverter.a; - ProtoChunkTickList protochunkticklist = new ProtoChunkTickList<>((block) -> { - return block.getBlockData().isAir(); - }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::getOrDefault, new ChunkCoordIntPair(i, j)); - ProtoChunkTickList protochunkticklist1 = new ProtoChunkTickList<>((fluidtype) -> { - return fluidtype == FluidTypes.EMPTY; - }, IRegistry.FLUID::getKey, IRegistry.FLUID::getOrDefault, new ChunkCoordIntPair(i, j)); - long i1 = nbttagcompound.getLong("InhabitedTime"); - Chunk chunk = new Chunk(generatoraccess.getMinecraftWorld(), i, j, abiomebase, chunkconverter, protochunkticklist, protochunkticklist1, i1); - - chunk.c(nbttagcompound.getString("Status")); - NBTTagList nbttaglist = nbttagcompound.getList("Sections", 10); - - chunk.a(this.a((IWorldReader) generatoraccess, nbttaglist)); - NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Heightmaps"); - HeightMap.Type[] aheightmap_type = HeightMap.Type.values(); - int j1 = aheightmap_type.length; - - int k1; - - for (k1 = 0; k1 < j1; ++k1) { - HeightMap.Type heightmap_type = aheightmap_type[k1]; - - if (heightmap_type.c() == HeightMap.Use.LIVE_WORLD) { - String s = heightmap_type.b(); - - if (nbttagcompound1.hasKeyOfType(s, 12)) { - chunk.a(heightmap_type, nbttagcompound1.o(s)); - } else { - chunk.b(heightmap_type).a(); - } - } - } - - NBTTagCompound nbttagcompound2 = nbttagcompound.getCompound("Structures"); - - chunk.a(this.c(generatoraccess, nbttagcompound2)); - chunk.b(this.b(nbttagcompound2)); - NBTTagList nbttaglist1 = nbttagcompound.getList("PostProcessing", 9); - - for (k1 = 0; k1 < nbttaglist1.size(); ++k1) { - NBTTagList nbttaglist2 = nbttaglist1.f(k1); - - for (int l1 = 0; l1 < nbttaglist2.size(); ++l1) { - chunk.a(nbttaglist2.g(l1), k1); - } - } - - protochunkticklist.a(nbttagcompound.getList("ToBeTicked", 9)); - protochunkticklist1.a(nbttagcompound.getList("LiquidsToBeTicked", 9)); - if (nbttagcompound.getBoolean("shouldSave")) { - chunk.a(true); - } - - return chunk; - } - - public void loadEntities(NBTTagCompound nbttagcompound, Chunk chunk) { + private static void loadEntities(NBTTagCompound nbttagcompound, Chunk chunk) { NBTTagList nbttaglist = nbttagcompound.getList("Entities", 10); World world = chunk.getWorld(); world.timings.chunkLoadLevelTimer.startTiming(); // Spigot @@ -799,8 +568,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { for (int i = 0; i < nbttaglist.size(); ++i) { NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); - a(nbttagcompound1, world, chunk); - chunk.f(true); + EntityTypes.a(nbttagcompound1, world, (entity) -> { + chunk.a(entity); + return entity; + }); + chunk.d(true); } NBTTagList nbttaglist1 = nbttagcompound.getList("TileEntities", 10); @@ -819,162 +591,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { } } } - - if (nbttagcompound.hasKeyOfType("TileTicks", 9) && world.getBlockTickList() instanceof TickListServer) { - ((TickListServer) world.getBlockTickList()).a(nbttagcompound.getList("TileTicks", 10)); - } - - if (nbttagcompound.hasKeyOfType("LiquidTicks", 9) && world.getFluidTickList() instanceof TickListServer) { - ((TickListServer) world.getFluidTickList()).a(nbttagcompound.getList("LiquidTicks", 10)); - } - world.timings.chunkLoadLevelTimer.stopTiming(); // Spigot + world.timings.chunkLoadLevelTimer.stopTiming(); // Paper } - private ProtoChunk b(GeneratorAccess generatoraccess, NBTTagCompound nbttagcompound) { - int i = nbttagcompound.getInt("xPos"); - int j = nbttagcompound.getInt("zPos"); - BiomeBase[] abiomebase = new BiomeBase[256]; - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - - if (nbttagcompound.hasKeyOfType("Biomes", 11)) { - int[] aint = nbttagcompound.getIntArray("Biomes"); - - for (int k = 0; k < aint.length; ++k) { - abiomebase[k] = (BiomeBase) IRegistry.BIOME.fromId(aint[k]); - if (abiomebase[k] == null) { - abiomebase[k] = generatoraccess.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(blockposition_mutableblockposition.c((k & 15) + (i << 4), 0, (k >> 4 & 15) + (j << 4)), Biomes.PLAINS); - } - } - } else { - for (int l = 0; l < abiomebase.length; ++l) { - abiomebase[l] = generatoraccess.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(blockposition_mutableblockposition.c((l & 15) + (i << 4), 0, (l >> 4 & 15) + (j << 4)), Biomes.PLAINS); - } - } - - ChunkConverter chunkconverter = nbttagcompound.hasKeyOfType("UpgradeData", 10) ? new ChunkConverter(nbttagcompound.getCompound("UpgradeData")) : ChunkConverter.a; - ProtoChunk protochunk = new ProtoChunk(i, j, chunkconverter, generatoraccess); // Paper - Anti-Xray - - protochunk.a(abiomebase); - protochunk.b(nbttagcompound.getLong("InhabitedTime")); - protochunk.c(nbttagcompound.getString("Status")); - NBTTagList nbttaglist = nbttagcompound.getList("Sections", 10); - - protochunk.a(this.a((IWorldReader) generatoraccess, nbttaglist)); - NBTTagList nbttaglist1 = nbttagcompound.getList("Entities", 10); - - for (int i1 = 0; i1 < nbttaglist1.size(); ++i1) { - protochunk.b(nbttaglist1.getCompound(i1)); - } - - NBTTagList nbttaglist2 = nbttagcompound.getList("TileEntities", 10); - - for (int j1 = 0; j1 < nbttaglist2.size(); ++j1) { - NBTTagCompound nbttagcompound1 = nbttaglist2.getCompound(j1); - - protochunk.a(nbttagcompound1); - } - - NBTTagList nbttaglist3 = nbttagcompound.getList("Lights", 9); - - for (int k1 = 0; k1 < nbttaglist3.size(); ++k1) { - NBTTagList nbttaglist4 = nbttaglist3.f(k1); - - for (int l1 = 0; l1 < nbttaglist4.size(); ++l1) { - protochunk.a(nbttaglist4.g(l1), k1); - } - } - - NBTTagList nbttaglist5 = nbttagcompound.getList("PostProcessing", 9); - - for (int i2 = 0; i2 < nbttaglist5.size(); ++i2) { - NBTTagList nbttaglist6 = nbttaglist5.f(i2); - - for (int j2 = 0; j2 < nbttaglist6.size(); ++j2) { - protochunk.b(nbttaglist6.g(j2), i2); - } - } - - protochunk.k().a(nbttagcompound.getList("ToBeTicked", 9)); - protochunk.l().a(nbttagcompound.getList("LiquidsToBeTicked", 9)); - NBTTagCompound nbttagcompound2 = nbttagcompound.getCompound("Heightmaps"); - Iterator iterator = nbttagcompound2.getKeys().iterator(); - - while (iterator.hasNext()) { - String s = (String) iterator.next(); - - protochunk.a(HeightMap.Type.a(s), nbttagcompound2.o(s)); - } - - NBTTagCompound nbttagcompound3 = nbttagcompound.getCompound("Structures"); - - protochunk.a(this.c(generatoraccess, nbttagcompound3)); - protochunk.b(this.b(nbttagcompound3)); - NBTTagCompound nbttagcompound4 = nbttagcompound.getCompound("CarvingMasks"); - Iterator iterator1 = nbttagcompound4.getKeys().iterator(); - - while (iterator1.hasNext()) { - String s1 = (String) iterator1.next(); - WorldGenStage.Features worldgenstage_features = WorldGenStage.Features.valueOf(s1); - - protochunk.a(worldgenstage_features, BitSet.valueOf(nbttagcompound4.getByteArray(s1))); - } - - return protochunk; - } - - private NBTTagList a(World world, ChunkSection[] achunksection, boolean worldHasSkyLight) { // Spigot - NBTTagList nbttaglist = new NBTTagList(); - boolean flag = worldHasSkyLight; // Spigot - ChunkSection[] achunksection1 = achunksection; - int i = achunksection.length; - - for (int j = 0; j < i; ++j) { - ChunkSection chunksection = achunksection1[j]; - - if (chunksection != Chunk.a) { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - - nbttagcompound.setByte("Y", (byte) (chunksection.getYPosition() >> 4 & 255)); - chunksection.getBlocks().b(nbttagcompound, "Palette", "BlockStates"); - nbttagcompound.setByteArray("BlockLight", chunksection.getEmittedLightArray().asBytes()); - if (flag) { - nbttagcompound.setByteArray("SkyLight", chunksection.getSkyLightArray().asBytes()); - } else { - nbttagcompound.setByteArray("SkyLight", new byte[chunksection.getEmittedLightArray().asBytes().length]); - } - - nbttaglist.add((NBTBase) nbttagcompound); - } - } - - return nbttaglist; - } - - private ChunkSection[] a(IWorldReader iworldreader, NBTTagList nbttaglist) { - boolean flag = true; - ChunkSection[] achunksection = new ChunkSection[16]; - boolean flag1 = iworldreader.o().g(); - - for (int i = 0; i < nbttaglist.size(); ++i) { - NBTTagCompound nbttagcompound = nbttaglist.getCompound(i); - byte b0 = nbttagcompound.getByte("Y"); - ChunkSection chunksection = new ChunkSection(b0 << 4, flag1, null, iworldreader, false); // Paper - Anti-Xray - - chunksection.getBlocks().a(nbttagcompound, "Palette", "BlockStates"); - chunksection.a(new NibbleArray(nbttagcompound.getByteArray("BlockLight"))); - if (flag1) { - chunksection.b(new NibbleArray(nbttagcompound.getByteArray("SkyLight"))); - } - - chunksection.recalcBlockCounts(); - achunksection[b0] = chunksection; - } - - return achunksection; - } - - private NBTTagCompound a(int i, int j, Map map, Map map1) { + private static NBTTagCompound a(ChunkCoordIntPair chunkcoordintpair, Map map, Map map1) { NBTTagCompound nbttagcompound = new NBTTagCompound(); NBTTagCompound nbttagcompound1 = new NBTTagCompound(); Iterator iterator = map.entrySet().iterator(); @@ -982,7 +603,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { while (iterator.hasNext()) { Entry entry = (Entry) iterator.next(); - nbttagcompound1.set((String) entry.getKey(), ((StructureStart) entry.getValue()).a(i, j)); + nbttagcompound1.set((String) entry.getKey(), ((StructureStart) entry.getValue()).a(chunkcoordintpair.x, chunkcoordintpair.z)); } nbttagcompound.set("Starts", nbttagcompound1); @@ -999,7 +620,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { return nbttagcompound; } - private Map c(GeneratorAccess generatoraccess, NBTTagCompound nbttagcompound) { + private static Map a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, WorldChunkManager worldchunkmanager, NBTTagCompound nbttagcompound) { Map map = Maps.newHashMap(); NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Starts"); Iterator iterator = nbttagcompound1.getKeys().iterator(); @@ -1007,13 +628,13 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { while (iterator.hasNext()) { String s = (String) iterator.next(); - map.put(s, WorldGenFactory.a(nbttagcompound1.getCompound(s), generatoraccess)); + map.put(s, WorldGenFactory.a(chunkgenerator, definedstructuremanager, worldchunkmanager, nbttagcompound1.getCompound(s))); } return map; } - private Map b(NBTTagCompound nbttagcompound) { + private static Map b(NBTTagCompound nbttagcompound) { Map map = Maps.newHashMap(); NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("References"); Iterator iterator = nbttagcompound1.getKeys().iterator(); @@ -1021,7 +642,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { while (iterator.hasNext()) { String s = (String) iterator.next(); - map.put(s, new LongOpenHashSet(nbttagcompound1.o(s))); + map.put(s, new LongOpenHashSet(nbttagcompound1.getLongArray(s))); } return map; @@ -1042,117 +663,13 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { while (shortlistiterator.hasNext()) { Short oshort = (Short) shortlistiterator.next(); - nbttaglist1.add((NBTBase) (new NBTTagShort(oshort))); + nbttaglist1.add(new NBTTagShort(oshort)); } } - nbttaglist.add((NBTBase) nbttaglist1); + nbttaglist.add(nbttaglist1); } return nbttaglist; } - - @Nullable - private static Entity a(NBTTagCompound nbttagcompound, World world, Function function) { - Entity entity = a(nbttagcompound, world); - - if (entity == null) { - return null; - } else { - entity = (Entity) function.apply(entity); - if (entity != null && nbttagcompound.hasKeyOfType("Passengers", 9)) { - NBTTagList nbttaglist = nbttagcompound.getList("Passengers", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - Entity entity1 = a(nbttaglist.getCompound(i), world, function); - - if (entity1 != null) { - entity1.a(entity, true); - } - } - } - - return entity; - } - } - - @Nullable - public static Entity a(NBTTagCompound nbttagcompound, World world, Chunk chunk) { - return a(nbttagcompound, world, (entity) -> { - chunk.a(entity); - return entity; - }); - } - - @Nullable - // CraftBukkit start - public static Entity a(NBTTagCompound nbttagcompound, World world, double d0, double d1, double d2, boolean flag) { - return spawnEntity(nbttagcompound, world, d0, d1, d2, flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); - } - - public static Entity spawnEntity(NBTTagCompound nbttagcompound, World world, double d0, double d1, double d2, boolean flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { - // CraftBukkit end - return a(nbttagcompound, world, (entity) -> { - entity.setPositionRotation(d0, d1, d2, entity.yaw, entity.pitch); - return flag && !world.addEntity(entity, spawnReason) ? null : entity; - }); - } - - @Nullable - // CraftBukkit start - public static Entity a(NBTTagCompound nbttagcompound, World world, boolean flag) { - return spawnEntity(nbttagcompound, world, flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); - } - - public static Entity spawnEntity(NBTTagCompound nbttagcompound, World world, boolean flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { - // CraftBukkit end - return a(nbttagcompound, world, (entity) -> { - return flag && !world.addEntity(entity, spawnReason) ? null : entity; // CraftBukkit - }); - } - - @Nullable - protected static Entity a(NBTTagCompound nbttagcompound, World world) { - try { - return EntityTypes.a(nbttagcompound, world); - } catch (RuntimeException runtimeexception) { - ChunkRegionLoader.a.warn("Exception loading entity: ", runtimeexception); - return null; - } - } - - // CraftBukkit start - public static void a(Entity entity, GeneratorAccess generatoraccess) { - a(entity, generatoraccess, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); - } - - public static void a(Entity entity, GeneratorAccess generatoraccess, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { - if (!entity.valid && generatoraccess.addEntity(entity, reason) && entity.isVehicle()) { // Paper - // CraftBukkit end - Iterator iterator = entity.bP().iterator(); - - while (iterator.hasNext()) { - Entity entity1 = (Entity) iterator.next(); - - a(entity1, generatoraccess, reason); // Paper - } - } - - } - - public boolean a(ChunkCoordIntPair chunkcoordintpair, DimensionManager dimensionmanager, PersistentCollection persistentcollection) { - boolean flag = false; - - try { - this.a(dimensionmanager, persistentcollection, chunkcoordintpair.x, chunkcoordintpair.z, null); // CraftBukkit - - while (this.a()) { - flag = true; - } - } catch (IOException ioexception) { - ; - } - - return flag; - } } diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java index 883d87e93..584b3e639 100644 --- a/src/main/java/net/minecraft/server/ChunkSection.java +++ b/src/main/java/net/minecraft/server/ChunkSection.java @@ -1,93 +1,112 @@ package net.minecraft.server; +import javax.annotation.Nullable; + public class ChunkSection { public static final DataPalette GLOBAL_PALETTE = new DataPaletteGlobal<>(Block.REGISTRY_ID, Blocks.AIR.getBlockData()); private final int yPos; - private int nonEmptyBlockCount; - private int tickingBlockCount; - private int e; + short nonEmptyBlockCount; // Paper - private -> package-private + private short tickingBlockCount; + private short e; final DataPaletteBlock blockIds; // Paper - package - private NibbleArray emittedLight; - private NibbleArray skyLight; - // Paper start - Anti-Xray - Support default constructor - public ChunkSection(int i, boolean flag) { - this(i, flag, null, null, true); + public ChunkSection(int i) { + // Paper start - add parameters + this(i, (IChunkAccess)null, (IWorldReader)null, true); + } + public ChunkSection(int i, IChunkAccess chunk, IWorldReader world, boolean initializeBlocks) { + this(i, (short) 0, (short) 0, (short) 0, chunk, world, initializeBlocks); + // Paper end } - // Paper end - public ChunkSection(int i, boolean flag, IChunkAccess chunk, IWorldReader world, boolean initializeBlocks) { // Paper - Anti-Xray + public ChunkSection(int i, short short0, short short1, short short2) { + // Paper start - add parameters + this(i, short0, short1, short2, (IChunkAccess)null, (IWorldReader)null, true); + } + public ChunkSection(int i, short short0, short short1, short short2, IChunkAccess chunk, IWorldReader world, boolean initializeBlocks) { + // Paper end this.yPos = i; - this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData(), world instanceof GeneratorAccess ? ((GeneratorAccess) world).getMinecraftWorld().chunkPacketBlockController.getPredefinedBlockData(world, chunk, this, flag, initializeBlocks) : null, initializeBlocks); // Paper - Anti-Xray - Add predefined block data - this.emittedLight = new NibbleArray(); - if (flag) { - this.skyLight = new NibbleArray(); - } - - // Paper start - Async Chunks - Lock during world gen - if (chunk instanceof ProtoChunk) { - this.blockIds.enableLocks(); - } else { - this.blockIds.disableLocks(); - } + this.nonEmptyBlockCount = short0; + this.tickingBlockCount = short1; + this.e = short2; + this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData(), world instanceof GeneratorAccess ? ((GeneratorAccess) world).getMinecraftWorld().chunkPacketBlockController.getPredefinedBlockData(world, chunk, this, initializeBlocks) : null, initializeBlocks); // Paper - Anti-Xray - Add predefined block data } - void disableLocks() { - this.blockIds.disableLocks(); - } - // Paper end public IBlockData getType(int i, int j, int k) { return (IBlockData) this.blockIds.a(i, j, k); } public Fluid b(int i, int j, int k) { - return ((IBlockData) this.blockIds.a(i, j, k)).s(); + return ((IBlockData) this.blockIds.a(i, j, k)).p(); } - public void setType(int i, int j, int k, IBlockData iblockdata) { - IBlockData iblockdata1 = this.getType(i, j, k); - Fluid fluid = this.b(i, j, k); - Fluid fluid1 = iblockdata.s(); + public void a() { + this.blockIds.a(); + } + + public void b() { + this.blockIds.b(); + } + + public IBlockData setType(int i, int j, int k, IBlockData iblockdata) { + return this.setType(i, j, k, iblockdata, true); + } + + public IBlockData setType(int i, int j, int k, IBlockData iblockdata, boolean flag) { + IBlockData iblockdata1; + + if (flag) { + iblockdata1 = (IBlockData) this.blockIds.setBlock(i, j, k, iblockdata); + } else { + iblockdata1 = (IBlockData) this.blockIds.b(i, j, k, iblockdata); + } + + Fluid fluid = iblockdata1.p(); + Fluid fluid1 = iblockdata.p(); if (!iblockdata1.isAir()) { --this.nonEmptyBlockCount; - if (iblockdata1.t()) { + if (iblockdata1.q()) { --this.tickingBlockCount; } } - if (!fluid.e()) { + if (!fluid.isEmpty()) { --this.e; } if (!iblockdata.isAir()) { ++this.nonEmptyBlockCount; - if (iblockdata.t()) { + if (iblockdata.q()) { ++this.tickingBlockCount; } } - if (!fluid1.e()) { - --this.e; + if (!fluid1.isEmpty()) { + ++this.e; } - this.blockIds.setBlock(i, j, k, iblockdata); + return iblockdata1; } - public boolean a() { + public boolean c() { return this.nonEmptyBlockCount == 0; } - public boolean b() { - return this.shouldTick() || this.d(); + public static boolean a(@Nullable ChunkSection chunksection) { + return chunksection == Chunk.a || chunksection.c(); + } + + public boolean d() { + return this.shouldTick() || this.f(); } public boolean shouldTick() { return this.tickingBlockCount > 0; } - public boolean d() { + public boolean f() { return this.e > 0; } @@ -95,69 +114,44 @@ public class ChunkSection { return this.yPos; } - public synchronized void a(int i, int j, int k, int l) { // Akarin - synchronized - this.skyLight.a(i, j, k, l); - } - - public synchronized int c(int i, int j, int k) { // Akarin - synchronized - return this.skyLight.a(i, j, k); - } - - public synchronized void b(int i, int j, int k, int l) { // Akarin - synchronized - this.emittedLight.a(i, j, k, l); - } - - public synchronized int d(int i, int j, int k) { // Akarin - synchronized - return this.emittedLight.a(i, j, k); - } - public void recalcBlockCounts() { this.nonEmptyBlockCount = 0; this.tickingBlockCount = 0; this.e = 0; + this.blockIds.a((iblockdata, i) -> { + Fluid fluid = iblockdata.p(); - for (int i = 0; i < 16; ++i) { - for (int j = 0; j < 16; ++j) { - for (int k = 0; k < 16; ++k) { - IBlockData iblockdata = this.getType(i, j, k); - Fluid fluid = this.b(i, j, k); - - if (!iblockdata.isAir()) { - ++this.nonEmptyBlockCount; - if (iblockdata.t()) { - ++this.tickingBlockCount; - } - } - - if (!fluid.e()) { - ++this.nonEmptyBlockCount; - if (fluid.h()) { - ++this.e; - } - } + if (!iblockdata.isAir()) { + this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i); + if (iblockdata.q()) { + this.tickingBlockCount = (short) (this.tickingBlockCount + i); } } - } + if (!fluid.isEmpty()) { + this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i); + if (fluid.h()) { + this.e = (short) (this.e + i); + } + } + + }); } public DataPaletteBlock getBlocks() { return this.blockIds; } - public NibbleArray getEmittedLightArray() { - return this.emittedLight; + public void b(PacketDataSerializer packetdataserializer) { + packetdataserializer.writeShort(this.nonEmptyBlockCount); + this.blockIds.b(packetdataserializer); } - public NibbleArray getSkyLightArray() { - return this.skyLight; + public int j() { + return 2 + this.blockIds.c(); } - public void a(NibbleArray nibblearray) { - this.emittedLight = nibblearray; - } - - public void b(NibbleArray nibblearray) { - this.skyLight = nibblearray; + public boolean a(IBlockData iblockdata) { + return this.blockIds.a(iblockdata); // Paper - decompile fix } } diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java new file mode 100644 index 000000000..abb0d69d2 --- /dev/null +++ b/src/main/java/net/minecraft/server/ChunkStatus.java @@ -0,0 +1,261 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.mojang.datafixers.util.Either; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import javax.annotation.Nullable; + +public class ChunkStatus { + + private static final EnumSet n = EnumSet.of(HeightMap.Type.OCEAN_FLOOR_WG, HeightMap.Type.WORLD_SURFACE_WG); + private static final EnumSet o = EnumSet.of(HeightMap.Type.OCEAN_FLOOR, HeightMap.Type.WORLD_SURFACE, HeightMap.Type.MOTION_BLOCKING, HeightMap.Type.MOTION_BLOCKING_NO_LEAVES); + private static final ChunkStatus.c p = (chunkstatus, worldserver, definedstructuremanager, lightenginethreaded, function, ichunkaccess) -> { + if (ichunkaccess instanceof ProtoChunk && !ichunkaccess.getChunkStatus().b(chunkstatus)) { + ((ProtoChunk) ichunkaccess).a(chunkstatus); + } + + return CompletableFuture.completedFuture(Either.left(ichunkaccess)); + }; + public static final ChunkStatus EMPTY = a("empty", (ChunkStatus) null, -1, ChunkStatus.n, ChunkStatus.Type.PROTOCHUNK, (worldserver, chunkgenerator, list, ichunkaccess) -> { + }); + public static final ChunkStatus STRUCTURE_STARTS = a("structure_starts", ChunkStatus.EMPTY, 0, ChunkStatus.n, ChunkStatus.Type.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, definedstructuremanager, lightenginethreaded, function, list, ichunkaccess) -> { + if (!ichunkaccess.getChunkStatus().b(chunkstatus)) { + if (worldserver.getWorldData().shouldGenerateMapFeatures()) { + chunkgenerator.createStructures(ichunkaccess, chunkgenerator, definedstructuremanager); + } + + if (ichunkaccess instanceof ProtoChunk) { + ((ProtoChunk) ichunkaccess).a(chunkstatus); + } + } + + return CompletableFuture.completedFuture(Either.left(ichunkaccess)); + }); + public static final ChunkStatus STRUCTURE_REFERENCES = a("structure_references", ChunkStatus.STRUCTURE_STARTS, 8, ChunkStatus.n, ChunkStatus.Type.PROTOCHUNK, (worldserver, chunkgenerator, list, ichunkaccess) -> { + chunkgenerator.storeStructures(new RegionLimitedWorldAccess(worldserver, list), ichunkaccess); + }); + public static final ChunkStatus BIOMES = a("biomes", ChunkStatus.STRUCTURE_REFERENCES, 0, ChunkStatus.n, ChunkStatus.Type.PROTOCHUNK, (worldserver, chunkgenerator, list, ichunkaccess) -> { + chunkgenerator.createBiomes(ichunkaccess); + }); + public static final ChunkStatus NOISE = a("noise", ChunkStatus.BIOMES, 8, ChunkStatus.n, ChunkStatus.Type.PROTOCHUNK, (worldserver, chunkgenerator, list, ichunkaccess) -> { + chunkgenerator.buildNoise(new RegionLimitedWorldAccess(worldserver, list), ichunkaccess); + }); + public static final ChunkStatus SURFACE = a("surface", ChunkStatus.NOISE, 0, ChunkStatus.n, ChunkStatus.Type.PROTOCHUNK, (worldserver, chunkgenerator, list, ichunkaccess) -> { + chunkgenerator.buildBase(ichunkaccess); + }); + public static final ChunkStatus CARVERS = a("carvers", ChunkStatus.SURFACE, 0, ChunkStatus.n, ChunkStatus.Type.PROTOCHUNK, (worldserver, chunkgenerator, list, ichunkaccess) -> { + chunkgenerator.doCarving(ichunkaccess, WorldGenStage.Features.AIR); + }); + public static final ChunkStatus LIQUID_CARVERS = a("liquid_carvers", ChunkStatus.CARVERS, 0, ChunkStatus.o, ChunkStatus.Type.PROTOCHUNK, (worldserver, chunkgenerator, list, ichunkaccess) -> { + chunkgenerator.doCarving(ichunkaccess, WorldGenStage.Features.LIQUID); + }); + public static final ChunkStatus FEATURES = a("features", ChunkStatus.LIQUID_CARVERS, 8, ChunkStatus.o, ChunkStatus.Type.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, definedstructuremanager, lightenginethreaded, function, list, ichunkaccess) -> { + ichunkaccess.a((LightEngine) lightenginethreaded); + if (!ichunkaccess.getChunkStatus().b(chunkstatus)) { + HeightMap.a(ichunkaccess, EnumSet.of(HeightMap.Type.MOTION_BLOCKING, HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, HeightMap.Type.OCEAN_FLOOR, HeightMap.Type.WORLD_SURFACE)); + chunkgenerator.addDecorations(new RegionLimitedWorldAccess(worldserver, list)); + if (ichunkaccess instanceof ProtoChunk) { + ((ProtoChunk) ichunkaccess).a(chunkstatus); + } + } + + return CompletableFuture.completedFuture(Either.left(ichunkaccess)); + }); + public static final ChunkStatus LIGHT = a("light", ChunkStatus.FEATURES, 1, ChunkStatus.o, ChunkStatus.Type.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, definedstructuremanager, lightenginethreaded, function, list, ichunkaccess) -> { + return a(chunkstatus, lightenginethreaded, ichunkaccess); + }, (chunkstatus, worldserver, definedstructuremanager, lightenginethreaded, function, ichunkaccess) -> { + return a(chunkstatus, lightenginethreaded, ichunkaccess); + }); + public static final ChunkStatus SPAWN = a("spawn", ChunkStatus.LIGHT, 0, ChunkStatus.o, ChunkStatus.Type.PROTOCHUNK, (worldserver, chunkgenerator, list, ichunkaccess) -> { + chunkgenerator.addMobs(new RegionLimitedWorldAccess(worldserver, list)); + }); + public static final ChunkStatus HEIGHTMAPS = a("heightmaps", ChunkStatus.SPAWN, 0, ChunkStatus.o, ChunkStatus.Type.PROTOCHUNK, (worldserver, chunkgenerator, list, ichunkaccess) -> { + }); + public static final ChunkStatus FULL = a("full", ChunkStatus.HEIGHTMAPS, 0, ChunkStatus.o, ChunkStatus.Type.LEVELCHUNK, (chunkstatus, worldserver, chunkgenerator, definedstructuremanager, lightenginethreaded, function, list, ichunkaccess) -> { + return (CompletableFuture) function.apply(ichunkaccess); + }, (chunkstatus, worldserver, definedstructuremanager, lightenginethreaded, function, ichunkaccess) -> { + return (CompletableFuture) function.apply(ichunkaccess); + }); + private static final List q = ImmutableList.of(ChunkStatus.FULL, ChunkStatus.FEATURES, ChunkStatus.LIQUID_CARVERS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS); + private static final IntList r = (IntList) SystemUtils.a((new IntArrayList(a().size())), (java.util.function.Consumer)(IntArrayList intarraylist) -> { // Paper - decompile fix + int i = 0; + + for (int j = a().size() - 1; j >= 0; --j) { + while (i + 1 < ChunkStatus.q.size() && j <= ((ChunkStatus) ChunkStatus.q.get(i + 1)).c()) { + ++i; + } + + intarraylist.add(0, i); + } + + }); + private final String s; + private final int t; + private final ChunkStatus u; + private final ChunkStatus.b v; + private final ChunkStatus.c w; + private final int x; + private final ChunkStatus.Type y; + private final EnumSet z; + + private static CompletableFuture> a(ChunkStatus chunkstatus, LightEngineThreaded lightenginethreaded, IChunkAccess ichunkaccess) { + boolean flag = a(chunkstatus, ichunkaccess); + + if (!ichunkaccess.getChunkStatus().b(chunkstatus)) { + ((ProtoChunk) ichunkaccess).a(chunkstatus); + } + + return lightenginethreaded.a(ichunkaccess, flag).thenApply(Either::left); + } + + private static ChunkStatus a(String s, @Nullable ChunkStatus chunkstatus, int i, EnumSet enumset, ChunkStatus.Type chunkstatus_type, ChunkStatus.d chunkstatus_d) { + return a(s, chunkstatus, i, enumset, chunkstatus_type, (ChunkStatus.b) chunkstatus_d); + } + + private static ChunkStatus a(String s, @Nullable ChunkStatus chunkstatus, int i, EnumSet enumset, ChunkStatus.Type chunkstatus_type, ChunkStatus.b chunkstatus_b) { + return a(s, chunkstatus, i, enumset, chunkstatus_type, chunkstatus_b, ChunkStatus.p); + } + + private static ChunkStatus a(String s, @Nullable ChunkStatus chunkstatus, int i, EnumSet enumset, ChunkStatus.Type chunkstatus_type, ChunkStatus.b chunkstatus_b, ChunkStatus.c chunkstatus_c) { + return (ChunkStatus) IRegistry.a((IRegistry) IRegistry.CHUNK_STATUS, s, (Object) (new ChunkStatus(s, chunkstatus, i, enumset, chunkstatus_type, chunkstatus_b, chunkstatus_c))); + } + + public static List a() { + List list = Lists.newArrayList(); + + ChunkStatus chunkstatus; + + for (chunkstatus = ChunkStatus.FULL; chunkstatus.e() != chunkstatus; chunkstatus = chunkstatus.e()) { + list.add(chunkstatus); + } + + list.add(chunkstatus); + Collections.reverse(list); + return list; + } + + private static boolean a(ChunkStatus chunkstatus, IChunkAccess ichunkaccess) { + return ichunkaccess.getChunkStatus().b(chunkstatus) && ichunkaccess.r(); + } + + public static ChunkStatus a(int i) { + return i >= ChunkStatus.q.size() ? ChunkStatus.EMPTY : (i < 0 ? ChunkStatus.FULL : (ChunkStatus) ChunkStatus.q.get(i)); + } + + public static int b() { + return ChunkStatus.q.size(); + } + + public static int getTicketLevelOffset(ChunkStatus status) { return ChunkStatus.a(status); } // Paper - OBFHELPER + public static int a(ChunkStatus chunkstatus) { + return ChunkStatus.r.getInt(chunkstatus.c()); + } + + ChunkStatus(String s, @Nullable ChunkStatus chunkstatus, int i, EnumSet enumset, ChunkStatus.Type chunkstatus_type, ChunkStatus.b chunkstatus_b, ChunkStatus.c chunkstatus_c) { + this.s = s; + this.u = chunkstatus == null ? this : chunkstatus; + this.v = chunkstatus_b; + this.w = chunkstatus_c; + this.x = i; + this.y = chunkstatus_type; + this.z = enumset; + this.t = chunkstatus == null ? 0 : chunkstatus.c() + 1; + } + + public int c() { + return this.t; + } + + public String d() { + return this.s; + } + + public ChunkStatus getPreviousStatus() { return this.e(); } // Paper - OBFHELPER + public ChunkStatus e() { + return this.u; + } + + public CompletableFuture> a(WorldServer worldserver, ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, LightEngineThreaded lightenginethreaded, Function>> function, List list) { + return this.v.doWork(this, worldserver, chunkgenerator, definedstructuremanager, lightenginethreaded, function, list, (IChunkAccess) list.get(list.size() / 2)); + } + + public CompletableFuture> a(WorldServer worldserver, DefinedStructureManager definedstructuremanager, LightEngineThreaded lightenginethreaded, Function>> function, IChunkAccess ichunkaccess) { + return this.w.doWork(this, worldserver, definedstructuremanager, lightenginethreaded, function, ichunkaccess); + } + + public int f() { + return this.x; + } + + public ChunkStatus.Type getType() { + return this.y; + } + + // Paper start + public static ChunkStatus getStatus(String name) { + try { + // We need this otherwise we return EMPTY for invalid names + MinecraftKey key = new MinecraftKey(name); + return IRegistry.CHUNK_STATUS.getOptional(key).orElse(null); + } catch (Exception ex) { + return null; // invalid name + } + } + // Paper end + public static ChunkStatus a(String s) { + return (ChunkStatus) IRegistry.CHUNK_STATUS.get(MinecraftKey.a(s)); + } + + public EnumSet h() { + return this.z; + } + + public boolean b(ChunkStatus chunkstatus) { + return this.c() >= chunkstatus.c(); + } + + public String toString() { + return IRegistry.CHUNK_STATUS.getKey(this).toString(); + } + + public static enum Type { + + PROTOCHUNK, LEVELCHUNK; + + private Type() {} + } + + interface d extends ChunkStatus.b { + + @Override + default CompletableFuture> doWork(ChunkStatus chunkstatus, WorldServer worldserver, ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, LightEngineThreaded lightenginethreaded, Function>> function, List list, IChunkAccess ichunkaccess) { + if (!ichunkaccess.getChunkStatus().b(chunkstatus)) { + this.doWork(worldserver, chunkgenerator, list, ichunkaccess); + if (ichunkaccess instanceof ProtoChunk) { + ((ProtoChunk) ichunkaccess).a(chunkstatus); + } + } + + return CompletableFuture.completedFuture(Either.left(ichunkaccess)); + } + + void doWork(WorldServer worldserver, ChunkGenerator chunkgenerator, List list, IChunkAccess ichunkaccess); + } + + interface c { + + CompletableFuture> doWork(ChunkStatus chunkstatus, WorldServer worldserver, DefinedStructureManager definedstructuremanager, LightEngineThreaded lightenginethreaded, Function>> function, IChunkAccess ichunkaccess); + } + + interface b { + + CompletableFuture> doWork(ChunkStatus chunkstatus, WorldServer worldserver, ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, LightEngineThreaded lightenginethreaded, Function>> function, List list, IChunkAccess ichunkaccess); + } +} diff --git a/src/main/java/net/minecraft/server/ChunkTaskScheduler.java b/src/main/java/net/minecraft/server/ChunkTaskScheduler.java deleted file mode 100644 index 8f061f5ca..000000000 --- a/src/main/java/net/minecraft/server/ChunkTaskScheduler.java +++ /dev/null @@ -1,148 +0,0 @@ -package net.minecraft.server; - -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.objects.ObjectIterator; -import java.io.IOException; -import java.util.EnumMap; -import java.util.Map; -import java.util.function.BooleanSupplier; -import javax.annotation.Nullable; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class ChunkTaskScheduler extends Scheduler { - - private static final Logger b = LogManager.getLogger(); - private final World c; private final World getWorld() { return this.c; } // Paper - OBFHELPER - private final ChunkGenerator d; - private final IChunkLoader e; - private final IAsyncTaskHandler f; - protected final Long2ObjectMap.a> progressCache = new ExpiringMap.a>(8192, 5000) { // Paper - protected - protected boolean a(Scheduler.a scheduler_a) { - ProtoChunk protochunk = (ProtoChunk) scheduler_a.a(); - - return !protochunk.ab_() /*&& !protochunk.h()*/; // Paper - } - }; - private final Long2ObjectMap> pendingSchedulers = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(); // Paper - - public ChunkTaskScheduler(int i, World world, ChunkGenerator chunkgenerator, IChunkLoader ichunkloader, IAsyncTaskHandler iasynctaskhandler) { - super("WorldGen", i, ChunkStatus.FINALIZED, () -> { - return new EnumMap(ChunkStatus.class); - }, () -> { - return new EnumMap(ChunkStatus.class); - }); - this.c = world; - this.d = chunkgenerator; - this.e = ichunkloader; - this.f = iasynctaskhandler; - } - - // CraftBukkit start - public void forcePolluteCache(ChunkCoordIntPair chunkcoordintpair) { - this.progressCache.put(chunkcoordintpair.a(), new Scheduler.a(chunkcoordintpair, new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.getWorld()), ChunkStatus.EMPTY)); // Paper - Anti-Xray - } - // CraftBukkit end - - @Nullable - protected Scheduler.a a(ChunkCoordIntPair chunkcoordintpair, boolean flag) { - IChunkLoader ichunkloader = this.e; - - // Paper start - refactor a lot of this - avoid generating a chunk while holding lock on expiring map - java.util.concurrent.CompletableFuture pending = null; - boolean created = false; - long key = chunkcoordintpair.a(); - synchronized (pendingSchedulers) { - Scheduler.a existing = this.progressCache.get(key); - if (existing != null) { - return existing; - } - pending = this.pendingSchedulers.get(key); - if (pending == null) { - if (!flag) { - return null; - } - created = true; - pending = new java.util.concurrent.CompletableFuture<>(); - pendingSchedulers.put(key, pending); - } - } - if (created) { - java.util.function.Function get = (i) -> { - // Paper end - ProtoChunk protochunk; - - try { - protochunk = this.e.b(this.c, chunkcoordintpair.x, chunkcoordintpair.z, (ichunkaccess) -> { - }); - } catch (ReportedException reportedexception) { - throw reportedexception; - } catch (Exception exception) { - ChunkTaskScheduler.b.error("Couldn't load protochunk", exception); - protochunk = null; - } - - if (protochunk != null) { - protochunk.setLastSaved(this.c.getTime()); - return new Scheduler.a(chunkcoordintpair, protochunk, protochunk.i()); - } else { - return new Scheduler.a(chunkcoordintpair, new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.getWorld()), ChunkStatus.EMPTY); // Paper - Anti-Xray - } - // Paper start - }; - Scheduler.a scheduler = get.apply(key); - progressCache.put(key, scheduler); - pending.complete(scheduler); - synchronized (pendingSchedulers) { - pendingSchedulers.remove(key); - } - return scheduler; - } - return pending.join(); - // Paper end - } - - protected ProtoChunk a(ChunkCoordIntPair chunkcoordintpair, ChunkStatus chunkstatus, Map map) { - return chunkstatus.a(this.c, this.d, map, chunkcoordintpair.x, chunkcoordintpair.z); - } - - protected Scheduler.a a(ChunkCoordIntPair chunkcoordintpair, Scheduler.a scheduler_a) { - ((ProtoChunk) scheduler_a.a()).a(1); - return scheduler_a; - } - - protected void b(ChunkCoordIntPair chunkcoordintpair, Scheduler.a scheduler_a) { - ((ProtoChunk) scheduler_a.a()).a(-1); - } - - public void a(BooleanSupplier booleansupplier) { - if (true) return; // Paper - we don't save proto chunks, and don't want to block thread - IChunkLoader ichunkloader = this.e; - - synchronized (this.e) { - ObjectIterator objectiterator = this.progressCache.values().iterator(); - - do { - if (!objectiterator.hasNext()) { - return; - } - - Scheduler.a scheduler_a = (Scheduler.a) objectiterator.next(); - ProtoChunk protochunk = (ProtoChunk) scheduler_a.a(); - - if (protochunk.h() && protochunk.i().d() == ChunkStatus.Type.PROTOCHUNK) { - try { - protochunk.setLastSaved(this.c.getTime()); - this.e.saveChunk(this.c, protochunk); - protochunk.a(false); - } catch (IOException ioexception) { - ChunkTaskScheduler.b.error("Couldn't save chunk", ioexception); - } catch (ExceptionWorldConflict exceptionworldconflict) { - ChunkTaskScheduler.b.error("Couldn't save chunk; already in use by another instance of Minecraft?", exceptionworldconflict); - } - } - } while (booleansupplier.getAsBoolean()); - - } - } -} diff --git a/src/main/java/net/minecraft/server/CombatTracker.java b/src/main/java/net/minecraft/server/CombatTracker.java index 19750ceed..f563a7b63 100644 --- a/src/main/java/net/minecraft/server/CombatTracker.java +++ b/src/main/java/net/minecraft/server/CombatTracker.java @@ -22,7 +22,7 @@ public class CombatTracker { public void a() { this.k(); - if (this.b.z_()) { + if (this.b.isClimbing()) { Block block = this.b.world.getType(new BlockPosition(this.b.locX, this.b.getBoundingBox().minY, this.b.locZ)).getBlock(); if (block == Blocks.LADDER) { @@ -55,7 +55,7 @@ public class CombatTracker { public IChatBaseComponent getDeathMessage() { if (this.a.isEmpty()) { - return new ChatMessage("death.attack.generic", new Object[] { this.b.getScoreboardDisplayName()}); + return new ChatMessage("death.attack.generic", new Object[]{this.b.getScoreboardDisplayName()}); } else { CombatEntry combatentry = this.j(); CombatEntry combatentry1 = (CombatEntry) this.a.get(this.a.size() - 1); @@ -72,23 +72,23 @@ public class CombatTracker { ItemStack itemstack = entity1 instanceof EntityLiving ? ((EntityLiving) entity1).getItemInMainHand() : ItemStack.a; if (!itemstack.isEmpty() && itemstack.hasName()) { - object = new ChatMessage("death.fell.assist.item", new Object[] { this.b.getScoreboardDisplayName(), ichatbasecomponent1, itemstack.A()}); + object = new ChatMessage("death.fell.assist.item", new Object[]{this.b.getScoreboardDisplayName(), ichatbasecomponent1, itemstack.B()}); } else { - object = new ChatMessage("death.fell.assist", new Object[] { this.b.getScoreboardDisplayName(), ichatbasecomponent1}); + object = new ChatMessage("death.fell.assist", new Object[]{this.b.getScoreboardDisplayName(), ichatbasecomponent1}); } } else if (ichatbasecomponent != null) { ItemStack itemstack1 = entity instanceof EntityLiving ? ((EntityLiving) entity).getItemInMainHand() : ItemStack.a; if (!itemstack1.isEmpty() && itemstack1.hasName()) { - object = new ChatMessage("death.fell.finish.item", new Object[] { this.b.getScoreboardDisplayName(), ichatbasecomponent, itemstack1.A()}); + object = new ChatMessage("death.fell.finish.item", new Object[]{this.b.getScoreboardDisplayName(), ichatbasecomponent, itemstack1.B()}); } else { - object = new ChatMessage("death.fell.finish", new Object[] { this.b.getScoreboardDisplayName(), ichatbasecomponent}); + object = new ChatMessage("death.fell.finish", new Object[]{this.b.getScoreboardDisplayName(), ichatbasecomponent}); } } else { - object = new ChatMessage("death.fell.killer", new Object[] { this.b.getScoreboardDisplayName()}); + object = new ChatMessage("death.fell.killer", new Object[]{this.b.getScoreboardDisplayName()}); } } else { - object = new ChatMessage("death.fell.accident." + this.a(combatentry), new Object[] { this.b.getScoreboardDisplayName()}); + object = new ChatMessage("death.fell.accident." + this.a(combatentry), new Object[]{this.b.getScoreboardDisplayName()}); } } else { object = combatentry1.a().getLocalizedDeathMessage(this.b); diff --git a/src/main/java/net/minecraft/server/CommandBan.java b/src/main/java/net/minecraft/server/CommandBan.java deleted file mode 100644 index 68356c4dc..000000000 --- a/src/main/java/net/minecraft/server/CommandBan.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.minecraft.server; - -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.builder.RequiredArgumentBuilder; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import java.util.Collection; -import java.util.Date; -import java.util.Iterator; -import javax.annotation.Nullable; - -public class CommandBan { - - private static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("commands.ban.failed", new Object[0])); - - public static void a(com.mojang.brigadier.CommandDispatcher com_mojang_brigadier_commanddispatcher) { - com_mojang_brigadier_commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) CommandDispatcher.a("ban").requires((commandlistenerwrapper) -> { - return commandlistenerwrapper.getServer().getPlayerList().getProfileBans().isEnabled() && commandlistenerwrapper.hasPermission(3); - })).then(((RequiredArgumentBuilder) CommandDispatcher.a("targets", (ArgumentType) ArgumentProfile.a()).executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentProfile.a(commandcontext, "targets"), (IChatBaseComponent) null); - })).then(CommandDispatcher.a("reason", (ArgumentType) ArgumentChat.a()).executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentProfile.a(commandcontext, "targets"), ArgumentChat.a(commandcontext, "reason")); - })))); - } - - private static int a(CommandListenerWrapper commandlistenerwrapper, Collection collection, @Nullable IChatBaseComponent ichatbasecomponent) throws CommandSyntaxException { - GameProfileBanList gameprofilebanlist = commandlistenerwrapper.getServer().getPlayerList().getProfileBans(); - int i = 0; - Iterator iterator = collection.iterator(); - - while (iterator.hasNext()) { - GameProfile gameprofile = (GameProfile) iterator.next(); - - if (!gameprofilebanlist.isBanned(gameprofile)) { - GameProfileBanEntry gameprofilebanentry = new GameProfileBanEntry(gameprofile, (Date) null, commandlistenerwrapper.getName(), (Date) null, ichatbasecomponent == null ? null : ichatbasecomponent.getString()); - - gameprofilebanlist.add(gameprofilebanentry); - ++i; - commandlistenerwrapper.sendMessage(new ChatMessage("commands.ban.success", new Object[] { ChatComponentUtils.a(gameprofile), gameprofilebanentry.getReason()}), true); - EntityPlayer entityplayer = commandlistenerwrapper.getServer().getPlayerList().getPlayer(gameprofile.getName()); // Akarin - - if (entityplayer != null) { - entityplayer.playerConnection.disconnect(new ChatMessage("multiplayer.disconnect.banned", new Object[0])); - } - } - } - - if (i == 0) { - throw CommandBan.a.create(); - } else { - return i; - } - } -} diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java index a245df1dc..23a69ba57 100644 --- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java +++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java @@ -8,14 +8,14 @@ import org.bukkit.command.CommandSender; public abstract class CommandBlockListenerAbstract implements ICommandListener { - private static final SimpleDateFormat a = new SimpleDateFormat("HH:mm:ss"); - private long b = -1L; - private boolean c = true; - private int d; - private boolean e = true; - private IChatBaseComponent f; - private String g = ""; - private IChatBaseComponent h = new ChatComponentText("@"); + private static final SimpleDateFormat b = new SimpleDateFormat("HH:mm:ss"); + private long lastExecution = -1L; + private boolean updateLastExecution = true; + private int successCount; + private boolean trackOutput = true; + private IChatBaseComponent lastOutput; + private String command = ""; + private IChatBaseComponent customName = new ChatComponentText("@"); // CraftBukkit start @Override public abstract CommandSender getBukkitSender(CommandListenerWrapper wrapper); @@ -24,90 +24,90 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { public CommandBlockListenerAbstract() {} public int i() { - return this.d; + return this.successCount; } public void a(int i) { - this.d = i; + this.successCount = i; } public IChatBaseComponent j() { - return (IChatBaseComponent) (this.f == null ? new ChatComponentText("") : this.f); + return (IChatBaseComponent) (this.lastOutput == null ? new ChatComponentText("") : this.lastOutput); } public NBTTagCompound a(NBTTagCompound nbttagcompound) { - nbttagcompound.setString("Command", this.g); - nbttagcompound.setInt("SuccessCount", this.d); - nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(this.h)); - nbttagcompound.setBoolean("TrackOutput", this.e); - if (this.f != null && this.e) { - nbttagcompound.setString("LastOutput", IChatBaseComponent.ChatSerializer.a(this.f)); + nbttagcompound.setString("Command", this.command); + nbttagcompound.setInt("SuccessCount", this.successCount); + nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(this.customName)); + nbttagcompound.setBoolean("TrackOutput", this.trackOutput); + if (this.lastOutput != null && this.trackOutput) { + nbttagcompound.setString("LastOutput", IChatBaseComponent.ChatSerializer.a(this.lastOutput)); } - nbttagcompound.setBoolean("UpdateLastExecution", this.c); - if (this.c && this.b > 0L) { - nbttagcompound.setLong("LastExecution", this.b); + nbttagcompound.setBoolean("UpdateLastExecution", this.updateLastExecution); + if (this.updateLastExecution && this.lastExecution > 0L) { + nbttagcompound.setLong("LastExecution", this.lastExecution); } return nbttagcompound; } public void b(NBTTagCompound nbttagcompound) { - this.g = nbttagcompound.getString("Command"); - this.d = nbttagcompound.getInt("SuccessCount"); + this.command = nbttagcompound.getString("Command"); + this.successCount = nbttagcompound.getInt("SuccessCount"); if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.h = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException + this.customName = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException } if (nbttagcompound.hasKeyOfType("TrackOutput", 1)) { - this.e = nbttagcompound.getBoolean("TrackOutput"); + this.trackOutput = nbttagcompound.getBoolean("TrackOutput"); } - if (nbttagcompound.hasKeyOfType("LastOutput", 8) && this.e) { + if (nbttagcompound.hasKeyOfType("LastOutput", 8) && this.trackOutput) { try { - this.f = IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("LastOutput")); + this.lastOutput = IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("LastOutput")); } catch (Throwable throwable) { - this.f = new ChatComponentText(throwable.getMessage()); + this.lastOutput = new ChatComponentText(throwable.getMessage()); } } else { - this.f = null; + this.lastOutput = null; } if (nbttagcompound.hasKey("UpdateLastExecution")) { - this.c = nbttagcompound.getBoolean("UpdateLastExecution"); + this.updateLastExecution = nbttagcompound.getBoolean("UpdateLastExecution"); } - if (this.c && nbttagcompound.hasKey("LastExecution")) { - this.b = nbttagcompound.getLong("LastExecution"); + if (this.updateLastExecution && nbttagcompound.hasKey("LastExecution")) { + this.lastExecution = nbttagcompound.getLong("LastExecution"); } else { - this.b = -1L; + this.lastExecution = -1L; } } public void setCommand(String s) { - this.g = s; - this.d = 0; + this.command = s; + this.successCount = 0; } public String getCommand() { - return this.g; + return this.command; } public boolean a(World world) { - if (!world.isClientSide && world.getTime() != this.b) { - if ("Searge".equalsIgnoreCase(this.g)) { - this.f = new ChatComponentText("#itzlipofutzli"); - this.d = 1; + if (!world.isClientSide && world.getTime() != this.lastExecution) { + if ("Searge".equalsIgnoreCase(this.command)) { + this.lastOutput = new ChatComponentText("#itzlipofutzli"); + this.successCount = 1; return true; } else { - this.d = 0; + this.successCount = 0; MinecraftServer minecraftserver = this.d().getMinecraftServer(); - if (minecraftserver != null && minecraftserver.D() && minecraftserver.getEnableCommandBlock() && !UtilColor.b(this.g)) { + if (minecraftserver != null && minecraftserver.F() && minecraftserver.getEnableCommandBlock() && !UtilColor.b(this.command)) { try { - this.f = null; - this.d = minecraftserver.getCommandDispatcher().dispatchServerCommand(this.getWrapper(), this.g); // CraftBukkit + this.lastOutput = null; + this.successCount = minecraftserver.getCommandDispatcher().dispatchServerCommand(this.getWrapper(), this.command); // CraftBukkit } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Executing command block"); CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Command to be executed"); @@ -120,10 +120,10 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { } } - if (this.c) { - this.b = world.getTime(); + if (this.updateLastExecution) { + this.lastExecution = world.getTime(); } else { - this.b = -1L; + this.lastExecution = -1L; } return true; @@ -134,7 +134,7 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { } public IChatBaseComponent getName() { - return this.h; + return this.customName; } public void setName(IChatBaseComponent ichatbasecomponent) { @@ -143,12 +143,13 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { ichatbasecomponent = new ChatComponentText("@"); } // CraftBukkit end - this.h = ichatbasecomponent; + this.customName = ichatbasecomponent; } + @Override public void sendMessage(IChatBaseComponent ichatbasecomponent) { - if (this.e) { - this.f = (new ChatComponentText("[" + CommandBlockListenerAbstract.a.format(new Date()) + "] ")).addSibling(ichatbasecomponent); + if (this.trackOutput) { + this.lastOutput = (new ChatComponentText("[" + CommandBlockListenerAbstract.b.format(new Date()) + "] ")).addSibling(ichatbasecomponent); this.e(); } @@ -159,11 +160,11 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { public abstract void e(); public void c(@Nullable IChatBaseComponent ichatbasecomponent) { - this.f = ichatbasecomponent; + this.lastOutput = ichatbasecomponent; } public void a(boolean flag) { - this.e = flag; + this.trackOutput = flag; } public boolean a(EntityHuman entityhuman) { @@ -180,15 +181,18 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener { public abstract CommandListenerWrapper getWrapper(); - public boolean a() { - return this.d().getGameRules().getBoolean("sendCommandFeedback") && this.e; + @Override + public boolean shouldSendSuccess() { + return this.d().getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK) && this.trackOutput; } - public boolean b() { - return this.e; + @Override + public boolean shouldSendFailure() { + return this.trackOutput; } - public boolean B_() { - return this.d().getGameRules().getBoolean("commandBlockOutput"); + @Override + public boolean shouldBroadcastCommands() { + return this.d().getGameRules().getBoolean(GameRules.COMMAND_BLOCK_OUTPUT); } } diff --git a/src/main/java/net/minecraft/server/CommandDebug.java b/src/main/java/net/minecraft/server/CommandDebug.java deleted file mode 100644 index 5dd29094b..000000000 --- a/src/main/java/net/minecraft/server/CommandDebug.java +++ /dev/null @@ -1,149 +0,0 @@ -package net.minecraft.server; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStreamWriter; -import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import org.apache.commons.io.IOUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class CommandDebug { - - private static final Logger a = LogManager.getLogger(); - private static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("commands.debug.notRunning", new Object[0])); - private static final SimpleCommandExceptionType c = new SimpleCommandExceptionType(new ChatMessage("commands.debug.alreadyRunning", new Object[0])); - - public static void a(com.mojang.brigadier.CommandDispatcher com_mojang_brigadier_commanddispatcher) { - com_mojang_brigadier_commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) CommandDispatcher.a("debug").requires((commandlistenerwrapper) -> { - return commandlistenerwrapper.hasPermission(3); - })).then(CommandDispatcher.a("start").executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource()); - }))).then(CommandDispatcher.a("stop").executes((commandcontext) -> { - return b((CommandListenerWrapper) commandcontext.getSource()); - }))); - } - - private static int a(CommandListenerWrapper commandlistenerwrapper) throws CommandSyntaxException { - // CraftBukkit start - only allow use when enabled (so that no blank profile results occur) - if (!commandlistenerwrapper.getServer().methodProfiler.ENABLED) { - commandlistenerwrapper.sendFailureMessage(new ChatComponentText("Vanilla debug profiling is disabled.")); - commandlistenerwrapper.sendFailureMessage(new ChatComponentText("To enable, restart the server with `-DenableDebugMethodProfiler=true' before `-jar'.")); - commandlistenerwrapper.sendFailureMessage(new ChatComponentText("Use `/timings' for plugin timings.")); - return 0; - } - // CraftBukkit end - MinecraftServer minecraftserver = commandlistenerwrapper.getServer(); - MethodProfiler methodprofiler = minecraftserver.methodProfiler; - - if (methodprofiler.a()) { - throw CommandDebug.c.create(); - } else { - minecraftserver.ai(); - commandlistenerwrapper.sendMessage(new ChatMessage("commands.debug.started", new Object[] { "Started the debug profiler. Type '/debug stop' to stop it."}), true); - return 0; - } - } - - private static int b(CommandListenerWrapper commandlistenerwrapper) throws CommandSyntaxException { - // CraftBukkit start - only allow use when enabled (so that no blank profile results occur) - if (!commandlistenerwrapper.getServer().methodProfiler.ENABLED) { - commandlistenerwrapper.sendFailureMessage(new ChatComponentText("Vanilla debug profiling is disabled.")); - commandlistenerwrapper.sendFailureMessage(new ChatComponentText("To enable, restart the server with `-DenableDebugMethodProfiler=true' before `-jar'.")); - commandlistenerwrapper.sendFailureMessage(new ChatComponentText("Use `/timings' for plugin timings.")); - return 0; - } - // CraftBukkit end - MinecraftServer minecraftserver = commandlistenerwrapper.getServer(); - MethodProfiler methodprofiler = minecraftserver.methodProfiler; - - if (!methodprofiler.a()) { - throw CommandDebug.b.create(); - } else { - long i = SystemUtils.getMonotonicNanos(); - int j = minecraftserver.ah(); - long k = i - methodprofiler.c(); - int l = j - methodprofiler.d(); - File file = new File(minecraftserver.c("debug"), "profile-results-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + ".txt"); - - file.getParentFile().mkdirs(); - OutputStreamWriter outputstreamwriter = null; - - try { - outputstreamwriter = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); - outputstreamwriter.write(a(k, l, methodprofiler)); - } catch (Throwable throwable) { - CommandDebug.a.error("Could not save profiler results to {}", file, throwable); - } finally { - IOUtils.closeQuietly(outputstreamwriter); - } - - methodprofiler.b(); - float f = (float) k / 1.0E9F; - float f1 = (float) l / f; - - commandlistenerwrapper.sendMessage(new ChatMessage("commands.debug.stopped", new Object[] { String.format(Locale.ROOT, "%.2f", f), l, String.format("%.2f", f1)}), true); - return MathHelper.d(f1); - } - } - - private static String a(long i, int j, MethodProfiler methodprofiler) { - StringBuilder stringbuilder = new StringBuilder(); - - stringbuilder.append("---- Minecraft Profiler Results ----\n"); - stringbuilder.append("// "); - stringbuilder.append(a()); - stringbuilder.append("\n\n"); - stringbuilder.append("Time span: ").append(i).append(" ms\n"); - stringbuilder.append("Tick span: ").append(j).append(" ticks\n"); - stringbuilder.append("// This is approximately ").append(String.format(Locale.ROOT, "%.2f", (float) j / ((float) i / 1.0E9F))).append(" ticks per second. It should be ").append(20).append(" ticks per second\n\n"); - stringbuilder.append("--- BEGIN PROFILE DUMP ---\n\n"); - a(0, "root", stringbuilder, methodprofiler); - stringbuilder.append("--- END PROFILE DUMP ---\n\n"); - return stringbuilder.toString(); - } - - private static void a(int i, String s, StringBuilder stringbuilder, MethodProfiler methodprofiler) { - List list = methodprofiler.b(s); - - if (list != null && list.size() >= 3) { - for (int j = 1; j < list.size(); ++j) { - MethodProfiler.ProfilerInfo methodprofiler_profilerinfo = (MethodProfiler.ProfilerInfo) list.get(j); - - stringbuilder.append(String.format("[%02d] ", i)); - - for (int k = 0; k < i; ++k) { - stringbuilder.append("| "); - } - - stringbuilder.append(methodprofiler_profilerinfo.c).append(" - ").append(String.format(Locale.ROOT, "%.2f", methodprofiler_profilerinfo.a)).append("%/").append(String.format(Locale.ROOT, "%.2f", methodprofiler_profilerinfo.b)).append("%\n"); - if (!"unspecified".equals(methodprofiler_profilerinfo.c)) { - try { - a(i + 1, s + "." + methodprofiler_profilerinfo.c, stringbuilder, methodprofiler); - } catch (Exception exception) { - stringbuilder.append("[[ EXCEPTION ").append(exception).append(" ]]"); - } - } - } - - } - } - - private static String a() { - String[] astring = new String[] { "Shiny numbers!", "Am I not running fast enough? :(", "I'm working as hard as I can!", "Will I ever be good enough for you? :(", "Speedy. Zoooooom!", "Hello world", "40% better than a crash report.", "Now with extra numbers", "Now with less numbers", "Now with the same numbers", "You should add flames to things, it makes them go faster!", "Do you feel the need for... optimization?", "*cracks redstone whip*", "Maybe if you treated it better then it'll have more motivation to work faster! Poor server."}; - - try { - return astring[(int) (SystemUtils.getMonotonicNanos() % (long) astring.length)]; - } catch (Throwable throwable) { - return "Witty comment unavailable :("; - } - } -} diff --git a/src/main/java/net/minecraft/server/CommandDispatcher.java b/src/main/java/net/minecraft/server/CommandDispatcher.java index c6cbb9919..686878fb0 100644 --- a/src/main/java/net/minecraft/server/CommandDispatcher.java +++ b/src/main/java/net/minecraft/server/CommandDispatcher.java @@ -1,8 +1,6 @@ package net.minecraft.server; import com.google.common.collect.Maps; -import com.google.common.io.Files; -import com.google.gson.GsonBuilder; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.builder.ArgumentBuilder; @@ -12,9 +10,6 @@ import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.RootCommandNode; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.Iterator; import java.util.Map; @@ -32,7 +27,7 @@ import org.bukkit.event.server.ServerCommandEvent; public class CommandDispatcher { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private final com.mojang.brigadier.CommandDispatcher b = new com.mojang.brigadier.CommandDispatcher(); // CraftBukkit start @@ -52,6 +47,7 @@ public class CommandDispatcher { CommandEnchant.a(this.b); CommandXp.a(this.b); CommandFill.a(this.b); + CommandForceload.a(this.b); CommandFunction.a(this.b); CommandGamemode.a(this.b); CommandGamerule.a(this.b); @@ -61,6 +57,7 @@ public class CommandDispatcher { CommandKill.a(this.b); CommandList.a(this.b); CommandLocate.a(this.b); + CommandLoot.a(this.b); CommandTell.a(this.b); CommandParticle.a(this.b); CommandPlaySound.a(this.b); @@ -69,6 +66,7 @@ public class CommandDispatcher { CommandRecipe.a(this.b); CommandReplaceItem.a(this.b); CommandSay.a(this.b); + CommandSchedule.a(this.b); CommandScoreboard.a(this.b); CommandSeed.a(this.b); CommandSetBlock.a(this.b); @@ -79,9 +77,9 @@ public class CommandDispatcher { CommandSummon.a(this.b); CommandTag.a(this.b); CommandTeam.a(this.b); + CommandTeamMsg.a(this.b); CommandTeleport.a(this.b); CommandTellRaw.a(this.b); - CommandForceload.a(this.b); CommandTime.a(this.b); CommandTitle.a(this.b); CommandTrigger.a(this.b); @@ -104,7 +102,7 @@ public class CommandDispatcher { } this.b.findAmbiguities((commandnode, commandnode1, commandnode2, collection) -> { - // CommandDispatcher.a.warn("Ambiguity between arguments {} and {} with inputs: {}", this.b.getPath(commandnode1), this.b.getPath(commandnode2), collection); // CraftBukkit + // CommandDispatcher.LOGGER.warn("Ambiguity between arguments {} and {} with inputs: {}", this.b.getPath(commandnode1), this.b.getPath(commandnode2), collection); // CraftBukkit }); return this; } @@ -116,15 +114,6 @@ public class CommandDispatcher { }); } - public void a(File file) { - try { - Files.write((new GsonBuilder()).setPrettyPrinting().create().toJson(ArgumentRegistry.a(this.b, (CommandNode) this.b.getRoot())), file, StandardCharsets.UTF_8); - } catch (IOException ioexception) { - CommandDispatcher.a.error("Couldn't write out command tree!", ioexception); - } - - } - // CraftBukkit start public int dispatchServerCommand(CommandListenerWrapper sender, String command) { Joiner joiner = Joiner.on(" "); @@ -172,7 +161,7 @@ public class CommandDispatcher { stringreader.skip(); } - //commandlistenerwrapper.getServer().methodProfiler.enter(s); // Akarin - remove caller + commandlistenerwrapper.getServer().getMethodProfiler().enter(s); byte b0; @@ -221,7 +210,7 @@ public class CommandDispatcher { ChatMessage chatmessage1 = new ChatMessage("command.failed", new Object[0]); chatcomponenttext = new ChatComponentText(exception.getMessage() == null ? exception.getClass().getName() : exception.getMessage()); - if (CommandDispatcher.a.isDebugEnabled()) { + if (CommandDispatcher.LOGGER.isDebugEnabled()) { StackTraceElement[] astacktraceelement = exception.getStackTrace(); for (int k = 0; k < Math.min(astacktraceelement.length, 3); ++k) { @@ -236,7 +225,7 @@ public class CommandDispatcher { return b1; } } finally { - //commandlistenerwrapper.getServer().methodProfiler.exit(); // Akarin - remove caller + commandlistenerwrapper.getServer().getMethodProfiler().exit(); } return b0; @@ -246,7 +235,7 @@ public class CommandDispatcher { if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot // CraftBukkit start // Register Vanilla commands into builtRoot as before - Map, CommandNode> map = com.koloboke.collect.map.hash.HashObjObjMaps.getDefaultFactory().withNullKeyAllowed(true).withKeyEquivalence(com.koloboke.collect.Equivalence.identity()).newMutableMap(); // Use identity to prevent aliasing issues // Akarin - koloboke + Map, CommandNode> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues RootCommandNode vanillaRoot = new RootCommandNode(); RootCommandNode vanilla = entityplayer.server.vanillaCommandDispatcher.a().getRoot(); diff --git a/src/main/java/net/minecraft/server/CommandEffect.java b/src/main/java/net/minecraft/server/CommandEffect.java index 290cb03fc..f52e6752f 100644 --- a/src/main/java/net/minecraft/server/CommandEffect.java +++ b/src/main/java/net/minecraft/server/CommandEffect.java @@ -21,11 +21,11 @@ public class CommandEffect { public static void a(com.mojang.brigadier.CommandDispatcher com_mojang_brigadier_commanddispatcher) { com_mojang_brigadier_commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) CommandDispatcher.a("effect").requires((commandlistenerwrapper) -> { return commandlistenerwrapper.hasPermission(2); - })).then(CommandDispatcher.a("clear").then(((RequiredArgumentBuilder) CommandDispatcher.a("targets", (ArgumentType) ArgumentEntity.b()).executes((commandcontext) -> { + })).then(CommandDispatcher.a("clear").then(((RequiredArgumentBuilder) CommandDispatcher.a("targets", (ArgumentType) ArgumentEntity.multipleEntities()).executes((commandcontext) -> { return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentEntity.b(commandcontext, "targets")); })).then(CommandDispatcher.a("effect", (ArgumentType) ArgumentMobEffect.a()).executes((commandcontext) -> { return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentEntity.b(commandcontext, "targets"), ArgumentMobEffect.a(commandcontext, "effect")); - }))))).then(CommandDispatcher.a("give").then(CommandDispatcher.a("targets", (ArgumentType) ArgumentEntity.b()).then(((RequiredArgumentBuilder) CommandDispatcher.a("effect", (ArgumentType) ArgumentMobEffect.a()).executes((commandcontext) -> { + }))))).then(CommandDispatcher.a("give").then(CommandDispatcher.a("targets", (ArgumentType) ArgumentEntity.multipleEntities()).then(((RequiredArgumentBuilder) CommandDispatcher.a("effect", (ArgumentType) ArgumentMobEffect.a()).executes((commandcontext) -> { return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentEntity.b(commandcontext, "targets"), ArgumentMobEffect.a(commandcontext, "effect"), (Integer) null, 0, true); })).then(((RequiredArgumentBuilder) CommandDispatcher.a("seconds", (ArgumentType) IntegerArgumentType.integer(1, 1000000)).executes((commandcontext) -> { return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentEntity.b(commandcontext, "targets"), ArgumentMobEffect.a(commandcontext, "effect"), IntegerArgumentType.getInteger(commandcontext, "seconds"), 0, true); @@ -70,9 +70,9 @@ public class CommandEffect { throw CommandEffect.a.create(); } else { if (collection.size() == 1) { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.give.success.single", new Object[] { mobeffectlist.d(), ((Entity) collection.iterator().next()).getScoreboardDisplayName(), k / 20}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.give.success.single", new Object[]{mobeffectlist.d(), ((Entity) collection.iterator().next()).getScoreboardDisplayName(), k / 20}), true); } else { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.give.success.multiple", new Object[] { mobeffectlist.d(), collection.size(), k / 20}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.give.success.multiple", new Object[]{mobeffectlist.d(), collection.size(), k / 20}), true); } return j; @@ -95,9 +95,9 @@ public class CommandEffect { throw CommandEffect.b.create(); } else { if (collection.size() == 1) { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.clear.everything.success.single", new Object[] { ((Entity) collection.iterator().next()).getScoreboardDisplayName()}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.clear.everything.success.single", new Object[]{((Entity) collection.iterator().next()).getScoreboardDisplayName()}), true); } else { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.clear.everything.success.multiple", new Object[] { collection.size()}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.clear.everything.success.multiple", new Object[]{collection.size()}), true); } return i; @@ -120,9 +120,9 @@ public class CommandEffect { throw CommandEffect.c.create(); } else { if (collection.size() == 1) { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.clear.specific.success.single", new Object[] { mobeffectlist.d(), ((Entity) collection.iterator().next()).getScoreboardDisplayName()}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.clear.specific.success.single", new Object[]{mobeffectlist.d(), ((Entity) collection.iterator().next()).getScoreboardDisplayName()}), true); } else { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.clear.specific.success.multiple", new Object[] { mobeffectlist.d(), collection.size()}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.effect.clear.specific.success.multiple", new Object[]{mobeffectlist.d(), collection.size()}), true); } return i; diff --git a/src/main/java/net/minecraft/server/CommandForceload.java b/src/main/java/net/minecraft/server/CommandForceload.java deleted file mode 100644 index f0c30bf54..000000000 --- a/src/main/java/net/minecraft/server/CommandForceload.java +++ /dev/null @@ -1,142 +0,0 @@ -package net.minecraft.server; - -import com.google.common.base.Joiner; -import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.builder.RequiredArgumentBuilder; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import it.unimi.dsi.fastutil.longs.LongSet; - -public class CommandForceload { - - private static final Dynamic2CommandExceptionType a = new Dynamic2CommandExceptionType((object, object1) -> { - return new ChatMessage("commands.forceload.toobig", new Object[] { object, object1}); - }); - private static final Dynamic2CommandExceptionType b = new Dynamic2CommandExceptionType((object, object1) -> { - return new ChatMessage("commands.forceload.query.failure", new Object[] { object, object1}); - }); - private static final SimpleCommandExceptionType c = new SimpleCommandExceptionType(new ChatMessage("commands.forceload.added.failure", new Object[0])); - private static final SimpleCommandExceptionType d = new SimpleCommandExceptionType(new ChatMessage("commands.forceload.removed.failure", new Object[0])); - - public static void a(com.mojang.brigadier.CommandDispatcher com_mojang_brigadier_commanddispatcher) { - com_mojang_brigadier_commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) CommandDispatcher.a("forceload").requires((commandlistenerwrapper) -> { - return commandlistenerwrapper.hasPermission(4); - })).then(CommandDispatcher.a("add").then(((RequiredArgumentBuilder) CommandDispatcher.a("from", (ArgumentType) ArgumentVec2I.a()).executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentVec2I.a(commandcontext, "from"), ArgumentVec2I.a(commandcontext, "from"), true); - })).then(CommandDispatcher.a("to", (ArgumentType) ArgumentVec2I.a()).executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentVec2I.a(commandcontext, "from"), ArgumentVec2I.a(commandcontext, "to"), true); - }))))).then(((LiteralArgumentBuilder) CommandDispatcher.a("remove").then(((RequiredArgumentBuilder) CommandDispatcher.a("from", (ArgumentType) ArgumentVec2I.a()).executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentVec2I.a(commandcontext, "from"), ArgumentVec2I.a(commandcontext, "from"), false); - })).then(CommandDispatcher.a("to", (ArgumentType) ArgumentVec2I.a()).executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentVec2I.a(commandcontext, "from"), ArgumentVec2I.a(commandcontext, "to"), false); - })))).then(CommandDispatcher.a("all").executes((commandcontext) -> { - return b((CommandListenerWrapper) commandcontext.getSource()); - })))).then(((LiteralArgumentBuilder) CommandDispatcher.a("query").executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource()); - })).then(CommandDispatcher.a("pos", (ArgumentType) ArgumentVec2I.a()).executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentVec2I.a(commandcontext, "pos")); - })))); - } - - private static int a(CommandListenerWrapper commandlistenerwrapper, ArgumentVec2I.a argumentvec2i_a) throws CommandSyntaxException { - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(argumentvec2i_a.a >> 4, argumentvec2i_a.b >> 4); - DimensionManager dimensionmanager = commandlistenerwrapper.getWorld().dimension; // CraftBukkit - boolean flag = commandlistenerwrapper.getServer().getWorldServer(dimensionmanager).isForceLoaded(chunkcoordintpair.x, chunkcoordintpair.z); - - if (flag) { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.forceload.query.success", new Object[] { chunkcoordintpair, dimensionmanager}), false); - return 1; - } else { - throw CommandForceload.b.create(chunkcoordintpair, dimensionmanager); - } - } - - private static int a(CommandListenerWrapper commandlistenerwrapper) { - DimensionManager dimensionmanager = commandlistenerwrapper.getWorld().dimension; // CraftBukkit - LongSet longset = commandlistenerwrapper.getServer().getWorldServer(dimensionmanager).ag(); - int i = longset.size(); - - if (i > 0) { - String s = Joiner.on(", ").join(longset.stream().sorted().map(ChunkCoordIntPair::new).map(ChunkCoordIntPair::toString).iterator()); - - if (i == 1) { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.forceload.list.single", new Object[] { dimensionmanager, s}), false); - } else { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.forceload.list.multiple", new Object[] { i, dimensionmanager, s}), false); - } - } else { - commandlistenerwrapper.sendFailureMessage(new ChatMessage("commands.forceload.added.none", new Object[] { dimensionmanager})); - } - - return i; - } - - private static int b(CommandListenerWrapper commandlistenerwrapper) { - DimensionManager dimensionmanager = commandlistenerwrapper.getWorld().dimension; // CraftBukkit - WorldServer worldserver = commandlistenerwrapper.getServer().getWorldServer(dimensionmanager); - LongSet longset = worldserver.ag(); - - longset.forEach((java.util.function.LongConsumer) (i) -> { // CraftBukkit - decompile error - worldserver.setForceLoaded(ChunkCoordIntPair.a(i), ChunkCoordIntPair.b(i), false); - }); - commandlistenerwrapper.sendMessage(new ChatMessage("commands.forceload.removed.all", new Object[] { dimensionmanager}), true); - return 0; - } - - private static int a(CommandListenerWrapper commandlistenerwrapper, ArgumentVec2I.a argumentvec2i_a, ArgumentVec2I.a argumentvec2i_a1, boolean flag) throws CommandSyntaxException { - int i = Math.min(argumentvec2i_a.a, argumentvec2i_a1.a); - int j = Math.min(argumentvec2i_a.b, argumentvec2i_a1.b); - int k = Math.max(argumentvec2i_a.a, argumentvec2i_a1.a); - int l = Math.max(argumentvec2i_a.b, argumentvec2i_a1.b); - - if (i >= -30000000 && j >= -30000000 && k < 30000000 && l < 30000000) { - int i1 = i >> 4; - int j1 = j >> 4; - int k1 = k >> 4; - int l1 = l >> 4; - long i2 = ((long) (k1 - i1) + 1L) * ((long) (l1 - j1) + 1L); - - if (i2 > 256L) { - throw CommandForceload.a.create(256, i2); - } else { - DimensionManager dimensionmanager = commandlistenerwrapper.getWorld().dimension; // CraftBukkit - WorldServer worldserver = commandlistenerwrapper.getServer().getWorldServer(dimensionmanager); - ChunkCoordIntPair chunkcoordintpair = null; - int j2 = 0; - - for (int k2 = i1; k2 <= k1; ++k2) { - for (int l2 = j1; l2 <= l1; ++l2) { - boolean flag1 = worldserver.setForceLoaded(k2, l2, flag); - - if (flag1) { - ++j2; - if (chunkcoordintpair == null) { - chunkcoordintpair = new ChunkCoordIntPair(k2, l2); - } - } - } - } - - if (j2 == 0) { - throw (flag ? CommandForceload.c : CommandForceload.d).create(); - } else { - if (j2 == 1) { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.forceload." + (flag ? "added" : "removed") + ".single", new Object[] { chunkcoordintpair, dimensionmanager}), true); - } else { - ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(i1, j1); - ChunkCoordIntPair chunkcoordintpair2 = new ChunkCoordIntPair(k1, l1); - - commandlistenerwrapper.sendMessage(new ChatMessage("commands.forceload." + (flag ? "added" : "removed") + ".multiple", new Object[] { j2, dimensionmanager, chunkcoordintpair1, chunkcoordintpair2}), true); - } - - return j2; - } - } - } else { - throw ArgumentPosition.b.create(); - } - } -} diff --git a/src/main/java/net/minecraft/server/CommandGamemode.java b/src/main/java/net/minecraft/server/CommandGamemode.java index 0af2af091..fd03d57a5 100644 --- a/src/main/java/net/minecraft/server/CommandGamemode.java +++ b/src/main/java/net/minecraft/server/CommandGamemode.java @@ -35,13 +35,13 @@ public class CommandGamemode { ChatMessage chatmessage = new ChatMessage("gameMode." + enumgamemode.b(), new Object[0]); if (commandlistenerwrapper.getEntity() == entityplayer) { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.gamemode.success.self", new Object[] { chatmessage}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.gamemode.success.self", new Object[]{chatmessage}), true); } else { - if (commandlistenerwrapper.getWorld().getGameRules().getBoolean("sendCommandFeedback")) { - entityplayer.sendMessage(new ChatMessage("gameMode.changed", new Object[] { chatmessage})); + if (commandlistenerwrapper.getWorld().getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK)) { + entityplayer.sendMessage(new ChatMessage("gameMode.changed", new Object[]{chatmessage})); } - commandlistenerwrapper.sendMessage(new ChatMessage("commands.gamemode.success.other", new Object[] { entityplayer.getScoreboardDisplayName(), chatmessage}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.gamemode.success.other", new Object[]{entityplayer.getScoreboardDisplayName(), chatmessage}), true); } } diff --git a/src/main/java/net/minecraft/server/CommandGamerule.java b/src/main/java/net/minecraft/server/CommandGamerule.java index ee8c0eca3..1ae60aae1 100644 --- a/src/main/java/net/minecraft/server/CommandGamerule.java +++ b/src/main/java/net/minecraft/server/CommandGamerule.java @@ -2,42 +2,40 @@ package net.minecraft.server; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; -import java.util.Iterator; -import java.util.Map.Entry; public class CommandGamerule { public static void a(com.mojang.brigadier.CommandDispatcher com_mojang_brigadier_commanddispatcher) { - LiteralArgumentBuilder literalargumentbuilder = (LiteralArgumentBuilder) CommandDispatcher.a("gamerule").requires((commandlistenerwrapper) -> { + final LiteralArgumentBuilder literalargumentbuilder = (LiteralArgumentBuilder) CommandDispatcher.a("gamerule").requires((commandlistenerwrapper) -> { return commandlistenerwrapper.hasPermission(2); }); - Iterator iterator = GameRules.getGameRules().entrySet().iterator(); - - while (iterator.hasNext()) { - Entry entry = (Entry) iterator.next(); - - literalargumentbuilder.then(((LiteralArgumentBuilder) CommandDispatcher.a((String) entry.getKey()).executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource(), (String) entry.getKey()); - })).then(((GameRules.GameRuleDefinition) entry.getValue()).b().a("value").executes((commandcontext) -> { - return a((CommandListenerWrapper) commandcontext.getSource(), (String) entry.getKey(), commandcontext); - }))); - } + GameRules.a(new GameRules.GameRuleVisitor() { + @Override + public > void a(GameRules.GameRuleKey gamerules_gamerulekey, GameRules.GameRuleDefinition gamerules_gameruledefinition) { + literalargumentbuilder.then(((LiteralArgumentBuilder) CommandDispatcher.a(gamerules_gamerulekey.a()).executes((commandcontext) -> { + return CommandGamerule.b((CommandListenerWrapper) commandcontext.getSource(), gamerules_gamerulekey); + })).then(gamerules_gameruledefinition.a("value").executes((commandcontext) -> { + return CommandGamerule.b(commandcontext, gamerules_gamerulekey); + }))); + } + }); com_mojang_brigadier_commanddispatcher.register(literalargumentbuilder); } - private static int a(CommandListenerWrapper commandlistenerwrapper, String s, CommandContext commandcontext) { - GameRules.GameRuleValue gamerules_gamerulevalue = commandlistenerwrapper.getWorld().getGameRules().get(s); // CraftBukkit + private static > int b(CommandContext commandcontext, GameRules.GameRuleKey gamerules_gamerulekey) { + CommandListenerWrapper commandlistenerwrapper = (CommandListenerWrapper) commandcontext.getSource(); + T t0 = commandlistenerwrapper.getWorld().getGameRules().get(gamerules_gamerulekey); // CraftBukkit - gamerules_gamerulevalue.getType().a(commandcontext, "value", gamerules_gamerulevalue); - commandlistenerwrapper.sendMessage(new ChatMessage("commands.gamerule.set", new Object[] { s, gamerules_gamerulevalue.a()}), true); - return gamerules_gamerulevalue.c(); + t0.b(commandcontext, "value"); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.gamerule.set", new Object[]{gamerules_gamerulekey.a(), t0.toString()}), true); + return t0.getIntValue(); } - private static int a(CommandListenerWrapper commandlistenerwrapper, String s) { - GameRules.GameRuleValue gamerules_gamerulevalue = commandlistenerwrapper.getWorld().getGameRules().get(s); // CraftBukkit + private static > int b(CommandListenerWrapper commandlistenerwrapper, GameRules.GameRuleKey gamerules_gamerulekey) { + T t0 = commandlistenerwrapper.getWorld().getGameRules().get(gamerules_gamerulekey); // CraftBukkit - commandlistenerwrapper.sendMessage(new ChatMessage("commands.gamerule.query", new Object[] { s, gamerules_gamerulevalue.a()}), false); - return gamerules_gamerulevalue.c(); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.gamerule.query", new Object[]{gamerules_gamerulekey.a(), t0.toString()}), false); + return t0.getIntValue(); } } diff --git a/src/main/java/net/minecraft/server/CommandListenerWrapper.java b/src/main/java/net/minecraft/server/CommandListenerWrapper.java index 5aa3a93ce..0b23a0548 100644 --- a/src/main/java/net/minecraft/server/CommandListenerWrapper.java +++ b/src/main/java/net/minecraft/server/CommandListenerWrapper.java @@ -9,10 +9,10 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.brigadier.tree.CommandNode; import java.util.Collection; -import java.util.Collections; import java.util.Iterator; import java.util.concurrent.CompletableFuture; import java.util.function.BinaryOperator; +import java.util.stream.Stream; import javax.annotation.Nullable; public class CommandListenerWrapper implements ICompletionProvider { @@ -106,8 +106,8 @@ public class CommandListenerWrapper implements ICompletionProvider { double d1 = vec3d.y - vec3d1.y; double d2 = vec3d.z - vec3d1.z; double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2); - float f = MathHelper.g((float) (-(MathHelper.c(d1, d3) * 57.2957763671875D))); - float f1 = MathHelper.g((float) (MathHelper.c(d2, d0) * 57.2957763671875D) - 90.0F); + float f = MathHelper.g((float) (-(MathHelper.d(d1, d3) * 57.2957763671875D))); + float f1 = MathHelper.g((float) (MathHelper.d(d2, d0) * 57.2957763671875D) - 90.0F); return this.a(new Vec2F(f, f1)); } @@ -120,6 +120,7 @@ public class CommandListenerWrapper implements ICompletionProvider { return this.g; } + @Override public boolean hasPermission(int i) { // CraftBukkit start if (currentCommand != null) { @@ -179,39 +180,39 @@ public class CommandListenerWrapper implements ICompletionProvider { } public void sendMessage(IChatBaseComponent ichatbasecomponent, boolean flag) { - if (this.base.a() && !this.j) { + if (this.base.shouldSendSuccess() && !this.j) { this.base.sendMessage(ichatbasecomponent); } - if (flag && this.base.B_() && !this.j) { + if (flag && this.base.shouldBroadcastCommands() && !this.j) { this.sendAdminMessage(ichatbasecomponent); } } private void sendAdminMessage(IChatBaseComponent ichatbasecomponent) { - IChatBaseComponent ichatbasecomponent1 = (new ChatMessage("chat.type.admin", new Object[] { this.getScoreboardDisplayName(), ichatbasecomponent})).a(new EnumChatFormat[] { EnumChatFormat.GRAY, EnumChatFormat.ITALIC}); + IChatBaseComponent ichatbasecomponent1 = (new ChatMessage("chat.type.admin", new Object[]{this.getScoreboardDisplayName(), ichatbasecomponent})).a(new EnumChatFormat[]{EnumChatFormat.GRAY, EnumChatFormat.ITALIC}); - if (this.i.getGameRules().getBoolean("sendCommandFeedback")) { - Iterator iterator = this.i.getPlayerList().v().iterator(); + if (this.i.getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK)) { + Iterator iterator = this.i.getPlayerList().getPlayers().iterator(); while (iterator.hasNext()) { EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - if (entityplayer != this.base && this.i.getPlayerList().isOp(entityplayer.getProfile())) { + if (entityplayer != this.base && entityplayer.getBukkitEntity().hasPermission("minecraft.admin.command_feedback")) { // CraftBukkit entityplayer.sendMessage(ichatbasecomponent1); } } } - if (this.base != this.i && this.i.getGameRules().getBoolean("logAdminCommands") && !org.spigotmc.SpigotConfig.silentCommandBlocks) { // Spigot + if (this.base != this.i && this.i.getGameRules().getBoolean(GameRules.LOG_ADMIN_COMMANDS) && !org.spigotmc.SpigotConfig.silentCommandBlocks) { // Spigot this.i.sendMessage(ichatbasecomponent1); } } public void sendFailureMessage(IChatBaseComponent ichatbasecomponent) { - if (this.base.b() && !this.j) { + if (this.base.shouldSendFailure() && !this.j) { this.base.sendMessage((new ChatComponentText("")).addSibling(ichatbasecomponent).a(EnumChatFormat.RED)); } @@ -224,30 +225,31 @@ public class CommandListenerWrapper implements ICompletionProvider { } + @Override public Collection l() { return Lists.newArrayList(this.i.getPlayers()); } + @Override public Collection m() { return this.i.getScoreboard().f(); } + @Override public Collection n() { return IRegistry.SOUND_EVENT.keySet(); } - public Collection o() { + @Override + public Stream o() { return this.i.getCraftingManager().c(); } + @Override public CompletableFuture a(CommandContext commandcontext, SuggestionsBuilder suggestionsbuilder) { return null; } - public Collection a(boolean flag) { - return Collections.singleton(ICompletionProvider.a.b); - } - // CraftBukkit start public org.bukkit.command.CommandSender getBukkitSender() { return base.getBukkitSender(this); diff --git a/src/main/java/net/minecraft/server/CommandSpreadPlayers.java b/src/main/java/net/minecraft/server/CommandSpreadPlayers.java index 5b6127e0d..e7f230c7e 100644 --- a/src/main/java/net/minecraft/server/CommandSpreadPlayers.java +++ b/src/main/java/net/minecraft/server/CommandSpreadPlayers.java @@ -19,16 +19,16 @@ import java.util.Set; public class CommandSpreadPlayers { private static final Dynamic4CommandExceptionType a = new Dynamic4CommandExceptionType((object, object1, object2, object3) -> { - return new ChatMessage("commands.spreadplayers.failed.teams", new Object[] { object, object1, object2, object3}); + return new ChatMessage("commands.spreadplayers.failed.teams", new Object[]{object, object1, object2, object3}); }); private static final Dynamic4CommandExceptionType b = new Dynamic4CommandExceptionType((object, object1, object2, object3) -> { - return new ChatMessage("commands.spreadplayers.failed.entities", new Object[] { object, object1, object2, object3}); + return new ChatMessage("commands.spreadplayers.failed.entities", new Object[]{object, object1, object2, object3}); }); public static void a(com.mojang.brigadier.CommandDispatcher com_mojang_brigadier_commanddispatcher) { com_mojang_brigadier_commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) CommandDispatcher.a("spreadplayers").requires((commandlistenerwrapper) -> { return commandlistenerwrapper.hasPermission(2); - })).then(CommandDispatcher.a("center", (ArgumentType) ArgumentVec2.a()).then(CommandDispatcher.a("spreadDistance", (ArgumentType) FloatArgumentType.floatArg(0.0F)).then(CommandDispatcher.a("maxRange", (ArgumentType) FloatArgumentType.floatArg(1.0F)).then(CommandDispatcher.a("respectTeams", (ArgumentType) BoolArgumentType.bool()).then(CommandDispatcher.a("targets", (ArgumentType) ArgumentEntity.b()).executes((commandcontext) -> { + })).then(CommandDispatcher.a("center", (ArgumentType) ArgumentVec2.a()).then(CommandDispatcher.a("spreadDistance", (ArgumentType) FloatArgumentType.floatArg(0.0F)).then(CommandDispatcher.a("maxRange", (ArgumentType) FloatArgumentType.floatArg(1.0F)).then(CommandDispatcher.a("respectTeams", (ArgumentType) BoolArgumentType.bool()).then(CommandDispatcher.a("targets", (ArgumentType) ArgumentEntity.multipleEntities()).executes((commandcontext) -> { return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentVec2.a(commandcontext, "center"), FloatArgumentType.getFloat(commandcontext, "spreadDistance"), FloatArgumentType.getFloat(commandcontext, "maxRange"), BoolArgumentType.getBool(commandcontext, "respectTeams"), ArgumentEntity.b(commandcontext, "targets")); }))))))); } @@ -44,7 +44,7 @@ public class CommandSpreadPlayers { a(vec2f, (double) f, commandlistenerwrapper.getWorld(), random, d0, d1, d2, d3, acommandspreadplayers_a, flag); double d4 = a(collection, commandlistenerwrapper.getWorld(), acommandspreadplayers_a, flag); - commandlistenerwrapper.sendMessage(new ChatMessage("commands.spreadplayers.success." + (flag ? "teams" : "entities"), new Object[] { acommandspreadplayers_a.length, vec2f.i, vec2f.j, String.format(Locale.ROOT, "%.2f", d4)}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.spreadplayers.success." + (flag ? "teams" : "entities"), new Object[]{acommandspreadplayers_a.length, vec2f.i, vec2f.j, String.format(Locale.ROOT, "%.2f", d4)}), true); return acommandspreadplayers_a.length; } @@ -168,7 +168,7 @@ public class CommandSpreadPlayers { commandspreadplayers_a = acommandspreadplayers_a[i++]; } - entity.enderTeleportTo((double) ((float) MathHelper.floor(commandspreadplayers_a.a) + 0.5F), (double) commandspreadplayers_a.a((IBlockAccess) worldserver), (double) MathHelper.floor(commandspreadplayers_a.b) + 0.5D); + entity.enderTeleportAndLoad((double) ((float) MathHelper.floor(commandspreadplayers_a.a) + 0.5F), (double) commandspreadplayers_a.a((IBlockAccess) worldserver), (double) MathHelper.floor(commandspreadplayers_a.b) + 0.5D); d1 = Double.MAX_VALUE; CommandSpreadPlayers.a[] acommandspreadplayers_a1 = acommandspreadplayers_a; int j = acommandspreadplayers_a.length; @@ -297,7 +297,7 @@ public class CommandSpreadPlayers { // CraftBukkit start - add a version of getType which force loads chunks private static IBlockData getType(IBlockAccess iblockaccess, BlockPosition position) { - ((ChunkProviderServer) ((World) iblockaccess).chunkProvider).getChunkAt(position.getX() >> 4, position.getZ() >> 4, true, true); + ((ChunkProviderServer) ((World) iblockaccess).chunkProvider).getChunkAt(position.getX() >> 4, position.getZ() >> 4, true); return iblockaccess.getType(position); } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/CommandSummon.java b/src/main/java/net/minecraft/server/CommandSummon.java index f97be3bf9..b9e103724 100644 --- a/src/main/java/net/minecraft/server/CommandSummon.java +++ b/src/main/java/net/minecraft/server/CommandSummon.java @@ -31,20 +31,23 @@ public class CommandSummon { EntityLightning entitylightning = new EntityLightning(commandlistenerwrapper.getWorld(), vec3d.x, vec3d.y, vec3d.z, false); commandlistenerwrapper.getWorld().strikeLightning(entitylightning, org.bukkit.event.weather.LightningStrikeEvent.Cause.COMMAND); // CraftBukkit - commandlistenerwrapper.sendMessage(new ChatMessage("commands.summon.success", new Object[] { entitylightning.getScoreboardDisplayName()}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.summon.success", new Object[]{entitylightning.getScoreboardDisplayName()}), true); return 1; } else { - Entity entity = ChunkRegionLoader.a(nbttagcompound1, commandlistenerwrapper.getWorld(), vec3d.x, vec3d.y, vec3d.z, true); + WorldServer worldserver = commandlistenerwrapper.getWorld(); + Entity entity = EntityTypes.a(nbttagcompound1, worldserver, (entity1) -> { + entity1.setPositionRotation(vec3d.x, vec3d.y, vec3d.z, entity1.yaw, entity1.pitch); + return !worldserver.addEntitySerialized(entity1) ? null : entity1; + }); if (entity == null) { throw CommandSummon.a.create(); } else { - entity.setPositionRotation(vec3d.x, vec3d.y, vec3d.z, entity.yaw, entity.pitch); if (flag && entity instanceof EntityInsentient) { - ((EntityInsentient) entity).prepare(commandlistenerwrapper.getWorld().getDamageScaler(new BlockPosition(entity)), (GroupDataEntity) null, (NBTTagCompound) null); + ((EntityInsentient) entity).prepare(commandlistenerwrapper.getWorld(), commandlistenerwrapper.getWorld().getDamageScaler(new BlockPosition(entity)), EnumMobSpawn.COMMAND, (GroupDataEntity) null, (NBTTagCompound) null); } - commandlistenerwrapper.sendMessage(new ChatMessage("commands.summon.success", new Object[] { entity.getScoreboardDisplayName()}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.summon.success", new Object[]{entity.getScoreboardDisplayName()}), true); return 1; } } diff --git a/src/main/java/net/minecraft/server/CommandTeleport.java b/src/main/java/net/minecraft/server/CommandTeleport.java index dafd31540..a95775fe2 100644 --- a/src/main/java/net/minecraft/server/CommandTeleport.java +++ b/src/main/java/net/minecraft/server/CommandTeleport.java @@ -23,7 +23,7 @@ public class CommandTeleport { public static void a(com.mojang.brigadier.CommandDispatcher com_mojang_brigadier_commanddispatcher) { LiteralCommandNode literalcommandnode = com_mojang_brigadier_commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) CommandDispatcher.a("teleport").requires((commandlistenerwrapper) -> { return commandlistenerwrapper.hasPermission(2); - })).then(((RequiredArgumentBuilder) CommandDispatcher.a("targets", (ArgumentType) ArgumentEntity.b()).then(((RequiredArgumentBuilder) ((RequiredArgumentBuilder) CommandDispatcher.a("location", (ArgumentType) ArgumentVec3.a()).executes((commandcontext) -> { + })).then(((RequiredArgumentBuilder) CommandDispatcher.a("targets", (ArgumentType) ArgumentEntity.multipleEntities()).then(((RequiredArgumentBuilder) ((RequiredArgumentBuilder) CommandDispatcher.a("location", (ArgumentType) ArgumentVec3.a()).executes((commandcontext) -> { return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentEntity.b(commandcontext, "targets"), ((CommandListenerWrapper) commandcontext.getSource()).getWorld(), ArgumentVec3.b(commandcontext, "location"), (IVectorPosition) null, (CommandTeleport.a) null); })).then(CommandDispatcher.a("rotation", (ArgumentType) ArgumentRotation.a()).executes((commandcontext) -> { return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentEntity.b(commandcontext, "targets"), ((CommandListenerWrapper) commandcontext.getSource()).getWorld(), ArgumentVec3.b(commandcontext, "location"), ArgumentRotation.a(commandcontext, "rotation"), (CommandTeleport.a) null); @@ -52,13 +52,13 @@ public class CommandTeleport { while (iterator.hasNext()) { Entity entity1 = (Entity) iterator.next(); - a(commandlistenerwrapper, entity1, (WorldServer) entity.world, entity.locX, entity.locY, entity.locZ, EnumSet.noneOf(PacketPlayOutPosition.EnumPlayerTeleportFlags.class), entity.yaw, entity.pitch, (CommandTeleport.a) null); // SPIGOT-4245, MC-128441 - use target world as destination + a(commandlistenerwrapper, entity1, (WorldServer) entity.world, entity.locX, entity.locY, entity.locZ, EnumSet.noneOf(PacketPlayOutPosition.EnumPlayerTeleportFlags.class), entity.yaw, entity.pitch, (CommandTeleport.a) null); } if (collection.size() == 1) { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.teleport.success.entity.single", new Object[] { ((Entity) collection.iterator().next()).getScoreboardDisplayName(), entity.getScoreboardDisplayName()}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.teleport.success.entity.single", new Object[]{((Entity) collection.iterator().next()).getScoreboardDisplayName(), entity.getScoreboardDisplayName()}), true); } else { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.teleport.success.entity.multiple", new Object[] { collection.size(), entity.getScoreboardDisplayName()}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.teleport.success.entity.multiple", new Object[]{collection.size(), entity.getScoreboardDisplayName()}), true); } return collection.size(); @@ -107,9 +107,9 @@ public class CommandTeleport { } if (collection.size() == 1) { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.teleport.success.location.single", new Object[] { ((Entity) collection.iterator().next()).getScoreboardDisplayName(), vec3d.x, vec3d.y, vec3d.z}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.teleport.success.location.single", new Object[]{((Entity) collection.iterator().next()).getScoreboardDisplayName(), vec3d.x, vec3d.y, vec3d.z}), true); } else { - commandlistenerwrapper.sendMessage(new ChatMessage("commands.teleport.success.location.multiple", new Object[] { collection.size(), vec3d.x, vec3d.y, vec3d.z}), true); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.teleport.success.location.multiple", new Object[]{collection.size(), vec3d.x, vec3d.y, vec3d.z}), true); } return collection.size(); @@ -117,9 +117,12 @@ public class CommandTeleport { private static void a(CommandListenerWrapper commandlistenerwrapper, Entity entity, WorldServer worldserver, double d0, double d1, double d2, Set set, float f, float f1, @Nullable CommandTeleport.a commandteleport_a) { if (entity instanceof EntityPlayer) { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(d0, d1, d2)); + + worldserver.getChunkProvider().addTicket(TicketType.POST_TELEPORT, chunkcoordintpair, 1, entity.getId()); entity.stopRiding(); if (((EntityPlayer) entity).isSleeping()) { - ((EntityPlayer) entity).a(true, true, false); + ((EntityPlayer) entity).wakeup(true, true, false); } if (worldserver == entity.world) { @@ -153,14 +156,11 @@ public class CommandTeleport { entity.setPositionRotation(d0, d1, d2, f2, f3); entity.setHeadRotation(f2); } else { - WorldServer worldserver1 = (WorldServer) entity.world; - - worldserver1.kill(entity); + entity.decouple(); entity.dimension = worldserver.worldProvider.getDimensionManager(); - entity.dead = false; Entity entity1 = entity; - entity = entity.P().a((World) worldserver); + entity = entity.getEntityType().a((World) worldserver); if (entity == null) { return; } @@ -168,12 +168,7 @@ public class CommandTeleport { entity.v(entity1); entity.setPositionRotation(d0, d1, d2, f2, f3); entity.setHeadRotation(f2); - boolean flag = entity.attachedToPlayer; - - entity.attachedToPlayer = true; - worldserver.addEntity(entity); - entity.attachedToPlayer = flag; - worldserver.entityJoinedWorld(entity, false); + worldserver.addEntityTeleport(entity); entity1.dead = true; } } @@ -182,8 +177,8 @@ public class CommandTeleport { commandteleport_a.a(commandlistenerwrapper, entity); } - if (!(entity instanceof EntityLiving) || !((EntityLiving) entity).dc()) { - entity.motY = 0.0D; + if (!(entity instanceof EntityLiving) || !((EntityLiving) entity).isGliding()) { + entity.setMot(entity.getMot().d(1.0D, 0.0D, 1.0D)); entity.onGround = true; } diff --git a/src/main/java/net/minecraft/server/Container.java b/src/main/java/net/minecraft/server/Container.java index c1002b007..b38cb8dd2 100644 --- a/src/main/java/net/minecraft/server/Container.java +++ b/src/main/java/net/minecraft/server/Container.java @@ -8,6 +8,7 @@ import java.util.Set; import javax.annotation.Nullable; // CraftBukkit start +import com.google.common.base.Preconditions; import java.util.HashMap; import java.util.Map; import org.bukkit.craftbukkit.inventory.CraftInventory; @@ -22,12 +23,15 @@ public abstract class Container { public NonNullList items = NonNullList.a(); public List slots = Lists.newArrayList(); - public int windowId; + private final List d = Lists.newArrayList(); + @Nullable + private final Containers e; + public final int windowId; private int dragType = -1; - private int g; - private final Set h = Sets.newHashSet(); - protected List listeners = Lists.newArrayList(); - private final Set i = Sets.newHashSet(); + private int h; + private final Set i = Sets.newHashSet(); + private final List listeners = Lists.newArrayList(); + private final Set k = Sets.newHashSet(); // CraftBukkit start public boolean checkReachable = true; @@ -39,9 +43,51 @@ public abstract class Container { ((CraftInventory) destination.getTopInventory()).getInventory().onOpen(player); ((CraftInventory) destination.getBottomInventory()).getInventory().onOpen(player); } + private IChatBaseComponent title; + public final IChatBaseComponent getTitle() { + Preconditions.checkState(this.title != null, "Title not set"); + return this.title; + } + public final void setTitle(IChatBaseComponent title) { + Preconditions.checkState(this.title == null, "Title already set"); + this.title = title; + } // CraftBukkit end - public Container() {} + protected Container(@Nullable Containers containers, int i) { + this.e = containers; + this.windowId = i; + } + + protected static boolean a(ContainerAccess containeraccess, EntityHuman entityhuman, Block block) { + return (Boolean) containeraccess.a((world, blockposition) -> { + return world.getType(blockposition).getBlock() != block ? false : entityhuman.e((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) <= 64.0D; + }, true); + } + + public Containers getType() { + if (this.e == null) { + throw new UnsupportedOperationException("Unable to construct this menu by type"); + } else { + return this.e; + } + } + + protected static void a(IInventory iinventory, int i) { + int j = iinventory.getSize(); + + if (j < i) { + throw new IllegalArgumentException("Container size " + j + " is smaller than expected " + i); + } + } + + protected static void a(IContainerProperties icontainerproperties, int i) { + int j = icontainerproperties.a(); + + if (j < i) { + throw new IllegalArgumentException("Container data count " + j + " is smaller than expected " + i); + } + } protected Slot a(Slot slot) { slot.rawSlotIndex = this.slots.size(); @@ -50,17 +96,27 @@ public abstract class Container { return slot; } + protected ContainerProperty a(ContainerProperty containerproperty) { + this.d.add(containerproperty); + return containerproperty; + } + + protected void a(IContainerProperties icontainerproperties) { + for (int i = 0; i < icontainerproperties.a(); ++i) { + this.a(ContainerProperty.a(icontainerproperties, i)); + } + + } + public void addSlotListener(ICrafting icrafting) { - if (this.listeners.contains(icrafting)) { - throw new IllegalArgumentException("Listener already listening"); - } else { + if (!this.listeners.contains(icrafting)) { this.listeners.add(icrafting); - icrafting.a(this, this.a()); - this.b(); + icrafting.a(this, this.b()); + this.c(); } } - public NonNullList a() { + public NonNullList b() { NonNullList nonnulllist = NonNullList.a(); for (int i = 0; i < this.slots.size(); ++i) { @@ -70,17 +126,36 @@ public abstract class Container { return nonnulllist; } - public void b() { - for (int i = 0; i < this.slots.size(); ++i) { + public void c() { + int i; + + for (i = 0; i < this.slots.size(); ++i) { ItemStack itemstack = ((Slot) this.slots.get(i)).getItem(); ItemStack itemstack1 = (ItemStack) this.items.get(i); if (!ItemStack.matches(itemstack1, itemstack)) { itemstack1 = itemstack.isEmpty() ? ItemStack.a : itemstack.cloneItemStack(); this.items.set(i, itemstack1); + Iterator iterator = this.listeners.iterator(); - for (int j = 0; j < this.listeners.size(); ++j) { - ((ICrafting) this.listeners.get(j)).a(this, i, itemstack1); + while (iterator.hasNext()) { + ICrafting icrafting = (ICrafting) iterator.next(); + + icrafting.a(this, i, itemstack1); + } + } + } + + for (i = 0; i < this.d.size(); ++i) { + ContainerProperty containerproperty = (ContainerProperty) this.d.get(i); + + if (containerproperty.c()) { + Iterator iterator1 = this.listeners.iterator(); + + while (iterator1.hasNext()) { + ICrafting icrafting1 = (ICrafting) iterator1.next(); + + icrafting1.setContainerData(this, i, containerproperty.get()); } } } @@ -91,19 +166,6 @@ public abstract class Container { return false; } - @Nullable - public Slot getSlot(IInventory iinventory, int i) { - for (int j = 0; j < this.slots.size(); ++j) { - Slot slot = (Slot) this.slots.get(j); - - if (slot.a(iinventory, i)) { - return slot; - } - } - - return null; - } - public Slot getSlot(int i) { return (Slot) this.slots.get(i); } @@ -123,44 +185,44 @@ public abstract class Container { int l; if (inventoryclicktype == InventoryClickType.QUICK_CRAFT) { - int i1 = this.g; + int i1 = this.h; - this.g = c(j); - if ((i1 != 1 || this.g != 2) && i1 != this.g) { - this.c(); + this.h = c(j); + if ((i1 != 1 || this.h != 2) && i1 != this.h) { + this.d(); } else if (playerinventory.getCarried().isEmpty()) { - this.c(); - } else if (this.g == 0) { + this.d(); + } else if (this.h == 0) { this.dragType = b(j); if (a(this.dragType, entityhuman)) { - this.g = 1; - this.h.clear(); + this.h = 1; + this.i.clear(); } else { - this.c(); + this.d(); } - } else if (this.g == 1) { + } else if (this.h == 1) { Slot slot = i < this.slots.size() ? this.slots.get(i) : null; // Paper - Ensure drag in bounds itemstack1 = playerinventory.getCarried(); - if (slot != null && a(slot, itemstack1, true) && slot.isAllowed(itemstack1) && (this.dragType == 2 || itemstack1.getCount() > this.h.size()) && this.b(slot)) { - this.h.add(slot); + if (slot != null && a(slot, itemstack1, true) && slot.isAllowed(itemstack1) && (this.dragType == 2 || itemstack1.getCount() > this.i.size()) && this.b(slot)) { + this.i.add(slot); } - } else if (this.g == 2) { - if (!this.h.isEmpty()) { + } else if (this.h == 2) { + if (!this.i.isEmpty()) { itemstack2 = playerinventory.getCarried().cloneItemStack(); k = playerinventory.getCarried().getCount(); - Iterator iterator = this.h.iterator(); + Iterator iterator = this.i.iterator(); Map draggedSlots = new HashMap(); // CraftBukkit - Store slots from drag in map (raw slot id -> new stack) while (iterator.hasNext()) { Slot slot1 = (Slot) iterator.next(); ItemStack itemstack3 = playerinventory.getCarried(); - if (slot1 != null && a(slot1, itemstack3, true) && slot1.isAllowed(itemstack3) && (this.dragType == 2 || itemstack3.getCount() >= this.h.size()) && this.b(slot1)) { + if (slot1 != null && a(slot1, itemstack3, true) && slot1.isAllowed(itemstack3) && (this.dragType == 2 || itemstack3.getCount() >= this.i.size()) && this.b(slot1)) { ItemStack itemstack4 = itemstack2.cloneItemStack(); int j1 = slot1.hasItem() ? slot1.getItem().getCount() : 0; - a(this.h, this.dragType, itemstack4, j1); + a(this.i, this.dragType, itemstack4, j1); l = Math.min(itemstack4.getMaxStackSize(), slot1.getMaxStackSize(itemstack4)); if (itemstack4.getCount() > l) { itemstack4.setCount(l); @@ -211,12 +273,12 @@ public abstract class Container { // CraftBukkit end } - this.c(); + this.d(); } else { - this.c(); + this.d(); } - } else if (this.g != 0) { - this.c(); + } else if (this.h != 0) { + this.d(); } else { Slot slot2; int k1; @@ -316,14 +378,13 @@ public abstract class Container { } } - slot2.f(); + slot2.d(); // CraftBukkit start - Make sure the client has the right slot contents if (entityhuman instanceof EntityPlayer && slot2.getMaxStackSize() != 64) { - boolean crafting = this.getBukkitView().getType() == InventoryType.WORKBENCH || this.getBukkitView().getType() == InventoryType.CRAFTING; // Akarin - if (!crafting) ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, slot2.rawSlotIndex, slot2.getItem())); // Akarin + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, slot2.rawSlotIndex, slot2.getItem())); // Updating a crafting inventory makes the client reset the result slot, have to send it again - if (crafting) { // Akarin - ((EntityPlayer) entityhuman).playerConnection.sendPackets(new PacketPlayOutSetSlot(this.windowId, slot2.rawSlotIndex, slot2.getItem()), new PacketPlayOutSetSlot(this.windowId, 0, this.getSlot(0).getItem())); // Akarin + if (this.getBukkitView().getType() == InventoryType.WORKBENCH || this.getBukkitView().getType() == InventoryType.CRAFTING) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, 0, this.getSlot(0).getItem())); } } // CraftBukkit end @@ -410,7 +471,7 @@ public abstract class Container { } } - this.b(); + this.c(); } } @@ -455,22 +516,26 @@ public abstract class Container { } public void a(IInventory iinventory) { - this.b(); + this.c(); } public void setItem(int i, ItemStack itemstack) { this.getSlot(i).set(itemstack); } + public void a(int i, int j) { + ((ContainerProperty) this.d.get(i)).set(j); + } + public boolean c(EntityHuman entityhuman) { - return !this.i.contains(entityhuman); + return !this.k.contains(entityhuman); } public void a(EntityHuman entityhuman, boolean flag) { if (flag) { - this.i.remove(entityhuman); + this.k.remove(entityhuman); } else { - this.i.add(entityhuman); + this.k.add(entityhuman); } } @@ -506,12 +571,12 @@ public abstract class Container { if (l <= itemstack.getMaxStackSize()) { itemstack.setCount(0); itemstack1.setCount(l); - slot.f(); + slot.d(); flag1 = true; } else if (itemstack1.getCount() < itemstack.getMaxStackSize()) { itemstack.subtract(itemstack.getMaxStackSize() - itemstack1.getCount()); itemstack1.setCount(itemstack.getMaxStackSize()); - slot.f(); + slot.d(); flag1 = true; } } @@ -549,7 +614,7 @@ public abstract class Container { slot.set(itemstack.cloneAndSubtract(itemstack.getCount())); } - slot.f(); + slot.d(); flag1 = true; break; } @@ -577,9 +642,9 @@ public abstract class Container { return i == 0 ? true : (i == 1 ? true : i == 2 && entityhuman.abilities.canInstantlyBuild); } - protected void c() { - this.g = 0; - this.h.clear(); + protected void d() { + this.h = 0; + this.i.clear(); } public static boolean a(@Nullable Slot slot, ItemStack itemstack, boolean flag) { @@ -590,14 +655,14 @@ public abstract class Container { public static void a(Set set, int i, ItemStack itemstack, int j) { switch (i) { - case 0: - itemstack.setCount(MathHelper.d((float) itemstack.getCount() / (float) set.size())); - break; - case 1: - itemstack.setCount(1); - break; - case 2: - itemstack.setCount(itemstack.getItem().getMaxStackSize()); + case 0: + itemstack.setCount(MathHelper.d((float) itemstack.getCount() / (float) set.size())); + break; + case 1: + itemstack.setCount(1); + break; + case 2: + itemstack.setCount(itemstack.getItem().getMaxStackSize()); } itemstack.add(j); @@ -631,20 +696,4 @@ public abstract class Container { return MathHelper.d(f * 14.0F) + (i > 0 ? 1 : 0); } } - - protected void a(World world, EntityHuman entityhuman, IInventory iinventory, InventoryCraftResult inventorycraftresult) { - if (!world.isClientSide) { - EntityPlayer entityplayer = (EntityPlayer) entityhuman; - ItemStack itemstack = ItemStack.a; - IRecipe irecipe = world.getMinecraftServer().getCraftingManager().b(iinventory, world); - - if (inventorycraftresult.a(world, entityplayer, irecipe) && irecipe != null) { - itemstack = irecipe.craftItem(iinventory); - } - itemstack = org.bukkit.craftbukkit.event.CraftEventFactory.callPreCraftEvent(iinventory, inventorycraftresult, itemstack, getBukkitView(), false); // CraftBukkit - - inventorycraftresult.setItem(0, itemstack); - entityplayer.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, 0, itemstack)); - } - } } diff --git a/src/main/java/net/minecraft/server/ContainerAccess.java b/src/main/java/net/minecraft/server/ContainerAccess.java new file mode 100644 index 000000000..6ba10d61a --- /dev/null +++ b/src/main/java/net/minecraft/server/ContainerAccess.java @@ -0,0 +1,63 @@ +package net.minecraft.server; + +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; + +public interface ContainerAccess { + + // CraftBukkit start + default World getWorld() { + throw new UnsupportedOperationException("Not supported yet."); + } + + default BlockPosition getPosition() { + throw new UnsupportedOperationException("Not supported yet."); + } + + default org.bukkit.Location getLocation() { + return new org.bukkit.Location(getWorld().getWorld(), getPosition().getX(), getPosition().getY(), getPosition().getZ()); + } + // CraftBukkit end + + ContainerAccess a = new ContainerAccess() { + @Override + public Optional a(BiFunction bifunction) { + return Optional.empty(); + } + }; + + static ContainerAccess at(final World world, final BlockPosition blockposition) { + return new ContainerAccess() { + // CraftBukkit start + @Override + public World getWorld() { + return world; + } + + @Override + public BlockPosition getPosition() { + return blockposition; + } + // CraftBukkit end + + @Override + public Optional a(BiFunction bifunction) { + return Optional.of(bifunction.apply(world, blockposition)); + } + }; + } + + Optional a(BiFunction bifunction); + + default T a(BiFunction bifunction, T t0) { + return this.a(bifunction).orElse(t0); + } + + default void a(BiConsumer biconsumer) { + this.a((world, blockposition) -> { + biconsumer.accept(world, blockposition); + return Optional.empty(); + }); + } +} diff --git a/src/main/java/net/minecraft/server/ContainerAnvil.java b/src/main/java/net/minecraft/server/ContainerAnvil.java index d206e0465..7718c5a3b 100644 --- a/src/main/java/net/minecraft/server/ContainerAnvil.java +++ b/src/main/java/net/minecraft/server/ContainerAnvil.java @@ -12,18 +12,12 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView; public class ContainerAnvil extends Container { - private static final Logger f = LogManager.getLogger(); - private final IInventory resultInventory = new InventoryCraftResult(); - private final IInventory repairInventory = new InventorySubcontainer(new ChatComponentText("Repair"), 2) { - public void update() { - super.update(); - ContainerAnvil.this.a((IInventory) this); - } - }; - private final World world; - private final BlockPosition position; - public int levelCost; - private int k; + private static final Logger LOGGER = LogManager.getLogger(); + private final IInventory resultInventory; + private final IInventory repairInventory; + public final ContainerProperty levelCost; + private final ContainerAccess containerAccess; + private int h; public String renameText; private final EntityHuman player; // CraftBukkit start @@ -33,33 +27,50 @@ public class ContainerAnvil extends Container { private PlayerInventory playerInventory; // CraftBukkit end - public ContainerAnvil(PlayerInventory playerinventory, final World world, final BlockPosition blockposition, EntityHuman entityhuman) { + public ContainerAnvil(int i, PlayerInventory playerinventory) { + this(i, playerinventory, ContainerAccess.a); + } + + public ContainerAnvil(int i, PlayerInventory playerinventory, final ContainerAccess containeraccess) { + super(Containers.ANVIL, i); this.playerInventory = playerinventory; // CraftBukkit - this.position = blockposition; - this.world = world; - this.player = entityhuman; + this.resultInventory = new InventoryCraftResult(); + this.repairInventory = new InventorySubcontainer(2) { + @Override + public void update() { + super.update(); + ContainerAnvil.this.a((IInventory) this); + } + }; + this.levelCost = ContainerProperty.a(); + this.containerAccess = containeraccess; + this.player = playerinventory.player; + this.a(this.levelCost); this.a(new Slot(this.repairInventory, 0, 27, 47)); this.a(new Slot(this.repairInventory, 1, 76, 47)); this.a(new Slot(this.resultInventory, 2, 134, 47) { + @Override public boolean isAllowed(ItemStack itemstack) { return false; } - public boolean isAllowed(EntityHuman entityhuman1) { - return (entityhuman1.abilities.canInstantlyBuild || entityhuman1.expLevel >= ContainerAnvil.this.levelCost) && ContainerAnvil.this.levelCost > 0 && this.hasItem(); + @Override + public boolean isAllowed(EntityHuman entityhuman) { + return (entityhuman.abilities.canInstantlyBuild || entityhuman.expLevel >= ContainerAnvil.this.levelCost.get()) && ContainerAnvil.this.levelCost.get() > 0 && this.hasItem(); } - public ItemStack a(EntityHuman entityhuman1, ItemStack itemstack) { - if (!entityhuman1.abilities.canInstantlyBuild) { - entityhuman1.levelDown(-ContainerAnvil.this.levelCost); + @Override + public ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { + if (!entityhuman.abilities.canInstantlyBuild) { + entityhuman.levelDown(-ContainerAnvil.this.levelCost.get()); } ContainerAnvil.this.repairInventory.setItem(0, ItemStack.a); - if (ContainerAnvil.this.k > 0) { + if (ContainerAnvil.this.h > 0) { ItemStack itemstack1 = ContainerAnvil.this.repairInventory.getItem(1); - if (!itemstack1.isEmpty() && itemstack1.getCount() > ContainerAnvil.this.k) { - itemstack1.subtract(ContainerAnvil.this.k); + if (!itemstack1.isEmpty() && itemstack1.getCount() > ContainerAnvil.this.h) { + itemstack1.subtract(ContainerAnvil.this.h); ContainerAnvil.this.repairInventory.setItem(1, itemstack1); } else { ContainerAnvil.this.repairInventory.setItem(1, ItemStack.a); @@ -68,16 +79,16 @@ public class ContainerAnvil extends Container { ContainerAnvil.this.repairInventory.setItem(1, ItemStack.a); } - ContainerAnvil.this.levelCost = 0; - IBlockData iblockdata = world.getType(blockposition); + ContainerAnvil.this.levelCost.set(0); + containeraccess.a((world, blockposition) -> { + IBlockData iblockdata = world.getType(blockposition); - if (!world.isClientSide) { - if (!entityhuman1.abilities.canInstantlyBuild && iblockdata.a(TagsBlock.ANVIL) && entityhuman1.getRandom().nextFloat() < 0.12F) { + if (!entityhuman.abilities.canInstantlyBuild && iblockdata.a(TagsBlock.ANVIL) && entityhuman.getRandom().nextFloat() < 0.12F) { IBlockData iblockdata1 = BlockAnvil.a_(iblockdata); // Paper start com.destroystokyo.paper.event.block.AnvilDamagedEvent event = new com.destroystokyo.paper.event.block.AnvilDamagedEvent(getBukkitView(), iblockdata1 != null ? org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(iblockdata1) : null); if (!event.callEvent()) { - return itemstack; + return; } else if (event.getDamageState() == com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.BROKEN) { iblockdata1 = null; } else { @@ -86,7 +97,7 @@ public class ContainerAnvil extends Container { // Paper end if (iblockdata1 == null) { - world.setAir(blockposition); + world.a(blockposition, false); world.triggerEffect(1029, blockposition, 0); } else { world.setTypeAndData(blockposition, iblockdata1, 2); @@ -95,52 +106,53 @@ public class ContainerAnvil extends Container { } else { world.triggerEffect(1030, blockposition, 0); } - } + }); return itemstack; } }); - int i; + int j; - for (i = 0; i < 3; ++i) { - for (int j = 0; j < 9; ++j) { - this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); } } + @Override public void a(IInventory iinventory) { super.a(iinventory); if (iinventory == this.repairInventory) { - this.d(); + this.e(); } } - public void d() { + public void e() { ItemStack itemstack = this.repairInventory.getItem(0); - this.levelCost = 1; + this.levelCost.set(1); int i = 0; byte b0 = 0; byte b1 = 0; if (itemstack.isEmpty()) { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), ItemStack.a); // CraftBukkit - this.levelCost = 0; + this.levelCost.set(0); } else { ItemStack itemstack1 = itemstack.cloneItemStack(); ItemStack itemstack2 = this.repairInventory.getItem(1); Map map = EnchantmentManager.a(itemstack1); int j = b0 + itemstack.getRepairCost() + (itemstack2.isEmpty() ? 0 : itemstack2.getRepairCost()); - this.k = 0; + this.h = 0; if (!itemstack2.isEmpty()) { boolean flag = itemstack2.getItem() == Items.ENCHANTED_BOOK && !ItemEnchantedBook.e(itemstack2).isEmpty(); int k; @@ -151,7 +163,7 @@ public class ContainerAnvil extends Container { k = Math.min(itemstack1.getDamage(), itemstack1.h() / 4); if (k <= 0) { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), ItemStack.a); // CraftBukkit - this.levelCost = 0; + this.levelCost.set(0); return; } @@ -162,11 +174,11 @@ public class ContainerAnvil extends Container { k = Math.min(itemstack1.getDamage(), itemstack1.h() / 4); } - this.k = i1; + this.h = i1; } else { if (!flag && (itemstack1.getItem() != itemstack2.getItem() || !itemstack1.e())) { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), ItemStack.a); // CraftBukkit - this.levelCost = 0; + this.levelCost.set(0); return; } @@ -211,7 +223,7 @@ public class ContainerAnvil extends Container { while (iterator1.hasNext()) { Enchantment enchantment1 = (Enchantment) iterator1.next(); - if (enchantment1 != enchantment && !enchantment.b(enchantment1)) { + if (enchantment1 != enchantment && !enchantment.isCompatible(enchantment1)) { flag3 = false; ++i; } @@ -229,17 +241,17 @@ public class ContainerAnvil extends Container { int j2 = 0; switch (enchantment.d()) { - case COMMON: - j2 = 1; - break; - case UNCOMMON: - j2 = 2; - break; - case RARE: - j2 = 4; - break; - case VERY_RARE: - j2 = 8; + case COMMON: + j2 = 1; + break; + case UNCOMMON: + j2 = 2; + break; + case RARE: + j2 = 4; + break; + case VERY_RARE: + j2 = 8; } if (flag) { @@ -256,7 +268,7 @@ public class ContainerAnvil extends Container { if (flag2 && !flag1) { org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), ItemStack.a); // CraftBukkit - this.levelCost = 0; + this.levelCost.set(0); return; } } @@ -266,7 +278,7 @@ public class ContainerAnvil extends Container { if (itemstack.hasName()) { b1 = 1; i += b1; - itemstack1.r(); + itemstack1.s(); } } else if (!this.renameText.equals(itemstack.getName().getString())) { b1 = 1; @@ -274,16 +286,16 @@ public class ContainerAnvil extends Container { itemstack1.a((IChatBaseComponent) (new ChatComponentText(this.renameText))); } - this.levelCost = j + i; + this.levelCost.set(j + i); if (i <= 0) { itemstack1 = ItemStack.a; } - if (b1 == i && b1 > 0 && this.levelCost >= maximumRepairCost) { // CraftBukkit - this.levelCost = maximumRepairCost - 1; // CraftBukkit + if (b1 == i && b1 > 0 && this.levelCost.get() >= maximumRepairCost) { // CraftBukkit + this.levelCost.set(maximumRepairCost - 1); // CraftBukkit } - if (this.levelCost >= maximumRepairCost && !this.player.abilities.canInstantlyBuild) { // CraftBukkit + if (this.levelCost.get() >= maximumRepairCost && !this.player.abilities.canInstantlyBuild) { // CraftBukkit itemstack1 = ItemStack.a; } @@ -295,7 +307,7 @@ public class ContainerAnvil extends Container { } if (b1 != i || b1 == 0) { - k2 = k2 * 2 + 1; + k2 = d(k2); } itemstack1.setRepairCost(k2); @@ -303,27 +315,31 @@ public class ContainerAnvil extends Container { } org.bukkit.craftbukkit.event.CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), itemstack1); // CraftBukkit - this.b(); + this.c(); } } - public void addSlotListener(ICrafting icrafting) { - super.addSlotListener(icrafting); - icrafting.setContainerData(this, 0, this.levelCost); + public static int d(int i) { + return i * 2 + 1; } + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); - if (!this.world.isClientSide) { - this.a(entityhuman, this.world, this.repairInventory); - } + this.containerAccess.a((world, blockposition) -> { + this.a(entityhuman, world, this.repairInventory); + }); } + @Override public boolean canUse(EntityHuman entityhuman) { if (!this.checkReachable) return true; // CraftBukkit - return !this.world.getType(this.position).a(TagsBlock.ANVIL) ? false : entityhuman.d((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + return (Boolean) this.containerAccess.a((world, blockposition) -> { + return !world.getType(blockposition).a(TagsBlock.ANVIL) ? false : entityhuman.e((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) <= 64.0D; + }, true); } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -349,7 +365,7 @@ public class ContainerAnvil extends Container { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } if (itemstack1.getCount() == itemstack.getCount()) { @@ -368,31 +384,16 @@ public class ContainerAnvil extends Container { ItemStack itemstack = this.getSlot(2).getItem(); if (StringUtils.isBlank(s)) { - itemstack.r(); + itemstack.s(); } else { itemstack.a((IChatBaseComponent) (new ChatComponentText(this.renameText))); } } - this.d(); + this.e(); } // CraftBukkit start - @Override - public void b() { - super.b(); - - for (int i = 0; i < this.listeners.size(); ++i) { - ICrafting icrafting = (ICrafting) this.listeners.get(i); - - //if (this.lastLevelCost != this.levelCost) { // Paper - this was the wrong solution to this, fixing it correctly in CraftPlayer - icrafting.setContainerData(this, 0, this.levelCost); - //} // Paper - } - - this.lastLevelCost = this.levelCost; - } - @Override public CraftInventoryView getBukkitView() { if (bukkitEntity != null) { @@ -400,7 +401,7 @@ public class ContainerAnvil extends Container { } org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryAnvil( - new org.bukkit.Location(world.getWorld(), position.getX(), position.getY(), position.getZ()), this.repairInventory, this.resultInventory, this); + containerAccess.getLocation(), this.repairInventory, this.resultInventory, this); bukkitEntity = new CraftInventoryView(this.player.getBukkitEntity(), inventory, this); return bukkitEntity; } diff --git a/src/main/java/net/minecraft/server/ContainerBeacon.java b/src/main/java/net/minecraft/server/ContainerBeacon.java index 5cec73391..436c74489 100644 --- a/src/main/java/net/minecraft/server/ContainerBeacon.java +++ b/src/main/java/net/minecraft/server/ContainerBeacon.java @@ -5,47 +5,60 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit public class ContainerBeacon extends Container { private final IInventory beacon; - private final ContainerBeacon.SlotBeacon f; + private final ContainerBeacon.SlotBeacon d; + private final ContainerAccess containerAccess; + private final IContainerProperties containerProperties; // CraftBukkit start private CraftInventoryView bukkitEntity = null; private PlayerInventory player; // CraftBukkit end - public ContainerBeacon(IInventory iinventory, IInventory iinventory1) { + public ContainerBeacon(int i, IInventory iinventory) { + this(i, iinventory, new ContainerProperties(3), ContainerAccess.a); + } + + public ContainerBeacon(int i, IInventory iinventory, IContainerProperties icontainerproperties, ContainerAccess containeraccess) { + super(Containers.BEACON, i); player = (PlayerInventory) iinventory; // CraftBukkit - TODO: check this - this.beacon = iinventory1; - this.f = new ContainerBeacon.SlotBeacon(iinventory1, 0, 136, 110); - this.a((Slot) this.f); + this.beacon = new InventorySubcontainer(1) { + @Override + public boolean b(int j, ItemStack itemstack) { + return itemstack.getItem() == Items.EMERALD || itemstack.getItem() == Items.DIAMOND || itemstack.getItem() == Items.GOLD_INGOT || itemstack.getItem() == Items.IRON_INGOT; + } + + @Override + public int getMaxStackSize() { + return 1; + } + }; + a(icontainerproperties, 3); + this.containerProperties = icontainerproperties; + this.containerAccess = containeraccess; + this.d = new ContainerBeacon.SlotBeacon(this.beacon, 0, 136, 110); + this.a((Slot) this.d); + this.a(icontainerproperties); boolean flag = true; boolean flag1 = true; - int i; + int j; - for (i = 0; i < 3; ++i) { - for (int j = 0; j < 9; ++j) { - this.a(new Slot(iinventory, j + i * 9 + 9, 36 + j * 18, 137 + i * 18)); + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(iinventory, k + j * 9 + 9, 36 + k * 18, 137 + j * 18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(iinventory, i, 36 + i * 18, 195)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(iinventory, j, 36 + j * 18, 195)); } } - public void addSlotListener(ICrafting icrafting) { - super.addSlotListener(icrafting); - icrafting.setContainerData(this, this.beacon); - } - - public IInventory d() { - return this.beacon; - } - + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); if (!entityhuman.world.isClientSide) { - ItemStack itemstack = this.f.a(this.f.getMaxStackSize()); + ItemStack itemstack = this.d.a(this.d.getMaxStackSize()); if (!itemstack.isEmpty()) { entityhuman.drop(itemstack, false); @@ -54,11 +67,19 @@ public class ContainerBeacon extends Container { } } + @Override public boolean canUse(EntityHuman entityhuman) { if (!this.checkReachable) return true; // CraftBukkit - return this.beacon.a(entityhuman); + return a(this.containerAccess, entityhuman, Blocks.BEACON); } + @Override + public void a(int i, int j) { + super.a(i, j); + this.c(); + } + + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -73,7 +94,7 @@ public class ContainerBeacon extends Container { } slot.a(itemstack1, itemstack); - } else if (!this.f.hasItem() && this.f.isAllowed(itemstack1) && itemstack1.getCount() == 1) { + } else if (!this.d.hasItem() && this.d.isAllowed(itemstack1) && itemstack1.getCount() == 1) { if (!this.a(itemstack1, 0, 1, false)) { return ItemStack.a; } @@ -92,7 +113,7 @@ public class ContainerBeacon extends Container { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } if (itemstack1.getCount() == itemstack.getCount()) { @@ -105,18 +126,29 @@ public class ContainerBeacon extends Container { return itemstack; } + public void c(int i, int j) { + if (this.d.hasItem()) { + this.containerProperties.setProperty(1, i); + this.containerProperties.setProperty(2, j); + this.d.a(1); + } + + } + class SlotBeacon extends Slot { public SlotBeacon(IInventory iinventory, int i, int j, int k) { super(iinventory, i, j, k); } + @Override public boolean isAllowed(ItemStack itemstack) { Item item = itemstack.getItem(); return item == Items.EMERALD || item == Items.DIAMOND || item == Items.GOLD_INGOT || item == Items.IRON_INGOT; } + @Override public int getMaxStackSize() { return 1; } @@ -129,7 +161,7 @@ public class ContainerBeacon extends Container { return bukkitEntity; } - org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryBeacon((TileEntityBeacon) this.beacon); // TODO - check this + org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryBeacon(this.beacon); bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); return bukkitEntity; } diff --git a/src/main/java/net/minecraft/server/ContainerBrewingStand.java b/src/main/java/net/minecraft/server/ContainerBrewingStand.java index b475578e6..647502efc 100644 --- a/src/main/java/net/minecraft/server/ContainerBrewingStand.java +++ b/src/main/java/net/minecraft/server/ContainerBrewingStand.java @@ -8,67 +8,53 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView; public class ContainerBrewingStand extends Container { private final IInventory brewingStand; - private final Slot f; - private int g; - private int h; + private final IContainerProperties d; + private final Slot e; // CraftBukkit start private CraftInventoryView bukkitEntity = null; private PlayerInventory player; // CraftBukkit end - public ContainerBrewingStand(PlayerInventory playerinventory, IInventory iinventory) { + public ContainerBrewingStand(int i, PlayerInventory playerinventory) { + this(i, playerinventory, new InventorySubcontainer(5), new ContainerProperties(2)); + } + + public ContainerBrewingStand(int i, PlayerInventory playerinventory, IInventory iinventory, IContainerProperties icontainerproperties) { + super(Containers.BREWING_STAND, i); player = playerinventory; // CraftBukkit + a(iinventory, 5); + a(icontainerproperties, 2); this.brewingStand = iinventory; + this.d = icontainerproperties; this.a((Slot) (new ContainerBrewingStand.SlotPotionBottle(iinventory, 0, 56, 51))); this.a((Slot) (new ContainerBrewingStand.SlotPotionBottle(iinventory, 1, 79, 58))); this.a((Slot) (new ContainerBrewingStand.SlotPotionBottle(iinventory, 2, 102, 51))); - this.f = this.a((Slot) (new ContainerBrewingStand.SlotBrewing(iinventory, 3, 79, 17))); + this.e = this.a((Slot) (new ContainerBrewingStand.SlotBrewing(iinventory, 3, 79, 17))); this.a((Slot) (new ContainerBrewingStand.a(iinventory, 4, 17, 17))); + this.a(icontainerproperties); - int i; + int j; - for (i = 0; i < 3; ++i) { - for (int j = 0; j < 9; ++j) { - this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); } } - public void addSlotListener(ICrafting icrafting) { - super.addSlotListener(icrafting); - icrafting.setContainerData(this, this.brewingStand); - } - - public void b() { - super.b(); - - for (int i = 0; i < this.listeners.size(); ++i) { - ICrafting icrafting = (ICrafting) this.listeners.get(i); - - if (this.g != this.brewingStand.getProperty(0)) { - icrafting.setContainerData(this, 0, this.brewingStand.getProperty(0)); - } - - if (this.h != this.brewingStand.getProperty(1)) { - icrafting.setContainerData(this, 1, this.brewingStand.getProperty(1)); - } - } - - this.g = this.brewingStand.getProperty(0); - this.h = this.brewingStand.getProperty(1); - } - + @Override public boolean canUse(EntityHuman entityhuman) { if (!this.checkReachable) return true; // CraftBukkit return this.brewingStand.a(entityhuman); } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -78,15 +64,15 @@ public class ContainerBrewingStand extends Container { itemstack = itemstack1.cloneItemStack(); if ((i < 0 || i > 2) && i != 3 && i != 4) { - if (this.f.isAllowed(itemstack1)) { + if (this.e.isAllowed(itemstack1)) { if (!this.a(itemstack1, 3, 4, false)) { return ItemStack.a; } - } else if (ContainerBrewingStand.SlotPotionBottle.c_(itemstack) && itemstack.getCount() == 1) { + } else if (ContainerBrewingStand.SlotPotionBottle.b_(itemstack) && itemstack.getCount() == 1) { if (!this.a(itemstack1, 0, 3, false)) { return ItemStack.a; } - } else if (ContainerBrewingStand.a.b_(itemstack)) { + } else if (ContainerBrewingStand.a.a_(itemstack)) { if (!this.a(itemstack1, 4, 5, false)) { return ItemStack.a; } @@ -112,7 +98,7 @@ public class ContainerBrewingStand extends Container { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } if (itemstack1.getCount() == itemstack.getCount()) { @@ -131,14 +117,16 @@ public class ContainerBrewingStand extends Container { super(iinventory, i, j, k); } + @Override public boolean isAllowed(ItemStack itemstack) { - return b_(itemstack); + return a_(itemstack); } - public static boolean b_(ItemStack itemstack) { + public static boolean a_(ItemStack itemstack) { return itemstack.getItem() == Items.BLAZE_POWDER; } + @Override public int getMaxStackSize() { return 64; } @@ -150,10 +138,12 @@ public class ContainerBrewingStand extends Container { super(iinventory, i, j, k); } + @Override public boolean isAllowed(ItemStack itemstack) { return PotionBrewer.a(itemstack); } + @Override public int getMaxStackSize() { return 64; } @@ -165,14 +155,17 @@ public class ContainerBrewingStand extends Container { super(iinventory, i, j, k); } + @Override public boolean isAllowed(ItemStack itemstack) { - return c_(itemstack); + return b_(itemstack); } + @Override public int getMaxStackSize() { return 1; } + @Override public ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { PotionRegistry potionregistry = PotionUtil.d(itemstack); @@ -184,7 +177,7 @@ public class ContainerBrewingStand extends Container { return itemstack; } - public static boolean c_(ItemStack itemstack) { + public static boolean b_(ItemStack itemstack) { Item item = itemstack.getItem(); return item == Items.POTION || item == Items.SPLASH_POTION || item == Items.LINGERING_POTION || item == Items.GLASS_BOTTLE; diff --git a/src/main/java/net/minecraft/server/ContainerCartography.java b/src/main/java/net/minecraft/server/ContainerCartography.java new file mode 100644 index 000000000..1806c76ed --- /dev/null +++ b/src/main/java/net/minecraft/server/ContainerCartography.java @@ -0,0 +1,272 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.Location; +import org.bukkit.craftbukkit.inventory.CraftInventoryCartography; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.entity.Player; +// CraftBukkit end + +public class ContainerCartography extends Container { + + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private Player player; + + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryCartography inventory = new CraftInventoryCartography(this.inventory, this.resultInventory); + bukkitEntity = new CraftInventoryView(this.player, inventory, this); + return bukkitEntity; + } + // CraftBukkit end + private final ContainerAccess containerAccess; + private boolean e; + public final IInventory inventory; + private final InventoryCraftResult resultInventory; + + public ContainerCartography(int i, PlayerInventory playerinventory) { + this(i, playerinventory, ContainerAccess.a); + } + + public ContainerCartography(int i, PlayerInventory playerinventory, final ContainerAccess containeraccess) { + super(Containers.CARTOGRAPHY, i); + this.inventory = new InventorySubcontainer(2) { + @Override + public void update() { + ContainerCartography.this.a((IInventory) this); + super.update(); + } + }; + this.resultInventory = new InventoryCraftResult() { + @Override + public void update() { + ContainerCartography.this.a((IInventory) this); + super.update(); + } + + // CraftBukkit start + @Override + public Location getLocation() { + return containeraccess.getLocation(); + } + // CraftBukkit end + }; + this.containerAccess = containeraccess; + this.a(new Slot(this.inventory, 0, 15, 15) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return itemstack.getItem() == Items.FILLED_MAP; + } + }); + this.a(new Slot(this.inventory, 1, 15, 52) { + @Override + public boolean isAllowed(ItemStack itemstack) { + Item item = itemstack.getItem(); + + return item == Items.PAPER || item == Items.MAP || item == Items.df; + } + }); + this.a(new Slot(this.resultInventory, 2, 145, 39) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return false; + } + + @Override + public ItemStack a(int j) { + ItemStack itemstack = super.a(j); + ItemStack itemstack1 = (ItemStack) containeraccess.a((world, blockposition) -> { + if (!ContainerCartography.this.e && ContainerCartography.this.inventory.getItem(1).getItem() == Items.df) { + ItemStack itemstack2 = ItemWorldMap.b(world, ContainerCartography.this.inventory.getItem(0)); + + if (itemstack2 != null) { + itemstack2.setCount(1); + return itemstack2; + } + } + + return itemstack; + }).orElse(itemstack); + + ContainerCartography.this.inventory.splitStack(0, 1); + ContainerCartography.this.inventory.splitStack(1, 1); + return itemstack1; + } + + @Override + protected void a(ItemStack itemstack, int j) { + this.a(j); + super.a(itemstack, j); + } + + @Override + public ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { + itemstack.getItem().b(itemstack, entityhuman.world, entityhuman); + containeraccess.a((world, blockposition) -> { + world.playSound((EntityHuman) null, blockposition, SoundEffects.UI_CARTOGRAPHY_TABLE_TAKE_RESULT, SoundCategory.BLOCKS, 1.0F, 1.0F); + }); + return super.a(entityhuman, itemstack); + } + }); + + int j; + + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); + } + } + + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); + } + + player = (Player) playerinventory.player.getBukkitEntity(); // CraftBukkit + } + + @Override + public boolean canUse(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return a(this.containerAccess, entityhuman, Blocks.CARTOGRAPHY_TABLE); + } + + @Override + public void a(IInventory iinventory) { + ItemStack itemstack = this.inventory.getItem(0); + ItemStack itemstack1 = this.inventory.getItem(1); + ItemStack itemstack2 = this.resultInventory.getItem(2); + + if (!itemstack2.isEmpty() && (itemstack.isEmpty() || itemstack1.isEmpty())) { + this.resultInventory.splitWithoutUpdate(2); + } else if (!itemstack.isEmpty() && !itemstack1.isEmpty()) { + this.a(itemstack, itemstack1, itemstack2); + } + + } + + private void a(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2) { + this.containerAccess.a((world, blockposition) -> { + Item item = itemstack1.getItem(); + WorldMap worldmap = ItemWorldMap.a(itemstack, world); + + if (worldmap != null) { + ItemStack itemstack3; + + if (item == Items.PAPER && !worldmap.locked && worldmap.scale < 4) { + itemstack3 = itemstack.cloneItemStack(); + itemstack3.setCount(1); + itemstack3.getOrCreateTag().setInt("map_scale_direction", 1); + this.c(); + } else if (item == Items.df && !worldmap.locked) { + itemstack3 = itemstack.cloneItemStack(); + itemstack3.setCount(1); + this.c(); + } else { + if (item != Items.MAP) { + this.resultInventory.splitWithoutUpdate(2); + this.c(); + return; + } + + itemstack3 = itemstack.cloneItemStack(); + itemstack3.setCount(2); + this.c(); + } + + if (!ItemStack.matches(itemstack3, itemstack2)) { + this.resultInventory.setItem(2, itemstack3); + this.c(); + } + + } + }); + } + + @Override + public boolean a(ItemStack itemstack, Slot slot) { + return false; + } + + @Override + public ItemStack shiftClick(EntityHuman entityhuman, int i) { + ItemStack itemstack = ItemStack.a; + Slot slot = (Slot) this.slots.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + ItemStack itemstack2 = itemstack1; + Item item = itemstack1.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == 2) { + if (this.inventory.getItem(1).getItem() == Items.df) { + itemstack2 = (ItemStack) this.containerAccess.a((world, blockposition) -> { + ItemStack itemstack3 = ItemWorldMap.b(world, this.inventory.getItem(0)); + + if (itemstack3 != null) { + itemstack3.setCount(1); + return itemstack3; + } else { + return itemstack1; + } + }).orElse(itemstack1); + } + + item.b(itemstack2, entityhuman.world, entityhuman); + if (!this.a(itemstack2, 3, 39, true)) { + return ItemStack.a; + } + + slot.a(itemstack2, itemstack); + } else if (i != 1 && i != 0) { + if (item == Items.FILLED_MAP) { + if (!this.a(itemstack1, 0, 1, false)) { + return ItemStack.a; + } + } else if (item != Items.PAPER && item != Items.MAP && item != Items.df) { + if (i >= 3 && i < 30) { + if (!this.a(itemstack1, 30, 39, false)) { + return ItemStack.a; + } + } else if (i >= 30 && i < 39 && !this.a(itemstack1, 3, 30, false)) { + return ItemStack.a; + } + } else if (!this.a(itemstack1, 1, 2, false)) { + return ItemStack.a; + } + } else if (!this.a(itemstack1, 3, 39, false)) { + return ItemStack.a; + } + + if (itemstack2.isEmpty()) { + slot.set(ItemStack.a); + } + + slot.d(); + if (itemstack2.getCount() == itemstack.getCount()) { + return ItemStack.a; + } + + this.e = true; + slot.a(entityhuman, itemstack2); + this.e = false; + this.c(); + } + + return itemstack; + } + + @Override + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + this.resultInventory.splitWithoutUpdate(2); + this.containerAccess.a((world, blockposition) -> { + this.a(entityhuman, entityhuman.world, this.inventory); + }); + } +} diff --git a/src/main/java/net/minecraft/server/ContainerChest.java b/src/main/java/net/minecraft/server/ContainerChest.java index 8115991d9..0ee6524b8 100644 --- a/src/main/java/net/minecraft/server/ContainerChest.java +++ b/src/main/java/net/minecraft/server/ContainerChest.java @@ -8,7 +8,7 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView; public class ContainerChest extends Container { private final IInventory container; - private final int f; + private final int d; // CraftBukkit start private CraftInventoryView bukkitEntity = null; private PlayerInventory player; @@ -33,43 +33,82 @@ public class ContainerChest extends Container { } // CraftBukkit end - public ContainerChest(IInventory iinventory, IInventory iinventory1, EntityHuman entityhuman) { - this.container = iinventory1; - this.f = iinventory1.getSize() / 9; - iinventory1.startOpen(entityhuman); - int i = (this.f - 4) * 18; + private ContainerChest(Containers containers, int i, PlayerInventory playerinventory, int j) { + this(containers, i, playerinventory, new InventorySubcontainer(9 * j), j); + } + + public static ContainerChest a(int i, PlayerInventory playerinventory) { + return new ContainerChest(Containers.GENERIC_9X1, i, playerinventory, 1); + } + + public static ContainerChest b(int i, PlayerInventory playerinventory) { + return new ContainerChest(Containers.GENERIC_9X2, i, playerinventory, 2); + } + + public static ContainerChest c(int i, PlayerInventory playerinventory) { + return new ContainerChest(Containers.GENERIC_9X3, i, playerinventory, 3); + } + + public static ContainerChest d(int i, PlayerInventory playerinventory) { + return new ContainerChest(Containers.GENERIC_9X4, i, playerinventory, 4); + } + + public static ContainerChest e(int i, PlayerInventory playerinventory) { + return new ContainerChest(Containers.GENERIC_9X5, i, playerinventory, 5); + } + + public static ContainerChest f(int i, PlayerInventory playerinventory) { + return new ContainerChest(Containers.GENERIC_9X6, i, playerinventory, 6); + } + + public static ContainerChest a(int i, PlayerInventory playerinventory, IInventory iinventory) { + return new ContainerChest(Containers.GENERIC_9X3, i, playerinventory, iinventory, 3); + } + + public static ContainerChest b(int i, PlayerInventory playerinventory, IInventory iinventory) { + return new ContainerChest(Containers.GENERIC_9X6, i, playerinventory, iinventory, 6); + } + + public ContainerChest(Containers containers, int i, PlayerInventory playerinventory, IInventory iinventory, int j) { + super(containers, i); + a(iinventory, j * 9); + this.container = iinventory; + this.d = j; + iinventory.startOpen(playerinventory.player); + int k = (this.d - 4) * 18; // CraftBukkit start - Save player - // TODO: Should we check to make sure it really is an InventoryPlayer? - this.player = (PlayerInventory) iinventory; + this.player = playerinventory; // CraftBukkit end - int j; - int k; + int l; + int i1; - for (j = 0; j < this.f; ++j) { - for (k = 0; k < 9; ++k) { - this.a(new Slot(iinventory1, k + j * 9, 8 + k * 18, 18 + j * 18)); + for (l = 0; l < this.d; ++l) { + for (i1 = 0; i1 < 9; ++i1) { + this.a(new Slot(iinventory, i1 + l * 9, 8 + i1 * 18, 18 + l * 18)); } } - for (j = 0; j < 3; ++j) { - for (k = 0; k < 9; ++k) { - this.a(new Slot(iinventory, k + j * 9 + 9, 8 + k * 18, 103 + j * 18 + i)); + for (l = 0; l < 3; ++l) { + for (i1 = 0; i1 < 9; ++i1) { + this.a(new Slot(playerinventory, i1 + l * 9 + 9, 8 + i1 * 18, 103 + l * 18 + k)); } } - for (j = 0; j < 9; ++j) { - this.a(new Slot(iinventory, j, 8 + j * 18, 161 + i)); + for (l = 0; l < 9; ++l) { + this.a(new Slot(playerinventory, l, 8 + l * 18, 161 + k)); } } + @Override public boolean canUse(EntityHuman entityhuman) { if (!this.checkReachable) return true; // CraftBukkit return this.container.a(entityhuman); } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -78,30 +117,31 @@ public class ContainerChest extends Container { ItemStack itemstack1 = slot.getItem(); itemstack = itemstack1.cloneItemStack(); - if (i < this.f * 9) { - if (!this.a(itemstack1, this.f * 9, this.slots.size(), true)) { + if (i < this.d * 9) { + if (!this.a(itemstack1, this.d * 9, this.slots.size(), true)) { return ItemStack.a; } - } else if (!this.a(itemstack1, 0, this.f * 9, false)) { + } else if (!this.a(itemstack1, 0, this.d * 9, false)) { return ItemStack.a; } if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } } return itemstack; } + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); this.container.closeContainer(entityhuman); } - public IInventory d() { + public IInventory e() { return this.container; } } diff --git a/src/main/java/net/minecraft/server/ContainerDispenser.java b/src/main/java/net/minecraft/server/ContainerDispenser.java index 8b6533d02..1af91fb54 100644 --- a/src/main/java/net/minecraft/server/ContainerDispenser.java +++ b/src/main/java/net/minecraft/server/ContainerDispenser.java @@ -13,39 +13,48 @@ public class ContainerDispenser extends Container { private PlayerInventory player; // CraftBukkit end - public ContainerDispenser(IInventory iinventory, IInventory iinventory1) { - this.items = iinventory1; + public ContainerDispenser(int i, PlayerInventory playerinventory) { + this(i, playerinventory, new InventorySubcontainer(9)); + } + + public ContainerDispenser(int i, PlayerInventory playerinventory, IInventory iinventory) { + super(Containers.GENERIC_3X3, i); // CraftBukkit start - Save player - // TODO: Should we check to make sure it really is an InventoryPlayer? - this.player = (PlayerInventory)iinventory; + this.player = playerinventory; // CraftBukkit end - int i; + a(iinventory, 9); + this.items = iinventory; + iinventory.startOpen(playerinventory.player); + int j; + int k; - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - this.a(new Slot(iinventory1, j + i * 3, 62 + j * 18, 17 + i * 18)); + for (j = 0; j < 3; ++j) { + for (k = 0; k < 3; ++k) { + this.a(new Slot(iinventory, k + j * 3, 62 + k * 18, 17 + j * 18)); } } - for (i = 0; i < 3; ++i) { - for (j = 0; j < 9; ++j) { - this.a(new Slot(iinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + for (j = 0; j < 3; ++j) { + for (k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(iinventory, i, 8 + i * 18, 142)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); } } + @Override public boolean canUse(EntityHuman entityhuman) { if (!this.checkReachable) return true; // CraftBukkit return this.items.a(entityhuman); } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -65,7 +74,7 @@ public class ContainerDispenser extends Container { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } if (itemstack1.getCount() == itemstack.getCount()) { @@ -78,6 +87,12 @@ public class ContainerDispenser extends Container { return itemstack; } + @Override + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + this.items.closeContainer(entityhuman); + } + // CraftBukkit start @Override public CraftInventoryView getBukkitView() { diff --git a/src/main/java/net/minecraft/server/ContainerEnchantTable.java b/src/main/java/net/minecraft/server/ContainerEnchantTable.java index e4b9fdc55..19b4df4a0 100644 --- a/src/main/java/net/minecraft/server/ContainerEnchantTable.java +++ b/src/main/java/net/minecraft/server/ContainerEnchantTable.java @@ -20,136 +20,125 @@ import org.bukkit.entity.Player; public class ContainerEnchantTable extends Container { - public IInventory enchantSlots = new InventorySubcontainer(new ChatComponentText("Enchant"), 2) { - public int getMaxStackSize() { - return 64; - } - - public void update() { - super.update(); - ContainerEnchantTable.this.a((IInventory) this); - } - - // CraftBukkit start - @Override - public Location getLocation() { - return new org.bukkit.Location(world.getWorld(), position.getX(), position.getY(), position.getZ()); - } - // CraftBukkit end - }; - public World world; - private final BlockPosition position; - private final Random l = new Random(); - public int f; - public int[] costs = new int[3]; - public int[] h = new int[] { -1, -1, -1}; - public int[] i = new int[] { -1, -1, -1}; + private final IInventory enchantSlots; + private final ContainerAccess containerAccess; + private final Random h; + private final ContainerProperty i; + public final int[] costs; + public final int[] enchantments; + public final int[] levels; // CraftBukkit start private CraftInventoryView bukkitEntity = null; private Player player; // CraftBukkit end - public ContainerEnchantTable(PlayerInventory playerinventory, World world, BlockPosition blockposition) { - this.world = world; - this.position = blockposition; - this.f = playerinventory.player.du(); + public ContainerEnchantTable(int i, PlayerInventory playerinventory) { + this(i, playerinventory, ContainerAccess.a); + } + + public ContainerEnchantTable(int i, PlayerInventory playerinventory, ContainerAccess containeraccess) { + super(Containers.ENCHANTMENT, i); + this.enchantSlots = new InventorySubcontainer(2) { + @Override + public void update() { + super.update(); + ContainerEnchantTable.this.a((IInventory) this); + } + + // CraftBukkit start + @Override + public Location getLocation() { + return containeraccess.getLocation(); + } + // CraftBukkit end + }; + this.h = new Random(); + this.i = ContainerProperty.a(); + this.costs = new int[3]; + this.enchantments = new int[]{-1, -1, -1}; + this.levels = new int[]{-1, -1, -1}; + this.containerAccess = containeraccess; this.a(new Slot(this.enchantSlots, 0, 15, 47) { + @Override public boolean isAllowed(ItemStack itemstack) { return true; } + @Override public int getMaxStackSize() { return 1; } }); this.a(new Slot(this.enchantSlots, 1, 35, 47) { + @Override public boolean isAllowed(ItemStack itemstack) { return itemstack.getItem() == Items.LAPIS_LAZULI; } }); - int i; + int j; - for (i = 0; i < 3; ++i) { - for (int j = 0; j < 9; ++j) { - this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); } + this.a(ContainerProperty.a(this.costs, 0)); + this.a(ContainerProperty.a(this.costs, 1)); + this.a(ContainerProperty.a(this.costs, 2)); + this.a(this.i).set(playerinventory.player.dM()); + this.a(ContainerProperty.a(this.enchantments, 0)); + this.a(ContainerProperty.a(this.enchantments, 1)); + this.a(ContainerProperty.a(this.enchantments, 2)); + this.a(ContainerProperty.a(this.levels, 0)); + this.a(ContainerProperty.a(this.levels, 1)); + this.a(ContainerProperty.a(this.levels, 2)); // CraftBukkit start player = (Player) playerinventory.player.getBukkitEntity(); // CraftBukkit end } - protected void c(ICrafting icrafting) { - icrafting.setContainerData(this, 0, this.costs[0]); - icrafting.setContainerData(this, 1, this.costs[1]); - icrafting.setContainerData(this, 2, this.costs[2]); - icrafting.setContainerData(this, 3, this.f & -16); - icrafting.setContainerData(this, 4, this.h[0]); - icrafting.setContainerData(this, 5, this.h[1]); - icrafting.setContainerData(this, 6, this.h[2]); - icrafting.setContainerData(this, 7, this.i[0]); - icrafting.setContainerData(this, 8, this.i[1]); - icrafting.setContainerData(this, 9, this.i[2]); - } - - public void addSlotListener(ICrafting icrafting) { - super.addSlotListener(icrafting); - this.c(icrafting); - } - - public void b() { - super.b(); - - for (int i = 0; i < this.listeners.size(); ++i) { - ICrafting icrafting = (ICrafting) this.listeners.get(i); - - this.c(icrafting); - } - - } - + @Override public void a(IInventory iinventory) { if (iinventory == this.enchantSlots) { ItemStack itemstack = iinventory.getItem(0); - int i; if (!itemstack.isEmpty()) { // CraftBukkit - relax condition - if (!this.world.isClientSide) { - i = 0; + this.containerAccess.a((world, blockposition) -> { + int i = 0; int j; for (j = -1; j <= 1; ++j) { for (int k = -1; k <= 1; ++k) { - if ((j != 0 || k != 0) && this.world.isEmpty(this.position.a(k, 0, j)) && this.world.isEmpty(this.position.a(k, 1, j))) { - if (this.world.getType(this.position.a(k * 2, 0, j * 2)).getBlock() == Blocks.BOOKSHELF) { + if ((j != 0 || k != 0) && world.isEmpty(blockposition.b(k, 0, j)) && world.isEmpty(blockposition.b(k, 1, j))) { + if (world.getType(blockposition.b(k * 2, 0, j * 2)).getBlock() == Blocks.BOOKSHELF) { ++i; } - if (this.world.getType(this.position.a(k * 2, 1, j * 2)).getBlock() == Blocks.BOOKSHELF) { + if (world.getType(blockposition.b(k * 2, 1, j * 2)).getBlock() == Blocks.BOOKSHELF) { ++i; } if (k != 0 && j != 0) { - if (this.world.getType(this.position.a(k * 2, 0, j)).getBlock() == Blocks.BOOKSHELF) { + if (world.getType(blockposition.b(k * 2, 0, j)).getBlock() == Blocks.BOOKSHELF) { ++i; } - if (this.world.getType(this.position.a(k * 2, 1, j)).getBlock() == Blocks.BOOKSHELF) { + if (world.getType(blockposition.b(k * 2, 1, j)).getBlock() == Blocks.BOOKSHELF) { ++i; } - if (this.world.getType(this.position.a(k, 0, j * 2)).getBlock() == Blocks.BOOKSHELF) { + if (world.getType(blockposition.b(k, 0, j * 2)).getBlock() == Blocks.BOOKSHELF) { ++i; } - if (this.world.getType(this.position.a(k, 1, j * 2)).getBlock() == Blocks.BOOKSHELF) { + if (world.getType(blockposition.b(k, 1, j * 2)).getBlock() == Blocks.BOOKSHELF) { ++i; } } @@ -157,12 +146,12 @@ public class ContainerEnchantTable extends Container { } } - this.l.setSeed((long) this.f); + this.h.setSeed((long) this.i.get()); for (j = 0; j < 3; ++j) { - this.costs[j] = EnchantmentManager.a(this.l, j, i, itemstack); - this.h[j] = -1; - this.i[j] = -1; + this.costs[j] = EnchantmentManager.a(this.h, j, i, itemstack); + this.enchantments[j] = -1; + this.levels[j] = -1; if (this.costs[j] < j + 1) { this.costs[j] = 0; } @@ -173,10 +162,10 @@ public class ContainerEnchantTable extends Container { List list = this.a(itemstack, j, this.costs[j]); if (list != null && !list.isEmpty()) { - WeightedRandomEnchant weightedrandomenchant = (WeightedRandomEnchant) list.get(this.l.nextInt(list.size())); + WeightedRandomEnchant weightedrandomenchant = (WeightedRandomEnchant) list.get(this.h.nextInt(list.size())); - this.h[j] = IRegistry.ENCHANTMENT.a(weightedrandomenchant.enchantment); // CraftBukkit - decompile error - this.i[j] = weightedrandomenchant.level; + this.enchantments[j] = IRegistry.ENCHANTMENT.a(weightedrandomenchant.enchantment); // CraftBukkit - decompile error + this.levels[j] = weightedrandomenchant.level; } } } @@ -185,19 +174,19 @@ public class ContainerEnchantTable extends Container { CraftItemStack item = CraftItemStack.asCraftMirror(itemstack); org.bukkit.enchantments.EnchantmentOffer[] offers = new EnchantmentOffer[3]; for (j = 0; j < 3; ++j) { - org.bukkit.enchantments.Enchantment enchantment = (this.h[j] >= 0) ? org.bukkit.enchantments.Enchantment.getByKey(CraftNamespacedKey.fromMinecraft(IRegistry.ENCHANTMENT.getKey(IRegistry.ENCHANTMENT.fromId(this.h[j])))) : null; - offers[j] = (enchantment != null) ? new EnchantmentOffer(enchantment, this.i[j], this.costs[j]) : null; + org.bukkit.enchantments.Enchantment enchantment = (this.enchantments[j] >= 0) ? org.bukkit.enchantments.Enchantment.getByKey(CraftNamespacedKey.fromMinecraft(IRegistry.ENCHANTMENT.getKey(IRegistry.ENCHANTMENT.fromId(this.enchantments[j])))) : null; + offers[j] = (enchantment != null) ? new EnchantmentOffer(enchantment, this.levels[j], this.costs[j]) : null; } - PrepareItemEnchantEvent event = new PrepareItemEnchantEvent(player, this.getBukkitView(), this.world.getWorld().getBlockAt(position), item, offers, i); // Akarin + PrepareItemEnchantEvent event = new PrepareItemEnchantEvent(player, this.getBukkitView(), containerAccess.getLocation().getBlock(), item, offers, i); event.setCancelled(!itemstack.canEnchant()); - this.world.getServer().getPluginManager().callEvent(event); + world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { for (j = 0; j < 3; ++j) { this.costs[j] = 0; - this.h[j] = -1; - this.i[j] = -1; + this.enchantments[j] = -1; + this.levels[j] = -1; } return; } @@ -206,29 +195,30 @@ public class ContainerEnchantTable extends Container { EnchantmentOffer offer = event.getOffers()[j]; if (offer != null) { this.costs[j] = offer.getCost(); - this.h[j] = IRegistry.ENCHANTMENT.a(IRegistry.ENCHANTMENT.get(CraftNamespacedKey.toMinecraft(offer.getEnchantment().getKey()))); - this.i[j] = offer.getEnchantmentLevel(); + this.enchantments[j] = IRegistry.ENCHANTMENT.a(IRegistry.ENCHANTMENT.get(CraftNamespacedKey.toMinecraft(offer.getEnchantment().getKey()))); + this.levels[j] = offer.getEnchantmentLevel(); } else { this.costs[j] = 0; - this.h[j] = -1; - this.i[j] = -1; + this.enchantments[j] = -1; + this.levels[j] = -1; } } // CraftBukkit end - this.b(); - } + this.c(); + }); } else { - for (i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++i) { this.costs[i] = 0; - this.h[i] = -1; - this.i[i] = -1; + this.enchantments[i] = -1; + this.levels[i] = -1; } } } } + @Override public boolean a(EntityHuman entityhuman, int i) { ItemStack itemstack = this.enchantSlots.getItem(0); ItemStack itemstack1 = this.enchantSlots.getItem(1); @@ -237,7 +227,8 @@ public class ContainerEnchantTable extends Container { if ((itemstack1.isEmpty() || itemstack1.getCount() < j) && !entityhuman.abilities.canInstantlyBuild) { return false; } else if (this.costs[i] > 0 && !itemstack.isEmpty() && (entityhuman.expLevel >= j && entityhuman.expLevel >= this.costs[i] || entityhuman.abilities.canInstantlyBuild)) { - if (!this.world.isClientSide) { + this.containerAccess.a((world, blockposition) -> { + ItemStack itemstack2 = itemstack; List list = this.a(itemstack, i, this.costs[i]); // CraftBukkit start @@ -249,19 +240,19 @@ public class ContainerEnchantTable extends Container { WeightedRandomEnchant instance = (WeightedRandomEnchant) obj; enchants.put(org.bukkit.enchantments.Enchantment.getByKey(CraftNamespacedKey.fromMinecraft(IRegistry.ENCHANTMENT.getKey(instance.enchantment))), instance.level); } - CraftItemStack item = CraftItemStack.asCraftMirror(itemstack); + CraftItemStack item = CraftItemStack.asCraftMirror(itemstack2); - EnchantItemEvent event = new EnchantItemEvent((Player) entityhuman.getBukkitEntity(), this.getBukkitView(), this.world.getWorld().getBlockAt(position), item, this.costs[i], enchants, i); // Akarin - this.world.getServer().getPluginManager().callEvent(event); + EnchantItemEvent event = new EnchantItemEvent((Player) entityhuman.getBukkitEntity(), this.getBukkitView(), containerAccess.getLocation().getBlock(), item, this.costs[i], enchants, i); + world.getServer().getPluginManager().callEvent(event); int level = event.getExpLevelCost(); if (event.isCancelled() || (level > entityhuman.expLevel && !entityhuman.abilities.canInstantlyBuild) || event.getEnchantsToAdd().isEmpty()) { - return false; + return; } if (flag) { - itemstack = new ItemStack(Items.ENCHANTED_BOOK); - this.enchantSlots.setItem(0, itemstack); + itemstack2 = new ItemStack(Items.ENCHANTED_BOOK); + this.enchantSlots.setItem(0, itemstack2); } for (Map.Entry entry : event.getEnchantsToAdd().entrySet()) { @@ -274,7 +265,7 @@ public class ContainerEnchantTable extends Container { } WeightedRandomEnchant weightedrandomenchant = new WeightedRandomEnchant(nms, entry.getValue()); - ItemEnchantedBook.a(itemstack, weightedrandomenchant); + ItemEnchantedBook.a(itemstack2, weightedrandomenchant); } else { item.addUnsafeEnchantment(entry.getKey(), entry.getValue()); } @@ -296,16 +287,16 @@ public class ContainerEnchantTable extends Container { entityhuman.a(StatisticList.ENCHANT_ITEM); if (entityhuman instanceof EntityPlayer) { - CriterionTriggers.i.a((EntityPlayer) entityhuman, itemstack, j); + CriterionTriggers.i.a((EntityPlayer) entityhuman, itemstack2, j); } this.enchantSlots.update(); - this.f = entityhuman.du(); + this.i.set(entityhuman.dM()); this.a(this.enchantSlots); - this.world.a((EntityHuman) null, this.position, SoundEffects.BLOCK_ENCHANTMENT_TABLE_USE, SoundCategory.BLOCKS, 1.0F, this.world.random.nextFloat() * 0.1F + 0.9F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_ENCHANTMENT_TABLE_USE, SoundCategory.BLOCKS, 1.0F, world.random.nextFloat() * 0.1F + 0.9F); } - } + }); return true; } else { return false; @@ -313,33 +304,31 @@ public class ContainerEnchantTable extends Container { } private List a(ItemStack itemstack, int i, int j) { - this.l.setSeed((long) (this.f + i)); - List list = EnchantmentManager.b(this.l, itemstack, j, false); + this.h.setSeed((long) (this.i.get() + i)); + List list = EnchantmentManager.b(this.h, itemstack, j, false); if (itemstack.getItem() == Items.BOOK && list.size() > 1) { - list.remove(this.l.nextInt(list.size())); + list.remove(this.h.nextInt(list.size())); } return list; } + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); - // CraftBukkit Start - If an enchantable was opened from a null location, set the world to the player's world, preventing a crash - if (this.world == null) { - this.world = entityhuman.getWorld(); - } - // CraftBukkit end - if (!this.world.isClientSide) { + this.containerAccess.a((world, blockposition) -> { this.a(entityhuman, entityhuman.world, this.enchantSlots); - } + }); } + @Override public boolean canUse(EntityHuman entityhuman) { if (!this.checkReachable) return true; // CraftBukkit - return this.world.getType(this.position).getBlock() != Blocks.ENCHANTING_TABLE ? false : entityhuman.d((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + return a(this.containerAccess, entityhuman, Blocks.ENCHANTING_TABLE); } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -381,7 +370,7 @@ public class ContainerEnchantTable extends Container { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } if (itemstack1.getCount() == itemstack.getCount()) { diff --git a/src/main/java/net/minecraft/server/ContainerFurnace.java b/src/main/java/net/minecraft/server/ContainerFurnace.java index 00bedffd8..71cc65a7c 100644 --- a/src/main/java/net/minecraft/server/ContainerFurnace.java +++ b/src/main/java/net/minecraft/server/ContainerFurnace.java @@ -1,19 +1,16 @@ package net.minecraft.server; -import java.util.Iterator; // CraftBukkit start import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace; import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit end -public class ContainerFurnace extends ContainerRecipeBook { +public abstract class ContainerFurnace extends ContainerRecipeBook { private final IInventory furnace; - private final World f; - private int g; - private int h; - private int i; - private int j; + private final IContainerProperties e; + protected final World c; + private final Recipes f; // CraftBukkit start private CraftInventoryView bukkitEntity = null; @@ -31,33 +28,39 @@ public class ContainerFurnace extends ContainerRecipeBook { } // CraftBukkit end - public ContainerFurnace(PlayerInventory playerinventory, IInventory iinventory) { + protected ContainerFurnace(Containers containers, Recipes recipes, int i, PlayerInventory playerinventory) { + this(containers, recipes, i, playerinventory, new InventorySubcontainer(3), new ContainerProperties(4)); + } + + protected ContainerFurnace(Containers containers, Recipes recipes, int i, PlayerInventory playerinventory, IInventory iinventory, IContainerProperties icontainerproperties) { + super(containers, i); + this.f = recipes; + a(iinventory, 3); + a(icontainerproperties, 4); this.furnace = iinventory; - this.f = playerinventory.player.world; + this.e = icontainerproperties; + this.c = playerinventory.player.world; this.a(new Slot(iinventory, 0, 56, 17)); - this.a((Slot) (new SlotFurnaceFuel(iinventory, 1, 56, 53))); + this.a((Slot) (new SlotFurnaceFuel(this, iinventory, 1, 56, 53))); this.a((Slot) (new SlotFurnaceResult(playerinventory.player, iinventory, 2, 116, 35))); this.player = playerinventory; // CraftBukkit - save player - int i; + int j; - for (i = 0; i < 3; ++i) { - for (int j = 0; j < 9; ++j) { - this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); } + this.a(icontainerproperties); } - public void addSlotListener(ICrafting icrafting) { - super.addSlotListener(icrafting); - icrafting.setContainerData(this, this.furnace); - } - + @Override public void a(AutoRecipeStackManager autorecipestackmanager) { if (this.furnace instanceof AutoRecipeOutput) { ((AutoRecipeOutput) this.furnace).a(autorecipestackmanager); @@ -65,61 +68,43 @@ public class ContainerFurnace extends ContainerRecipeBook { } - public void d() { + @Override + public void e() { this.furnace.clear(); } - public boolean a(IRecipe irecipe) { - return irecipe.a(this.furnace, this.f); + @Override + public void a(boolean flag, IRecipe irecipe, EntityPlayer entityplayer) { + (new AutoRecipeFurnace(this)).a(entityplayer, irecipe, flag); // CraftBukkit - decompile error } - public int e() { + @Override + public boolean a(IRecipe irecipe) { + return irecipe.a(this.furnace, this.c); + } + + @Override + public int f() { return 2; } - public int f() { - return 1; - } - + @Override public int g() { return 1; } - public void b() { - super.b(); - Iterator iterator = this.listeners.iterator(); - - while (iterator.hasNext()) { - ICrafting icrafting = (ICrafting) iterator.next(); - - if (this.g != this.furnace.getProperty(2)) { - icrafting.setContainerData(this, 2, this.furnace.getProperty(2)); - } - - if (this.i != this.furnace.getProperty(0)) { - icrafting.setContainerData(this, 0, this.furnace.getProperty(0)); - } - - if (this.j != this.furnace.getProperty(1)) { - icrafting.setContainerData(this, 1, this.furnace.getProperty(1)); - } - - if (this.h != this.furnace.getProperty(3)) { - icrafting.setContainerData(this, 3, this.furnace.getProperty(3)); - } - } - - this.g = this.furnace.getProperty(2); - this.i = this.furnace.getProperty(0); - this.j = this.furnace.getProperty(1); - this.h = this.furnace.getProperty(3); + @Override + public int h() { + return 1; } + @Override public boolean canUse(EntityHuman entityhuman) { if (!this.checkReachable) return true; // CraftBukkit return this.furnace.a(entityhuman); } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -139,7 +124,7 @@ public class ContainerFurnace extends ContainerRecipeBook { if (!this.a(itemstack1, 0, 1, false)) { return ItemStack.a; } - } else if (TileEntityFurnace.isFuel(itemstack1)) { + } else if (this.b(itemstack1)) { if (!this.a(itemstack1, 1, 2, false)) { return ItemStack.a; } @@ -157,7 +142,7 @@ public class ContainerFurnace extends ContainerRecipeBook { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } if (itemstack1.getCount() == itemstack.getCount()) { @@ -170,19 +155,11 @@ public class ContainerFurnace extends ContainerRecipeBook { return itemstack; } - private boolean a(ItemStack itemstack) { - Iterator iterator = this.f.getCraftingManager().b().iterator(); + protected boolean a(ItemStack itemstack) { + return this.c.getCraftingManager().craft((Recipes) this.f, new InventorySubcontainer(new ItemStack[]{itemstack}), this.c).isPresent(); // Eclipse fail + } - IRecipe irecipe; - - do { - if (!iterator.hasNext()) { - return false; - } - - irecipe = (IRecipe) iterator.next(); - } while (!(irecipe instanceof FurnaceRecipe) || !((RecipeItemStack) irecipe.e().get(0)).test(itemstack)); - - return true; + protected boolean b(ItemStack itemstack) { + return TileEntityFurnace.isFuel(itemstack); } } diff --git a/src/main/java/net/minecraft/server/ContainerGrindstone.java b/src/main/java/net/minecraft/server/ContainerGrindstone.java new file mode 100644 index 000000000..ed88e208d --- /dev/null +++ b/src/main/java/net/minecraft/server/ContainerGrindstone.java @@ -0,0 +1,320 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; +// CraftBukkit start +import org.bukkit.Location; +import org.bukkit.craftbukkit.inventory.CraftInventoryGrindstone; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.entity.Player; +// CraftBukkit end + +public class ContainerGrindstone extends Container { + + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private Player player; + + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryGrindstone inventory = new CraftInventoryGrindstone(this.craftInventory, this.resultInventory); + bukkitEntity = new CraftInventoryView(this.player, inventory, this); + return bukkitEntity; + } + // CraftBukkit end + private final IInventory resultInventory; + private final IInventory craftInventory; + private final ContainerAccess containerAccess; + + public ContainerGrindstone(int i, PlayerInventory playerinventory) { + this(i, playerinventory, ContainerAccess.a); + } + + public ContainerGrindstone(int i, PlayerInventory playerinventory, final ContainerAccess containeraccess) { + super(Containers.GRINDSTONE, i); + this.resultInventory = new InventoryCraftResult(); + this.craftInventory = new InventorySubcontainer(2) { + @Override + public void update() { + super.update(); + ContainerGrindstone.this.a((IInventory) this); + } + + // CraftBukkit start + @Override + public Location getLocation() { + return containeraccess.getLocation(); + } + // CraftBukkit end + }; + this.containerAccess = containeraccess; + this.a(new Slot(this.craftInventory, 0, 49, 19) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return itemstack.e() || itemstack.getItem() == Items.ENCHANTED_BOOK || itemstack.hasEnchantments(); + } + }); + this.a(new Slot(this.craftInventory, 1, 49, 40) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return itemstack.e() || itemstack.getItem() == Items.ENCHANTED_BOOK || itemstack.hasEnchantments(); + } + }); + this.a(new Slot(this.resultInventory, 2, 129, 34) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return false; + } + + @Override + public ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { + containeraccess.a((world, blockposition) -> { + int j = this.a(world); + + while (j > 0) { + int k = EntityExperienceOrb.getOrbValue(j); + + j -= k; + world.addEntity(new EntityExperienceOrb(world, (double) blockposition.getX(), (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, k, org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, entityhuman)); // Paper + } + + world.triggerEffect(1042, blockposition, 0); + }); + ContainerGrindstone.this.craftInventory.setItem(0, ItemStack.a); + ContainerGrindstone.this.craftInventory.setItem(1, ItemStack.a); + return itemstack; + } + + private int a(World world) { + byte b0 = 0; + int j = b0 + this.e(ContainerGrindstone.this.craftInventory.getItem(0)); + + j += this.e(ContainerGrindstone.this.craftInventory.getItem(1)); + if (j > 0) { + int k = (int) Math.ceil((double) j / 2.0D); + + return k + world.random.nextInt(k); + } else { + return 0; + } + } + + private int e(ItemStack itemstack) { + int j = 0; + Map map = EnchantmentManager.a(itemstack); + Iterator iterator = map.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + Enchantment enchantment = (Enchantment) entry.getKey(); + Integer integer = (Integer) entry.getValue(); + + if (!enchantment.c()) { + j += enchantment.a(integer); + } + } + + return j; + } + }); + + int j; + + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); + } + } + + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); + } + + player = (Player) playerinventory.player.getBukkitEntity(); // CraftBukkit + } + + @Override + public void a(IInventory iinventory) { + super.a(iinventory); + if (iinventory == this.craftInventory) { + this.e(); + } + + } + + private void e() { + ItemStack itemstack = this.craftInventory.getItem(0); + ItemStack itemstack1 = this.craftInventory.getItem(1); + boolean flag = !itemstack.isEmpty() || !itemstack1.isEmpty(); + boolean flag1 = !itemstack.isEmpty() && !itemstack1.isEmpty(); + + if (flag) { + boolean flag2 = !itemstack.isEmpty() && itemstack.getItem() != Items.ENCHANTED_BOOK && !itemstack.hasEnchantments() || !itemstack1.isEmpty() && itemstack1.getItem() != Items.ENCHANTED_BOOK && !itemstack1.hasEnchantments(); + + if (itemstack.getCount() > 1 || itemstack1.getCount() > 1 || !flag1 && flag2) { + this.resultInventory.setItem(0, ItemStack.a); + this.c(); + return; + } + + byte b0 = 1; + int i; + ItemStack itemstack2; + + if (flag1) { + if (itemstack.getItem() != itemstack1.getItem()) { + this.resultInventory.setItem(0, ItemStack.a); + this.c(); + return; + } + + Item item = itemstack.getItem(); + int j = item.getMaxDurability() - itemstack.getDamage(); + int k = item.getMaxDurability() - itemstack1.getDamage(); + int l = j + k + item.getMaxDurability() * 5 / 100; + + i = Math.max(item.getMaxDurability() - l, 0); + itemstack2 = this.b(itemstack, itemstack1); + if (!itemstack2.e()) { + if (!ItemStack.matches(itemstack, itemstack1)) { + this.resultInventory.setItem(0, ItemStack.a); + this.c(); + return; + } + + b0 = 2; + } + } else { + boolean flag3 = !itemstack.isEmpty(); + + i = flag3 ? itemstack.getDamage() : itemstack1.getDamage(); + itemstack2 = flag3 ? itemstack : itemstack1; + } + + this.resultInventory.setItem(0, this.a(itemstack2, i, b0)); + } else { + this.resultInventory.setItem(0, ItemStack.a); + } + + this.c(); + } + + private ItemStack b(ItemStack itemstack, ItemStack itemstack1) { + ItemStack itemstack2 = itemstack.cloneItemStack(); + Map map = EnchantmentManager.a(itemstack1); + Iterator iterator = map.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + Enchantment enchantment = (Enchantment) entry.getKey(); + + if (!enchantment.c() || EnchantmentManager.getEnchantmentLevel(enchantment, itemstack2) == 0) { + itemstack2.addEnchantment(enchantment, (Integer) entry.getValue()); + } + } + + return itemstack2; + } + + private ItemStack a(ItemStack itemstack, int i, int j) { + ItemStack itemstack1 = itemstack.cloneItemStack(); + + itemstack1.removeTag("Enchantments"); + itemstack1.removeTag("StoredEnchantments"); + if (i > 0) { + itemstack1.setDamage(i); + } else { + itemstack1.removeTag("Damage"); + } + + itemstack1.setCount(j); + Map map = (Map) EnchantmentManager.a(itemstack).entrySet().stream().filter((entry) -> { + return ((Enchantment) entry.getKey()).c(); + }).collect(Collectors.toMap(Entry::getKey, Entry::getValue)); + + EnchantmentManager.a(map, itemstack1); + itemstack1.setRepairCost(0); + if (itemstack1.getItem() == Items.ENCHANTED_BOOK && map.size() == 0) { + itemstack1 = new ItemStack(Items.BOOK); + if (itemstack.hasName()) { + itemstack1.a(itemstack.getName()); + } + } + + for (int k = 0; k < map.size(); ++k) { + itemstack1.setRepairCost(ContainerAnvil.d(itemstack1.getRepairCost())); + } + + return itemstack1; + } + + @Override + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + this.containerAccess.a((world, blockposition) -> { + this.a(entityhuman, world, this.craftInventory); + }); + } + + @Override + public boolean canUse(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return a(this.containerAccess, entityhuman, Blocks.GRINDSTONE); + } + + @Override + public ItemStack shiftClick(EntityHuman entityhuman, int i) { + ItemStack itemstack = ItemStack.a; + Slot slot = (Slot) this.slots.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + ItemStack itemstack2 = this.craftInventory.getItem(0); + ItemStack itemstack3 = this.craftInventory.getItem(1); + + if (i == 2) { + if (!this.a(itemstack1, 3, 39, true)) { + return ItemStack.a; + } + + slot.a(itemstack1, itemstack); + } else if (i != 0 && i != 1) { + if (!itemstack2.isEmpty() && !itemstack3.isEmpty()) { + if (i >= 3 && i < 30) { + if (!this.a(itemstack1, 30, 39, false)) { + return ItemStack.a; + } + } else if (i >= 30 && i < 39 && !this.a(itemstack1, 3, 30, false)) { + return ItemStack.a; + } + } else if (!this.a(itemstack1, 0, 2, false)) { + return ItemStack.a; + } + } else if (!this.a(itemstack1, 3, 39, false)) { + return ItemStack.a; + } + + if (itemstack1.isEmpty()) { + slot.set(ItemStack.a); + } else { + slot.d(); + } + + if (itemstack1.getCount() == itemstack.getCount()) { + return ItemStack.a; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } +} diff --git a/src/main/java/net/minecraft/server/ContainerHopper.java b/src/main/java/net/minecraft/server/ContainerHopper.java index 1d7a38323..91ff331c9 100644 --- a/src/main/java/net/minecraft/server/ContainerHopper.java +++ b/src/main/java/net/minecraft/server/ContainerHopper.java @@ -25,35 +25,43 @@ public class ContainerHopper extends Container { } // CraftBukkit end - public ContainerHopper(PlayerInventory playerinventory, IInventory iinventory, EntityHuman entityhuman) { + public ContainerHopper(int i, PlayerInventory playerinventory) { + this(i, playerinventory, new InventorySubcontainer(5)); + } + + public ContainerHopper(int i, PlayerInventory playerinventory, IInventory iinventory) { + super(Containers.HOPPER, i); this.hopper = iinventory; this.player = playerinventory; // CraftBukkit - save player - iinventory.startOpen(entityhuman); + a(iinventory, 5); + iinventory.startOpen(playerinventory.player); boolean flag = true; - int i; + int j; - for (i = 0; i < iinventory.getSize(); ++i) { - this.a(new Slot(iinventory, i, 44 + i * 18, 20)); + for (j = 0; j < 5; ++j) { + this.a(new Slot(iinventory, j, 44 + j * 18, 20)); } - for (i = 0; i < 3; ++i) { - for (int j = 0; j < 9; ++j) { - this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, i * 18 + 51)); + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, j * 18 + 51)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(playerinventory, i, 8 + i * 18, 109)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 109)); } } + @Override public boolean canUse(EntityHuman entityhuman) { if (!this.checkReachable) return true; // CraftBukkit return this.hopper.a(entityhuman); } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -73,13 +81,14 @@ public class ContainerHopper extends Container { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } } return itemstack; } + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); this.hopper.closeContainer(entityhuman); diff --git a/src/main/java/net/minecraft/server/ContainerHorse.java b/src/main/java/net/minecraft/server/ContainerHorse.java index e5c7ca73e..ad4e0a45c 100644 --- a/src/main/java/net/minecraft/server/ContainerHorse.java +++ b/src/main/java/net/minecraft/server/ContainerHorse.java @@ -7,8 +7,8 @@ import org.bukkit.inventory.InventoryView; public class ContainerHorse extends Container { - private final IInventory a; - private final EntityHorseAbstract f; + private final IInventory c; + private final EntityHorseAbstract d; // CraftBukkit start org.bukkit.craftbukkit.inventory.CraftInventoryView bukkitEntity; @@ -20,60 +20,66 @@ public class ContainerHorse extends Container { return bukkitEntity; } - return bukkitEntity = new CraftInventoryView(player.player.getBukkitEntity(), a.getOwner().getInventory(), this); + return bukkitEntity = new CraftInventoryView(player.player.getBukkitEntity(), c.getOwner().getInventory(), this); } - public ContainerHorse(IInventory iinventory, IInventory iinventory1, final EntityHorseAbstract entityhorseabstract, EntityHuman entityhuman) { - player = (PlayerInventory) iinventory; + public ContainerHorse(int i, PlayerInventory playerinventory, IInventory iinventory, final EntityHorseAbstract entityhorseabstract) { + super((Containers) null, i); + player = playerinventory; // CraftBukkit end - this.a = iinventory1; - this.f = entityhorseabstract; + this.c = iinventory; + this.d = entityhorseabstract; boolean flag = true; - iinventory1.startOpen(entityhuman); + iinventory.startOpen(playerinventory.player); boolean flag1 = true; - this.a(new Slot(iinventory1, 0, 8, 18) { + this.a(new Slot(iinventory, 0, 8, 18) { + @Override public boolean isAllowed(ItemStack itemstack) { - return itemstack.getItem() == Items.SADDLE && !this.hasItem() && entityhorseabstract.dU(); + return itemstack.getItem() == Items.SADDLE && !this.hasItem() && entityhorseabstract.ep(); } }); - this.a(new Slot(iinventory1, 1, 8, 36) { + this.a(new Slot(iinventory, 1, 8, 36) { + @Override public boolean isAllowed(ItemStack itemstack) { - return entityhorseabstract.g(itemstack); + return entityhorseabstract.j(itemstack); } + @Override public int getMaxStackSize() { return 1; } }); - int i; int j; + int k; if (entityhorseabstract instanceof EntityHorseChestedAbstract && ((EntityHorseChestedAbstract) entityhorseabstract).isCarryingChest()) { - for (i = 0; i < 3; ++i) { - for (j = 0; j < ((EntityHorseChestedAbstract) entityhorseabstract).dH(); ++j) { - this.a(new Slot(iinventory1, 2 + j + i * ((EntityHorseChestedAbstract) entityhorseabstract).dH(), 80 + j * 18, 18 + i * 18)); + for (j = 0; j < 3; ++j) { + for (k = 0; k < ((EntityHorseChestedAbstract) entityhorseabstract).dZ(); ++k) { + this.a(new Slot(iinventory, 2 + k + j * ((EntityHorseChestedAbstract) entityhorseabstract).dZ(), 80 + k * 18, 18 + j * 18)); } } } - for (i = 0; i < 3; ++i) { - for (j = 0; j < 9; ++j) { - this.a(new Slot(iinventory, j + i * 9 + 9, 8 + j * 18, 102 + i * 18 + -18)); + for (j = 0; j < 3; ++j) { + for (k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 102 + j * 18 + -18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(iinventory, i, 8 + i * 18, 142)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); } } + @Override public boolean canUse(EntityHuman entityhuman) { - return this.a.a(entityhuman) && this.f.isAlive() && this.f.g((Entity) entityhuman) < 8.0F; + return this.c.a(entityhuman) && (this.d.isAlive() && this.d.valid) && this.d.g((Entity) entityhuman) < 8.0F; // Paper - Fix MC-161754 } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -82,8 +88,8 @@ public class ContainerHorse extends Container { ItemStack itemstack1 = slot.getItem(); itemstack = itemstack1.cloneItemStack(); - if (i < this.a.getSize()) { - if (!this.a(itemstack1, this.a.getSize(), this.slots.size(), true)) { + if (i < this.c.getSize()) { + if (!this.a(itemstack1, this.c.getSize(), this.slots.size(), true)) { return ItemStack.a; } } else if (this.getSlot(1).isAllowed(itemstack1) && !this.getSlot(1).hasItem()) { @@ -94,22 +100,23 @@ public class ContainerHorse extends Container { if (!this.a(itemstack1, 0, 1, false)) { return ItemStack.a; } - } else if (this.a.getSize() <= 2 || !this.a(itemstack1, 2, this.a.getSize(), false)) { + } else if (this.c.getSize() <= 2 || !this.a(itemstack1, 2, this.c.getSize(), false)) { return ItemStack.a; } if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } } return itemstack; } + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); - this.a.closeContainer(entityhuman); + this.c.closeContainer(entityhuman); } } diff --git a/src/main/java/net/minecraft/server/ContainerLectern.java b/src/main/java/net/minecraft/server/ContainerLectern.java new file mode 100644 index 000000000..5aa24831b --- /dev/null +++ b/src/main/java/net/minecraft/server/ContainerLectern.java @@ -0,0 +1,109 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.inventory.CraftInventoryLectern; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTakeLecternBookEvent; +// CraftBukkit end + +public class ContainerLectern extends Container { + + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private Player player; + + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryLectern inventory = new CraftInventoryLectern(this.inventory); + bukkitEntity = new CraftInventoryView(this.player, inventory, this); + return bukkitEntity; + } + // CraftBukkit end + private final IInventory inventory; + private final IContainerProperties containerProperties; + + // CraftBukkit start - add player + public ContainerLectern(int i, PlayerInventory playerinventory) { + this(i, new InventorySubcontainer(1), new ContainerProperties(1), playerinventory); + } + + public ContainerLectern(int i, IInventory iinventory, IContainerProperties icontainerproperties, PlayerInventory playerinventory) { + // CraftBukkit end + super(Containers.LECTERN, i); + a(iinventory, 1); + a(icontainerproperties, 1); + this.inventory = iinventory; + this.containerProperties = icontainerproperties; + this.a(new Slot(iinventory, 0, 0, 0) { + @Override + public void d() { + super.d(); + ContainerLectern.this.a(this.inventory); + } + }); + this.a(icontainerproperties); + player = (Player) playerinventory.player.getBukkitEntity(); // CraftBukkit + } + + @Override + public boolean a(EntityHuman entityhuman, int i) { + int j; + + if (i >= 100) { + j = i - 100; + this.a(0, j); + return true; + } else { + switch (i) { + case 1: + j = this.containerProperties.getProperty(0); + this.a(0, j - 1); + return true; + case 2: + j = this.containerProperties.getProperty(0); + this.a(0, j + 1); + return true; + case 3: + if (!entityhuman.dQ()) { + return false; + } + + // CraftBukkit start - Event for taking the book + PlayerTakeLecternBookEvent event = new PlayerTakeLecternBookEvent(player, ((CraftInventoryLectern) getBukkitView().getTopInventory()).getHolder()); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } + // CraftBukkit end + ItemStack itemstack = this.inventory.splitWithoutUpdate(0); + + this.inventory.update(); + if (!entityhuman.inventory.pickup(itemstack)) { + entityhuman.drop(itemstack, false); + } + + return true; + default: + return false; + } + } + } + + @Override + public void a(int i, int j) { + super.a(i, j); + this.c(); + } + + @Override + public boolean canUse(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.inventory.a(entityhuman); + } +} diff --git a/src/main/java/net/minecraft/server/ContainerLoom.java b/src/main/java/net/minecraft/server/ContainerLoom.java new file mode 100644 index 000000000..0d69fa607 --- /dev/null +++ b/src/main/java/net/minecraft/server/ContainerLoom.java @@ -0,0 +1,275 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.Location; +import org.bukkit.craftbukkit.inventory.CraftInventoryLoom; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.entity.Player; +// CraftBukkit end + +public class ContainerLoom extends Container { + + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private Player player; + + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryLoom inventory = new CraftInventoryLoom(this.craftInventory, this.resultInventory); + bukkitEntity = new CraftInventoryView(this.player, inventory, this); + return bukkitEntity; + } + // CraftBukkit end + private final ContainerAccess containerAccess; + private final ContainerProperty d; + private Runnable e; + private final Slot f; + private final Slot g; + private final Slot h; + private final Slot i; + private final IInventory craftInventory; + private final IInventory resultInventory; + + public ContainerLoom(int i, PlayerInventory playerinventory) { + this(i, playerinventory, ContainerAccess.a); + } + + public ContainerLoom(int i, PlayerInventory playerinventory, final ContainerAccess containeraccess) { + super(Containers.LOOM, i); + this.d = ContainerProperty.a(); + this.e = () -> { + }; + this.craftInventory = new InventorySubcontainer(3) { + @Override + public void update() { + super.update(); + ContainerLoom.this.a((IInventory) this); + ContainerLoom.this.e.run(); + } + + // CraftBukkit start + @Override + public Location getLocation() { + return containeraccess.getLocation(); + } + // CraftBukkit end + }; + this.resultInventory = new InventorySubcontainer(1) { + @Override + public void update() { + super.update(); + ContainerLoom.this.e.run(); + } + + // CraftBukkit start + @Override + public Location getLocation() { + return containeraccess.getLocation(); + } + // CraftBukkit end + }; + this.containerAccess = containeraccess; + this.f = this.a(new Slot(this.craftInventory, 0, 13, 26) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return itemstack.getItem() instanceof ItemBanner; + } + }); + this.g = this.a(new Slot(this.craftInventory, 1, 33, 26) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return itemstack.getItem() instanceof ItemDye; + } + }); + this.h = this.a(new Slot(this.craftInventory, 2, 23, 45) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return itemstack.getItem() instanceof ItemBannerPattern; + } + }); + this.i = this.a(new Slot(this.resultInventory, 0, 143, 58) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return false; + } + + @Override + public ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { + ContainerLoom.this.f.a(1); + ContainerLoom.this.g.a(1); + if (!ContainerLoom.this.f.hasItem() || !ContainerLoom.this.g.hasItem()) { + ContainerLoom.this.d.set(0); + } + + containeraccess.a((world, blockposition) -> { + world.playSound((EntityHuman) null, blockposition, SoundEffects.UI_LOOM_TAKE_RESULT, SoundCategory.BLOCKS, 1.0F, 1.0F); + }); + return super.a(entityhuman, itemstack); + } + }); + + int j; + + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); + } + } + + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); + } + + this.a(this.d); + player = (Player) playerinventory.player.getBukkitEntity(); // CraftBukkit + } + + @Override + public boolean canUse(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return a(this.containerAccess, entityhuman, Blocks.LOOM); + } + + @Override + public boolean a(EntityHuman entityhuman, int i) { + if (i > 0 && i <= EnumBannerPatternType.P) { + this.d.set(i); + this.j(); + return true; + } else { + return false; + } + } + + @Override + public void a(IInventory iinventory) { + ItemStack itemstack = this.f.getItem(); + ItemStack itemstack1 = this.g.getItem(); + ItemStack itemstack2 = this.h.getItem(); + ItemStack itemstack3 = this.i.getItem(); + + if (!itemstack3.isEmpty() && (itemstack.isEmpty() || itemstack1.isEmpty() || this.d.get() <= 0 || this.d.get() >= EnumBannerPatternType.O - 5 && itemstack2.isEmpty())) { + this.i.set(ItemStack.a); + this.d.set(0); + } else if (!itemstack2.isEmpty() && itemstack2.getItem() instanceof ItemBannerPattern) { + NBTTagCompound nbttagcompound = itemstack.a("BlockEntityTag"); + boolean flag = nbttagcompound.hasKeyOfType("Patterns", 9) && !itemstack.isEmpty() && nbttagcompound.getList("Patterns", 10).size() >= 6; + + if (flag) { + this.d.set(0); + } else { + this.d.set(((ItemBannerPattern) itemstack2.getItem()).b().ordinal()); + } + } + + this.j(); + this.c(); + } + + @Override + public ItemStack shiftClick(EntityHuman entityhuman, int i) { + ItemStack itemstack = ItemStack.a; + Slot slot = (Slot) this.slots.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == this.i.rawSlotIndex) { + if (!this.a(itemstack1, 4, 40, true)) { + return ItemStack.a; + } + + slot.a(itemstack1, itemstack); + } else if (i != this.g.rawSlotIndex && i != this.f.rawSlotIndex && i != this.h.rawSlotIndex) { + if (itemstack1.getItem() instanceof ItemBanner) { + if (!this.a(itemstack1, this.f.rawSlotIndex, this.f.rawSlotIndex + 1, false)) { + return ItemStack.a; + } + } else if (itemstack1.getItem() instanceof ItemDye) { + if (!this.a(itemstack1, this.g.rawSlotIndex, this.g.rawSlotIndex + 1, false)) { + return ItemStack.a; + } + } else if (itemstack1.getItem() instanceof ItemBannerPattern) { + if (!this.a(itemstack1, this.h.rawSlotIndex, this.h.rawSlotIndex + 1, false)) { + return ItemStack.a; + } + } else if (i >= 4 && i < 31) { + if (!this.a(itemstack1, 31, 40, false)) { + return ItemStack.a; + } + } else if (i >= 31 && i < 40 && !this.a(itemstack1, 4, 31, false)) { + return ItemStack.a; + } + } else if (!this.a(itemstack1, 4, 40, false)) { + return ItemStack.a; + } + + if (itemstack1.isEmpty()) { + slot.set(ItemStack.a); + } else { + slot.d(); + } + + if (itemstack1.getCount() == itemstack.getCount()) { + return ItemStack.a; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } + + @Override + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + this.containerAccess.a((world, blockposition) -> { + this.a(entityhuman, entityhuman.world, this.craftInventory); + }); + } + + private void j() { + if (this.d.get() > 0) { + ItemStack itemstack = this.f.getItem(); + ItemStack itemstack1 = this.g.getItem(); + ItemStack itemstack2 = ItemStack.a; + + if (!itemstack.isEmpty() && !itemstack1.isEmpty()) { + itemstack2 = itemstack.cloneItemStack(); + itemstack2.setCount(1); + EnumBannerPatternType enumbannerpatterntype = EnumBannerPatternType.values()[this.d.get()]; + EnumColor enumcolor = ((ItemDye) itemstack1.getItem()).d(); + NBTTagCompound nbttagcompound = itemstack2.a("BlockEntityTag"); + NBTTagList nbttaglist; + + if (nbttagcompound.hasKeyOfType("Patterns", 9)) { + nbttaglist = nbttagcompound.getList("Patterns", 10); + // CraftBukkit start + while (nbttaglist.size() > 20) { + nbttaglist.remove(20); + } + // CraftBukkit end + } else { + nbttaglist = new NBTTagList(); + nbttagcompound.set("Patterns", nbttaglist); + } + + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setString("Pattern", enumbannerpatterntype.b()); + nbttagcompound1.setInt("Color", enumcolor.getColorIndex()); + nbttaglist.add(nbttagcompound1); + } + + if (!ItemStack.matches(itemstack2, this.i.getItem())) { + this.i.set(itemstack2); + } + } + + } +} diff --git a/src/main/java/net/minecraft/server/ContainerMerchant.java b/src/main/java/net/minecraft/server/ContainerMerchant.java index c8e07d8ae..b6b62ac53 100644 --- a/src/main/java/net/minecraft/server/ContainerMerchant.java +++ b/src/main/java/net/minecraft/server/ContainerMerchant.java @@ -5,8 +5,7 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit public class ContainerMerchant extends Container { private final IMerchant merchant; - private final InventoryMerchant f; - private final World g; + private final InventoryMerchant inventoryMerchant; // CraftBukkit start private CraftInventoryView bukkitEntity = null; @@ -15,52 +14,60 @@ public class ContainerMerchant extends Container { @Override public CraftInventoryView getBukkitView() { if (bukkitEntity == null) { - bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), new org.bukkit.craftbukkit.inventory.CraftInventoryMerchant((InventoryMerchant) f), this); + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), new org.bukkit.craftbukkit.inventory.CraftInventoryMerchant(merchant, inventoryMerchant), this); } return bukkitEntity; } // CraftBukkit end - public ContainerMerchant(PlayerInventory playerinventory, IMerchant imerchant, World world) { + public ContainerMerchant(int i, PlayerInventory playerinventory) { + this(i, playerinventory, new MerchantWrapper(playerinventory.player)); + } + + public ContainerMerchant(int i, PlayerInventory playerinventory, IMerchant imerchant) { + super(Containers.MERCHANT, i); this.merchant = imerchant; - this.g = world; - this.f = new InventoryMerchant(playerinventory.player, imerchant); - this.a(new Slot(this.f, 0, 36, 53)); - this.a(new Slot(this.f, 1, 62, 53)); - this.a((Slot) (new SlotMerchantResult(playerinventory.player, imerchant, this.f, 2, 120, 53))); + this.inventoryMerchant = new InventoryMerchant(imerchant); + this.a(new Slot(this.inventoryMerchant, 0, 136, 37)); + this.a(new Slot(this.inventoryMerchant, 1, 162, 37)); + this.a((Slot) (new SlotMerchantResult(playerinventory.player, imerchant, this.inventoryMerchant, 2, 220, 37))); this.player = playerinventory; // CraftBukkit - save player - int i; + int j; - for (i = 0; i < 3; ++i) { - for (int j = 0; j < 9; ++j) { - this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 108 + k * 18, 84 + j * 18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 108 + j * 18, 142)); } } - public InventoryMerchant d() { - return this.f; - } - + @Override public void a(IInventory iinventory) { - this.f.i(); + this.inventoryMerchant.f(); super.a(iinventory); } public void d(int i) { - this.f.d(i); + this.inventoryMerchant.c(i); } + @Override public boolean canUse(EntityHuman entityhuman) { return this.merchant.getTrader() == entityhuman; } + @Override + public boolean a(ItemStack itemstack, Slot slot) { + return false; + } + + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -75,6 +82,7 @@ public class ContainerMerchant extends Container { } slot.a(itemstack1, itemstack); + this.k(); } else if (i != 0 && i != 1) { if (i >= 3 && i < 30) { if (!this.a(itemstack1, 30, 39, false)) { @@ -90,7 +98,7 @@ public class ContainerMerchant extends Container { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } if (itemstack1.getCount() == itemstack.getCount()) { @@ -103,22 +111,102 @@ public class ContainerMerchant extends Container { return itemstack; } + private void k() { + if (!this.merchant.getWorld().isClientSide && this.merchant instanceof Entity) { // CraftBukkit - SPIGOT-5035 + Entity entity = (Entity) this.merchant; + + this.merchant.getWorld().a(entity.locX, entity.locY, entity.locZ, this.merchant.eb(), SoundCategory.NEUTRAL, 1.0F, 1.0F, false); + } + + } + + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); this.merchant.setTradingPlayer((EntityHuman) null); - super.b(entityhuman); - if (!this.g.isClientSide) { - ItemStack itemstack = this.f.splitWithoutUpdate(0); + if (!this.merchant.getWorld().isClientSide) { + if (entityhuman.isAlive() && (!(entityhuman instanceof EntityPlayer) || !((EntityPlayer) entityhuman).o())) { + entityhuman.inventory.a(entityhuman.world, this.inventoryMerchant.splitWithoutUpdate(0)); + entityhuman.inventory.a(entityhuman.world, this.inventoryMerchant.splitWithoutUpdate(1)); + } else { + ItemStack itemstack = this.inventoryMerchant.splitWithoutUpdate(0); - if (!itemstack.isEmpty()) { - entityhuman.drop(itemstack, false); - } + if (!itemstack.isEmpty()) { + entityhuman.drop(itemstack, false); + } - itemstack = this.f.splitWithoutUpdate(1); - if (!itemstack.isEmpty()) { - entityhuman.drop(itemstack, false); + itemstack = this.inventoryMerchant.splitWithoutUpdate(1); + if (!itemstack.isEmpty()) { + entityhuman.drop(itemstack, false); + } } } } + + public void g(int i) { + if (this.i().size() > i) { + ItemStack itemstack = this.inventoryMerchant.getItem(0); + + if (!itemstack.isEmpty()) { + if (!this.a(itemstack, 3, 39, true)) { + return; + } + + this.inventoryMerchant.setItem(0, itemstack); + } + + ItemStack itemstack1 = this.inventoryMerchant.getItem(1); + + if (!itemstack1.isEmpty()) { + if (!this.a(itemstack1, 3, 39, true)) { + return; + } + + this.inventoryMerchant.setItem(1, itemstack1); + } + + if (this.inventoryMerchant.getItem(0).isEmpty() && this.inventoryMerchant.getItem(1).isEmpty()) { + ItemStack itemstack2 = ((MerchantRecipe) this.i().get(i)).getBuyItem1(); + + this.c(0, itemstack2); + ItemStack itemstack3 = ((MerchantRecipe) this.i().get(i)).getBuyItem2(); + + this.c(1, itemstack3); + } + + } + } + + private void c(int i, ItemStack itemstack) { + if (!itemstack.isEmpty()) { + for (int j = 3; j < 39; ++j) { + ItemStack itemstack1 = ((Slot) this.slots.get(j)).getItem(); + + if (!itemstack1.isEmpty() && this.b(itemstack, itemstack1)) { + ItemStack itemstack2 = this.inventoryMerchant.getItem(i); + int k = itemstack2.isEmpty() ? 0 : itemstack2.getCount(); + int l = Math.min(itemstack.getMaxStackSize() - k, itemstack1.getCount()); + ItemStack itemstack3 = itemstack1.cloneItemStack(); + int i1 = k + l; + + itemstack1.subtract(l); + itemstack3.setCount(i1); + this.inventoryMerchant.setItem(i, itemstack3); + if (i1 >= itemstack.getMaxStackSize()) { + break; + } + } + } + } + + } + + private boolean b(ItemStack itemstack, ItemStack itemstack1) { + return itemstack.getItem() == itemstack1.getItem() && ItemStack.equals(itemstack, itemstack1); + } + + public MerchantRecipeList i() { + return this.merchant.getOffers(); + } } diff --git a/src/main/java/net/minecraft/server/ContainerPlayer.java b/src/main/java/net/minecraft/server/ContainerPlayer.java index 7cc91ee40..e08e542f7 100644 --- a/src/main/java/net/minecraft/server/ContainerPlayer.java +++ b/src/main/java/net/minecraft/server/ContainerPlayer.java @@ -5,13 +5,15 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit end -public class ContainerPlayer extends ContainerRecipeBook { +public class ContainerPlayer extends ContainerRecipeBook { - private static final String[] h = new String[] { "item/empty_armor_slot_boots", "item/empty_armor_slot_leggings", "item/empty_armor_slot_chestplate", "item/empty_armor_slot_helmet"}; - private static final EnumItemSlot[] i = new EnumItemSlot[] { EnumItemSlot.HEAD, EnumItemSlot.CHEST, EnumItemSlot.LEGS, EnumItemSlot.FEET}; - public InventoryCrafting craftInventory = new InventoryCrafting(this, 2, 2); - public InventoryCraftResult resultInventory = new InventoryCraftResult(); - public boolean g; + private static final String[] d = new String[]{"item/empty_armor_slot_boots", "item/empty_armor_slot_leggings", "item/empty_armor_slot_chestplate", "item/empty_armor_slot_helmet"}; + private static final EnumItemSlot[] e = new EnumItemSlot[]{EnumItemSlot.HEAD, EnumItemSlot.CHEST, EnumItemSlot.LEGS, EnumItemSlot.FEET}; + // CraftBukkit start + private final InventoryCrafting craftInventory; + private final InventoryCraftResult resultInventory; + // CraftBukkit end + public final boolean c; private final EntityHuman owner; // CraftBukkit start private CraftInventoryView bukkitEntity = null; @@ -19,13 +21,15 @@ public class ContainerPlayer extends ContainerRecipeBook { // CraftBukkit end public ContainerPlayer(PlayerInventory playerinventory, boolean flag, EntityHuman entityhuman) { - this.g = flag; + super((Containers) null, 0); + this.c = flag; this.owner = entityhuman; // CraftBukkit start this.resultInventory = new InventoryCraftResult(); // CraftBukkit - moved to before InventoryCrafting construction this.craftInventory = new InventoryCrafting(this, 2, 2, playerinventory.player); // CraftBukkit - pass player this.craftInventory.resultInventory = this.resultInventory; // CraftBukkit - let InventoryCrafting know about its result slot this.player = playerinventory; // CraftBukkit - save player + setTitle(new ChatMessage("container.crafting")); // SPIGOT-4722: Allocate title for player inventory // CraftBukkit end this.a((Slot) (new SlotResult(playerinventory.player, this.craftInventory, this.resultInventory, 0, 154, 28))); @@ -39,21 +43,24 @@ public class ContainerPlayer extends ContainerRecipeBook { } for (i = 0; i < 4; ++i) { - final EnumItemSlot enumitemslot = ContainerPlayer.i[i]; + final EnumItemSlot enumitemslot = ContainerPlayer.e[i]; this.a(new Slot(playerinventory, 39 - i, 8, 8 + i * 18) { + @Override public int getMaxStackSize() { return 1; } + @Override public boolean isAllowed(ItemStack itemstack) { - return enumitemslot == EntityInsentient.e(itemstack); + return enumitemslot == EntityInsentient.h(itemstack); } + @Override public boolean isAllowed(EntityHuman entityhuman1) { ItemStack itemstack = this.getItem(); - return !itemstack.isEmpty() && !entityhuman1.u() && EnchantmentManager.d(itemstack) ? false : super.isAllowed(entityhuman1); + return !itemstack.isEmpty() && !entityhuman1.isCreative() && EnchantmentManager.d(itemstack) ? false : super.isAllowed(entityhuman1); } }); } @@ -72,35 +79,42 @@ public class ContainerPlayer extends ContainerRecipeBook { }); } + @Override public void a(AutoRecipeStackManager autorecipestackmanager) { this.craftInventory.a(autorecipestackmanager); } - public void d() { + @Override + public void e() { this.resultInventory.clear(); this.craftInventory.clear(); } - public boolean a(IRecipe irecipe) { + @Override + public boolean a(IRecipe irecipe) { return irecipe.a(this.craftInventory, this.owner.world); } + @Override public void a(IInventory iinventory) { - this.a(this.owner.world, this.owner, this.craftInventory, this.resultInventory); + ContainerWorkbench.a(this.windowId, this.owner.world, this.owner, this.craftInventory, this.resultInventory, this); // CraftBukkit } + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); this.resultInventory.clear(); if (!entityhuman.world.isClientSide) { - this.a(entityhuman, entityhuman.world, this.craftInventory); + this.a(entityhuman, entityhuman.world, (IInventory) this.craftInventory); } } + @Override public boolean canUse(EntityHuman entityhuman) { return true; } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -109,7 +123,7 @@ public class ContainerPlayer extends ContainerRecipeBook { ItemStack itemstack1 = slot.getItem(); itemstack = itemstack1.cloneItemStack(); - EnumItemSlot enumitemslot = EntityInsentient.e(itemstack); + EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); if (i == 0) { if (!this.a(itemstack1, 9, 45, true)) { @@ -150,7 +164,7 @@ public class ContainerPlayer extends ContainerRecipeBook { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } if (itemstack1.getCount() == itemstack.getCount()) { @@ -167,20 +181,24 @@ public class ContainerPlayer extends ContainerRecipeBook { return itemstack; } + @Override public boolean a(ItemStack itemstack, Slot slot) { return slot.inventory != this.resultInventory && super.a(itemstack, slot); } - public int e() { + @Override + public int f() { return 0; } - public int f() { - return this.craftInventory.U_(); + @Override + public int g() { + return this.craftInventory.g(); } - public int g() { - return this.craftInventory.n(); + @Override + public int h() { + return this.craftInventory.f(); } // CraftBukkit start diff --git a/src/main/java/net/minecraft/server/ContainerShulkerBox.java b/src/main/java/net/minecraft/server/ContainerShulkerBox.java index 5f2179783..9bfd9af9c 100644 --- a/src/main/java/net/minecraft/server/ContainerShulkerBox.java +++ b/src/main/java/net/minecraft/server/ContainerShulkerBox.java @@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView; public class ContainerShulkerBox extends Container { - private final IInventory a; + private final IInventory c; // CraftBukkit start private CraftInventoryView bukkitEntity; private PlayerInventory player; @@ -18,43 +18,51 @@ public class ContainerShulkerBox extends Container { return bukkitEntity; } - bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), new CraftInventory(this.a), this); + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), new CraftInventory(this.c), this); return bukkitEntity; } // CraftBukkit end - public ContainerShulkerBox(PlayerInventory playerinventory, IInventory iinventory, EntityHuman entityhuman) { - this.a = iinventory; + public ContainerShulkerBox(int i, PlayerInventory playerinventory) { + this(i, playerinventory, new InventorySubcontainer(27)); + } + + public ContainerShulkerBox(int i, PlayerInventory playerinventory, IInventory iinventory) { + super(Containers.SHULKER_BOX, i); + a(iinventory, 27); + this.c = iinventory; this.player = playerinventory; // CraftBukkit - save player - iinventory.startOpen(entityhuman); + iinventory.startOpen(playerinventory.player); boolean flag = true; boolean flag1 = true; - int i; int j; + int k; - for (i = 0; i < 3; ++i) { - for (j = 0; j < 9; ++j) { - this.a((Slot) (new SlotShulkerBox(iinventory, j + i * 9, 8 + j * 18, 18 + i * 18))); + for (j = 0; j < 3; ++j) { + for (k = 0; k < 9; ++k) { + this.a((Slot) (new SlotShulkerBox(iinventory, k + j * 9, 8 + k * 18, 18 + j * 18))); } } - for (i = 0; i < 3; ++i) { - for (j = 0; j < 9; ++j) { - this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + for (j = 0; j < 3; ++j) { + for (k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); } } + @Override public boolean canUse(EntityHuman entityhuman) { - return this.a.a(entityhuman); + return this.c.a(entityhuman); } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -63,26 +71,27 @@ public class ContainerShulkerBox extends Container { ItemStack itemstack1 = slot.getItem(); itemstack = itemstack1.cloneItemStack(); - if (i < this.a.getSize()) { - if (!this.a(itemstack1, this.a.getSize(), this.slots.size(), true)) { + if (i < this.c.getSize()) { + if (!this.a(itemstack1, this.c.getSize(), this.slots.size(), true)) { return ItemStack.a; } - } else if (!this.a(itemstack1, 0, this.a.getSize(), false)) { + } else if (!this.a(itemstack1, 0, this.c.getSize(), false)) { return ItemStack.a; } if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } } return itemstack; } + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); - this.a.closeContainer(entityhuman); + this.c.closeContainer(entityhuman); } } diff --git a/src/main/java/net/minecraft/server/ContainerStonecutter.java b/src/main/java/net/minecraft/server/ContainerStonecutter.java new file mode 100644 index 000000000..e7fdf7273 --- /dev/null +++ b/src/main/java/net/minecraft/server/ContainerStonecutter.java @@ -0,0 +1,225 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import java.util.List; +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftInventoryStonecutter; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.entity.Player; +// CraftBukkit end + +public class ContainerStonecutter extends Container { + + static final ImmutableList c = ImmutableList.of(Items.b, Items.aq, Items.ge, Items.eq, Items.m, Items.cX, Items.bL, Items.ds, Items.gm, Items.bU, Items.fX, Items.fY, new Item[]{Items.fZ, Items.g, Items.h, Items.c, Items.d, Items.e, Items.f, Items.cY, Items.bO, Items.bJ, Items.bI, Items.bH, Items.dx, Items.dy, Items.bK, Items.as, Items.gg}); + private final ContainerAccess containerAccess; + private final ContainerProperty containerProperty; + private final World world; + private List j; + private ItemStack k; + private long l; + final Slot d; + final Slot e; + private Runnable m; + public final IInventory inventory; + private final InventoryCraftResult resultInventory; + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private Player player; + + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryStonecutter inventory = new CraftInventoryStonecutter(this.inventory, this.resultInventory); + bukkitEntity = new CraftInventoryView(this.player, inventory, this); + return bukkitEntity; + } + // CraftBukkit end + + public ContainerStonecutter(int i, PlayerInventory playerinventory) { + this(i, playerinventory, ContainerAccess.a); + } + + public ContainerStonecutter(int i, PlayerInventory playerinventory, final ContainerAccess containeraccess) { + super(Containers.STONECUTTER, i); + this.containerProperty = ContainerProperty.a(); + this.j = Lists.newArrayList(); + this.k = ItemStack.a; + this.m = () -> { + }; + this.inventory = new InventorySubcontainer(1) { + @Override + public void update() { + super.update(); + ContainerStonecutter.this.a((IInventory) this); + ContainerStonecutter.this.m.run(); + } + }; + this.resultInventory = new InventoryCraftResult(); + this.containerAccess = containeraccess; + this.world = playerinventory.player.world; + this.d = this.a(new Slot(this.inventory, 0, 20, 33)); + this.e = this.a(new Slot(this.resultInventory, 1, 143, 33) { + @Override + public boolean isAllowed(ItemStack itemstack) { + return false; + } + + @Override + public ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { + ItemStack itemstack1 = ContainerStonecutter.this.d.a(1); + + if (!itemstack1.isEmpty()) { + ContainerStonecutter.this.i(); + } + + itemstack.getItem().b(itemstack, entityhuman.world, entityhuman); + containeraccess.a((world, blockposition) -> { + long j = world.getTime(); + + if (ContainerStonecutter.this.l != j) { + world.playSound((EntityHuman) null, blockposition, SoundEffects.UI_STONECUTTER_TAKE_RESULT, SoundCategory.BLOCKS, 1.0F, 1.0F); + ContainerStonecutter.this.l = j; + } + + }); + return super.a(entityhuman, itemstack); + } + }); + + int j; + + for (j = 0; j < 3; ++j) { + for (int k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); + } + } + + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); + } + + this.a(this.containerProperty); + player = (Player) playerinventory.player.getBukkitEntity(); // CraftBukkit + } + + @Override + public boolean canUse(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return a(this.containerAccess, entityhuman, Blocks.STONECUTTER); + } + + @Override + public boolean a(EntityHuman entityhuman, int i) { + if (i >= 0 && i < this.j.size()) { + this.containerProperty.set(i); + this.i(); + } + + return true; + } + + @Override + public void a(IInventory iinventory) { + ItemStack itemstack = this.d.getItem(); + + if (itemstack.getItem() != this.k.getItem()) { + this.k = itemstack.cloneItemStack(); + this.a(iinventory, itemstack); + } + + } + + private void a(IInventory iinventory, ItemStack itemstack) { + this.j.clear(); + this.containerProperty.set(-1); + this.e.set(ItemStack.a); + if (!itemstack.isEmpty()) { + this.j = this.world.getCraftingManager().b(Recipes.STONECUTTING, iinventory, this.world); + } + + } + + private void i() { + if (!this.j.isEmpty()) { + RecipeStonecutting recipestonecutting = (RecipeStonecutting) this.j.get(this.containerProperty.get()); + + this.e.set(recipestonecutting.a(this.inventory)); + } else { + this.e.set(ItemStack.a); + } + + this.c(); + } + + @Override + public Containers getType() { + return Containers.STONECUTTER; + } + + @Override + public boolean a(ItemStack itemstack, Slot slot) { + return false; + } + + @Override + public ItemStack shiftClick(EntityHuman entityhuman, int i) { + ItemStack itemstack = ItemStack.a; + Slot slot = (Slot) this.slots.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + Item item = itemstack1.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == 1) { + item.b(itemstack1, entityhuman.world, entityhuman); + if (!this.a(itemstack1, 2, 38, true)) { + return ItemStack.a; + } + + slot.a(itemstack1, itemstack); + } else if (i == 0) { + if (!this.a(itemstack1, 2, 38, false)) { + return ItemStack.a; + } + } else if (ContainerStonecutter.c.contains(item)) { + if (!this.a(itemstack1, 0, 1, false)) { + return ItemStack.a; + } + } else if (i >= 2 && i < 29) { + if (!this.a(itemstack1, 29, 38, false)) { + return ItemStack.a; + } + } else if (i >= 29 && i < 38 && !this.a(itemstack1, 2, 29, false)) { + return ItemStack.a; + } + + if (itemstack1.isEmpty()) { + slot.set(ItemStack.a); + } + + slot.d(); + if (itemstack1.getCount() == itemstack.getCount()) { + return ItemStack.a; + } + + slot.a(entityhuman, itemstack1); + this.c(); + } + + return itemstack; + } + + @Override + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + this.resultInventory.splitWithoutUpdate(1); + this.containerAccess.a((world, blockposition) -> { + this.a(entityhuman, entityhuman.world, this.inventory); + }); + } +} diff --git a/src/main/java/net/minecraft/server/ContainerWorkbench.java b/src/main/java/net/minecraft/server/ContainerWorkbench.java index 707685e8b..035a45f44 100644 --- a/src/main/java/net/minecraft/server/ContainerWorkbench.java +++ b/src/main/java/net/minecraft/server/ContainerWorkbench.java @@ -1,84 +1,117 @@ package net.minecraft.server; +import java.util.Optional; // CraftBukkit start import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit end -public class ContainerWorkbench extends ContainerRecipeBook { +public class ContainerWorkbench extends ContainerRecipeBook { - public InventoryCrafting craftInventory; // CraftBukkit - move initialization into constructor - public InventoryCraftResult resultInventory; // CraftBukkit - move initialization into constructor - private final World g; - private final BlockPosition h; - private final EntityHuman i; + private final InventoryCrafting craftInventory; + private final InventoryCraftResult resultInventory; + public final ContainerAccess containerAccess; + private final EntityHuman f; // CraftBukkit start private CraftInventoryView bukkitEntity = null; private PlayerInventory player; // CraftBukkit end - public ContainerWorkbench(PlayerInventory playerinventory, World world, BlockPosition blockposition) { + public ContainerWorkbench(int i, PlayerInventory playerinventory) { + this(i, playerinventory, ContainerAccess.a); + } + + public ContainerWorkbench(int i, PlayerInventory playerinventory, ContainerAccess containeraccess) { + super(Containers.CRAFTING, i); // CraftBukkit start - Switched order of IInventory construction and stored player this.resultInventory = new InventoryCraftResult(); this.craftInventory = new InventoryCrafting(this, 3, 3, playerinventory.player); // CraftBukkit - pass player this.craftInventory.resultInventory = this.resultInventory; this.player = playerinventory; // CraftBukkit end - this.g = world; - this.h = blockposition; - this.i = playerinventory.player; + this.containerAccess = containeraccess; + this.f = playerinventory.player; this.a((Slot) (new SlotResult(playerinventory.player, this.craftInventory, this.resultInventory, 0, 124, 35))); - int i; int j; + int k; - for (i = 0; i < 3; ++i) { - for (j = 0; j < 3; ++j) { - this.a(new Slot(this.craftInventory, j + i * 3, 30 + j * 18, 17 + i * 18)); + for (j = 0; j < 3; ++j) { + for (k = 0; k < 3; ++k) { + this.a(new Slot(this.craftInventory, k + j * 3, 30 + k * 18, 17 + j * 18)); } } - for (i = 0; i < 3; ++i) { - for (j = 0; j < 9; ++j) { - this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + for (j = 0; j < 3; ++j) { + for (k = 0; k < 9; ++k) { + this.a(new Slot(playerinventory, k + j * 9 + 9, 8 + k * 18, 84 + j * 18)); } } - for (i = 0; i < 9; ++i) { - this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j, 8 + j * 18, 142)); } } + protected static void a(int i, World world, EntityHuman entityhuman, InventoryCrafting inventorycrafting, InventoryCraftResult inventorycraftresult, Container container) { // CraftBukkit + if (!world.isClientSide) { + EntityPlayer entityplayer = (EntityPlayer) entityhuman; + ItemStack itemstack = ItemStack.a; + Optional optional = world.getMinecraftServer().getCraftingManager().craft(Recipes.CRAFTING, inventorycrafting, world); + + if (optional.isPresent()) { + RecipeCrafting recipecrafting = (RecipeCrafting) optional.get(); + + if (inventorycraftresult.a(world, entityplayer, recipecrafting)) { + itemstack = recipecrafting.a(inventorycrafting); + } + } + itemstack = org.bukkit.craftbukkit.event.CraftEventFactory.callPreCraftEvent(inventorycrafting, inventorycraftresult, itemstack, container.getBukkitView(), false); // CraftBukkit + + inventorycraftresult.setItem(0, itemstack); + entityplayer.playerConnection.sendPacket(new PacketPlayOutSetSlot(i, 0, itemstack)); + } + } + + @Override public void a(IInventory iinventory) { - this.a(this.g, this.i, this.craftInventory, this.resultInventory); + this.containerAccess.a((world, blockposition) -> { + a(this.windowId, world, this.f, this.craftInventory, this.resultInventory, this); // CraftBukkit + }); } + @Override public void a(AutoRecipeStackManager autorecipestackmanager) { this.craftInventory.a(autorecipestackmanager); } - public void d() { + @Override + public void e() { this.craftInventory.clear(); this.resultInventory.clear(); } - public boolean a(IRecipe irecipe) { - return irecipe.a(this.craftInventory, this.i.world); + @Override + public boolean a(IRecipe irecipe) { + return irecipe.a(this.craftInventory, this.f.world); } + @Override public void b(EntityHuman entityhuman) { super.b(entityhuman); - if (!this.g.isClientSide) { - this.a(entityhuman, this.g, this.craftInventory); - } + this.containerAccess.a((world, blockposition) -> { + this.a(entityhuman, world, (IInventory) this.craftInventory); + }); } + @Override public boolean canUse(EntityHuman entityhuman) { if (!this.checkReachable) return true; // CraftBukkit - return this.g.getType(this.h).getBlock() != Blocks.CRAFTING_TABLE ? false : entityhuman.d((double) this.h.getX() + 0.5D, (double) this.h.getY() + 0.5D, (double) this.h.getZ() + 0.5D) <= 64.0D; + return a(this.containerAccess, entityhuman, Blocks.CRAFTING_TABLE); } + @Override public ItemStack shiftClick(EntityHuman entityhuman, int i) { ItemStack itemstack = ItemStack.a; Slot slot = (Slot) this.slots.get(i); @@ -88,7 +121,9 @@ public class ContainerWorkbench extends ContainerRecipeBook { itemstack = itemstack1.cloneItemStack(); if (i == 0) { - itemstack1.getItem().b(itemstack1, this.g, entityhuman); + this.containerAccess.a((world, blockposition) -> { + itemstack1.getItem().b(itemstack1, world, entityhuman); + }); if (!this.a(itemstack1, 10, 46, true)) { return ItemStack.a; } @@ -109,7 +144,7 @@ public class ContainerWorkbench extends ContainerRecipeBook { if (itemstack1.isEmpty()) { slot.set(ItemStack.a); } else { - slot.f(); + slot.d(); } if (itemstack1.getCount() == itemstack.getCount()) { @@ -126,20 +161,24 @@ public class ContainerWorkbench extends ContainerRecipeBook { return itemstack; } + @Override public boolean a(ItemStack itemstack, Slot slot) { return slot.inventory != this.resultInventory && super.a(itemstack, slot); } - public int e() { + @Override + public int f() { return 0; } - public int f() { - return this.craftInventory.U_(); + @Override + public int g() { + return this.craftInventory.g(); } - public int g() { - return this.craftInventory.n(); + @Override + public int h() { + return this.craftInventory.f(); } // CraftBukkit start diff --git a/src/main/java/net/minecraft/server/Containers.java b/src/main/java/net/minecraft/server/Containers.java new file mode 100644 index 000000000..387fb9215 --- /dev/null +++ b/src/main/java/net/minecraft/server/Containers.java @@ -0,0 +1,46 @@ +package net.minecraft.server; + +public class Containers { + + public static final Containers GENERIC_9X1 = a("generic_9x1", ContainerChest::a); + public static final Containers GENERIC_9X2 = a("generic_9x2", ContainerChest::b); + public static final Containers GENERIC_9X3 = a("generic_9x3", ContainerChest::c); + public static final Containers GENERIC_9X4 = a("generic_9x4", ContainerChest::d); + public static final Containers GENERIC_9X5 = a("generic_9x5", ContainerChest::e); + public static final Containers GENERIC_9X6 = a("generic_9x6", ContainerChest::f); + public static final Containers GENERIC_3X3 = a("generic_3x3", ContainerDispenser::new); + public static final Containers ANVIL = a("anvil", ContainerAnvil::new); + public static final Containers BEACON = a("beacon", ContainerBeacon::new); + public static final Containers BLAST_FURNACE = a("blast_furnace", ContainerBlastFurnace::new); + public static final Containers BREWING_STAND = a("brewing_stand", ContainerBrewingStand::new); + public static final Containers CRAFTING = a("crafting", ContainerWorkbench::new); + public static final Containers ENCHANTMENT = a("enchantment", ContainerEnchantTable::new); + public static final Containers FURNACE = a("furnace", ContainerFurnaceFurnace::new); + public static final Containers GRINDSTONE = a("grindstone", ContainerGrindstone::new); + public static final Containers HOPPER = a("hopper", ContainerHopper::new); + public static final Containers LECTERN = a("lectern", (i, playerinventory) -> { + return new ContainerLectern(i, playerinventory); // CraftBukkit + }); + public static final Containers LOOM = a("loom", ContainerLoom::new); + public static final Containers MERCHANT = a("merchant", ContainerMerchant::new); + public static final Containers SHULKER_BOX = a("shulker_box", ContainerShulkerBox::new); + public static final Containers SMOKER = a("smoker", ContainerSmoker::new); + public static final Containers CARTOGRAPHY = a("cartography", ContainerCartography::new); + public static final Containers STONECUTTER = a("stonecutter", ContainerStonecutter::new); + private final Containers.Supplier x; + + private static Containers a(String s, Containers.Supplier containers_supplier) { + return (Containers) IRegistry.a(IRegistry.MENU, s, (new Containers<>(containers_supplier))); // CraftBukkit - decompile error + } + + private Containers(Containers.Supplier containers_supplier) { + this.x = containers_supplier; + } + + // CraftBukkit start + interface Supplier { + + T supply(int id, PlayerInventory playerinventory); + } + // CraftBukkit end +} diff --git a/src/main/java/net/minecraft/server/ControllerJump.java b/src/main/java/net/minecraft/server/ControllerJump.java index 489beed26..8a6856e0f 100644 --- a/src/main/java/net/minecraft/server/ControllerJump.java +++ b/src/main/java/net/minecraft/server/ControllerJump.java @@ -9,13 +9,13 @@ public class ControllerJump { this.b = entityinsentient; } - public void a() { + public void jump() { this.a = true; } public void jumpIfSet() { this.b(); } // Paper - OBFHELPER public void b() { - this.b.o(this.a); + this.b.setJumping(this.a); this.a = false; } } diff --git a/src/main/java/net/minecraft/server/CraftingManager.java b/src/main/java/net/minecraft/server/CraftingManager.java index 14ab1063d..6fb734c64 100644 --- a/src/main/java/net/minecraft/server/CraftingManager.java +++ b/src/main/java/net/minecraft/server/CraftingManager.java @@ -1,161 +1,152 @@ package net.minecraft.server; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; +import com.google.common.collect.ImmutableMap.Builder; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; -import java.io.IOException; -import java.nio.charset.StandardCharsets; +import com.google.gson.JsonSyntaxException; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; +import java.util.List; import java.util.Map; -import javax.annotation.Nullable; -import org.apache.commons.io.IOUtils; +import java.util.Objects; +import java.util.Optional; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -public class CraftingManager implements IResourcePackListener { +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; // CraftBukkit - private static final Logger c = LogManager.getLogger(); - public static final int a = "recipes/".length(); - public static final int b = ".json".length(); - public it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap recipes = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>(); // CraftBukkit - private boolean e; +public class CraftingManager extends ResourceDataJson { - public CraftingManager() {} + private static final Gson a = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create(); + private static final Logger LOGGER = LogManager.getLogger(); + public Map, Object2ObjectLinkedOpenHashMap>> recipes = ImmutableMap.of(); // CraftBukkit + private boolean d; - public void a(IResourceManager iresourcemanager) { - Gson gson = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create(); + public CraftingManager() { + super(CraftingManager.a, "recipes"); + } - this.e = false; - this.recipes.clear(); - Iterator iterator = iresourcemanager.a("recipes", (s) -> { - return s.endsWith(".json"); - }).iterator(); + protected void a(Map map, IResourceManager iresourcemanager, GameProfilerFiller gameprofilerfiller) { + this.d = false; + Map, Object2ObjectLinkedOpenHashMap>> map1 = Maps.newHashMap(); // CraftBukkit + Iterator iterator = map.entrySet().iterator(); while (iterator.hasNext()) { - MinecraftKey minecraftkey = (MinecraftKey) iterator.next(); - String s = minecraftkey.getKey(); - MinecraftKey minecraftkey1 = new MinecraftKey(minecraftkey.b(), s.substring(CraftingManager.a, s.length() - CraftingManager.b)); + Entry entry = (Entry) iterator.next(); + MinecraftKey minecraftkey = (MinecraftKey) entry.getKey(); try { - IResource iresource = iresourcemanager.a(minecraftkey); - Throwable throwable = null; + IRecipe irecipe = a(minecraftkey, (JsonObject) entry.getValue()); - try { - JsonObject jsonobject = (JsonObject) ChatDeserializer.a(gson, IOUtils.toString(iresource.b(), StandardCharsets.UTF_8), JsonObject.class); - - if (jsonobject == null) { - CraftingManager.c.error("Couldn't load recipe {} as it's null or empty", minecraftkey1); - } else { - this.a(RecipeSerializers.a(minecraftkey1, jsonobject)); - } - } catch (Throwable throwable1) { - throwable = throwable1; - throw throwable1; - } finally { - if (iresource != null) { - if (throwable != null) { - try { - iresource.close(); - } catch (Throwable throwable2) { - throwable.addSuppressed(throwable2); - } - } else { - iresource.close(); - } - } - - } + // CraftBukkit start - SPIGOT-4638: last recipe gets priority + (map1.computeIfAbsent(irecipe.g(), (recipes) -> { + return new Object2ObjectLinkedOpenHashMap<>(); + })).putAndMoveToFirst(minecraftkey, irecipe); + // CraftBukkit end } catch (IllegalArgumentException | JsonParseException jsonparseexception) { - CraftingManager.c.error("Parsing error loading recipe {}", minecraftkey1, jsonparseexception); - this.e = true; - } catch (IOException ioexception) { - CraftingManager.c.error("Couldn't read custom advancement {} from {}", minecraftkey1, minecraftkey, ioexception); - this.e = true; + CraftingManager.LOGGER.error("Parsing error loading recipe {}", minecraftkey, jsonparseexception); } } - CraftingManager.c.info("Loaded {} recipes", this.recipes.size()); + this.recipes = (Map) map1.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry1) -> { + return entry1.getValue(); // CraftBukkit // Paper - decompile fix - *shrugs internally* + })); + CraftingManager.LOGGER.info("Loaded {} recipes", map1.size()); } - public void a(IRecipe irecipe) { - //org.spigotmc.AsyncCatcher.catchOp("Recipe Add"); // Spigot // Akarin - if (this.recipes.containsKey(irecipe.getKey())) { + // CraftBukkit start + public void addRecipe(IRecipe irecipe) { + org.spigotmc.AsyncCatcher.catchOp("Recipe Add"); // Spigot + Object2ObjectLinkedOpenHashMap> map = this.recipes.get(irecipe.g()); // CraftBukkit + + if (map.containsKey(irecipe.getKey())) { throw new IllegalStateException("Duplicate recipe ignored with ID " + irecipe.getKey()); } else { - this.recipes.putAndMoveToFirst(irecipe.getKey(), irecipe); // CraftBukkit - SPIGOT-4638: last recipe gets priority + map.putAndMoveToFirst(irecipe.getKey(), irecipe); // CraftBukkit - SPIGOT-4638: last recipe gets priority + } + } + // CraftBukkit end + + public > Optional craft(Recipes recipes, C c0, World world) { + // CraftBukkit start + Optional recipe = this.a(recipes).values().stream().flatMap((irecipe) -> { + return SystemUtils.a(recipes.a(irecipe, world, c0)); + }).findFirst(); + c0.setCurrentRecipe(recipe.orElse(null)); // CraftBukkit - Clear recipe when no recipe is found + // CraftBukkit end + return recipe; + } + + public > List b(Recipes recipes, C c0, World world) { + return (List) this.a(recipes).values().stream().flatMap((irecipe) -> { + return SystemUtils.a(recipes.a(irecipe, world, c0)); + }).sorted(Comparator.comparing((irecipe) -> { + return irecipe.c().j(); + })).collect(Collectors.toList()); + } + + private > Map> a(Recipes recipes) { + return (Map) this.recipes.getOrDefault(recipes, new Object2ObjectLinkedOpenHashMap<>()); // CraftBukkit + } + + public > NonNullList c(Recipes recipes, C c0, World world) { + Optional optional = this.craft(recipes, c0, world); + + if (optional.isPresent()) { + return ((IRecipe) optional.get()).b(c0); + } else { + NonNullList nonnulllist = NonNullList.a(c0.getSize(), ItemStack.a); + + for (int i = 0; i < nonnulllist.size(); ++i) { + nonnulllist.set(i, c0.getItem(i)); + } + + return nonnulllist; } } - public ItemStack craft(IInventory iinventory, World world) { - Iterator iterator = this.recipes.values().iterator(); - - IRecipe irecipe; - - do { - if (!iterator.hasNext()) { - iinventory.setCurrentRecipe(null); // CraftBukkit - Clear recipe when no recipe is found - return ItemStack.a; - } - - irecipe = (IRecipe) iterator.next(); - } while (!irecipe.a(iinventory, world)); - - iinventory.setCurrentRecipe(irecipe); // CraftBukkit - return irecipe.craftItem(iinventory); + public Optional> a(MinecraftKey minecraftkey) { + return this.recipes.values().stream().map((map) -> { + return map.get(minecraftkey); // CraftBukkit - decompile error + }).filter(Objects::nonNull).findFirst(); } - @Nullable - public IRecipe b(IInventory iinventory, World world) { - Iterator iterator = this.recipes.values().iterator(); - - IRecipe irecipe; - - do { - if (!iterator.hasNext()) { - iinventory.setCurrentRecipe(null); // CraftBukkit - Clear recipe when no recipe is found - return null; - } - - irecipe = (IRecipe) iterator.next(); - } while (!irecipe.a(iinventory, world)); - - iinventory.setCurrentRecipe(irecipe); // CraftBukkit - return irecipe; + public Collection> b() { + return (Collection) this.recipes.values().stream().flatMap((map) -> { + return map.values().stream(); + }).collect(Collectors.toSet()); } - public NonNullList c(IInventory iinventory, World world) { - Iterator iterator = this.recipes.values().iterator(); + public Stream c() { + return this.recipes.values().stream().flatMap((map) -> { + return map.keySet().stream(); + }); + } - while (iterator.hasNext()) { - IRecipe irecipe = (IRecipe) iterator.next(); + public static IRecipe a(MinecraftKey minecraftkey, JsonObject jsonobject) { + String s = ChatDeserializer.h(jsonobject, "type"); - if (irecipe.a(iinventory, world)) { - return irecipe.b(iinventory); - } + return ((RecipeSerializer) IRegistry.RECIPE_SERIALIZER.getOptional(new MinecraftKey(s)).orElseThrow(() -> { + return new JsonSyntaxException("Invalid or unsupported recipe type '" + s + "'"); + })).a(minecraftkey, jsonobject); + } + + // CraftBukkit start + public void clearRecipes() { + this.recipes = Maps.newHashMap(); + + for (Recipes recipeType : IRegistry.RECIPE_TYPE) { + this.recipes.put(recipeType, new Object2ObjectLinkedOpenHashMap<>()); } - - NonNullList nonnulllist = NonNullList.a(iinventory.getSize(), ItemStack.a); - - for (int i = 0; i < nonnulllist.size(); ++i) { - nonnulllist.set(i, iinventory.getItem(i)); - } - - return nonnulllist; - } - - @Nullable - public IRecipe a(MinecraftKey minecraftkey) { - return (IRecipe) this.recipes.get(minecraftkey); - } - - public Collection b() { - return this.recipes.values(); - } - - public Collection c() { - return this.recipes.keySet(); } + // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/CrashReport.java b/src/main/java/net/minecraft/server/CrashReport.java index 62c147f97..d691a6e66 100644 --- a/src/main/java/net/minecraft/server/CrashReport.java +++ b/src/main/java/net/minecraft/server/CrashReport.java @@ -11,6 +11,7 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.concurrent.CompletionException; import java.util.stream.Collectors; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.ArrayUtils; @@ -19,7 +20,7 @@ import org.apache.logging.log4j.Logger; public class CrashReport { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private final String b; private final Throwable c; private final CrashReportSystemDetails d = new CrashReportSystemDetails(this, "System Details"); @@ -36,7 +37,10 @@ public class CrashReport { private void h() { this.d.a("Minecraft Version", () -> { - return "1.13.2"; + return SharedConstants.a().getName(); + }); + this.d.a("Minecraft Version ID", () -> { + return SharedConstants.a().getId(); }); this.d.a("Operating System", () -> { return System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ") version " + System.getProperty("os.version"); @@ -58,8 +62,9 @@ public class CrashReport { return k + " bytes (" + j1 + " MB) / " + j + " bytes (" + i1 + " MB) up to " + i + " bytes (" + l + " MB)"; }); + this.d.a("CPUs", (Object) Runtime.getRuntime().availableProcessors()); this.d.a("JVM Flags", () -> { - List list = (List) SystemUtils.f().collect(Collectors.toList()); + List list = (List) SystemUtils.h().collect(Collectors.toList()); return String.format("%d total; %s", list.size(), list.stream().collect(Collectors.joining(" "))); }); @@ -185,7 +190,7 @@ public class CrashReport { return flag1; } catch (Throwable throwable) { - CrashReport.a.error("Could not save crash report to {}", file, throwable); + CrashReport.LOGGER.error("Could not save crash report to {}", file, throwable); flag = false; } finally { IOUtils.closeQuietly(outputstreamwriter); @@ -242,7 +247,7 @@ public class CrashReport { } private static String i() { - String[] astring = new String[] { "Who set us up the TNT?", "Everything's going to plan. No, really, that was supposed to happen.", "Uh... Did I do that?", "Oops.", "Why did you do that?", "I feel sad now :(", "My bad.", "I'm sorry, Dave.", "I let you down. Sorry :(", "On the bright side, I bought you a teddy bear!", "Daisy, daisy...", "Oh - I know what I did wrong!", "Hey, that tickles! Hehehe!", "I blame Dinnerbone.", "You should try our sister game, Minceraft!", "Don't be sad. I'll do better next time, I promise!", "Don't be sad, have a hug! <3", "I just don't know what went wrong :(", "Shall we play a game?", "Quite honestly, I wouldn't worry myself about that.", "I bet Cylons wouldn't have this problem.", "Sorry :(", "Surprise! Haha. Well, this is awkward.", "Would you like a cupcake?", "Hi. I'm Minecraft, and I'm a crashaholic.", "Ooh. Shiny.", "This doesn't make any sense!", "Why is it breaking :(", "Don't do that.", "Ouch. That hurt :(", "You're mean.", "This is a token for 1 free hug. Redeem at your nearest Mojangsta: [~~HUG~~]", "There are four lights!", "But it works on my machine.", "Oh oh oh, Akarin feel so sad, we should ready some chocolate.", "Boom, Some bad things happened", "Oh no, It shouldn't happend!"}; + String[] astring = new String[]{"Who set us up the TNT?", "Everything's going to plan. No, really, that was supposed to happen.", "Uh... Did I do that?", "Oops.", "Why did you do that?", "I feel sad now :(", "My bad.", "I'm sorry, Dave.", "I let you down. Sorry :(", "On the bright side, I bought you a teddy bear!", "Daisy, daisy...", "Oh - I know what I did wrong!", "Hey, that tickles! Hehehe!", "I blame Dinnerbone.", "You should try our sister game, Minceraft!", "Don't be sad. I'll do better next time, I promise!", "Don't be sad, have a hug! <3", "I just don't know what went wrong :(", "Shall we play a game?", "Quite honestly, I wouldn't worry myself about that.", "I bet Cylons wouldn't have this problem.", "Sorry :(", "Surprise! Haha. Well, this is awkward.", "Would you like a cupcake?", "Hi. I'm Minecraft, and I'm a crashaholic.", "Ooh. Shiny.", "This doesn't make any sense!", "Why is it breaking :(", "Don't do that.", "Ouch. That hurt :(", "You're mean.", "This is a token for 1 free hug. Redeem at your nearest Mojangsta: [~~HUG~~]", "There are four lights!", "But it works on my machine."}; try { return astring[(int) (SystemUtils.getMonotonicNanos() % (long) astring.length)]; @@ -252,6 +257,10 @@ public class CrashReport { } public static CrashReport a(Throwable throwable, String s) { + while (throwable instanceof CompletionException && throwable.getCause() != null) { + throwable = throwable.getCause(); + } + CrashReport crashreport; if (throwable instanceof ReportedException) { diff --git a/src/main/java/net/minecraft/server/CustomFunction.java b/src/main/java/net/minecraft/server/CustomFunction.java index bc87cfc4b..49de6e997 100644 --- a/src/main/java/net/minecraft/server/CustomFunction.java +++ b/src/main/java/net/minecraft/server/CustomFunction.java @@ -6,6 +6,7 @@ import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.util.ArrayDeque; import java.util.List; +import java.util.Optional; import javax.annotation.Nullable; public class CustomFunction { @@ -57,7 +58,7 @@ public class CustomFunction { } try { - ParseResults parseresults = customfunctiondata.d().parse(stringreader, customfunctiondata.f()); // CraftBukkit + ParseResults parseresults = customfunctiondata.d().parse(stringreader, customfunctiondata.g()); // CraftBukkit if (parseresults.getReader().canRead()) { if (parseresults.getExceptions().size() == 1) { @@ -87,19 +88,19 @@ public class CustomFunction { @Nullable private final MinecraftKey b; private boolean c; - private CustomFunction d; + private Optional d = Optional.empty(); public a(@Nullable MinecraftKey minecraftkey) { this.b = minecraftkey; } public a(CustomFunction customfunction) { + this.c = true; this.b = null; - this.d = customfunction; + this.d = Optional.of(customfunction); } - @Nullable - public CustomFunction a(CustomFunctionData customfunctiondata) { + public Optional a(CustomFunctionData customfunctiondata) { if (!this.c) { if (this.b != null) { this.d = customfunctiondata.a(this.b); @@ -113,7 +114,9 @@ public class CustomFunction { @Nullable public MinecraftKey a() { - return this.d != null ? this.d.b : this.b; + return (MinecraftKey) this.d.map((customfunction) -> { + return customfunction.b; + }).orElse(this.b); } } @@ -125,10 +128,9 @@ public class CustomFunction { this.a = new CustomFunction.a(customfunction); } + @Override public void a(CustomFunctionData customfunctiondata, CommandListenerWrapper commandlistenerwrapper, ArrayDeque arraydeque, int i) { - CustomFunction customfunction = this.a.a(customfunctiondata); - - if (customfunction != null) { + this.a.a(customfunctiondata).ifPresent((customfunction) -> { CustomFunction.c[] acustomfunction_c = customfunction.b(); int j = i - arraydeque.size(); int k = Math.min(acustomfunction_c.length, j); @@ -136,8 +138,8 @@ public class CustomFunction { for (int l = k - 1; l >= 0; --l) { arraydeque.addFirst(new CustomFunctionData.a(customfunctiondata, commandlistenerwrapper, acustomfunction_c[l])); } - } + }); } public String toString() { @@ -153,8 +155,9 @@ public class CustomFunction { this.a = parseresults; } + @Override public void a(CustomFunctionData customfunctiondata, CommandListenerWrapper commandlistenerwrapper, ArrayDeque arraydeque, int i) throws CommandSyntaxException { - customfunctiondata.d().execute(new ParseResults(this.a.getContext().withSource(commandlistenerwrapper), this.a.getStartIndex(), this.a.getReader(), this.a.getExceptions())); + customfunctiondata.d().execute(new ParseResults(this.a.getContext().withSource(commandlistenerwrapper), this.a.getReader(), this.a.getExceptions())); } public String toString() { diff --git a/src/main/java/net/minecraft/server/CustomFunctionData.java b/src/main/java/net/minecraft/server/CustomFunctionData.java index 9bccbc3d0..721839b4c 100644 --- a/src/main/java/net/minecraft/server/CustomFunctionData.java +++ b/src/main/java/net/minecraft/server/CustomFunctionData.java @@ -9,6 +9,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import javax.annotation.Nullable; @@ -16,30 +17,28 @@ import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -public class CustomFunctionData implements ITickable, IResourcePackListener { +public class CustomFunctionData implements IResourcePackListener { - private static final Logger c = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final MinecraftKey d = new MinecraftKey("tick"); private static final MinecraftKey e = new MinecraftKey("load"); public static final int a = "functions/".length(); public static final int b = ".mcfunction".length(); private final MinecraftServer server; private final Map g = Maps.newHashMap(); - private final ArrayDeque h = new ArrayDeque(); - private boolean i; - private final Tags j = new Tags<>((minecraftkey) -> { - return this.a(minecraftkey) != null; - }, this::a, "tags/functions", true, "function"); - private final List k = Lists.newArrayList(); - private boolean l; + private boolean h; + private final ArrayDeque i = new ArrayDeque(); + private final List j = Lists.newArrayList(); + private final Tags k = new Tags<>(this::a, "tags/functions", true, "function"); + private final List l = Lists.newArrayList(); + private boolean m; public CustomFunctionData(MinecraftServer minecraftserver) { this.server = minecraftserver; } - @Nullable - public CustomFunction a(MinecraftKey minecraftkey) { - return (CustomFunction) this.g.get(minecraftkey); + public Optional a(MinecraftKey minecraftkey) { + return Optional.ofNullable(this.g.get(minecraftkey)); } public MinecraftServer a() { @@ -47,7 +46,7 @@ public class CustomFunctionData implements ITickable, IResourcePackListener { } public int b() { - return this.server.getGameRules().c("maxCommandChainLength"); + return this.server.getGameRules().getInt(GameRules.MAX_COMMAND_CHAIN_LENGTH); } public Map c() { @@ -59,10 +58,11 @@ public class CustomFunctionData implements ITickable, IResourcePackListener { } public void tick() { + GameProfiler gameprofiler = this.server.getMethodProfiler(); MinecraftKey minecraftkey = CustomFunctionData.d; - //this.server.methodProfiler.a(minecraftkey::toString); // Akarin - remove caller - Iterator iterator = this.k.iterator(); + gameprofiler.a(minecraftkey::toString); + Iterator iterator = this.l.iterator(); while (iterator.hasNext()) { CustomFunction customfunction = (CustomFunction) iterator.next(); @@ -70,13 +70,14 @@ public class CustomFunctionData implements ITickable, IResourcePackListener { this.a(customfunction, this.f()); } - //this.server.methodProfiler.exit(); // Akarin - remove caller - if (this.l) { - this.l = false; - Collection collection = this.g().b(CustomFunctionData.e).a(); + this.server.getMethodProfiler().exit(); + if (this.m) { + this.m = false; + Collection collection = this.h().b(CustomFunctionData.e).a(); + gameprofiler = this.server.getMethodProfiler(); minecraftkey = CustomFunctionData.e; - //this.server.methodProfiler.a(minecraftkey::toString); // Akarin - remove caller + gameprofiler.a(minecraftkey::toString); Iterator iterator1 = collection.iterator(); while (iterator1.hasNext()) { @@ -85,7 +86,7 @@ public class CustomFunctionData implements ITickable, IResourcePackListener { this.a(customfunction1, this.f()); } - //this.server.methodProfiler.exit(); // Akarin - remove caller + this.server.getMethodProfiler().exit(); } } @@ -93,32 +94,40 @@ public class CustomFunctionData implements ITickable, IResourcePackListener { public int a(CustomFunction customfunction, CommandListenerWrapper commandlistenerwrapper) { int i = this.b(); - if (this.i) { - if (this.h.size() < i) { - this.h.addFirst(new CustomFunctionData.a(this, commandlistenerwrapper, new CustomFunction.d(customfunction))); + if (this.h) { + if (this.i.size() + this.j.size() < i) { + this.j.add(new CustomFunctionData.a(this, commandlistenerwrapper, new CustomFunction.d(customfunction))); } return 0; } else { try (co.aikar.timings.Timing timing = customfunction.getTiming().startTiming()) { // Paper - this.i = true; + this.h = true; int j = 0; CustomFunction.c[] acustomfunction_c = customfunction.b(); int k; for (k = acustomfunction_c.length - 1; k >= 0; --k) { - this.h.push(new CustomFunctionData.a(this, commandlistenerwrapper, acustomfunction_c[k])); + this.i.push(new CustomFunctionData.a(this, commandlistenerwrapper, acustomfunction_c[k])); } - while (!this.h.isEmpty()) { + while (!this.i.isEmpty()) { try { - CustomFunctionData.a customfunctiondata_a = (CustomFunctionData.a) this.h.removeFirst(); + CustomFunctionData.a customfunctiondata_a = (CustomFunctionData.a) this.i.removeFirst(); - //this.server.methodProfiler.a(customfunctiondata_a::toString); // Akarin - remove caller - customfunctiondata_a.a(this.h, i); + this.server.getMethodProfiler().a(customfunctiondata_a::toString); + customfunctiondata_a.a(this.i, i); + if (!this.j.isEmpty()) { + List list = Lists.reverse(this.j); + ArrayDeque arraydeque = this.i; + + this.i.getClass(); + list.forEach(arraydeque::addFirst); + this.j.clear(); + } } finally { - //this.server.methodProfiler.exit(); // Akarin - remove caller + this.server.getMethodProfiler().exit(); } ++j; @@ -131,16 +140,17 @@ public class CustomFunctionData implements ITickable, IResourcePackListener { k = j; return k; } finally { - this.h.clear(); - this.i = false; + this.i.clear(); + this.j.clear(); + this.h = false; } } } + @Override public void a(IResourceManager iresourcemanager) { this.g.clear(); - this.k.clear(); - this.j.b(); + this.l.clear(); Collection collection = iresourcemanager.a("functions", (s) -> { return s.endsWith(".mcfunction"); }); @@ -150,31 +160,31 @@ public class CustomFunctionData implements ITickable, IResourcePackListener { while (iterator.hasNext()) { MinecraftKey minecraftkey = (MinecraftKey) iterator.next(); String s = minecraftkey.getKey(); - MinecraftKey minecraftkey1 = new MinecraftKey(minecraftkey.b(), s.substring(CustomFunctionData.a, s.length() - CustomFunctionData.b)); + MinecraftKey minecraftkey1 = new MinecraftKey(minecraftkey.getNamespace(), s.substring(CustomFunctionData.a, s.length() - CustomFunctionData.b)); list.add(CompletableFuture.supplyAsync(() -> { return a(iresourcemanager, minecraftkey); }, Resource.a).thenApplyAsync((list1) -> { return CustomFunction.a(minecraftkey1, this, list1); - }).handle((customfunction, throwable) -> { + }, this.server.aU()).handle((customfunction, throwable) -> { return this.a(customfunction, throwable, minecraftkey); })); } CompletableFuture.allOf((CompletableFuture[]) list.toArray(new CompletableFuture[0])).join(); if (!this.g.isEmpty()) { - CustomFunctionData.c.info("Loaded {} custom command functions", this.g.size()); + CustomFunctionData.LOGGER.info("Loaded {} custom command functions", this.g.size()); } - this.j.a(iresourcemanager); - this.k.addAll(this.j.b(CustomFunctionData.d).a()); - this.l = true; + this.k.a((Map) this.k.a(iresourcemanager, this.server.aU()).join()); + this.l.addAll(this.k.b(CustomFunctionData.d).a()); + this.m = true; } @Nullable private CustomFunction a(CustomFunction customfunction, @Nullable Throwable throwable, MinecraftKey minecraftkey) { if (throwable != null) { - CustomFunctionData.c.error("Couldn't load function at {}", minecraftkey, throwable); + CustomFunctionData.LOGGER.error("Couldn't load function at {}", minecraftkey, throwable); return null; } else { Map map = this.g; @@ -223,8 +233,12 @@ public class CustomFunctionData implements ITickable, IResourcePackListener { return this.server.getServerCommandListener().a(2).a(); } - public Tags g() { - return this.j; + public CommandListenerWrapper g() { + return new CommandListenerWrapper(ICommandListener.DUMMY, Vec3D.a, Vec2F.a, (WorldServer) null, this.server.k(), "", new ChatComponentText(""), this.server, (Entity) null); + } + + public Tags h() { + return this.k; } public static class a { diff --git a/src/main/java/net/minecraft/server/DamageSource.java b/src/main/java/net/minecraft/server/DamageSource.java index 71a6d858e..730a15f33 100644 --- a/src/main/java/net/minecraft/server/DamageSource.java +++ b/src/main/java/net/minecraft/server/DamageSource.java @@ -25,15 +25,16 @@ public class DamageSource { public static final DamageSource DRAGON_BREATH = (new DamageSource("dragonBreath")).setIgnoreArmor(); public static final DamageSource FIREWORKS = (new DamageSource("fireworks")).e(); public static final DamageSource DRYOUT = new DamageSource("dryout"); - private boolean w; + public static final DamageSource SWEET_BERRY_BUSH = new DamageSource("sweetBerryBush"); private boolean x; private boolean y; - private float z = 0.1F; - private boolean A; + private boolean z; + private float A = 0.1F; private boolean B; private boolean C; private boolean D; private boolean E; + private boolean F; public final String translationIndex; // CraftBukkit start private boolean sweep; @@ -97,39 +98,39 @@ public class DamageSource { } public boolean b() { - return this.B; + return this.C; } public DamageSource c() { - this.B = true; + this.C = true; return this; } public boolean isExplosion() { - return this.E; + return this.F; } public DamageSource e() { - this.E = true; + this.F = true; return this; } public boolean ignoresArmor() { - return this.w; - } - - public float getExhaustionCost() { - return this.z; - } - - public boolean ignoresInvulnerability() { return this.x; } - public boolean isStarvation() { + public float getExhaustionCost() { + return this.A; + } + + public boolean ignoresInvulnerability() { return this.y; } + public boolean isStarvation() { + return this.z; + } + protected DamageSource(String s) { this.translationIndex = s; } @@ -145,37 +146,37 @@ public class DamageSource { } protected DamageSource setIgnoreArmor() { - this.w = true; - this.z = 0.0F; + this.x = true; + this.A = 0.0F; return this; } protected DamageSource m() { - this.x = true; + this.y = true; return this; } protected DamageSource n() { - this.y = true; - this.z = 0.0F; + this.z = true; + this.A = 0.0F; return this; } protected DamageSource setExplosion() { - this.A = true; + this.B = true; return this; } public IChatBaseComponent getLocalizedDeathMessage(EntityLiving entityliving) { - EntityLiving entityliving1 = entityliving.cv(); + EntityLiving entityliving1 = entityliving.getKillingEntity(); String s = "death.attack." + this.translationIndex; String s1 = s + ".player"; - return entityliving1 != null ? new ChatMessage(s1, new Object[] { entityliving.getScoreboardDisplayName(), entityliving1.getScoreboardDisplayName()}) : new ChatMessage(s, new Object[] { entityliving.getScoreboardDisplayName()}); + return entityliving1 != null ? new ChatMessage(s1, new Object[]{entityliving.getScoreboardDisplayName(), entityliving1.getScoreboardDisplayName()}) : new ChatMessage(s, new Object[]{entityliving.getScoreboardDisplayName()}); } public boolean p() { - return this.A; + return this.B; } public String q() { @@ -183,20 +184,20 @@ public class DamageSource { } public DamageSource r() { - this.C = true; + this.D = true; return this; } public boolean s() { - return this.C; - } - - public boolean isMagic() { return this.D; } + public boolean isMagic() { + return this.E; + } + public DamageSource setMagic() { - this.D = true; + this.E = true; return this; } diff --git a/src/main/java/net/minecraft/server/DataBits.java b/src/main/java/net/minecraft/server/DataBits.java index fe5947b6c..a75b08ee3 100644 --- a/src/main/java/net/minecraft/server/DataBits.java +++ b/src/main/java/net/minecraft/server/DataBits.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.function.IntConsumer; import org.apache.commons.lang3.Validate; public class DataBits { @@ -26,13 +27,35 @@ public class DataBits { } } - public void a(int i, int j) { + public int a(int i, int j) { //Validate.inclusiveBetween(0L, (long) (this.d - 1), (long) i); // Paper //Validate.inclusiveBetween(0L, this.c, (long) j); // Paper int k = i * this.b; - int l = k / 64; - int i1 = ((i + 1) * this.b - 1) / 64; - int j1 = k % 64; + int l = k >> 6; + int i1 = (i + 1) * this.b - 1 >> 6; + int j1 = k ^ l << 6; + byte b0 = 0; + int k1 = b0 | (int) (this.a[l] >>> j1 & this.c); + + this.a[l] = this.a[l] & ~(this.c << j1) | ((long) j & this.c) << j1; + if (l != i1) { + int l1 = 64 - j1; + int i2 = this.b - l1; + + k1 |= (int) (this.a[i1] << l1 & this.c); + this.a[i1] = this.a[i1] >>> i2 << i2 | ((long) j & this.c) >> l1; + } + + return k1; + } + + public void b(int i, int j) { + //Validate.inclusiveBetween(0L, (long) (this.d - 1), (long) i); // Paper + //Validate.inclusiveBetween(0L, this.c, (long) j); // Paper + int k = i * this.b; + int l = k >> 6; + int i1 = (i + 1) * this.b - 1 >> 6; + int j1 = k ^ l << 6; this.a[l] = this.a[l] & ~(this.c << j1) | ((long) j & this.c) << j1; if (l != i1) { @@ -47,9 +70,9 @@ public class DataBits { public int a(int i) { //Validate.inclusiveBetween(0L, (long) (this.d - 1), (long) i); // Paper int j = i * this.b; - int k = j / 64; - int l = ((i + 1) * this.b - 1) / 64; - int i1 = j % 64; + int k = j >> 6; + int l = (i + 1) * this.b - 1 >> 6; + int i1 = j ^ k << 6; if (k == l) { return (int) (this.a[k] >>> i1 & this.c); @@ -72,4 +95,36 @@ public class DataBits { public int c() { return this.b; } + + public void a(IntConsumer intconsumer) { + int i = this.a.length; + + if (i != 0) { + int j = 0; + long k = this.a[0]; + long l = i > 1 ? this.a[1] : 0L; + + for (int i1 = 0; i1 < this.d; ++i1) { + int j1 = i1 * this.b; + int k1 = j1 >> 6; + int l1 = (i1 + 1) * this.b - 1 >> 6; + int i2 = j1 ^ k1 << 6; + + if (k1 != j) { + k = l; + l = k1 + 1 < i ? this.a[k1 + 1] : 0L; + j = k1; + } + + if (k1 == l1) { + intconsumer.accept((int) (k >>> i2 & this.c)); + } else { + int j2 = 64 - i2; + + intconsumer.accept((int) ((k >>> i2 | l << j2) & this.c)); + } + } + + } + } } diff --git a/src/main/java/net/minecraft/server/DataConverterFlatten.java b/src/main/java/net/minecraft/server/DataConverterFlatten.java index 36aa61415..e11f8b88b 100644 --- a/src/main/java/net/minecraft/server/DataConverterFlatten.java +++ b/src/main/java/net/minecraft/server/DataConverterFlatten.java @@ -346,7 +346,7 @@ public class DataConverterFlatten extends DataFix { private static final Set b = (Set) DataConverterFlatten.a.keySet().stream().map((s) -> { return s.substring(0, s.indexOf(46)); }).collect(Collectors.toSet()); - private static final Set c = Sets.newHashSet(new String[] { "minecraft:bow", "minecraft:carrot_on_a_stick", "minecraft:chainmail_boots", "minecraft:chainmail_chestplate", "minecraft:chainmail_helmet", "minecraft:chainmail_leggings", "minecraft:diamond_axe", "minecraft:diamond_boots", "minecraft:diamond_chestplate", "minecraft:diamond_helmet", "minecraft:diamond_hoe", "minecraft:diamond_leggings", "minecraft:diamond_pickaxe", "minecraft:diamond_shovel", "minecraft:diamond_sword", "minecraft:elytra", "minecraft:fishing_rod", "minecraft:flint_and_steel", "minecraft:golden_axe", "minecraft:golden_boots", "minecraft:golden_chestplate", "minecraft:golden_helmet", "minecraft:golden_hoe", "minecraft:golden_leggings", "minecraft:golden_pickaxe", "minecraft:golden_shovel", "minecraft:golden_sword", "minecraft:iron_axe", "minecraft:iron_boots", "minecraft:iron_chestplate", "minecraft:iron_helmet", "minecraft:iron_hoe", "minecraft:iron_leggings", "minecraft:iron_pickaxe", "minecraft:iron_shovel", "minecraft:iron_sword", "minecraft:leather_boots", "minecraft:leather_chestplate", "minecraft:leather_helmet", "minecraft:leather_leggings", "minecraft:shears", "minecraft:shield", "minecraft:stone_axe", "minecraft:stone_hoe", "minecraft:stone_pickaxe", "minecraft:stone_shovel", "minecraft:stone_sword", "minecraft:wooden_axe", "minecraft:wooden_hoe", "minecraft:wooden_pickaxe", "minecraft:wooden_shovel", "minecraft:wooden_sword"}); + private static final Set c = Sets.newHashSet(new String[]{"minecraft:bow", "minecraft:carrot_on_a_stick", "minecraft:chainmail_boots", "minecraft:chainmail_chestplate", "minecraft:chainmail_helmet", "minecraft:chainmail_leggings", "minecraft:diamond_axe", "minecraft:diamond_boots", "minecraft:diamond_chestplate", "minecraft:diamond_helmet", "minecraft:diamond_hoe", "minecraft:diamond_leggings", "minecraft:diamond_pickaxe", "minecraft:diamond_shovel", "minecraft:diamond_sword", "minecraft:elytra", "minecraft:fishing_rod", "minecraft:flint_and_steel", "minecraft:golden_axe", "minecraft:golden_boots", "minecraft:golden_chestplate", "minecraft:golden_helmet", "minecraft:golden_hoe", "minecraft:golden_leggings", "minecraft:golden_pickaxe", "minecraft:golden_shovel", "minecraft:golden_sword", "minecraft:iron_axe", "minecraft:iron_boots", "minecraft:iron_chestplate", "minecraft:iron_helmet", "minecraft:iron_hoe", "minecraft:iron_leggings", "minecraft:iron_pickaxe", "minecraft:iron_shovel", "minecraft:iron_sword", "minecraft:leather_boots", "minecraft:leather_chestplate", "minecraft:leather_helmet", "minecraft:leather_leggings", "minecraft:shears", "minecraft:shield", "minecraft:stone_axe", "minecraft:stone_hoe", "minecraft:stone_pickaxe", "minecraft:stone_shovel", "minecraft:stone_sword", "minecraft:wooden_axe", "minecraft:wooden_hoe", "minecraft:wooden_pickaxe", "minecraft:wooden_shovel", "minecraft:wooden_sword"}); public DataConverterFlatten(Schema schema, boolean flag) { super(schema, flag); @@ -354,7 +354,7 @@ public class DataConverterFlatten extends DataFix { public TypeRewriteRule makeRule() { Type type = this.getInputSchema().getType(DataConverterTypes.ITEM_STACK); - OpticFinder> opticfinder = DSL.fieldFinder("id", DSL.named(DataConverterTypes.q.typeName(), DSL.namespacedString())); + OpticFinder> opticfinder = DSL.fieldFinder("id", DSL.named(DataConverterTypes.r.typeName(), DSL.namespacedString())); OpticFinder opticfinder1 = type.findField("tag"); return this.fixTypeEverywhereTyped("ItemInstanceTheFlatteningFix", type, (typed) -> { @@ -365,11 +365,11 @@ public class DataConverterFlatten extends DataFix { } else { Typed typed1 = typed; Dynamic dynamic = (Dynamic) typed.get(DSL.remainderFinder()); - int i = dynamic.getInt("Damage"); + int i = dynamic.get("Damage").asInt(0); String s = a((String) ((Pair) optional.get()).getSecond(), i); if (s != null) { - typed1 = typed.set(opticfinder, Pair.of(DataConverterTypes.q.typeName(), s)); + typed1 = typed.set(opticfinder, Pair.of(DataConverterTypes.r.typeName(), s)); } if (DataConverterFlatten.c.contains(((Pair) optional.get()).getSecond())) { diff --git a/src/main/java/net/minecraft/server/DataConverterMap.java b/src/main/java/net/minecraft/server/DataConverterMap.java index d21d2a1d7..49af999b7 100644 --- a/src/main/java/net/minecraft/server/DataConverterMap.java +++ b/src/main/java/net/minecraft/server/DataConverterMap.java @@ -20,7 +20,7 @@ public class DataConverterMap extends DataFix { public TypeRewriteRule makeRule() { Type type = this.getInputSchema().getType(DataConverterTypes.ITEM_STACK); - OpticFinder> opticfinder = DSL.fieldFinder("id", DSL.named(DataConverterTypes.q.typeName(), DSL.namespacedString())); + OpticFinder> opticfinder = DSL.fieldFinder("id", DSL.named(DataConverterTypes.r.typeName(), DSL.namespacedString())); OpticFinder opticfinder1 = type.findField("tag"); return this.fixTypeEverywhereTyped("ItemInstanceMapIdFix", type, (typed) -> { @@ -31,7 +31,7 @@ public class DataConverterMap extends DataFix { Typed typed1 = typed.getOrCreateTyped(opticfinder1); Dynamic dynamic1 = (Dynamic) typed1.get(DSL.remainderFinder()); - if (!dynamic1.get("map").isPresent()) dynamic1 = dynamic1.set("map", dynamic1.createInt(dynamic.getInt("Damage"))); // CraftBukkit + if (!dynamic1.getElement("map").isPresent()) dynamic1 = dynamic1.set("map", dynamic1.createInt(dynamic.get("Damage").asInt(0))); // CraftBukkit return typed.set(opticfinder1, typed1.set(DSL.remainderFinder(), dynamic1)); } else { return typed; diff --git a/src/main/java/net/minecraft/server/DataConverterRegistry.java b/src/main/java/net/minecraft/server/DataConverterRegistry.java index db9af361d..645857604 100644 --- a/src/main/java/net/minecraft/server/DataConverterRegistry.java +++ b/src/main/java/net/minecraft/server/DataConverterRegistry.java @@ -7,7 +7,6 @@ import com.mojang.datafixers.DataFixerBuilder; import com.mojang.datafixers.Typed; import com.mojang.datafixers.schemas.Schema; import java.util.Objects; -import java.util.concurrent.ForkJoinPool; import java.util.function.BiFunction; public class DataConverterRegistry { @@ -17,15 +16,10 @@ public class DataConverterRegistry { private static final DataFixer c = b(); private static DataFixer b() { - DataFixerBuilder datafixerbuilder = new DataFixerBuilder(1631); + DataFixerBuilder datafixerbuilder = new DataFixerBuilder(SharedConstants.a().getWorldVersion()); a(datafixerbuilder); - // CraftBukkit start - ForkJoinPool pool = new ForkJoinPool(Integer.getInteger("net.minecraft.server.DataConverterRegistry.bootstrapThreads", Math.min(6, Math.max(Runtime.getRuntime().availableProcessors() - 2, 2)))); // Paper - use more reasonable default - 2 is hard minimum to avoid using unlimited threads - DataFixer fixer = datafixerbuilder.build(pool); - pool.shutdown(); - return fixer; - // CraftBukkit end + return datafixerbuilder.build(SystemUtils.e()); } public static DataFixer a() { @@ -118,7 +112,7 @@ public class DataConverterRegistry { datafixerbuilder.addFixer(new DataConverterPotionWater(schema26, false)); Schema schema27 = datafixerbuilder.addSchema(808, DataConverterSchemaV808::new); - datafixerbuilder.addFixer(new DataConverterAddChoices(schema27, "added shulker box", DataConverterTypes.j)); + datafixerbuilder.addFixer(new DataConverterAddChoices(schema27, "added shulker box", DataConverterTypes.k)); Schema schema28 = datafixerbuilder.addSchema(808, 1, DataConverterRegistry.b); datafixerbuilder.addFixer(new DataConverterShulker(schema28, false)); @@ -152,7 +146,7 @@ public class DataConverterRegistry { datafixerbuilder.addFixer(new DataConverterFlattenState(schema36, false)); Schema schema37 = datafixerbuilder.addSchema(1451, DataConverterSchemaV1451::new); - datafixerbuilder.addFixer(new DataConverterAddChoices(schema37, "AddTrappedChestFix", DataConverterTypes.j)); + datafixerbuilder.addFixer(new DataConverterAddChoices(schema37, "AddTrappedChestFix", DataConverterTypes.k)); Schema schema38 = datafixerbuilder.addSchema(1451, 1, DataConverterSchemaV1451_1::new); datafixerbuilder.addFixer(new ChunkConverterPalette(schema38, true)); @@ -169,7 +163,7 @@ public class DataConverterRegistry { datafixerbuilder.addFixer(new DataConverterFlatten(schema41, false)); Schema schema42 = datafixerbuilder.addSchema(1451, 5, DataConverterSchemaV1451_5::new); - datafixerbuilder.addFixer(new DataConverterAddChoices(schema42, "RemoveNoteBlockFlowerPotFix", DataConverterTypes.j)); + datafixerbuilder.addFixer(new DataConverterAddChoices(schema42, "RemoveNoteBlockFlowerPotFix", DataConverterTypes.k)); datafixerbuilder.addFixer(new DataConverterFlattenSpawnEgg(schema42, false)); datafixerbuilder.addFixer(new DataConverterWolf(schema42, false)); datafixerbuilder.addFixer(new DataConverterBannerColour(schema42, false)); @@ -237,7 +231,7 @@ public class DataConverterRegistry { })); Schema schema54 = datafixerbuilder.addSchema(1481, DataConverterSchemaV1481::new); - datafixerbuilder.addFixer(new DataConverterAddChoices(schema54, "Add conduit", DataConverterTypes.j)); + datafixerbuilder.addFixer(new DataConverterAddChoices(schema54, "Add conduit", DataConverterTypes.k)); Schema schema55 = datafixerbuilder.addSchema(1483, DataConverterSchemaV1483::new); datafixerbuilder.addFixer(new DataConverterEntityPufferfish(schema55, true)); @@ -275,12 +269,14 @@ public class DataConverterRegistry { datafixerbuilder.addFixer(DataConverterItemName.a(schema59, "Rename kelptop", (s) -> { return Objects.equals(s, "minecraft:kelp_top") ? "minecraft:kelp" : s; })); - datafixerbuilder.addFixer(new DataConverterNamedEntity(schema59, false, "Command block block entity custom name fix", DataConverterTypes.j, "minecraft:command_block") { + datafixerbuilder.addFixer(new DataConverterNamedEntity(schema59, false, "Command block block entity custom name fix", DataConverterTypes.k, "minecraft:command_block") { + @Override protected Typed a(Typed typed) { return typed.update(DSL.remainderFinder(), DataConverterCustomNameEntity::a); } }); datafixerbuilder.addFixer(new DataConverterNamedEntity(schema59, false, "Command block minecart custom name fix", DataConverterTypes.ENTITY, "minecraft:commandblock_minecart") { + @Override protected Typed a(Typed typed) { return typed.update(DSL.remainderFinder(), DataConverterCustomNameEntity::a); } @@ -342,5 +338,86 @@ public class DataConverterRegistry { Schema schema72 = datafixerbuilder.addSchema(1624, DataConverterRegistry.b); datafixerbuilder.addFixer(new DataConverterTrappedChest(schema72, false)); + Schema schema73 = datafixerbuilder.addSchema(1800, DataConverterSchemaV1800::new); + + datafixerbuilder.addFixer(new DataConverterAddChoices(schema73, "Added 1.14 mobs fix", DataConverterTypes.ENTITY)); + datafixerbuilder.addFixer(DataConverterItemName.a(schema73, "Rename dye items", (s) -> { + return (String) DataConverterDye.a.getOrDefault(s, s); + })); + Schema schema74 = datafixerbuilder.addSchema(1801, DataConverterSchemaV1801::new); + + datafixerbuilder.addFixer(new DataConverterAddChoices(schema74, "Added Illager Beast", DataConverterTypes.ENTITY)); + Schema schema75 = datafixerbuilder.addSchema(1802, DataConverterRegistry.b); + + datafixerbuilder.addFixer(DataConverterBlockRename.a(schema75, "Rename sign blocks & stone slabs", (s) -> { + return (String) ImmutableMap.of("minecraft:stone_slab", "minecraft:smooth_stone_slab", "minecraft:sign", "minecraft:oak_sign", "minecraft:wall_sign", "minecraft:oak_wall_sign").getOrDefault(s, s); + })); + datafixerbuilder.addFixer(DataConverterItemName.a(schema75, "Rename sign item & stone slabs", (s) -> { + return (String) ImmutableMap.of("minecraft:stone_slab", "minecraft:smooth_stone_slab", "minecraft:sign", "minecraft:oak_sign").getOrDefault(s, s); + })); + Schema schema76 = datafixerbuilder.addSchema(1803, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterItemLoreComponentize(schema76, false)); + Schema schema77 = datafixerbuilder.addSchema(1904, DataConverterSchemaV1904::new); + + datafixerbuilder.addFixer(new DataConverterAddChoices(schema77, "Added Cats", DataConverterTypes.ENTITY)); + datafixerbuilder.addFixer(new DataConverterEntityCatSplit(schema77, false)); + Schema schema78 = datafixerbuilder.addSchema(1905, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterChunkStatus(schema78, false)); + Schema schema79 = datafixerbuilder.addSchema(1906, DataConverterSchemaV1906::new); + + datafixerbuilder.addFixer(new DataConverterAddChoices(schema79, "Add POI Blocks", DataConverterTypes.k)); + Schema schema80 = datafixerbuilder.addSchema(1909, DataConverterSchemaV1909::new); + + datafixerbuilder.addFixer(new DataConverterAddChoices(schema80, "Add jigsaw", DataConverterTypes.k)); + Schema schema81 = datafixerbuilder.addSchema(1911, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterChunkStatus2(schema81, false)); + Schema schema82 = datafixerbuilder.addSchema(1917, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterCatType(schema82, false)); + Schema schema83 = datafixerbuilder.addSchema(1918, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterVillagerProfession(schema83, "minecraft:villager")); + datafixerbuilder.addFixer(new DataConverterVillagerProfession(schema83, "minecraft:zombie_villager")); + Schema schema84 = datafixerbuilder.addSchema(1920, DataConverterSchemaV1920::new); + + datafixerbuilder.addFixer(new DataConverterNewVillage(schema84, false)); + datafixerbuilder.addFixer(new DataConverterAddChoices(schema84, "Add campfire", DataConverterTypes.k)); + Schema schema85 = datafixerbuilder.addSchema(1925, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterMapId(schema85, false)); + Schema schema86 = datafixerbuilder.addSchema(1928, DataConverterSchemaV1928::new); + + datafixerbuilder.addFixer(new DataConverterEntityRavagerRename(schema86, true)); + datafixerbuilder.addFixer(DataConverterItemName.a(schema86, "Rename ravager egg item", (s) -> { + return (String) DataConverterEntityRavagerRename.a.getOrDefault(s, s); + })); + Schema schema87 = datafixerbuilder.addSchema(1929, DataConverterSchemaV1929::new); + + datafixerbuilder.addFixer(new DataConverterAddChoices(schema87, "Add Wandering Trader and Trader Llama", DataConverterTypes.ENTITY)); + Schema schema88 = datafixerbuilder.addSchema(1931, DataConverterSchemaV1931::new); + + datafixerbuilder.addFixer(new DataConverterAddChoices(schema88, "Added Fox", DataConverterTypes.ENTITY)); + Schema schema89 = datafixerbuilder.addSchema(1936, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterOptionsAddTextBackground(schema89, false)); + Schema schema90 = datafixerbuilder.addSchema(1946, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterPOI(schema90, false)); + Schema schema91 = datafixerbuilder.addSchema(1948, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterOminousBannerRename(schema91, false)); + Schema schema92 = datafixerbuilder.addSchema(1953, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterOminousBannerBlockEntityRename(schema92, false)); + Schema schema93 = datafixerbuilder.addSchema(1955, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterVillagerLevelXp(schema93, false)); + datafixerbuilder.addFixer(new DataConverterZombieVillagerLevelXp(schema93, false)); + Schema schema94 = datafixerbuilder.addSchema(1961, DataConverterRegistry.b); + + datafixerbuilder.addFixer(new DataConverterChunkLightRemove(schema94, false)); } } diff --git a/src/main/java/net/minecraft/server/DataPalette.java b/src/main/java/net/minecraft/server/DataPalette.java index 2ee879196..45403fbe3 100644 --- a/src/main/java/net/minecraft/server/DataPalette.java +++ b/src/main/java/net/minecraft/server/DataPalette.java @@ -7,6 +7,8 @@ public interface DataPalette { default int getOrCreateIdFor(T object) { return this.a(object); } // Paper - OBFHELPER int a(T t0); + boolean b(T t0); + @Nullable default T getObject(int dataBits) { return this.a(dataBits); } // Paper - OBFHELPER @Nullable T a(int i); diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java index dcbcb655c..8fba1e2f3 100644 --- a/src/main/java/net/minecraft/server/DataPaletteBlock.java +++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java @@ -1,9 +1,12 @@ package net.minecraft.server; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2IntMap.Entry; import com.destroystokyo.paper.antixray.ChunkPacketInfo; // Paper - Anti-Xray import java.util.Arrays; import java.util.Objects; -import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; import java.util.stream.Collectors; @@ -21,43 +24,29 @@ public class DataPaletteBlock implements DataPaletteExpandable { protected DataBits a; protected DataBits getDataBits() { return this.a; } // Paper - OBFHELPER private DataPalette h; private DataPalette getDataPalette() { return this.h; } // Paper - OBFHELPER private int i; private int getBitsPerObject() { return this.i; } // Paper - OBFHELPER - // Paper start - use read write locks only during generation, disable once back on main thread - private static final NoopLock NOOP_LOCK = new NoopLock(); - private java.util.concurrent.locks.Lock readLock = NOOP_LOCK; - private java.util.concurrent.locks.Lock writeLock = NOOP_LOCK; + private final com.destroystokyo.paper.util.ReentrantLockWithGetOwner j = new com.destroystokyo.paper.util.ReentrantLockWithGetOwner(); private com.destroystokyo.paper.util.ReentrantLockWithGetOwner getLock() { return this.j; } // Paper - change type to ReentrantLockWithGetOwner // Paper - OBFHELPER - private static class NoopLock extends ReentrantReadWriteLock.WriteLock { - private NoopLock() { - super(new ReentrantReadWriteLock()); - } - - @Override - public final void lock() { - } - - @Override - public final void unlock() { + public void a() { + // Paper start - log other thread + Thread owningThread; + if (this.j.isLocked() && (owningThread = this.getLock().getOwner()) != null && owningThread != Thread.currentThread()) { + // Paper end + String s = (String) Thread.getAllStackTraces().keySet().stream().filter(Objects::nonNull).map((thread) -> { + return thread.getName() + ": \n\tat " + (String) Arrays.stream(thread.getStackTrace()).map(Object::toString).collect(Collectors.joining("\n\tat ")); + }).collect(Collectors.joining("\n")); + CrashReport crashreport = new CrashReport("Writing into PalettedContainer from multiple threads (other thread: name: " + owningThread.getName() + ", class: " + owningThread.getClass().toString() + ")", new IllegalStateException()); // Paper - log other thread + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Thread dumps"); + crashreportsystemdetails.a("Thread dumps", (Object) s); + throw new ReportedException(crashreport); + } else { + this.j.lock(); } } - synchronized void enableLocks() { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - readLock = lock.readLock(); - writeLock = lock.writeLock(); + public void b() { + this.j.unlock(); } - synchronized void disableLocks() { - readLock = NOOP_LOCK; - writeLock = NOOP_LOCK; - } - - private void b() { - writeLock.lock(); - } - private void c() { - writeLock.unlock(); - } - // Paper end public DataPaletteBlock(DataPalette datapalette, RegistryBlockID registryblockid, Function function, Function function1, T t0) { // Paper start - Anti-Xray - Support default constructor @@ -79,17 +68,12 @@ public class DataPaletteBlock implements DataPaletteExpandable { // Default this.initialize(4); } else { - // TODO: MathHelper.d(int i) can be used here instead (see DataPaletteBlock#a(NBTTagCompound nbttagcompound, String s, String s1)) but I don't understand the implementation + // MathHelper.d() is trailingBits(roundCeilPow2(n)), alternatively; (int)ceil(log2(n)); however it's trash, use numberOfLeadingZeros instead // Count the bits of the maximum array index to initialize a data palette with enough space from the beginning // The length of the array is used because air is also added to the data palette from the beginning // Start with at least 4 int maxIndex = predefinedObjects.length >> 4; - int bitCount = 4; - - while (maxIndex != 0) { - maxIndex >>= 1; - bitCount++; - } + int bitCount = (32 - Integer.numberOfLeadingZeros(Math.max(16, maxIndex) - 1)); // Initialize with at least 15 free indixes this.initialize((1 << bitCount) - predefinedObjects.length < 16 ? bitCount + 1 : bitCount); @@ -99,6 +83,16 @@ public class DataPaletteBlock implements DataPaletteExpandable { // Paper end } + // Paper start - Anti-Xray - Add predefined objects + private void addPredefinedObjects() { + if (this.predefinedObjects != null && this.getDataPalette() != this.getDataPaletteGlobal()) { + for (int i = 0; i < this.predefinedObjects.length; i++) { + this.getDataPalette().getOrCreateIdFor(this.predefinedObjects[i]); + } + } + } + // Paper end + private static int b(int i, int j, int k) { return j << 8 | k << 4 | i; } @@ -122,18 +116,9 @@ public class DataPaletteBlock implements DataPaletteExpandable { } } - // Paper start - Anti-Xray - Add predefined objects - private void addPredefinedObjects() { - if (this.predefinedObjects != null && this.getDataPalette() != this.getDataPaletteGlobal()) { - for (int i = 0; i < this.predefinedObjects.length; i++) { - this.getDataPalette().getOrCreateIdFor(this.predefinedObjects[i]); - } - } - } - // Paper end - + @Override public int onResize(int i, T t0) { - this.b(); + this.a(); DataBits databits = this.a; DataPalette datapalette = this.h; @@ -151,20 +136,34 @@ public class DataPaletteBlock implements DataPaletteExpandable { } j = this.h.a(t0); - this.c(); + this.b(); return j; } - public void setBlock(int i, int j, int k, T t0) { + public T setBlock(int i, int j, int k, T t0) { + this.a(); + T t1 = this.a(b(i, j, k), t0); + this.b(); - this.setBlockIndex(b(i, j, k), t0); - this.c(); + return t1; + } + + public T b(int i, int j, int k, T t0) { + return this.a(b(i, j, k), t0); + } + + protected T a(int i, T t0) { + int j = this.h.a(t0); + int k = this.a.a(i, j); + T t1 = this.h.a(k); + + return t1 == null ? this.g : t1; } protected void setBlockIndex(int i, T t0) { int j = this.h.a(t0); - this.a.a(i, j); + this.a.b(i, j); } public T a(int i, int j, int k) { @@ -172,25 +171,19 @@ public class DataPaletteBlock implements DataPaletteExpandable { } protected T a(int i) { - try { // Paper start - read lock - readLock.lock(); - T object = this.h.a(this.a.a(i)); // Paper - decompile fix - return (T)(object == null ? this.g : object); - } finally { - readLock.unlock(); - } // Paper end + T t0 = this.h.a(this.a.a(i)); + + return t0 == null ? this.g : t0; } - // Paper start - Anti-Xray - Support default methods - public void writeDataPaletteBlock(PacketDataSerializer packetDataSerializer) { this.b(packetDataSerializer); } + public void writeDataPaletteBlock(PacketDataSerializer packetDataSerializer) { this.b(packetDataSerializer); } // Paper - OBFHELPER public void b(PacketDataSerializer packetdataserializer) { - this.b(packetdataserializer, null, 0); + // Paper start - add parameters + this.writeDataPaletteBlock(packetdataserializer, null, 0); } - // Paper end - - public void writeDataPaletteBlock(PacketDataSerializer packetDataSerializer, ChunkPacketInfo chunkPacketInfo, int chunkSectionIndex) { this.b(packetDataSerializer, chunkPacketInfo, chunkSectionIndex); } // Paper - OBFHELPER // Paper - Anti-Xray - Add chunk packet info - public void b(PacketDataSerializer packetdataserializer, ChunkPacketInfo chunkPacketInfo, int chunkSectionIndex) { // Paper - Anti-Xray - Add chunk packet info - this.b(); + public void writeDataPaletteBlock(PacketDataSerializer packetdataserializer, ChunkPacketInfo chunkPacketInfo, int chunkSectionIndex) { + // Paper end + this.a(); packetdataserializer.writeByte(this.i); this.h.b(packetdataserializer); @@ -204,12 +197,11 @@ public class DataPaletteBlock implements DataPaletteExpandable { // Paper end packetdataserializer.a(this.a.a()); - this.c(); + this.b(); } - public void a(NBTTagCompound nbttagcompound, String s, String s1) { - this.b(); - NBTTagList nbttaglist = nbttagcompound.getList(s, 10); + public void a(NBTTagList nbttaglist, long[] along) { + this.a(); // Paper - Anti-Xray - TODO: Should this.predefinedObjects.length just be added here (faster) or should the contents be compared to calculate the size (less RAM)? int i = Math.max(4, MathHelper.d(nbttaglist.size() + (this.predefinedObjects == null ? 0 : this.predefinedObjects.length))); // Paper - Anti-Xray - Calculate the size with predefined objects @@ -219,7 +211,6 @@ public class DataPaletteBlock implements DataPaletteExpandable { this.h.a(nbttaglist); this.addPredefinedObjects(); // Paper - Anti-Xray - Add predefined objects - long[] along = nbttagcompound.o(s1); int j = along.length * 64 / 4096; if (this.h == this.b) { @@ -229,7 +220,7 @@ public class DataPaletteBlock implements DataPaletteExpandable { DataBits databits = new DataBits(i, 4096, along); for (int k = 0; k < 4096; ++k) { - this.a.a(k, this.b.a(datapalette.a(databits.a(k)))); + this.a.b(k, this.b.a(datapalette.a(databits.a(k)))); } } else if (j == this.i) { System.arraycopy(along, 0, this.a.a(), 0, along.length); @@ -237,15 +228,15 @@ public class DataPaletteBlock implements DataPaletteExpandable { DataBits databits1 = new DataBits(j, 4096, along); for (int l = 0; l < 4096; ++l) { - this.a.a(l, databits1.a(l)); + this.a.b(l, databits1.a(l)); } } - this.c(); + this.b(); } - public void b(NBTTagCompound nbttagcompound, String s, String s1) { - this.b(); + public void a(NBTTagCompound nbttagcompound, String s, String s1) { + this.a(); DataPaletteHash datapalettehash = new DataPaletteHash<>(this.d, this.i, this.c, this.e, this.f); datapalettehash.a(this.g); @@ -263,14 +254,35 @@ public class DataPaletteBlock implements DataPaletteExpandable { DataBits databits = new DataBits(j, 4096); for (int k = 0; k < aint.length; ++k) { - databits.a(k, aint[k]); + databits.b(k, aint[k]); } nbttagcompound.a(s1, databits.a()); - this.c(); + this.b(); } - public int a() { + public int c() { return 1 + this.h.a() + PacketDataSerializer.a(this.a.b()) + this.a.a().length * 8; } + + public boolean a(T t0) { + return this.h.b(t0); + } + + public void a(DataPaletteBlock.a datapaletteblock_a) { + Int2IntOpenHashMap int2intopenhashmap = new Int2IntOpenHashMap(); + + this.a.a((i) -> { + int2intopenhashmap.put(i, int2intopenhashmap.get(i) + 1); + }); + int2intopenhashmap.int2IntEntrySet().forEach((entry) -> { + datapaletteblock_a.accept(this.h.a(entry.getIntKey()), entry.getIntValue()); + }); + } + + @FunctionalInterface + public interface a { + + void accept(T t0, int i); + } } diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java index dba69b885..e6f39878e 100644 --- a/src/main/java/net/minecraft/server/DataWatcher.java +++ b/src/main/java/net/minecraft/server/DataWatcher.java @@ -2,9 +2,6 @@ package net.minecraft.server; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.koloboke.collect.map.hash.HashObjIntMap; -import com.koloboke.collect.map.hash.HashObjIntMaps; - import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.EncoderException; import java.io.IOException; @@ -12,59 +9,52 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.annotation.Nullable; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; // Paper import org.apache.commons.lang3.ObjectUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class DataWatcher { - private static final Logger a = LogManager.getLogger(); - private static final Map, Integer> b = HashObjIntMaps.newMutableMap(255); private static final HashObjIntMap> entityTypeToIdMap() { return (HashObjIntMap>) b; }// Akarin - private final Entity c; - private final Map> d = new ConcurrentHashMap>(255); // Paper // Akarin - private final ReadWriteLock e = new ReentrantReadWriteLock(); + private static final Logger LOGGER = LogManager.getLogger(); + private static final Map, Integer> b = Maps.newHashMap(); + private final Entity entity; + private final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap> entries = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); // Spigot - use better map // PAIL + // private final ReadWriteLock lock = new ReentrantReadWriteLock(); // Spigot - not required private boolean f = true; private boolean g; public DataWatcher(Entity entity) { - this.c = entity; + this.entity = entity; } public static DataWatcherObject a(Class oclass, DataWatcherSerializer datawatcherserializer) { - if (DataWatcher.a.isDebugEnabled()) { + if (DataWatcher.LOGGER.isDebugEnabled()) { try { Class oclass1 = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName()); if (!oclass1.equals(oclass)) { - DataWatcher.a.debug("defineId called for: {} from {}", oclass, oclass1, new RuntimeException()); + DataWatcher.LOGGER.debug("defineId called for: {} from {}", oclass, oclass1, new RuntimeException()); } } catch (ClassNotFoundException classnotfoundexception) { ; } } - // Akarin start - int i = entityTypeToIdMap().getOrDefault(oclass, -1); + int i; - if (i != -1) { - i = i + 1; - // Akarin end + if (DataWatcher.b.containsKey(oclass)) { + i = (Integer) DataWatcher.b.get(oclass) + 1; } else { int j = 0; Class oclass2 = oclass; while (oclass2 != Entity.class) { oclass2 = oclass2.getSuperclass(); - // Akarin start - int superId = entityTypeToIdMap().getOrDefault(oclass2, -1); - if (superId != -1) { - j = superId + 1; - // Akarin end + if (DataWatcher.b.containsKey(oclass2)) { + j = (Integer) DataWatcher.b.get(oclass2) + 1; break; } } @@ -80,12 +70,14 @@ public class DataWatcher { } } + boolean registrationLocked; // Spigot public void register(DataWatcherObject datawatcherobject, T t0) { + if (this.registrationLocked) throw new IllegalStateException("Registering datawatcher object after entity initialization"); // Spigot int i = datawatcherobject.a(); if (i > 254) { throw new IllegalArgumentException("Data value id is too big with " + i + "! (Max is " + 254 + ")"); - } else if (this.d.containsKey(i)) { + } else if (this.entries.containsKey(i)) { throw new IllegalArgumentException("Duplicate id value for " + i + "!"); } else if (DataWatcherRegistry.b(datawatcherobject.b()) < 0) { throw new IllegalArgumentException("Unregistered serializer " + datawatcherobject.b() + " for " + i + "!"); @@ -97,29 +89,35 @@ public class DataWatcher { private void registerObject(DataWatcherObject datawatcherobject, T t0) { DataWatcher.Item datawatcher_item = new DataWatcher.Item<>(datawatcherobject, t0); - //this.e.writeLock().lock(); // Akarin - this.d.put(datawatcherobject.a(), datawatcher_item); + // this.lock.writeLock().lock(); // Spigot - not required + this.entries.put(datawatcherobject.a(), datawatcher_item); this.f = false; - //this.e.writeLock().unlock(); // Akarin + // this.lock.writeLock().unlock(); // Spigot - not required } private DataWatcher.Item b(DataWatcherObject datawatcherobject) { - //this.e.readLock().lock(); // Akarin + // Spigot start + /* + this.lock.readLock().lock(); DataWatcher.Item datawatcher_item; try { - datawatcher_item = (DataWatcher.Item) this.d.get(datawatcherobject.a()); + datawatcher_item = (DataWatcher.Item) this.entries.get(datawatcherobject.a()); } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Getting synched entity data"); CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Synched entity data"); crashreportsystemdetails.a("Data ID", (Object) datawatcherobject); throw new ReportedException(crashreport); + } finally { + this.lock.readLock().unlock(); } - //this.e.readLock().unlock(); // Akarin return datawatcher_item; + */ + return (DataWatcher.Item) this.entries.get(datawatcherobject.a()); + // Spigot end } public T get(DataWatcherObject datawatcherobject) { @@ -131,7 +129,7 @@ public class DataWatcher { if (ObjectUtils.notEqual(t0, datawatcher_item.b())) { datawatcher_item.a(t0); - this.c.a(datawatcherobject); + this.entity.a(datawatcherobject); datawatcher_item.a(true); this.g = true; } @@ -166,8 +164,8 @@ public class DataWatcher { List> list = null; if (this.g) { - //this.e.readLock().lock(); // Akarin - Iterator iterator = this.d.values().iterator(); + // this.lock.readLock().lock(); // Spigot - not required + Iterator iterator = this.entries.values().iterator(); while (iterator.hasNext()) { DataWatcher.Item datawatcher_item = (DataWatcher.Item) iterator.next(); @@ -182,7 +180,7 @@ public class DataWatcher { } } - //this.e.readLock().unlock(); // Akarin + // this.lock.readLock().unlock(); // Spigot - not required } this.g = false; @@ -190,8 +188,8 @@ public class DataWatcher { } public void a(PacketDataSerializer packetdataserializer) throws IOException { - //this.e.readLock().lock(); // Akarin - Iterator iterator = this.d.values().iterator(); + // this.lock.readLock().lock(); // Spigot - not required + Iterator iterator = this.entries.values().iterator(); while (iterator.hasNext()) { DataWatcher.Item datawatcher_item = (DataWatcher.Item) iterator.next(); @@ -199,7 +197,7 @@ public class DataWatcher { a(packetdataserializer, datawatcher_item); } - //this.e.readLock().unlock(); // Akarin + // this.lock.readLock().unlock(); // Spigot - not required packetdataserializer.writeByte(255); } @@ -207,18 +205,18 @@ public class DataWatcher { public List> c() { List> list = null; - //this.e.readLock().lock(); // Akarin + // this.lock.readLock().lock(); // Spigot - not required DataWatcher.Item datawatcher_item; - for (Iterator iterator = this.d.values().iterator(); iterator.hasNext(); list.add(datawatcher_item.d())) { + for (Iterator iterator = this.entries.values().iterator(); iterator.hasNext(); list.add(datawatcher_item.d())) { datawatcher_item = (DataWatcher.Item) iterator.next(); if (list == null) { list = Lists.newArrayList(); } } - //this.e.readLock().unlock(); // Akarin + // this.lock.readLock().unlock(); // Spigot - not required return list; } @@ -246,7 +244,7 @@ public class DataWatcher { arraylist = Lists.newArrayList(); } - int i = packetdataserializer.g(); + int i = packetdataserializer.i(); DataWatcherSerializer datawatcherserializer = DataWatcherRegistry.a(i); if (datawatcherserializer == null) { @@ -269,8 +267,8 @@ public class DataWatcher { public void e() { this.g = false; - //this.e.readLock().lock(); // Akarin - Iterator iterator = this.d.values().iterator(); + // this.lock.readLock().lock(); // Spigot - not required + Iterator iterator = this.entries.values().iterator(); while (iterator.hasNext()) { DataWatcher.Item datawatcher_item = (DataWatcher.Item) iterator.next(); @@ -278,7 +276,7 @@ public class DataWatcher { datawatcher_item.a(false); } - //this.e.readLock().unlock(); // Akarin + // this.lock.readLock().unlock(); // Spigot - not required } public static class Item { diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java index 04a6c8172..5bc19cd08 100644 --- a/src/main/java/net/minecraft/server/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/DedicatedServer.java @@ -1,7 +1,9 @@ package net.minecraft.server; +import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.gson.JsonObject; +import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfileRepository; import com.mojang.authlib.minecraft.MinecraftSessionService; import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; @@ -17,9 +19,11 @@ import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Random; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.function.BooleanSupplier; import java.util.regex.Pattern; +import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -38,21 +42,22 @@ import org.bukkit.event.server.RemoteServerCommandEvent; public class DedicatedServer extends MinecraftServer implements IMinecraftServer { private static final Logger LOGGER = LogManager.getLogger(); - private static final Pattern h = Pattern.compile("^[a-fA-F0-9]{40}$"); + private static final Pattern i = Pattern.compile("^[a-fA-F0-9]{40}$"); private final java.util.Queue serverCommandQueue = new java.util.concurrent.ConcurrentLinkedQueue(); // Paper - use a proper queue - private RemoteStatusListener j; - public final RemoteControlCommandListener remoteControlCommandListener = new RemoteControlCommandListener(this); - private RemoteControlListener l; - public PropertyManager propertyManager; - private EULA eula; - private boolean generateStructures; - private EnumGamemode p; - private boolean q; + private RemoteStatusListener remoteStatusListener; + public final RemoteControlCommandListener remoteControlCommandListener; + private RemoteControlListener remoteControlListener; + public DedicatedServerSettings propertyManager; + private EnumGamemode o; + @Nullable + private ServerGUI p; // CraftBukkit start - Signature changed - public DedicatedServer(joptsimple.OptionSet options, DataFixer datafixer, YggdrasilAuthenticationService yggdrasilauthenticationservice, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache) { - super(options, Proxy.NO_PROXY, datafixer, new CommandDispatcher().init(true), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, usercache); + public DedicatedServer(joptsimple.OptionSet options, DedicatedServerSettings dedicatedserversettings, DataFixer datafixer, YggdrasilAuthenticationService yggdrasilauthenticationservice, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache, WorldLoadListenerFactory worldloadlistenerfactory, String s) { + super(options, Proxy.NO_PROXY, datafixer, new CommandDispatcher().init(true), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, usercache, worldloadlistenerfactory, s); // CraftBukkit end + this.propertyManager = dedicatedserversettings; + this.remoteControlCommandListener = new RemoteControlCommandListener(this); Thread thread = new Thread("Server Infinisleeper") { { this.setDaemon(true); @@ -72,7 +77,8 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer }; } - public boolean init() throws IOException { // CraftBukkit - decompile error + @Override + public boolean init() throws IOException { Thread thread = new Thread("Server console handler") { public void run() { // CraftBukkit start @@ -95,7 +101,17 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer } else { s = bufferedreader.readLine(); } - if (s != null && s.trim().length() > 0) { // Trim to filter lines which are just spaces + + // SPIGOT-5220: Throttle if EOF (ctrl^d) or stdin is /dev/null + if (s == null) { + try { + Thread.sleep(50L); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + continue; + } + if (s.trim().length() > 0) { // Trim to filter lines which are just spaces DedicatedServer.this.issueCommand(s, DedicatedServer.this.getServerCommandListener()); } // CraftBukkit end @@ -127,7 +143,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer } } - new Thread(new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader)).start(); + new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader).start(); */ // Paper end @@ -140,285 +156,232 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer thread.setDaemon(true); thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(DedicatedServer.LOGGER)); thread.start(); - DedicatedServer.LOGGER.info("Starting minecraft server version 1.13.2"); + DedicatedServer.LOGGER.info("Starting minecraft server version " + SharedConstants.a().getName()); if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) { DedicatedServer.LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); } DedicatedServer.LOGGER.info("Loading properties"); - this.propertyManager = new PropertyManager(this.options); // CraftBukkit - CLI argument support - this.eula = new EULA(new File("eula.txt")); - // Spigot Start - boolean eulaAgreed = Boolean.getBoolean( "com.mojang.eula.agree" ); - if ( eulaAgreed ) - { - System.err.println( "You have used the Spigot command line EULA agreement flag." ); - System.err.println( "By using this setting you are indicating your agreement to Mojang's EULA (https://account.mojang.com/documents/minecraft_eula)." ); - System.err.println( "If you do not agree to the above EULA please stop your server and remove this flag immediately." ); + DedicatedServerProperties dedicatedserverproperties = this.propertyManager.getProperties(); + + if (this.isEmbeddedServer()) { + this.b("127.0.0.1"); + } else { + this.setOnlineMode(dedicatedserverproperties.onlineMode); + this.h(dedicatedserverproperties.preventProxyConnections); + this.b(dedicatedserverproperties.serverIp); } - // Spigot End - if (false && !this.eula.a() && !eulaAgreed) { // Spigot // Akarin - DedicatedServer.LOGGER.info("You need to agree to the EULA in order to run the server. Go to eula.txt for more info."); - this.eula.b(); + // Spigot start + this.a((PlayerList) (new DedicatedPlayerList(this))); + org.spigotmc.SpigotConfig.init((File) options.valueOf("spigot-settings")); + org.spigotmc.SpigotConfig.registerCommands(); + // Spigot end + // Paper start + try { + com.destroystokyo.paper.PaperConfig.init((File) options.valueOf("paper-settings")); + } catch (Exception e) { + DedicatedServer.LOGGER.error("Unable to load server configuration", e); + return false; + } + com.destroystokyo.paper.PaperConfig.registerCommands(); + com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now + // Paper end + + this.setSpawnAnimals(dedicatedserverproperties.spawnAnimals); + this.setSpawnNPCs(dedicatedserverproperties.spawnNpcs); + this.setPVP(dedicatedserverproperties.pvp); + this.setAllowFlight(dedicatedserverproperties.allowFlight); + this.setResourcePack(dedicatedserverproperties.resourcePack, this.aW()); + this.setMotd(dedicatedserverproperties.motd); + this.setForceGamemode(dedicatedserverproperties.forceGamemode); + super.setIdleTimeout((Integer) dedicatedserverproperties.playerIdleTimeout.get()); + this.n(dedicatedserverproperties.enforceWhitelist); + this.o = dedicatedserverproperties.gamemode; + DedicatedServer.LOGGER.info("Default game type: {}", this.o); + InetAddress inetaddress = null; + + if (!this.getServerIp().isEmpty()) { + inetaddress = InetAddress.getByName(this.getServerIp()); + } + + if (this.getPort() < 0) { + this.setPort(dedicatedserverproperties.serverPort); + } + + DedicatedServer.LOGGER.info("Generating keypair"); + this.a(MinecraftEncryption.b()); + DedicatedServer.LOGGER.info("Starting Minecraft server on {}:{}", this.getServerIp().isEmpty() ? "*" : this.getServerIp(), this.getPort()); + + try { + this.getServerConnection().a(inetaddress, this.getPort()); + } catch (IOException ioexception) { + DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!"); + DedicatedServer.LOGGER.warn("The exception was: {}", ioexception.toString()); + DedicatedServer.LOGGER.warn("Perhaps a server is already running on that port?"); + return false; + } + + // CraftBukkit start + // this.a((PlayerList) (new DedicatedPlayerList(this))); // Spigot - moved up + server.loadPlugins(); + server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP); + // CraftBukkit end + + if (!this.getOnlineMode()) { + DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); + DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware."); + // Spigot start + if (org.spigotmc.SpigotConfig.bungee) { + DedicatedServer.LOGGER.warn("Whilst this makes it possible to use BungeeCord, unless access to your server is properly restricted, it also opens up the ability for hackers to connect with any username they choose."); + DedicatedServer.LOGGER.warn("Please see http://www.spigotmc.org/wiki/firewall-guide/ for further information."); + } else { + DedicatedServer.LOGGER.warn("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose."); + } + // Spigot end + DedicatedServer.LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); + } + + if (this.convertNames()) { + this.getUserCache().c(); + } + + if (!NameReferencingFileConverter.e(this)) { return false; } else { - if (this.H()) { - this.b("127.0.0.1"); - } else { - this.setOnlineMode(this.propertyManager.getBoolean("online-mode", true)); - UserCache.a(this.propertyManager.getBoolean("online-mode", true)); // Akarin - this.f(this.propertyManager.getBoolean("prevent-proxy-connections", false)); - this.b(this.propertyManager.getString("server-ip", "")); - } + this.convertable = new Convertable(server.getWorldContainer().toPath(), server.getWorldContainer().toPath().resolve("../backups"), this.dataConverterManager); // CraftBukkit - moved from MinecraftServer constructor + long i = SystemUtils.getMonotonicNanos(); + String s = dedicatedserverproperties.levelSeed; + String s1 = dedicatedserverproperties.generatorSettings; + long j = (new Random()).nextLong(); - this.setSpawnAnimals(this.propertyManager.getBoolean("spawn-animals", true)); - this.setSpawnNPCs(this.propertyManager.getBoolean("spawn-npcs", true)); - this.setPVP(this.propertyManager.getBoolean("pvp", true)); - this.setAllowFlight(this.propertyManager.getBoolean("allow-flight", false)); - this.setResourcePack(this.propertyManager.getString("resource-pack", ""), this.aT()); - this.setMotd(this.propertyManager.getString("motd", "A Minecraft Server")); - this.setForceGamemode(this.propertyManager.getBoolean("force-gamemode", false)); - this.setIdleTimeout(this.propertyManager.getInt("player-idle-timeout", 0)); - this.l(this.propertyManager.getBoolean("enforce-whitelist", false)); - if (this.propertyManager.getInt("difficulty", 1) < 0) { - this.propertyManager.setProperty("difficulty", 0); - } else if (this.propertyManager.getInt("difficulty", 1) > 3) { - this.propertyManager.setProperty("difficulty", 3); - } + if (!s.isEmpty()) { + try { + long k = Long.parseLong(s); - this.generateStructures = this.propertyManager.getBoolean("generate-structures", true); - int i = this.propertyManager.getInt("gamemode", EnumGamemode.SURVIVAL.getId()); - - this.p = WorldSettings.a(i); - DedicatedServer.LOGGER.info("Default game type: {}", this.p); - InetAddress inetaddress = null; - - if (!this.getServerIp().isEmpty()) { - inetaddress = InetAddress.getByName(this.getServerIp()); - } - - if (this.getPort() < 0) { - this.setPort(this.propertyManager.getInt("server-port", 25565)); - } - // Spigot start - this.a((PlayerList) (new DedicatedPlayerList(this))); - org.spigotmc.SpigotConfig.init((File) options.valueOf("spigot-settings")); - org.spigotmc.SpigotConfig.registerCommands(); - // Spigot end - // Paper start - try { - com.destroystokyo.paper.PaperConfig.init((File) options.valueOf("paper-settings")); - } catch (Exception e) { - DedicatedServer.LOGGER.error("Unable to load server configuration", e); - return false; - } - com.destroystokyo.paper.PaperConfig.registerCommands(); - com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now - // Paper end - - DedicatedServer.LOGGER.info("Generating keypair"); - this.a(MinecraftEncryption.b()); - DedicatedServer.LOGGER.info("Starting Minecraft server on {}:{}", this.getServerIp().isEmpty() ? "*" : this.getServerIp(), this.getPort()); - - if (!org.spigotmc.SpigotConfig.lateBind) { - try { - this.getServerConnection().a(inetaddress, this.getPort()); - } catch (IOException ioexception) { - DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!"); - DedicatedServer.LOGGER.warn("The exception was: {}", ioexception.toString()); - DedicatedServer.LOGGER.warn("Perhaps a server is already running on that port?"); - return false; - } - } - - // CraftBukkit start - // this.a((PlayerList) (new DedicatedPlayerList(this))); // Spigot - moved up - server.loadPlugins(); - server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP); - // CraftBukkit end - - if (!this.getOnlineMode()) { - DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); - DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware."); - // Spigot start - if (org.spigotmc.SpigotConfig.bungee) { - DedicatedServer.LOGGER.warn("Whilst this makes it possible to use BungeeCord, unless access to your server is properly restricted, it also opens up the ability for hackers to connect with any username they choose."); - DedicatedServer.LOGGER.warn("Please see http://www.spigotmc.org/wiki/firewall-guide/ for further information."); - } else { - DedicatedServer.LOGGER.warn("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose."); - } - // Spigot end - DedicatedServer.LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); - } - - if (this.aX()) { - this.getModernUserCache().load(); // Akarin - } - - if (!NameReferencingFileConverter.a(this.propertyManager)) { - return false; - } else { - this.convertable = new WorldLoaderServer(server.getWorldContainer().toPath(), server.getWorldContainer().toPath().resolve("../backups"), this.dataConverterManager); // CraftBukkit - moved from MinecraftServer constructor - long j = SystemUtils.getMonotonicNanos(); - - if (this.getWorld() == null) { - this.setWorld(this.propertyManager.getString("level-name", "world")); - } - - String s = this.propertyManager.getString("level-seed", ""); - String s1 = this.propertyManager.getString("level-type", "DEFAULT"); - String s2 = this.propertyManager.getString("generator-settings", ""); - long k = (new Random()).nextLong(); - - if (!s.isEmpty()) { - try { - long l = Long.parseLong(s); - - if (l != 0L) { - k = l; - } - } catch (NumberFormatException numberformatexception) { - k = (long) s.hashCode(); + if (k != 0L) { + j = k; } + } catch (NumberFormatException numberformatexception) { + j = (long) s.hashCode(); } + } - WorldType worldtype = WorldType.getType(s1); + WorldType worldtype = dedicatedserverproperties.levelType; - if (worldtype == null) { - worldtype = WorldType.NORMAL; - } - - this.getEnableCommandBlock(); - this.j(); - this.getSnooperEnabled(); - this.aw(); - this.b(this.propertyManager.getInt("max-build-height", 256)); - this.b((this.getMaxBuildHeight() + 8) / 16 * 16); - this.b(MathHelper.clamp(this.getMaxBuildHeight(), 64, 256)); - this.propertyManager.setProperty("max-build-height", this.getMaxBuildHeight()); - TileEntitySkull.a(this.getUserCache()); - TileEntitySkull.a(this.ap()); - //UserCache.a(this.getOnlineMode()); // Akarin - DedicatedServer.LOGGER.info("Preparing level \"{}\"", this.getWorld()); - JsonObject jsonobject = new JsonObject(); - - if (worldtype == WorldType.FLAT) { - jsonobject.addProperty("flat_world_options", s2); - } else if (!s2.isEmpty()) { - // CraftBukkit start - try { - jsonobject = ChatDeserializer.a(s2); - } catch (Exception ex) { - DedicatedServer.LOGGER.warn("Invalid generator-settings, ignoring", ex); - } - // CraftBukkit end - } - - this.a(this.getWorld(), this.getWorld(), k, worldtype, jsonobject); - long i1 = SystemUtils.getMonotonicNanos() - j; - String s3 = String.format(Locale.ROOT, "%.3fs", (double) i1 / 1.0E9D); - - DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s3); - if (this.propertyManager.a("announce-player-achievements")) { - this.getGameRules().set("announceAdvancements", this.propertyManager.getBoolean("announce-player-achievements", true) ? "true" : "false", this); - this.propertyManager.b("announce-player-achievements"); - this.propertyManager.savePropertiesFile(); - } - - if (this.propertyManager.getBoolean("enable-query", false)) { - DedicatedServer.LOGGER.info("Starting GS4 status listener"); - this.j = new RemoteStatusListener(this); - this.j.a(); - } - - if (this.propertyManager.getBoolean("enable-rcon", false)) { - DedicatedServer.LOGGER.info("Starting remote control listener"); - this.l = new RemoteControlListener(this); - this.l.a(); - this.remoteConsole = new org.bukkit.craftbukkit.command.CraftRemoteConsoleCommandSender(this.remoteControlCommandListener); // CraftBukkit - } + this.b(dedicatedserverproperties.maxBuildHeight); + TileEntitySkull.a(this.getUserCache()); + TileEntitySkull.a(this.getMinecraftSessionService()); + UserCache.a(this.getOnlineMode()); + DedicatedServer.LOGGER.info("Preparing level \"{}\"", this.getWorld()); + JsonObject jsonobject = new JsonObject(); + if (worldtype == WorldType.FLAT) { + jsonobject.addProperty("flat_world_options", s1); + } else if (!s1.isEmpty()) { // CraftBukkit start - if (this.server.getBukkitSpawnRadius() > -1) { - DedicatedServer.LOGGER.info("'settings.spawn-radius' in bukkit.yml has been moved to 'spawn-protection' in server.properties. I will move your config for you."); - this.propertyManager.properties.remove("spawn-protection"); - this.propertyManager.getInt("spawn-protection", this.server.getBukkitSpawnRadius()); - this.server.removeBukkitSpawnRadius(); - this.propertyManager.savePropertiesFile(); + try { + jsonobject = ChatDeserializer.a(s1); + } catch (Exception ex) { + DedicatedServer.LOGGER.warn("Invalid generator-settings, ignoring", ex); } // CraftBukkit end - - if (org.spigotmc.SpigotConfig.lateBind) { - try { - this.getServerConnection().a(inetaddress, this.getPort()); - } catch (IOException ioexception) { - DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!"); - DedicatedServer.LOGGER.warn("The exception was: {}", ioexception.toString()); - DedicatedServer.LOGGER.warn("Perhaps a server is already running on that port?"); - return false; } - } - if (false && this.getMaxTickTime() > 0L) { // Spigot - disable - Thread thread1 = new Thread(new ThreadWatchdog(this)); + this.a(this.getWorld(), this.getWorld(), j, worldtype, jsonobject); + long l = SystemUtils.getMonotonicNanos() - i; + String s2 = String.format(Locale.ROOT, "%.3fs", (double) l / 1.0E9D); - thread1.setUncaughtExceptionHandler(new ThreadNamedUncaughtExceptionHandler(DedicatedServer.LOGGER)); - thread1.setName("Server Watchdog"); - thread1.setDaemon(true); - thread1.start(); - } - - Items.AIR.a(CreativeModeTab.g, NonNullList.a()); - return true; + DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s2); + if (dedicatedserverproperties.announcePlayerAchievements != null) { + ((GameRules.GameRuleBoolean) this.getGameRules().get(GameRules.ANNOUNCE_ADVANCEMENTS)).a(dedicatedserverproperties.announcePlayerAchievements, (MinecraftServer) this); } + + if (dedicatedserverproperties.enableQuery) { + DedicatedServer.LOGGER.info("Starting GS4 status listener"); + this.remoteStatusListener = new RemoteStatusListener(this); + this.remoteStatusListener.a(); + } + + if (dedicatedserverproperties.enableRcon) { + DedicatedServer.LOGGER.info("Starting remote control listener"); + this.remoteControlListener = new RemoteControlListener(this); + this.remoteControlListener.a(); + this.remoteConsole = new org.bukkit.craftbukkit.command.CraftRemoteConsoleCommandSender(this.remoteControlCommandListener); // CraftBukkit + } + + if (false && this.getMaxTickTime() > 0L) { // Spigot - disable + Thread thread1 = new Thread(new ThreadWatchdog(this)); + + thread1.setUncaughtExceptionHandler(new ThreadNamedUncaughtExceptionHandler(DedicatedServer.LOGGER)); + thread1.setName("Server Watchdog"); + thread1.setDaemon(true); + thread1.start(); + } + + Items.AIR.a(CreativeModeTab.g, NonNullList.a()); + return true; } } - public String aT() { - if (this.propertyManager.a("resource-pack-hash")) { - if (this.propertyManager.a("resource-pack-sha1")) { + public String aW() { + DedicatedServerProperties dedicatedserverproperties = this.propertyManager.getProperties(); + String s; + + if (!dedicatedserverproperties.resourcePackSha1.isEmpty()) { + s = dedicatedserverproperties.resourcePackSha1; + if (!Strings.isNullOrEmpty(dedicatedserverproperties.resourcePackHash)) { DedicatedServer.LOGGER.warn("resource-pack-hash is deprecated and found along side resource-pack-sha1. resource-pack-hash will be ignored."); - } else { - DedicatedServer.LOGGER.warn("resource-pack-hash is deprecated. Please use resource-pack-sha1 instead."); - this.propertyManager.getString("resource-pack-sha1", this.propertyManager.getString("resource-pack-hash", "")); - this.propertyManager.b("resource-pack-hash"); } + } else if (!Strings.isNullOrEmpty(dedicatedserverproperties.resourcePackHash)) { + DedicatedServer.LOGGER.warn("resource-pack-hash is deprecated. Please use resource-pack-sha1 instead."); + s = dedicatedserverproperties.resourcePackHash; + } else { + s = ""; } - String s = this.propertyManager.getString("resource-pack-sha1", ""); - - if (!s.isEmpty() && !DedicatedServer.h.matcher(s).matches()) { + if (!s.isEmpty() && !DedicatedServer.i.matcher(s).matches()) { DedicatedServer.LOGGER.warn("Invalid sha1 for ressource-pack-sha1"); } - if (!this.propertyManager.getString("resource-pack", "").isEmpty() && s.isEmpty()) { + if (!dedicatedserverproperties.resourcePack.isEmpty() && s.isEmpty()) { DedicatedServer.LOGGER.warn("You specified a resource pack without providing a sha1 hash. Pack will be updated on the client only if you change the name of the pack."); } return s; } + @Override public void setGamemode(EnumGamemode enumgamemode) { super.setGamemode(enumgamemode); - this.p = enumgamemode; + this.o = enumgamemode; } + @Override + public DedicatedServerProperties getDedicatedServerProperties() { + return this.propertyManager.getProperties(); + } + + @Override public boolean getGenerateStructures() { - return this.generateStructures; + return this.getDedicatedServerProperties().generateStructures; } + @Override public EnumGamemode getGamemode() { - return this.p; + return this.o; } + @Override public EnumDifficulty getDifficulty() { - return EnumDifficulty.getById(this.propertyManager.getInt("difficulty", EnumDifficulty.NORMAL.a())); + return this.getDedicatedServerProperties().difficulty; } + @Override public boolean isHardcore() { - return this.propertyManager.getBoolean("hardcore", false); + return this.getDedicatedServerProperties().hardcore; } + @Override public CrashReport b(CrashReport crashreport) { crashreport = super.b(crashreport); crashreport.g().a("Is Modded", () -> { @@ -432,43 +395,52 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer return crashreport; } - public void t() { // CraftBukkit - decompile error - System.exit(0); + @Override + public void exit() { + if (this.p != null) { + this.p.b(); + } + + if (this.remoteControlListener != null) { + this.remoteControlListener.b(); + } + + if (this.remoteStatusListener != null) { + this.remoteStatusListener.b(); + } + + System.exit(0); // CraftBukkit } - public void b(BooleanSupplier booleansupplier) { // CraftBukkit - fix decompile error + @Override + public void b(BooleanSupplier booleansupplier) { super.b(booleansupplier); this.handleCommandQueue(); } + @Override public boolean getAllowNether() { - return this.propertyManager.getBoolean("allow-nether", true); + return this.getDedicatedServerProperties().allowNether; } + @Override public boolean getSpawnMonsters() { - return this.propertyManager.getBoolean("spawn-monsters", true); + return this.getDedicatedServerProperties().spawnMonsters; } + @Override public void a(MojangStatisticsGenerator mojangstatisticsgenerator) { mojangstatisticsgenerator.a("whitelist_enabled", this.getPlayerList().getHasWhitelist()); mojangstatisticsgenerator.a("whitelist_count", this.getPlayerList().getWhitelisted().length); super.a(mojangstatisticsgenerator); } - public boolean getSnooperEnabled() { - if (this.propertyManager.getBoolean("snooper-enabled", true)) { - ; - } - - return false; - } - public void issueCommand(String s, CommandListenerWrapper commandlistenerwrapper) { this.serverCommandQueue.add(new ServerCommand(s, commandlistenerwrapper)); } public void handleCommandQueue() { - MinecraftTimings.serverCommandTimer.startTimingUnsafe(); // Spigot + MinecraftTimings.serverCommandTimer.startTiming(); // Spigot // Paper start - use proper queue ServerCommand servercommand; while ((servercommand = this.serverCommandQueue.poll()) != null) { @@ -485,84 +457,72 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer // CraftBukkit end } - MinecraftTimings.serverCommandTimer.stopTimingUnsafe(); // Spigot + MinecraftTimings.serverCommandTimer.stopTiming(); // Spigot } - public boolean Q() { + @Override + public boolean S() { return true; } - public boolean V() { - return this.propertyManager.getBoolean("use-native-transport", true); + @Override + public boolean X() { + return this.getDedicatedServerProperties().useNativeTransport; } + @Override public DedicatedPlayerList getPlayerList() { return (DedicatedPlayerList) super.getPlayerList(); } - public boolean ad() { + @Override + public boolean af() { return true; } - public int a(String s, int i) { - return this.propertyManager.getInt(s, i); - } - - public String a(String s, String s1) { - return this.propertyManager.getString(s, s1); - } - - public boolean a(String s, boolean flag) { - return this.propertyManager.getBoolean(s, flag); - } - - public void a(String s, Object object) { - this.propertyManager.setProperty(s, object); - } - - public void c_() { - this.propertyManager.savePropertiesFile(); - } - - public String d_() { - File file = this.propertyManager.c(); - - return file != null ? file.getAbsolutePath() : "No settings file"; - } - - public String e() { + @Override + public String e_() { return this.getServerIp(); } - public int e_() { + @Override + public int e() { return this.getPort(); } - public String m() { + @Override + public String f_() { return this.getMotd(); } - public void aW() { - ServerGUI.a(this); - this.q = true; + public void aZ() { + if (this.p == null) { + this.p = ServerGUI.a(this); + } + } - public boolean ag() { - return this.q; + @Override + public boolean ai() { + return this.p != null; } + @Override public boolean a(EnumGamemode enumgamemode, boolean flag, int i) { return false; } + @Override public boolean getEnableCommandBlock() { - return this.propertyManager.getBoolean("enable-command-block", false); + return this.getDedicatedServerProperties().enableCommandBlock; } + @Override public int getSpawnProtection() { - return this.propertyManager.getInt("spawn-protection", super.getSpawnProtection()); + return this.getDedicatedServerProperties().spawnProtection; } + @Override public boolean a(World world, BlockPosition blockposition, EntityHuman entityhuman) { if (world.worldProvider.getDimensionManager() != DimensionManager.OVERWORLD) { return false; @@ -582,41 +542,45 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer } } + @Override public int j() { - return this.propertyManager.getInt("op-permission-level", 4); + return this.getDedicatedServerProperties().opPermissionLevel; } + @Override + public int k() { + return this.getDedicatedServerProperties().functionPermissionLevel; + } + + @Override public void setIdleTimeout(int i) { super.setIdleTimeout(i); - this.propertyManager.setProperty("player-idle-timeout", i); - this.c_(); + this.propertyManager.setProperty((dedicatedserverproperties) -> { + return (DedicatedServerProperties) dedicatedserverproperties.playerIdleTimeout.set(i); + }); } - public boolean k() { - return this.propertyManager.getBoolean("broadcast-rcon-to-ops", true); + @Override + public boolean l() { + return this.getDedicatedServerProperties().broadcastRconToOps; } - public boolean B_() { - return this.propertyManager.getBoolean("broadcast-console-to-ops", true); - } - - public int au() { - int i = this.propertyManager.getInt("max-world-size", super.au()); - - if (i < 1) { - i = 1; - } else if (i > super.au()) { - i = super.au(); - } - - return i; + @Override + public boolean shouldBroadcastCommands() { + return this.getDedicatedServerProperties().broadcastConsoleToOps; } + @Override public int aw() { - return this.propertyManager.getInt("network-compression-threshold", super.aw()); + return this.getDedicatedServerProperties().maxWorldSize; } - protected boolean aX() { + @Override + public int az() { + return this.getDedicatedServerProperties().networkCompressionThreshold; + } + + protected boolean convertNames() { boolean flag = false; int i; @@ -624,7 +588,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer for (i = 0; !flag && i <= 2; ++i) { if (i > 0) { DedicatedServer.LOGGER.warn("Encountered a problem while converting the user banlist, retrying in a few seconds"); - this.ba(); + this.bk(); } flag = NameReferencingFileConverter.a((MinecraftServer) this); @@ -635,7 +599,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer for (i = 0; !flag1 && i <= 2; ++i) { if (i > 0) { DedicatedServer.LOGGER.warn("Encountered a problem while converting the ip banlist, retrying in a few seconds"); - this.ba(); + this.bk(); } flag1 = NameReferencingFileConverter.b((MinecraftServer) this); @@ -646,7 +610,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer for (i = 0; !flag2 && i <= 2; ++i) { if (i > 0) { DedicatedServer.LOGGER.warn("Encountered a problem while converting the op list, retrying in a few seconds"); - this.ba(); + this.bk(); } flag2 = NameReferencingFileConverter.c((MinecraftServer) this); @@ -657,10 +621,10 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer for (i = 0; !flag3 && i <= 2; ++i) { if (i > 0) { DedicatedServer.LOGGER.warn("Encountered a problem while converting the whitelist, retrying in a few seconds"); - this.ba(); + this.bk(); } - flag3 = NameReferencingFileConverter.d((MinecraftServer) this); + flag3 = NameReferencingFileConverter.d(this); } boolean flag4 = false; @@ -668,16 +632,16 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer for (i = 0; !flag4 && i <= 2; ++i) { if (i > 0) { DedicatedServer.LOGGER.warn("Encountered a problem while converting the player save files, retrying in a few seconds"); - this.ba(); + this.bk(); } - flag4 = NameReferencingFileConverter.a(this, this.propertyManager); + flag4 = NameReferencingFileConverter.a(this); } return flag || flag1 || flag2 || flag3 || flag4; } - private void ba() { + private void bk() { try { Thread.sleep(5000L); } catch (InterruptedException interruptedexception) { @@ -686,9 +650,10 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer } public long getMaxTickTime() { - return this.propertyManager.getLong("max-tick-time", TimeUnit.MINUTES.toMillis(1L)); + return this.getDedicatedServerProperties().maxTickTime; } + @Override public String getPlugins() { // CraftBukkit start - Whole method StringBuilder result = new StringBuilder(); @@ -716,53 +681,74 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer // CraftBukkit end } - // CraftBukkit start - fire RemoteServerCommandEvent - public String executeRemoteCommand(final String s) { - Waitable waitable = new Waitable() { - @Override - protected String evaluate() { - remoteControlCommandListener.clearMessages(); - // Event changes start - RemoteServerCommandEvent event = new RemoteServerCommandEvent(remoteConsole, s); - server.getPluginManager().callEvent(event); - if (event.isCancelled()) { - return ""; - } - // Event change end - ServerCommand serverCommand = new ServerCommand(event.getCommand(), remoteControlCommandListener.f()); - server.dispatchServerCommand(remoteConsole, serverCommand); - return remoteControlCommandListener.getMessages(); + @Override + public String executeRemoteCommand(String s) { + Waitable[] waitableArray = new Waitable[1]; + this.remoteControlCommandListener.clearMessages(); + this.executeSync(() -> { + // CraftBukkit start - fire RemoteServerCommandEvent + RemoteServerCommandEvent event = new RemoteServerCommandEvent(remoteConsole, s); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; } - }; + // Paper start + if (s.toLowerCase().startsWith("timings") && s.toLowerCase().matches("timings (report|paste|get|merged|seperate)")) { + org.bukkit.command.BufferedCommandSender sender = new org.bukkit.command.BufferedCommandSender(); + Waitable waitable = new Waitable() { + @Override + protected String evaluate() { + return sender.getBuffer(); + } + }; + waitableArray[0] = waitable; + co.aikar.timings.Timings.generateReport(new co.aikar.timings.TimingsReportListener(sender, waitable)); + } else { + // Paper end + ServerCommand serverCommand = new ServerCommand(event.getCommand(), remoteControlCommandListener.getWrapper()); + server.dispatchServerCommand(remoteConsole, serverCommand); + } // Paper + // CraftBukkit end + }); // Paper start - if (s.toLowerCase().startsWith("timings") && s.toLowerCase().matches("timings (report|paste|get|merged|seperate)")) { - org.bukkit.command.BufferedCommandSender sender = new org.bukkit.command.BufferedCommandSender(); - waitable = new Waitable() { - @Override - protected String evaluate() { - return sender.getBuffer(); - } - }; - co.aikar.timings.Timings.generateReport(new co.aikar.timings.TimingsReportListener(sender, waitable)); - } else { - processQueue.add(waitable); + if (waitableArray[0] != null) { + //noinspection unchecked + Waitable waitable = waitableArray[0]; + try { + return waitable.get(); + } catch (java.util.concurrent.ExecutionException e) { + throw new RuntimeException("Exception processing rcon command " + s, e.getCause()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // Maintain interrupted state + throw new RuntimeException("Interrupted processing rcon command " + s, e); + } + } // Paper end - try { - return waitable.get(); - } catch (java.util.concurrent.ExecutionException e) { - throw new RuntimeException("Exception processing rcon command " + s, e.getCause()); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // Maintain interrupted state - throw new RuntimeException("Interrupted processing rcon command " + s, e); - } - // CraftBukkit end + return this.remoteControlCommandListener.getMessages(); + } + + public void setHasWhitelist(boolean flag) { + this.propertyManager.setProperty((dedicatedserverproperties) -> { + return (DedicatedServerProperties) dedicatedserverproperties.whiteList.set(flag); + }); + } + + @Override + public void stop() { + super.stop(); + SystemUtils.f(); + } + + @Override + public boolean b(GameProfile gameprofile) { + return false; } // CraftBukkit start @Override - public PropertyManager getPropertyManager() { - return this.propertyManager; + public boolean isDebugging() { + return this.getDedicatedServerProperties().debug; } @Override diff --git a/src/main/java/net/minecraft/server/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/DedicatedServerProperties.java new file mode 100644 index 000000000..0c3ec8357 --- /dev/null +++ b/src/main/java/net/minecraft/server/DedicatedServerProperties.java @@ -0,0 +1,121 @@ +package net.minecraft.server; + +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import joptsimple.OptionSet; // CraftBukkit + +public class DedicatedServerProperties extends PropertyManager { + + public final boolean debug = this.getBoolean("debug", false); // CraftBukkit + public final boolean onlineMode = this.getBoolean("online-mode", true); + public final boolean preventProxyConnections = this.getBoolean("prevent-proxy-connections", false); + public final String serverIp = this.getString("server-ip", ""); + public final boolean spawnAnimals = this.getBoolean("spawn-animals", true); + public final boolean spawnNpcs = this.getBoolean("spawn-npcs", true); + public final boolean pvp = this.getBoolean("pvp", true); + public final boolean allowFlight = this.getBoolean("allow-flight", false); + public final String resourcePack = this.getString("resource-pack", ""); + public final String motd = this.getString("motd", "A Minecraft Server"); + public final boolean forceGamemode = this.getBoolean("force-gamemode", false); + public final boolean enforceWhitelist = this.getBoolean("enforce-whitelist", false); + public final boolean generateStructures = this.getBoolean("generate-structures", true); + public final EnumDifficulty difficulty; + public final EnumGamemode gamemode; + public final String levelName; + public final String levelSeed; + public final WorldType levelType; + public final String generatorSettings; + public final int serverPort; + public final int maxBuildHeight; + public final Boolean announcePlayerAchievements; + public final boolean enableQuery; + public final int queryPort; + public final boolean enableRcon; + public final int rconPort; + public final String rconPassword; + public final String resourcePackHash; + public final String resourcePackSha1; + public final boolean hardcore; + public final boolean allowNether; + public final boolean spawnMonsters; + public final boolean snooperEnabled; + public final boolean useNativeTransport; + public final boolean enableCommandBlock; + public final int spawnProtection; + public final int opPermissionLevel; + public final int functionPermissionLevel; + public final long maxTickTime; + public final int viewDistance; + public final int maxPlayers; + public final int networkCompressionThreshold; + public final boolean broadcastRconToOps; + public final boolean broadcastConsoleToOps; + public final int maxWorldSize; + public final PropertyManager.EditableProperty playerIdleTimeout; + public final PropertyManager.EditableProperty whiteList; + + public final String rconIp; // Paper - Add rcon ip + + // CraftBukkit start + public DedicatedServerProperties(Properties properties, OptionSet optionset) { + super(properties, optionset); + // CraftBukkit end + this.difficulty = (EnumDifficulty) this.a("difficulty", a(EnumDifficulty::getById, EnumDifficulty::a), EnumDifficulty::c, EnumDifficulty.EASY); + this.gamemode = (EnumGamemode) this.a("gamemode", a(EnumGamemode::getById, EnumGamemode::a), EnumGamemode::b, EnumGamemode.SURVIVAL); + this.levelName = this.getString("level-name", "world"); + this.levelSeed = this.getString("level-seed", ""); + this.levelType = (WorldType) this.a("level-type", WorldType::getType, WorldType::name, WorldType.NORMAL); + this.generatorSettings = this.getString("generator-settings", ""); + this.serverPort = this.getInt("server-port", 25565); + this.maxBuildHeight = this.a("max-build-height", (integer) -> { + return MathHelper.clamp((integer + 8) / 16 * 16, 64, 256); + }, 256); + this.announcePlayerAchievements = this.b("announce-player-achievements"); + this.enableQuery = this.getBoolean("enable-query", false); + this.queryPort = this.getInt("query.port", 25565); + this.enableRcon = this.getBoolean("enable-rcon", false); + this.rconPort = this.getInt("rcon.port", 25575); + this.rconPassword = this.getString("rcon.password", ""); + this.resourcePackHash = this.a("resource-pack-hash"); + this.resourcePackSha1 = this.getString("resource-pack-sha1", ""); + this.hardcore = this.getBoolean("hardcore", false); + this.allowNether = this.getBoolean("allow-nether", true); + this.spawnMonsters = this.getBoolean("spawn-monsters", true); + if (this.getBoolean("snooper-enabled", true)) { + ; + } + + this.snooperEnabled = false; + this.useNativeTransport = this.getBoolean("use-native-transport", true); + this.enableCommandBlock = this.getBoolean("enable-command-block", false); + this.spawnProtection = this.getInt("spawn-protection", 16); + this.opPermissionLevel = this.getInt("op-permission-level", 4); + this.functionPermissionLevel = this.getInt("function-permission-level", 2); + this.maxTickTime = this.getLong("max-tick-time", TimeUnit.MINUTES.toMillis(1L)); + this.viewDistance = this.getInt("view-distance", 10); + this.maxPlayers = this.getInt("max-players", 20); + this.networkCompressionThreshold = this.getInt("network-compression-threshold", 256); + this.broadcastRconToOps = this.getBoolean("broadcast-rcon-to-ops", true); + this.broadcastConsoleToOps = this.getBoolean("broadcast-console-to-ops", true); + this.maxWorldSize = this.a("max-world-size", (integer) -> { + return MathHelper.clamp(integer, 1, 29999984); + }, 29999984); + this.playerIdleTimeout = this.b("player-idle-timeout", 0); + this.whiteList = this.b("white-list", false); + // Paper start - Configurable rcon ip + final String rconIp = this.getSettingIfExists("rcon.ip"); + this.rconIp = rconIp == null ? this.serverIp : rconIp; + // Paper end + } + + // CraftBukkit start + public static DedicatedServerProperties load(java.nio.file.Path java_nio_file_path, OptionSet optionset) { + return new DedicatedServerProperties(loadPropertiesFile(java_nio_file_path), optionset); + } + + @Override + protected DedicatedServerProperties reload(Properties properties, OptionSet optionset) { + return new DedicatedServerProperties(properties, optionset); + // CraftBukkit end + } +} diff --git a/src/main/java/net/minecraft/server/DedicatedServerSettings.java b/src/main/java/net/minecraft/server/DedicatedServerSettings.java new file mode 100644 index 000000000..34f2ba53d --- /dev/null +++ b/src/main/java/net/minecraft/server/DedicatedServerSettings.java @@ -0,0 +1,33 @@ +package net.minecraft.server; + +import java.util.function.UnaryOperator; +// CraftBukkit start +import java.io.File; +import joptsimple.OptionSet; +// CraftBukkit end + +public class DedicatedServerSettings { + + private final java.nio.file.Path path; + private DedicatedServerProperties properties; + + // CraftBukkit start + public DedicatedServerSettings(OptionSet optionset) { + this.path = ((File) optionset.valueOf("config")).toPath(); + this.properties = DedicatedServerProperties.load(path, optionset); + // CraftBukkit end + } + + public DedicatedServerProperties getProperties() { + return this.properties; + } + + public void save() { + this.properties.savePropertiesFile(this.path); + } + + public DedicatedServerSettings setProperty(UnaryOperator unaryoperator) { + (this.properties = (DedicatedServerProperties) unaryoperator.apply(this.properties)).savePropertiesFile(this.path); + return this; + } +} diff --git a/src/main/java/net/minecraft/server/DefinedStructure.java b/src/main/java/net/minecraft/server/DefinedStructure.java index dd635292e..78dfaeeb7 100644 --- a/src/main/java/net/minecraft/server/DefinedStructure.java +++ b/src/main/java/net/minecraft/server/DefinedStructure.java @@ -1,12 +1,11 @@ package net.minecraft.server; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import com.mojang.datafixers.util.Pair; +import java.util.Comparator; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.Optional; import javax.annotation.Nullable; public class DefinedStructure { @@ -35,7 +34,7 @@ public class DefinedStructure { public void a(World world, BlockPosition blockposition, BlockPosition blockposition1, boolean flag, @Nullable Block block) { if (blockposition1.getX() >= 1 && blockposition1.getY() >= 1 && blockposition1.getZ() >= 1) { - BlockPosition blockposition2 = blockposition.a((BaseBlockPosition) blockposition1).a(-1, -1, -1); + BlockPosition blockposition2 = blockposition.a((BaseBlockPosition) blockposition1).b(-1, -1, -1); List list = Lists.newArrayList(); List list1 = Lists.newArrayList(); List list2 = Lists.newArrayList(); @@ -43,15 +42,15 @@ public class DefinedStructure { BlockPosition blockposition4 = new BlockPosition(Math.max(blockposition.getX(), blockposition2.getX()), Math.max(blockposition.getY(), blockposition2.getY()), Math.max(blockposition.getZ(), blockposition2.getZ())); this.c = blockposition1; - Iterator iterator = BlockPosition.b(blockposition3, blockposition4).iterator(); + Iterator iterator = BlockPosition.a(blockposition3, blockposition4).iterator(); while (iterator.hasNext()) { - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = (BlockPosition.MutableBlockPosition) iterator.next(); - BlockPosition blockposition5 = blockposition_mutableblockposition.b(blockposition3); - IBlockData iblockdata = world.getType(blockposition_mutableblockposition); + BlockPosition blockposition5 = (BlockPosition) iterator.next(); + BlockPosition blockposition6 = blockposition5.b(blockposition3); + IBlockData iblockdata = world.getType(blockposition5); if (block == null || block != iblockdata.getBlock()) { - TileEntity tileentity = world.getTileEntity(blockposition_mutableblockposition); + TileEntity tileentity = world.getTileEntity(blockposition5); if (tileentity != null) { NBTTagCompound nbttagcompound = tileentity.save(new NBTTagCompound()); @@ -59,11 +58,11 @@ public class DefinedStructure { nbttagcompound.remove("x"); nbttagcompound.remove("y"); nbttagcompound.remove("z"); - list1.add(new DefinedStructure.BlockInfo(blockposition5, iblockdata, nbttagcompound)); - } else if (!iblockdata.f(world, blockposition_mutableblockposition) && !iblockdata.g()) { - list2.add(new DefinedStructure.BlockInfo(blockposition5, iblockdata, (NBTTagCompound) null)); + list1.add(new DefinedStructure.BlockInfo(blockposition6, iblockdata, nbttagcompound)); + } else if (!iblockdata.g(world, blockposition5) && !iblockdata.o(world, blockposition5)) { + list2.add(new DefinedStructure.BlockInfo(blockposition6, iblockdata, (NBTTagCompound) null)); } else { - list.add(new DefinedStructure.BlockInfo(blockposition5, iblockdata, (NBTTagCompound) null)); + list.add(new DefinedStructure.BlockInfo(blockposition6, iblockdata, (NBTTagCompound) null)); } } } @@ -76,7 +75,7 @@ public class DefinedStructure { this.a.clear(); this.a.add(list3); if (flag) { - this.a(world, blockposition3, blockposition4.a(1, 1, 1)); + this.a(world, blockposition3, blockposition4.b(1, 1, 1)); } else { this.b.clear(); } @@ -85,7 +84,7 @@ public class DefinedStructure { } private void a(World world, BlockPosition blockposition, BlockPosition blockposition1) { - List list = world.a(Entity.class, new AxisAlignedBB(blockposition, blockposition1), (java.util.function.Predicate) (entity) -> { // Paper - decompile fix + List list = world.a(Entity.class, new AxisAlignedBB(blockposition, blockposition1), (java.util.function.Predicate) (entity) -> { // CraftBukkit - decompile error return !(entity instanceof EntityHuman); }); @@ -110,29 +109,29 @@ public class DefinedStructure { } - public Map a(BlockPosition blockposition, DefinedStructureInfo definedstructureinfo) { - Map map = Maps.newHashMap(); - StructureBoundingBox structureboundingbox = definedstructureinfo.j(); + public List a(BlockPosition blockposition, DefinedStructureInfo definedstructureinfo, Block block) { + return this.a(blockposition, definedstructureinfo, block, true); + } + + public List a(BlockPosition blockposition, DefinedStructureInfo definedstructureinfo, Block block, boolean flag) { + List list = Lists.newArrayList(); + StructureBoundingBox structureboundingbox = definedstructureinfo.h(); Iterator iterator = definedstructureinfo.a(this.a, blockposition).iterator(); while (iterator.hasNext()) { DefinedStructure.BlockInfo definedstructure_blockinfo = (DefinedStructure.BlockInfo) iterator.next(); - BlockPosition blockposition1 = a(definedstructureinfo, definedstructure_blockinfo.a).a((BaseBlockPosition) blockposition); + BlockPosition blockposition1 = flag ? a(definedstructureinfo, definedstructure_blockinfo.a).a((BaseBlockPosition) blockposition) : definedstructure_blockinfo.a; if (structureboundingbox == null || structureboundingbox.b((BaseBlockPosition) blockposition1)) { IBlockData iblockdata = definedstructure_blockinfo.b; - if (iblockdata.getBlock() == Blocks.STRUCTURE_BLOCK && definedstructure_blockinfo.c != null) { - BlockPropertyStructureMode blockpropertystructuremode = BlockPropertyStructureMode.valueOf(definedstructure_blockinfo.c.getString("mode")); - - if (blockpropertystructuremode == BlockPropertyStructureMode.DATA) { - map.put(blockposition1, definedstructure_blockinfo.c.getString("metadata")); - } + if (iblockdata.getBlock() == block) { + list.add(new DefinedStructure.BlockInfo(blockposition1, iblockdata.a(definedstructureinfo.d()), definedstructure_blockinfo.c)); } } } - return map; + return list; } public BlockPosition a(DefinedStructureInfo definedstructureinfo, BlockPosition blockposition, DefinedStructureInfo definedstructureinfo1, BlockPosition blockposition1) { @@ -143,32 +142,27 @@ public class DefinedStructure { } public static BlockPosition a(DefinedStructureInfo definedstructureinfo, BlockPosition blockposition) { - return a(blockposition, definedstructureinfo.b(), definedstructureinfo.c(), definedstructureinfo.d()); + return a(blockposition, definedstructureinfo.c(), definedstructureinfo.d(), definedstructureinfo.e()); } public void a(GeneratorAccess generatoraccess, BlockPosition blockposition, DefinedStructureInfo definedstructureinfo) { - definedstructureinfo.l(); + definedstructureinfo.k(); this.b(generatoraccess, blockposition, definedstructureinfo); } public void b(GeneratorAccess generatoraccess, BlockPosition blockposition, DefinedStructureInfo definedstructureinfo) { - this.a(generatoraccess, blockposition, new DefinedStructureProcessorRotation(blockposition, definedstructureinfo), definedstructureinfo, 2); + this.a(generatoraccess, blockposition, definedstructureinfo, 2); } public boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition, DefinedStructureInfo definedstructureinfo, int i) { - return this.a(generatoraccess, blockposition, new DefinedStructureProcessorRotation(blockposition, definedstructureinfo), definedstructureinfo, i); - } - - public boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition, @Nullable DefinedStructureProcessor definedstructureprocessor, DefinedStructureInfo definedstructureinfo, int i) { if (this.a.isEmpty()) { return false; } else { List list = definedstructureinfo.a(this.a, blockposition); - if ((!list.isEmpty() || !definedstructureinfo.h() && !this.b.isEmpty()) && this.c.getX() >= 1 && this.c.getY() >= 1 && this.c.getZ() >= 1) { - Block block = definedstructureinfo.i(); - StructureBoundingBox structureboundingbox = definedstructureinfo.j(); - List list1 = Lists.newArrayListWithCapacity(definedstructureinfo.m() ? list.size() : 0); + if ((!list.isEmpty() || !definedstructureinfo.g() && !this.b.isEmpty()) && this.c.getX() >= 1 && this.c.getY() >= 1 && this.c.getZ() >= 1) { + StructureBoundingBox structureboundingbox = definedstructureinfo.h(); + List list1 = Lists.newArrayListWithCapacity(definedstructureinfo.l() ? list.size() : 0); List> list2 = Lists.newArrayListWithCapacity(list.size()); int j = Integer.MAX_VALUE; int k = Integer.MAX_VALUE; @@ -176,58 +170,51 @@ public class DefinedStructure { int i1 = Integer.MIN_VALUE; int j1 = Integer.MIN_VALUE; int k1 = Integer.MIN_VALUE; - Iterator iterator = list.iterator(); + List list3 = a(generatoraccess, blockposition, definedstructureinfo, list); + Iterator iterator = list3.iterator(); + + TileEntity tileentity; while (iterator.hasNext()) { DefinedStructure.BlockInfo definedstructure_blockinfo = (DefinedStructure.BlockInfo) iterator.next(); - BlockPosition blockposition1 = a(definedstructureinfo, definedstructure_blockinfo.a).a((BaseBlockPosition) blockposition); - DefinedStructure.BlockInfo definedstructure_blockinfo1 = definedstructureprocessor != null ? definedstructureprocessor.a(generatoraccess, blockposition1, definedstructure_blockinfo) : definedstructure_blockinfo; + BlockPosition blockposition1 = definedstructure_blockinfo.a; - if (definedstructure_blockinfo1 != null) { - Block block1 = definedstructure_blockinfo1.b.getBlock(); + if (structureboundingbox == null || structureboundingbox.b((BaseBlockPosition) blockposition1)) { + Fluid fluid = definedstructureinfo.l() ? generatoraccess.getFluid(blockposition1) : null; + IBlockData iblockdata = definedstructure_blockinfo.b.a(definedstructureinfo.c()).a(definedstructureinfo.d()); - if ((block == null || block != block1) && (!definedstructureinfo.k() || block1 != Blocks.STRUCTURE_BLOCK) && (structureboundingbox == null || structureboundingbox.b((BaseBlockPosition) blockposition1))) { - Fluid fluid = definedstructureinfo.m() ? generatoraccess.getFluid(blockposition1) : null; - IBlockData iblockdata = definedstructure_blockinfo1.b.a(definedstructureinfo.b()); - IBlockData iblockdata1 = iblockdata.a(definedstructureinfo.c()); - TileEntity tileentity; + if (definedstructure_blockinfo.c != null) { + tileentity = generatoraccess.getTileEntity(blockposition1); + Clearable.a(tileentity); + generatoraccess.setTypeAndData(blockposition1, Blocks.BARRIER.getBlockData(), 20); + } - if (definedstructure_blockinfo1.c != null) { + if (generatoraccess.setTypeAndData(blockposition1, iblockdata, i)) { + j = Math.min(j, blockposition1.getX()); + k = Math.min(k, blockposition1.getY()); + l = Math.min(l, blockposition1.getZ()); + i1 = Math.max(i1, blockposition1.getX()); + j1 = Math.max(j1, blockposition1.getY()); + k1 = Math.max(k1, blockposition1.getZ()); + list2.add(Pair.of(blockposition1, definedstructure_blockinfo.c)); + if (definedstructure_blockinfo.c != null) { tileentity = generatoraccess.getTileEntity(blockposition1); - if (tileentity instanceof IInventory) { - ((IInventory) tileentity).clear(); + if (tileentity != null) { + definedstructure_blockinfo.c.setInt("x", blockposition1.getX()); + definedstructure_blockinfo.c.setInt("y", blockposition1.getY()); + definedstructure_blockinfo.c.setInt("z", blockposition1.getZ()); + tileentity.isLoadingStructure = true; // Paper + tileentity.load(definedstructure_blockinfo.c); + tileentity.a(definedstructureinfo.c()); + tileentity.a(definedstructureinfo.d()); + tileentity.isLoadingStructure = false; // Paper } - - generatoraccess.setTypeAndData(blockposition1, Blocks.BARRIER.getBlockData(), 4); } - if (generatoraccess.setTypeAndData(blockposition1, iblockdata1, i)) { - j = Math.min(j, blockposition1.getX()); - k = Math.min(k, blockposition1.getY()); - l = Math.min(l, blockposition1.getZ()); - i1 = Math.max(i1, blockposition1.getX()); - j1 = Math.max(j1, blockposition1.getY()); - k1 = Math.max(k1, blockposition1.getZ()); - list2.add(Pair.of(blockposition1, definedstructure_blockinfo.c)); - if (definedstructure_blockinfo1.c != null) { - tileentity = generatoraccess.getTileEntity(blockposition1); - if (tileentity != null) { - definedstructure_blockinfo1.c.setInt("x", blockposition1.getX()); - definedstructure_blockinfo1.c.setInt("y", blockposition1.getY()); - definedstructure_blockinfo1.c.setInt("z", blockposition1.getZ()); - tileentity.isLoadingStructure = true; // Paper - tileentity.load(definedstructure_blockinfo1.c); - tileentity.a(definedstructureinfo.b()); - tileentity.a(definedstructureinfo.c()); - tileentity.isLoadingStructure = false; // Paper - } - } - - if (fluid != null && iblockdata1.getBlock() instanceof IFluidContainer) { - ((IFluidContainer) iblockdata1.getBlock()).place(generatoraccess, blockposition1, iblockdata1, fluid); - if (!fluid.d()) { - list1.add(blockposition1); - } + if (fluid != null && iblockdata.getBlock() instanceof IFluidContainer) { + ((IFluidContainer) iblockdata.getBlock()).place(generatoraccess, blockposition1, iblockdata, fluid); + if (!fluid.isSource()) { + list1.add(blockposition1); } } } @@ -235,31 +222,38 @@ public class DefinedStructure { } boolean flag = true; - EnumDirection[] aenumdirection = new EnumDirection[] { EnumDirection.UP, EnumDirection.NORTH, EnumDirection.EAST, EnumDirection.SOUTH, EnumDirection.WEST}; + EnumDirection[] aenumdirection = new EnumDirection[]{EnumDirection.UP, EnumDirection.NORTH, EnumDirection.EAST, EnumDirection.SOUTH, EnumDirection.WEST}; - //int l1; // Paper - decompile fix + Iterator iterator1; + BlockPosition blockposition2; + IBlockData iblockdata1; while (flag && !list1.isEmpty()) { flag = false; - Iterator iterator1 = list1.iterator(); + iterator1 = list1.iterator(); while (iterator1.hasNext()) { - BlockPosition blockposition2 = (BlockPosition) iterator1.next(); - Fluid fluid1 = generatoraccess.getFluid(blockposition2); + BlockPosition blockposition3 = (BlockPosition) iterator1.next(); - for (int l1 = 0; l1 < aenumdirection.length && !fluid1.d(); ++l1) { // Paper - decompile fix - Fluid fluid2 = generatoraccess.getFluid(blockposition2.shift(aenumdirection[l1])); + blockposition2 = blockposition3; + Fluid fluid1 = generatoraccess.getFluid(blockposition3); - if (fluid2.getHeight() > fluid1.getHeight() || fluid2.d() && !fluid1.d()) { + for (int l1 = 0; l1 < aenumdirection.length && !fluid1.isSource(); ++l1) { + BlockPosition blockposition4 = blockposition2.shift(aenumdirection[l1]); + Fluid fluid2 = generatoraccess.getFluid(blockposition4); + + if (fluid2.getHeight(generatoraccess, blockposition4) > fluid1.getHeight(generatoraccess, blockposition2) || fluid2.isSource() && !fluid1.isSource()) { fluid1 = fluid2; + blockposition2 = blockposition4; } } - if (fluid1.d()) { - IBlockData iblockdata2 = generatoraccess.getType(blockposition2); + if (fluid1.isSource()) { + iblockdata1 = generatoraccess.getType(blockposition3); + Block block = iblockdata1.getBlock(); - if (iblockdata2.getBlock() instanceof IFluidContainer) { - ((IFluidContainer) iblockdata2.getBlock()).place(generatoraccess, blockposition2, iblockdata2, fluid1); + if (block instanceof IFluidContainer) { + ((IFluidContainer) block).place(generatoraccess, blockposition3, iblockdata1, fluid1); flag = true; iterator1.remove(); } @@ -268,65 +262,51 @@ public class DefinedStructure { } if (j <= i1) { - VoxelShapeBitSet voxelshapebitset = new VoxelShapeBitSet(i1 - j + 1, j1 - k + 1, k1 - l + 1); - int i2 = j; - int j2 = k; + if (!definedstructureinfo.i()) { + VoxelShapeBitSet voxelshapebitset = new VoxelShapeBitSet(i1 - j + 1, j1 - k + 1, k1 - l + 1); + int i2 = j; + int j2 = k; + int k2 = l; + Iterator iterator2 = list2.iterator(); - int l1 = l; // Paper - decompile fix - Iterator iterator2 = list2.iterator(); + while (iterator2.hasNext()) { + Pair pair = (Pair) iterator2.next(); + BlockPosition blockposition5 = (BlockPosition) pair.getFirst(); - Pair pair; - BlockPosition blockposition3; + voxelshapebitset.a(blockposition5.getX() - i2, blockposition5.getY() - j2, blockposition5.getZ() - k2, true, true); + } - while (iterator2.hasNext()) { - pair = (Pair) iterator2.next(); - blockposition3 = (BlockPosition) pair.getFirst(); - voxelshapebitset.a(blockposition3.getX() - i2, blockposition3.getY() - j2, blockposition3.getZ() - l1, true, true); + a(generatoraccess, i, voxelshapebitset, i2, j2, k2); } - voxelshapebitset.a((enumdirection, k2, l2, i3) -> { - BlockPosition blockposition4 = new BlockPosition(i2 + k2, j2 + l2, l1 + i3); - BlockPosition blockposition5 = blockposition4.shift(enumdirection); - IBlockData iblockdata3 = generatoraccess.getType(blockposition4); - IBlockData iblockdata4 = generatoraccess.getType(blockposition5); - IBlockData iblockdata5 = iblockdata3.updateState(enumdirection, iblockdata4, generatoraccess, blockposition4, blockposition5); + iterator1 = list2.iterator(); - if (iblockdata3 != iblockdata5) { - generatoraccess.setTypeAndData(blockposition4, iblockdata5, i & -2 | 16); + while (iterator1.hasNext()) { + Pair pair1 = (Pair) iterator1.next(); + + blockposition2 = (BlockPosition) pair1.getFirst(); + if (!definedstructureinfo.i()) { + IBlockData iblockdata2 = generatoraccess.getType(blockposition2); + + iblockdata1 = Block.b(iblockdata2, generatoraccess, blockposition2); + if (iblockdata2 != iblockdata1) { + generatoraccess.setTypeAndData(blockposition2, iblockdata1, i & -2 | 16); + } + + generatoraccess.update(blockposition2, iblockdata1.getBlock()); } - IBlockData iblockdata6 = iblockdata4.updateState(enumdirection.opposite(), iblockdata5, generatoraccess, blockposition5, blockposition4); - - if (iblockdata4 != iblockdata6) { - generatoraccess.setTypeAndData(blockposition5, iblockdata6, i & -2 | 16); - } - - }); - iterator2 = list2.iterator(); - - while (iterator2.hasNext()) { - pair = (Pair) iterator2.next(); - blockposition3 = (BlockPosition) pair.getFirst(); - IBlockData iblockdata3 = generatoraccess.getType(blockposition3); - IBlockData iblockdata4 = Block.b(iblockdata3, generatoraccess, blockposition3); - - if (iblockdata3 != iblockdata4) { - generatoraccess.setTypeAndData(blockposition3, iblockdata4, i & -2 | 16); - } - - generatoraccess.update(blockposition3, iblockdata4.getBlock()); - if (pair.getSecond() != null) { - TileEntity tileentity1 = generatoraccess.getTileEntity(blockposition3); - - if (tileentity1 != null) { - tileentity1.update(); + if (pair1.getSecond() != null) { + tileentity = generatoraccess.getTileEntity(blockposition2); + if (tileentity != null) { + tileentity.update(); } } } } - if (!definedstructureinfo.h()) { - this.a(generatoraccess, blockposition, definedstructureinfo.b(), definedstructureinfo.c(), definedstructureinfo.d(), structureboundingbox); + if (!definedstructureinfo.g()) { + this.a(generatoraccess, blockposition, definedstructureinfo.c(), definedstructureinfo.d(), definedstructureinfo.e(), structureboundingbox); } return true; @@ -336,6 +316,48 @@ public class DefinedStructure { } } + public static void a(GeneratorAccess generatoraccess, int i, VoxelShapeDiscrete voxelshapediscrete, int j, int k, int l) { + voxelshapediscrete.a((enumdirection, i1, j1, k1) -> { + BlockPosition blockposition = new BlockPosition(j + i1, k + j1, l + k1); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + IBlockData iblockdata = generatoraccess.getType(blockposition); + IBlockData iblockdata1 = generatoraccess.getType(blockposition1); + IBlockData iblockdata2 = iblockdata.updateState(enumdirection, iblockdata1, generatoraccess, blockposition, blockposition1); + + if (iblockdata != iblockdata2) { + generatoraccess.setTypeAndData(blockposition, iblockdata2, i & -2 | 16); + } + + IBlockData iblockdata3 = iblockdata1.updateState(enumdirection.opposite(), iblockdata2, generatoraccess, blockposition1, blockposition); + + if (iblockdata1 != iblockdata3) { + generatoraccess.setTypeAndData(blockposition1, iblockdata3, i & -2 | 16); + } + + }); + } + + public static List a(GeneratorAccess generatoraccess, BlockPosition blockposition, DefinedStructureInfo definedstructureinfo, List list) { + List list1 = Lists.newArrayList(); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + DefinedStructure.BlockInfo definedstructure_blockinfo = (DefinedStructure.BlockInfo) iterator.next(); + BlockPosition blockposition1 = a(definedstructureinfo, definedstructure_blockinfo.a).a((BaseBlockPosition) blockposition); + DefinedStructure.BlockInfo definedstructure_blockinfo1 = new DefinedStructure.BlockInfo(blockposition1, definedstructure_blockinfo.b, definedstructure_blockinfo.c); + + for (Iterator iterator1 = definedstructureinfo.j().iterator(); definedstructure_blockinfo1 != null && iterator1.hasNext(); definedstructure_blockinfo1 = ((DefinedStructureProcessor) iterator1.next()).a(generatoraccess, blockposition, definedstructure_blockinfo, definedstructure_blockinfo1, definedstructureinfo)) { + ; + } + + if (definedstructure_blockinfo1 != null) { + list1.add(definedstructure_blockinfo1); + } + } + + return list1; + } + private void a(GeneratorAccess generatoraccess, BlockPosition blockposition, EnumBlockMirror enumblockmirror, EnumBlockRotation enumblockrotation, BlockPosition blockposition1, @Nullable StructureBoundingBox structureboundingbox) { Iterator iterator = this.b.iterator(); @@ -349,39 +371,41 @@ public class DefinedStructure { Vec3D vec3d1 = vec3d.add((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); NBTTagList nbttaglist = new NBTTagList(); - nbttaglist.add((NBTBase) (new NBTTagDouble(vec3d1.x))); - nbttaglist.add((NBTBase) (new NBTTagDouble(vec3d1.y))); - nbttaglist.add((NBTBase) (new NBTTagDouble(vec3d1.z))); + nbttaglist.add(new NBTTagDouble(vec3d1.x)); + nbttaglist.add(new NBTTagDouble(vec3d1.y)); + nbttaglist.add(new NBTTagDouble(vec3d1.z)); nbttagcompound.set("Pos", nbttaglist); - nbttagcompound.a("UUID", UUID.randomUUID()); - - Entity entity; - - try { - entity = EntityTypes.a(nbttagcompound, generatoraccess.getMinecraftWorld()); - } catch (Exception exception) { - entity = null; - } - - if (entity != null) { + nbttagcompound.remove("UUIDMost"); + nbttagcompound.remove("UUIDLeast"); + a(generatoraccess, nbttagcompound).ifPresent((entity) -> { float f = entity.a(enumblockmirror); f += entity.yaw - entity.a(enumblockrotation); entity.setPositionRotation(vec3d1.x, vec3d1.y, vec3d1.z, f, entity.pitch); generatoraccess.addEntity(entity); - } + }); } } } + private static Optional a(GeneratorAccess generatoraccess, NBTTagCompound nbttagcompound) { + // CraftBukkit start + // try { + return EntityTypes.a(nbttagcompound, generatoraccess.getMinecraftWorld()); + // } catch (Exception exception) { + // return Optional.empty(); + // } + // CraftBukkit end + } + public BlockPosition a(EnumBlockRotation enumblockrotation) { switch (enumblockrotation) { - case COUNTERCLOCKWISE_90: - case CLOCKWISE_90: - return new BlockPosition(this.c.getZ(), this.c.getY(), this.c.getX()); - default: - return this.c; + case COUNTERCLOCKWISE_90: + case CLOCKWISE_90: + return new BlockPosition(this.c.getZ(), this.c.getY(), this.c.getX()); + default: + return this.c; } } @@ -392,28 +416,28 @@ public class DefinedStructure { boolean flag = true; switch (enumblockmirror) { - case LEFT_RIGHT: - k = -k; - break; - case FRONT_BACK: - i = -i; - break; - default: - flag = false; + case LEFT_RIGHT: + k = -k; + break; + case FRONT_BACK: + i = -i; + break; + default: + flag = false; } int l = blockposition1.getX(); int i1 = blockposition1.getZ(); switch (enumblockrotation) { - case COUNTERCLOCKWISE_90: - return new BlockPosition(l - i1 + k, j, l + i1 - i); - case CLOCKWISE_90: - return new BlockPosition(l + i1 - k, j, i1 - l + i); - case CLOCKWISE_180: - return new BlockPosition(l + l - i, j, i1 + i1 - k); - default: - return flag ? new BlockPosition(i, j, k) : blockposition; + case COUNTERCLOCKWISE_90: + return new BlockPosition(l - i1 + k, j, l + i1 - i); + case CLOCKWISE_90: + return new BlockPosition(l + i1 - k, j, i1 - l + i); + case CLOCKWISE_180: + return new BlockPosition(l + l - i, j, i1 + i1 - k); + default: + return flag ? new BlockPosition(i, j, k) : blockposition; } } @@ -424,28 +448,28 @@ public class DefinedStructure { boolean flag = true; switch (enumblockmirror) { - case LEFT_RIGHT: - d2 = 1.0D - d2; - break; - case FRONT_BACK: - d0 = 1.0D - d0; - break; - default: - flag = false; + case LEFT_RIGHT: + d2 = 1.0D - d2; + break; + case FRONT_BACK: + d0 = 1.0D - d0; + break; + default: + flag = false; } int i = blockposition.getX(); int j = blockposition.getZ(); switch (enumblockrotation) { - case COUNTERCLOCKWISE_90: - return new Vec3D((double) (i - j) + d2, d1, (double) (i + j + 1) - d0); - case CLOCKWISE_90: - return new Vec3D((double) (i + j + 1) - d2, d1, (double) (j - i) + d0); - case CLOCKWISE_180: - return new Vec3D((double) (i + i + 1) - d0, d1, (double) (j + j + 1) - d2); - default: - return flag ? new Vec3D(d0, d1, d2) : vec3d; + case COUNTERCLOCKWISE_90: + return new Vec3D((double) (i - j) + d2, d1, (double) (i + j + 1) - d0); + case CLOCKWISE_90: + return new Vec3D((double) (i + j + 1) - d2, d1, (double) (j - i) + d0); + case CLOCKWISE_180: + return new Vec3D((double) (i + i + 1) - d0, d1, (double) (j + j + 1) - d2); + default: + return flag ? new Vec3D(d0, d1, d2) : vec3d; } } @@ -461,22 +485,77 @@ public class DefinedStructure { BlockPosition blockposition1 = blockposition; switch (enumblockrotation) { - case COUNTERCLOCKWISE_90: - blockposition1 = blockposition.a(l, 0, i - k); - break; - case CLOCKWISE_90: - blockposition1 = blockposition.a(j - l, 0, k); - break; - case CLOCKWISE_180: - blockposition1 = blockposition.a(i - k, 0, j - l); - break; - case NONE: - blockposition1 = blockposition.a(k, 0, l); + case COUNTERCLOCKWISE_90: + blockposition1 = blockposition.b(l, 0, i - k); + break; + case CLOCKWISE_90: + blockposition1 = blockposition.b(j - l, 0, k); + break; + case CLOCKWISE_180: + blockposition1 = blockposition.b(i - k, 0, j - l); + break; + case NONE: + blockposition1 = blockposition.b(k, 0, l); } return blockposition1; } + public StructureBoundingBox b(DefinedStructureInfo definedstructureinfo, BlockPosition blockposition) { + EnumBlockRotation enumblockrotation = definedstructureinfo.d(); + BlockPosition blockposition1 = definedstructureinfo.e(); + BlockPosition blockposition2 = this.a(enumblockrotation); + EnumBlockMirror enumblockmirror = definedstructureinfo.c(); + int i = blockposition1.getX(); + int j = blockposition1.getZ(); + int k = blockposition2.getX() - 1; + int l = blockposition2.getY() - 1; + int i1 = blockposition2.getZ() - 1; + StructureBoundingBox structureboundingbox = new StructureBoundingBox(0, 0, 0, 0, 0, 0); + + switch (enumblockrotation) { + case COUNTERCLOCKWISE_90: + structureboundingbox = new StructureBoundingBox(i - j, 0, i + j - i1, i - j + k, l, i + j); + break; + case CLOCKWISE_90: + structureboundingbox = new StructureBoundingBox(i + j - k, 0, j - i, i + j, l, j - i + i1); + break; + case CLOCKWISE_180: + structureboundingbox = new StructureBoundingBox(i + i - k, 0, j + j - i1, i + i, l, j + j); + break; + case NONE: + structureboundingbox = new StructureBoundingBox(0, 0, 0, k, l, i1); + } + + switch (enumblockmirror) { + case LEFT_RIGHT: + this.a(enumblockrotation, i1, k, structureboundingbox, EnumDirection.NORTH, EnumDirection.SOUTH); + break; + case FRONT_BACK: + this.a(enumblockrotation, k, i1, structureboundingbox, EnumDirection.WEST, EnumDirection.EAST); + case NONE: + } + + structureboundingbox.a(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + return structureboundingbox; + } + + private void a(EnumBlockRotation enumblockrotation, int i, int j, StructureBoundingBox structureboundingbox, EnumDirection enumdirection, EnumDirection enumdirection1) { + BlockPosition blockposition = BlockPosition.ZERO; + + if (enumblockrotation != EnumBlockRotation.CLOCKWISE_90 && enumblockrotation != EnumBlockRotation.COUNTERCLOCKWISE_90) { + if (enumblockrotation == EnumBlockRotation.CLOCKWISE_180) { + blockposition = blockposition.shift(enumdirection1, i); + } else { + blockposition = blockposition.shift(enumdirection, i); + } + } else { + blockposition = blockposition.shift(enumblockrotation.a(enumdirection), j); + } + + structureboundingbox.a(blockposition.getX(), 0, blockposition.getZ()); + } + public NBTTagCompound a(NBTTagCompound nbttagcompound) { if (this.a.isEmpty()) { nbttagcompound.set("blocks", new NBTTagList()); @@ -506,12 +585,12 @@ public class DefinedStructure { nbttagcompound1.set("nbt", definedstructure_blockinfo.c); } - nbttaglist.add((NBTBase) nbttagcompound1); + nbttaglist.add(nbttagcompound1); for (int l = 1; l < this.a.size(); ++l) { DefinedStructure.a definedstructure_a1 = (DefinedStructure.a) list.get(l); - definedstructure_a1.a(((DefinedStructure.BlockInfo) ((List) this.a.get(j)).get(j)).b, k); + definedstructure_a1.a(((DefinedStructure.BlockInfo) ((List) this.a.get(l)).get(j)).b, k); } } @@ -526,7 +605,7 @@ public class DefinedStructure { while (iterator.hasNext()) { IBlockData iblockdata = (IBlockData) iterator.next(); - nbttaglist1.add((NBTBase) GameProfileSerializer.a(iblockdata)); + nbttaglist1.add(GameProfileSerializer.a(iblockdata)); } nbttagcompound.set("palette", nbttaglist1); @@ -542,10 +621,10 @@ public class DefinedStructure { while (iterator1.hasNext()) { IBlockData iblockdata1 = (IBlockData) iterator1.next(); - nbttaglist2.add((NBTBase) GameProfileSerializer.a(iblockdata1)); + nbttaglist2.add(GameProfileSerializer.a(iblockdata1)); } - nbttaglist1.add((NBTBase) nbttaglist2); + nbttaglist1.add(nbttaglist2); } nbttagcompound.set("palettes", nbttaglist1); @@ -556,7 +635,7 @@ public class DefinedStructure { NBTTagCompound nbttagcompound2; - for (Iterator iterator2 = this.b.iterator(); iterator2.hasNext(); nbttaglist3.add((NBTBase) nbttagcompound2)) { + for (Iterator iterator2 = this.b.iterator(); iterator2.hasNext(); nbttaglist3.add(nbttagcompound2)) { DefinedStructure.EntityInfo definedstructure_entityinfo = (DefinedStructure.EntityInfo) iterator2.next(); nbttagcompound2 = new NBTTagCompound(); @@ -569,7 +648,7 @@ public class DefinedStructure { nbttagcompound.set("entities", nbttaglist3); nbttagcompound.set("size", this.a(this.c.getX(), this.c.getY(), this.c.getZ())); - nbttagcompound.setInt("DataVersion", 1631); + nbttagcompound.setInt("DataVersion", SharedConstants.a().getWorldVersion()); return nbttagcompound; } @@ -578,7 +657,7 @@ public class DefinedStructure { this.b.clear(); NBTTagList nbttaglist = nbttagcompound.getList("size", 3); - this.c = new BlockPosition(nbttaglist.h(0), nbttaglist.h(1), nbttaglist.h(2)); + this.c = new BlockPosition(nbttaglist.e(0), nbttaglist.e(1), nbttaglist.e(2)); NBTTagList nbttaglist1 = nbttagcompound.getList("blocks", 10); NBTTagList nbttaglist2; int i; @@ -587,7 +666,7 @@ public class DefinedStructure { nbttaglist2 = nbttagcompound.getList("palettes", 9); for (i = 0; i < nbttaglist2.size(); ++i) { - this.a(nbttaglist2.f(i), nbttaglist1); + this.a(nbttaglist2.b(i), nbttaglist1); } } else { this.a(nbttagcompound.getList("palette", 10), nbttaglist1); @@ -598,9 +677,9 @@ public class DefinedStructure { for (i = 0; i < nbttaglist2.size(); ++i) { NBTTagCompound nbttagcompound1 = nbttaglist2.getCompound(i); NBTTagList nbttaglist3 = nbttagcompound1.getList("pos", 6); - Vec3D vec3d = new Vec3D(nbttaglist3.k(0), nbttaglist3.k(1), nbttaglist3.k(2)); + Vec3D vec3d = new Vec3D(nbttaglist3.h(0), nbttaglist3.h(1), nbttaglist3.h(2)); NBTTagList nbttaglist4 = nbttagcompound1.getList("blockPos", 3); - BlockPosition blockposition = new BlockPosition(nbttaglist4.h(0), nbttaglist4.h(1), nbttaglist4.h(2)); + BlockPosition blockposition = new BlockPosition(nbttaglist4.e(0), nbttaglist4.e(1), nbttaglist4.e(2)); if (nbttagcompound1.hasKey("nbt")) { NBTTagCompound nbttagcompound2 = nbttagcompound1.getCompound("nbt"); @@ -624,7 +703,7 @@ public class DefinedStructure { for (i = 0; i < nbttaglist1.size(); ++i) { NBTTagCompound nbttagcompound = nbttaglist1.getCompound(i); NBTTagList nbttaglist2 = nbttagcompound.getList("pos", 3); - BlockPosition blockposition = new BlockPosition(nbttaglist2.h(0), nbttaglist2.h(1), nbttaglist2.h(2)); + BlockPosition blockposition = new BlockPosition(nbttaglist2.e(0), nbttaglist2.e(1), nbttaglist2.e(2)); IBlockData iblockdata = definedstructure_a.a(nbttagcompound.getInt("state")); NBTTagCompound nbttagcompound1; @@ -637,6 +716,9 @@ public class DefinedStructure { list.add(new DefinedStructure.BlockInfo(blockposition, iblockdata, nbttagcompound1)); } + list.sort(Comparator.comparingInt((definedstructure_blockinfo) -> { + return definedstructure_blockinfo.a.getY(); + })); this.a.add(list); } @@ -648,7 +730,7 @@ public class DefinedStructure { for (int j = 0; j < i; ++j) { int k = aint1[j]; - nbttaglist.add((NBTBase) (new NBTTagInt(k))); + nbttaglist.add(new NBTTagInt(k)); } return nbttaglist; @@ -662,7 +744,7 @@ public class DefinedStructure { for (int j = 0; j < i; ++j) { double d0 = adouble1[j]; - nbttaglist.add((NBTBase) (new NBTTagDouble(d0))); + nbttaglist.add(new NBTTagDouble(d0)); } return nbttaglist; @@ -692,6 +774,10 @@ public class DefinedStructure { this.b = iblockdata; this.c = nbttagcompound; } + + public String toString() { + return String.format("", this.a, this.b, this.c); + } } static class a implements Iterable { @@ -719,7 +805,7 @@ public class DefinedStructure { public IBlockData a(int i) { IBlockData iblockdata = (IBlockData) this.b.fromId(i); - return iblockdata == null ? a : iblockdata; // Paper - decompile fix + return iblockdata == null ? a : iblockdata; // CraftBukkit - decompile error } public Iterator iterator() { diff --git a/src/main/java/net/minecraft/server/DefinedStructureManager.java b/src/main/java/net/minecraft/server/DefinedStructureManager.java index f45685099..fb27bd097 100644 --- a/src/main/java/net/minecraft/server/DefinedStructureManager.java +++ b/src/main/java/net/minecraft/server/DefinedStructureManager.java @@ -1,7 +1,6 @@ package net.minecraft.server; import com.google.common.collect.Maps; -import com.mojang.datafixers.DataFixTypes; import com.mojang.datafixers.DataFixer; import java.io.File; import java.io.FileInputStream; @@ -20,8 +19,8 @@ import org.apache.logging.log4j.Logger; public class DefinedStructureManager implements IResourcePackListener { - private static final Logger a = LogManager.getLogger(); - private final Map b = Maps.newConcurrentMap(); // Paper + private static final Logger LOGGER = LogManager.getLogger(); + private final Map b = Maps.newConcurrentMap(); // SPIGOT-5287 private final DataFixer c; private final MinecraftServer d; private final java.nio.file.Path e; @@ -30,7 +29,7 @@ public class DefinedStructureManager implements IResourcePackListener { this.d = minecraftserver; this.c = datafixer; this.e = file.toPath().resolve("generated").normalize(); - minecraftserver.getResourceManager().a((IResourcePackListener) this); + minecraftserver.getResourceManager().a((IReloadListener) this); } public DefinedStructure a(MinecraftKey minecraftkey) { @@ -53,13 +52,14 @@ public class DefinedStructureManager implements IResourcePackListener { }); } + @Override public void a(IResourceManager iresourcemanager) { this.b.clear(); } @Nullable private DefinedStructure e(MinecraftKey minecraftkey) { - MinecraftKey minecraftkey1 = new MinecraftKey(minecraftkey.b(), "structures/" + minecraftkey.getKey() + ".nbt"); + MinecraftKey minecraftkey1 = new MinecraftKey(minecraftkey.getNamespace(), "structures/" + minecraftkey.getKey() + ".nbt"); try { IResource iresource = this.d.getResourceManager().a(minecraftkey1); @@ -91,7 +91,7 @@ public class DefinedStructureManager implements IResourcePackListener { } catch (FileNotFoundException filenotfoundexception) { return null; } catch (Throwable throwable3) { - DefinedStructureManager.a.error("Couldn't load structure {}: {}", minecraftkey, throwable3.toString()); + DefinedStructureManager.LOGGER.error("Couldn't load structure {}: {}", minecraftkey, throwable3.toString()); return null; } } @@ -133,7 +133,7 @@ public class DefinedStructureManager implements IResourcePackListener { } catch (FileNotFoundException filenotfoundexception) { return null; } catch (IOException ioexception) { - DefinedStructureManager.a.error("Couldn't load structure from {}", java_nio_file_path, ioexception); + DefinedStructureManager.LOGGER.error("Couldn't load structure from {}", java_nio_file_path, ioexception); return null; } } @@ -167,7 +167,7 @@ public class DefinedStructureManager implements IResourcePackListener { try { Files.createDirectories(Files.exists(java_nio_file_path1, new LinkOption[0]) ? java_nio_file_path1.toRealPath() : java_nio_file_path1); } catch (IOException ioexception) { - DefinedStructureManager.a.error("Failed to create parent directory: {}", java_nio_file_path1); + DefinedStructureManager.LOGGER.error("Failed to create parent directory: {}", java_nio_file_path1); return false; } @@ -207,10 +207,10 @@ public class DefinedStructureManager implements IResourcePackListener { private java.nio.file.Path a(MinecraftKey minecraftkey, String s) { try { - java.nio.file.Path java_nio_file_path = this.e.resolve(minecraftkey.b()); + java.nio.file.Path java_nio_file_path = this.e.resolve(minecraftkey.getNamespace()); java.nio.file.Path java_nio_file_path1 = java_nio_file_path.resolve("structures"); - return SystemUtils.a(java_nio_file_path1, minecraftkey.getKey(), s); + return FileUtils.b(java_nio_file_path1, minecraftkey.getKey(), s); } catch (InvalidPathException invalidpathexception) { throw new ResourceKeyInvalidException("Invalid resource path: " + minecraftkey, invalidpathexception); } @@ -222,7 +222,7 @@ public class DefinedStructureManager implements IResourcePackListener { } else { java.nio.file.Path java_nio_file_path = this.a(minecraftkey, s); - if (java_nio_file_path.startsWith(this.e) && SystemUtils.a(java_nio_file_path) && SystemUtils.b(java_nio_file_path)) { + if (java_nio_file_path.startsWith(this.e) && FileUtils.a(java_nio_file_path) && FileUtils.b(java_nio_file_path)) { return java_nio_file_path; } else { throw new ResourceKeyInvalidException("Invalid resource path: " + java_nio_file_path); diff --git a/src/main/java/net/minecraft/server/DimensionManager.java b/src/main/java/net/minecraft/server/DimensionManager.java new file mode 100644 index 000000000..ac03498fa --- /dev/null +++ b/src/main/java/net/minecraft/server/DimensionManager.java @@ -0,0 +1,95 @@ +package net.minecraft.server; + +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.DynamicOps; +import java.io.File; +import java.util.function.BiFunction; +import javax.annotation.Nullable; + +public class DimensionManager implements MinecraftSerializable { + + // CraftBukkit start + public static final DimensionManager OVERWORLD = register("overworld", new DimensionManager(1, "", "", WorldProviderNormal::new, true, null)); + public static final DimensionManager NETHER = register("the_nether", new DimensionManager(0, "_nether", "DIM-1", WorldProviderHell::new, false, null)); + public static final DimensionManager THE_END = register("the_end", new DimensionManager(2, "_end", "DIM1", WorldProviderTheEnd::new, false, null)); + // CraftBukkit end + private final int id; + private final String suffix; + public final String folder; + public final BiFunction providerFactory; + private final boolean hasSkyLight; + + public static DimensionManager register(String s, DimensionManager dimensionmanager) { + return (DimensionManager) IRegistry.a(IRegistry.DIMENSION_TYPE, dimensionmanager.id, s, dimensionmanager); + } + + // CraftBukkit - add type + public DimensionManager(int i, String s, String s1, BiFunction bifunction, boolean flag, DimensionManager type) { + this.id = i; + this.suffix = s; + this.folder = s1; + this.providerFactory = bifunction; + this.hasSkyLight = flag; + this.type = type; // CraftBukkit + } + + public static DimensionManager a(Dynamic dynamic) { + return (DimensionManager) IRegistry.DIMENSION_TYPE.get(new MinecraftKey(dynamic.asString(""))); + } + + public static Iterable a() { + return IRegistry.DIMENSION_TYPE; + } + + public int getDimensionID() { + return this.id + -1; + } + + public String getSuffix() { + return this.suffix; + } + + public File a(File file) { + return this.folder.isEmpty() ? file : new File(file, this.folder); + } + + public WorldProvider getWorldProvider(World world) { + return (WorldProvider) this.providerFactory.apply(world, this); + } + + public String toString() { + return a(this).toString(); + } + + @Nullable + public static DimensionManager a(int i) { + return (DimensionManager) IRegistry.DIMENSION_TYPE.fromId(i - -1); + } + + @Nullable + public static DimensionManager a(MinecraftKey minecraftkey) { + return (DimensionManager) IRegistry.DIMENSION_TYPE.get(minecraftkey); + } + + @Nullable + public static MinecraftKey a(DimensionManager dimensionmanager) { + return IRegistry.DIMENSION_TYPE.getKey(dimensionmanager); + } + + public boolean hasSkyLight() { + return this.hasSkyLight; + } + + @Override + public T a(DynamicOps dynamicops) { + return dynamicops.createString(IRegistry.DIMENSION_TYPE.getKey(this).toString()); + } + + // CraftBukkit start + private final DimensionManager type; + + public DimensionManager getType() { + return (type == null) ? this : type; + } + // CraftBukkit end +} diff --git a/src/main/java/net/minecraft/server/DispenseBehaviorBoat.java b/src/main/java/net/minecraft/server/DispenseBehaviorBoat.java new file mode 100644 index 000000000..174e3f92d --- /dev/null +++ b/src/main/java/net/minecraft/server/DispenseBehaviorBoat.java @@ -0,0 +1,78 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +// CraftBukkit end + +public class DispenseBehaviorBoat extends DispenseBehaviorItem { + + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + private final EntityBoat.EnumBoatType c; + + public DispenseBehaviorBoat(EntityBoat.EnumBoatType entityboat_enumboattype) { + this.c = entityboat_enumboattype; + } + + @Override + public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); + World world = isourceblock.getWorld(); + double d0 = isourceblock.getX() + (double) ((float) enumdirection.getAdjacentX() * 1.125F); + double d1 = isourceblock.getY() + (double) ((float) enumdirection.getAdjacentY() * 1.125F); + double d2 = isourceblock.getZ() + (double) ((float) enumdirection.getAdjacentZ() * 1.125F); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + double d3; + + if (world.getFluid(blockposition).a(TagsFluid.WATER)) { + d3 = 1.0D; + } else { + if (!world.getType(blockposition).isAir() || !world.getFluid(blockposition.down()).a(TagsFluid.WATER)) { + return this.b.dispense(isourceblock, itemstack); + } + + d3 = 0.0D; + } + + // EntityBoat entityboat = new EntityBoat(world, d0, d1 + d3, d2); + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + + EntityBoat entityboat = new EntityBoat(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); + // CraftBukkit end + + entityboat.setType(this.c); + entityboat.yaw = enumdirection.l(); + if (!world.addEntity(entityboat)) itemstack.add(1); // CraftBukkit + // itemstack.subtract(1); // CraftBukkit - handled during event processing + return itemstack; + } + + @Override + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); + } +} diff --git a/src/main/java/net/minecraft/server/DispenseBehaviorItem.java b/src/main/java/net/minecraft/server/DispenseBehaviorItem.java index ceb298b32..722c0048c 100644 --- a/src/main/java/net/minecraft/server/DispenseBehaviorItem.java +++ b/src/main/java/net/minecraft/server/DispenseBehaviorItem.java @@ -2,6 +2,7 @@ package net.minecraft.server; // CraftBukkit start import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftVector; import org.bukkit.event.block.BlockDispenseEvent; // CraftBukkit end @@ -9,16 +10,17 @@ public class DispenseBehaviorItem implements IDispenseBehavior { public DispenseBehaviorItem() {} + @Override public final ItemStack dispense(ISourceBlock isourceblock, ItemStack itemstack) { ItemStack itemstack1 = this.a(isourceblock, itemstack); this.a(isourceblock); - this.a(isourceblock, (EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); + this.a(isourceblock, (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING)); return itemstack1; } protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); IPosition iposition = BlockDispenser.a(isourceblock); ItemStack itemstack1 = itemstack.cloneAndSubtract(1); @@ -48,18 +50,13 @@ public class DispenseBehaviorItem implements IDispenseBehavior { EntityItem entityitem = new EntityItem(world, d0, d1, d2, itemstack); double d3 = world.random.nextDouble() * 0.1D + 0.2D; - entityitem.motX = (double) enumdirection.getAdjacentX() * d3; - entityitem.motY = 0.20000000298023224D; - entityitem.motZ = (double) enumdirection.getAdjacentZ() * d3; - entityitem.motX += world.random.nextGaussian() * 0.007499999832361937D * (double) i; - entityitem.motY += world.random.nextGaussian() * 0.007499999832361937D * (double) i; - entityitem.motZ += world.random.nextGaussian() * 0.007499999832361937D * (double) i; + entityitem.setMot(world.random.nextGaussian() * 0.007499999832361937D * (double) i + (double) enumdirection.getAdjacentX() * d3, world.random.nextGaussian() * 0.007499999832361937D * (double) i + 0.20000000298023224D, world.random.nextGaussian() * 0.007499999832361937D * (double) i + (double) enumdirection.getAdjacentZ() * d3); // CraftBukkit start - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(entityitem.motX, entityitem.motY, entityitem.motZ)); + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), CraftVector.toBukkit(entityitem.getMot())); if (!BlockDispenser.eventFired) { world.getServer().getPluginManager().callEvent(event); } @@ -69,9 +66,7 @@ public class DispenseBehaviorItem implements IDispenseBehavior { } entityitem.setItemStack(CraftItemStack.asNMSCopy(event.getItem())); - entityitem.motX = event.getVelocity().getX(); - entityitem.motY = event.getVelocity().getY(); - entityitem.motZ = event.getVelocity().getZ(); + entityitem.setMot(CraftVector.toNMS(event.getVelocity())); if (!event.getItem().getType().equals(craftItem.getType())) { // Chain to handler for new item diff --git a/src/main/java/net/minecraft/server/DispenseBehaviorProjectile.java b/src/main/java/net/minecraft/server/DispenseBehaviorProjectile.java index 4455be9ed..38f920538 100644 --- a/src/main/java/net/minecraft/server/DispenseBehaviorProjectile.java +++ b/src/main/java/net/minecraft/server/DispenseBehaviorProjectile.java @@ -9,16 +9,17 @@ public abstract class DispenseBehaviorProjectile extends DispenseBehaviorItem { public DispenseBehaviorProjectile() {} + @Override public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { World world = isourceblock.getWorld(); IPosition iposition = BlockDispenser.a(isourceblock); - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); IProjectile iprojectile = this.a(world, iposition, itemstack); // iprojectile.shoot((double) enumdirection.getAdjacentX(), (double) ((float) enumdirection.getAdjacentY() + 0.1F), (double) enumdirection.getAdjacentZ(), this.getPower(), this.a()); // CraftBukkit start ItemStack itemstack1 = itemstack.cloneAndSubtract(1); - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) enumdirection.getAdjacentX(), (double) ((float) enumdirection.getAdjacentY() + 0.1F), (double) enumdirection.getAdjacentZ())); @@ -50,6 +51,7 @@ public abstract class DispenseBehaviorProjectile extends DispenseBehaviorItem { return itemstack; } + @Override protected void a(ISourceBlock isourceblock) { isourceblock.getWorld().triggerEffect(1002, isourceblock.getBlockPosition(), 0); } diff --git a/src/main/java/net/minecraft/server/DispenseBehaviorShulkerBox.java b/src/main/java/net/minecraft/server/DispenseBehaviorShulkerBox.java new file mode 100644 index 000000000..d8f2e2f8e --- /dev/null +++ b/src/main/java/net/minecraft/server/DispenseBehaviorShulkerBox.java @@ -0,0 +1,51 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +// CraftBukkit end + +public class DispenseBehaviorShulkerBox extends DispenseBehaviorMaybe { + + public DispenseBehaviorShulkerBox() {} + + @Override + protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + this.dispensed = false; + Item item = itemstack.getItem(); + + if (item instanceof ItemBlock) { + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + EnumDirection enumdirection1 = isourceblock.getWorld().isEmpty(blockposition.down()) ? enumdirection : EnumDirection.UP; + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = isourceblock.getWorld().getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + if (!BlockDispenser.eventFired) { + isourceblock.getWorld().getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + this.dispensed = ((ItemBlock) item).a((BlockActionContext) (new BlockActionContextDirectional(isourceblock.getWorld(), blockposition, enumdirection, itemstack, enumdirection1))) == EnumInteractionResult.SUCCESS; + } + + return itemstack; + } +} diff --git a/src/main/java/net/minecraft/server/DispenserRegistry.java b/src/main/java/net/minecraft/server/DispenserRegistry.java index bc1ca9360..d474197c1 100644 --- a/src/main/java/net/minecraft/server/DispenserRegistry.java +++ b/src/main/java/net/minecraft/server/DispenserRegistry.java @@ -1,8 +1,8 @@ package net.minecraft.server; import java.io.PrintStream; -import java.util.Iterator; -import java.util.Random; +import java.util.Set; +import java.util.TreeSet; import java.util.function.Function; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -21,686 +21,44 @@ public class DispenserRegistry { public static final PrintStream a = System.out; private static boolean b; - private static final Logger c = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); - public static boolean a() { - return DispenserRegistry.b; - } - - static void b() { - BlockDispenser.a((IMaterial) Items.ARROW, (IDispenseBehavior) (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { - EntityTippedArrow entitytippedarrow = new EntityTippedArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); - - entitytippedarrow.fromPlayer = EntityArrow.PickupStatus.ALLOWED; - return entitytippedarrow; - } - })); - BlockDispenser.a((IMaterial) Items.TIPPED_ARROW, (IDispenseBehavior) (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { - EntityTippedArrow entitytippedarrow = new EntityTippedArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); - - entitytippedarrow.b(itemstack); - entitytippedarrow.fromPlayer = EntityArrow.PickupStatus.ALLOWED; - return entitytippedarrow; - } - })); - BlockDispenser.a((IMaterial) Items.SPECTRAL_ARROW, (IDispenseBehavior) (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { - EntitySpectralArrow entityspectralarrow = new EntitySpectralArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); - - entityspectralarrow.fromPlayer = EntityArrow.PickupStatus.ALLOWED; - return entityspectralarrow; - } - })); - BlockDispenser.a((IMaterial) Items.EGG, (IDispenseBehavior) (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { - return new EntityEgg(world, iposition.getX(), iposition.getY(), iposition.getZ()); - } - })); - BlockDispenser.a((IMaterial) Items.SNOWBALL, (IDispenseBehavior) (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { - return new EntitySnowball(world, iposition.getX(), iposition.getY(), iposition.getZ()); - } - })); - BlockDispenser.a((IMaterial) Items.EXPERIENCE_BOTTLE, (IDispenseBehavior) (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { - return new EntityThrownExpBottle(world, iposition.getX(), iposition.getY(), iposition.getZ()); - } - - protected float a() { - return super.a() * 0.5F; - } - - protected float getPower() { - return super.getPower() * 1.25F; - } - })); - BlockDispenser.a((IMaterial) Items.SPLASH_POTION, new IDispenseBehavior() { - public ItemStack dispense(ISourceBlock isourceblock, final ItemStack itemstack) { - return (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack1) { - return new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), itemstack.cloneItemStack()); - } - - protected float a() { - return super.a() * 0.5F; - } - - protected float getPower() { - return super.getPower() * 1.25F; - } - }).dispense(isourceblock, itemstack); - } - }); - BlockDispenser.a((IMaterial) Items.LINGERING_POTION, new IDispenseBehavior() { - public ItemStack dispense(ISourceBlock isourceblock, final ItemStack itemstack) { - return (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack1) { - return new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), itemstack.cloneItemStack()); - } - - protected float a() { - return super.a() * 0.5F; - } - - protected float getPower() { - return super.getPower() * 1.25F; - } - }).dispense(isourceblock, itemstack); - } - }); - DispenseBehaviorItem dispensebehavioritem = new DispenseBehaviorItem() { - public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); - EntityTypes entitytypes = ((ItemMonsterEgg) itemstack.getItem()).b(itemstack.getTag()); - - // CraftBukkit start - World world = isourceblock.getWorld(); - ItemStack itemstack1 = itemstack.cloneAndSubtract(1); - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); - - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - itemstack.add(1); - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - itemstack.add(1); - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - - if (entitytypes != null) { - entitytypes.a(isourceblock.getWorld(), itemstack, (EntityHuman) null, isourceblock.getBlockPosition().shift(enumdirection), enumdirection != EnumDirection.UP, false); - } - - // itemstack.subtract(1); // Handled during event processing - // CraftBukkit end - return itemstack; - } - }; - Iterator iterator = ItemMonsterEgg.d().iterator(); - - while (iterator.hasNext()) { - ItemMonsterEgg itemmonsteregg = (ItemMonsterEgg) iterator.next(); - - BlockDispenser.a((IMaterial) itemmonsteregg, (IDispenseBehavior) dispensebehavioritem); - } - - BlockDispenser.a((IMaterial) Items.FIREWORK_ROCKET, (IDispenseBehavior) (new DispenseBehaviorItem() { - public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); - double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); - double d1 = (double) ((float) isourceblock.getBlockPosition().getY() + 0.2F); - double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); - // CraftBukkit start - World world = isourceblock.getWorld(); - ItemStack itemstack1 = itemstack.cloneAndSubtract(1); - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); - - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - itemstack.add(1); - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - itemstack.add(1); - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - - itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); - EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), itemstack1); - - isourceblock.getWorld().addEntity(entityfireworks); - // itemstack.subtract(1); // Handled during event processing - // CraftBukkit end - return itemstack; - } - - protected void a(ISourceBlock isourceblock) { - isourceblock.getWorld().triggerEffect(1004, isourceblock.getBlockPosition(), 0); - } - })); - BlockDispenser.a((IMaterial) Items.FIRE_CHARGE, (IDispenseBehavior) (new DispenseBehaviorItem() { - public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); - IPosition iposition = BlockDispenser.a(isourceblock); - double d0 = iposition.getX() + (double) ((float) enumdirection.getAdjacentX() * 0.3F); - double d1 = iposition.getY() + (double) ((float) enumdirection.getAdjacentY() * 0.3F); - double d2 = iposition.getZ() + (double) ((float) enumdirection.getAdjacentZ() * 0.3F); - World world = isourceblock.getWorld(); - Random random = world.random; - double d3 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentX(); - double d4 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentY(); - double d5 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentZ(); - - // CraftBukkit start - ItemStack itemstack1 = itemstack.cloneAndSubtract(1); - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); - - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d3, d4, d5)); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - itemstack.add(1); - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - itemstack.add(1); - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - - EntitySmallFireball fireball = new EntitySmallFireball(world, d0, d1, d2, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); - fireball.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) isourceblock.getTileEntity()); - - world.addEntity(fireball); - // itemstack.subtract(1); // Handled during event processing - // CraftBukkit end - return itemstack; - } - - protected void a(ISourceBlock isourceblock) { - isourceblock.getWorld().triggerEffect(1018, isourceblock.getBlockPosition(), 0); - } - })); - BlockDispenser.a((IMaterial) Items.OAK_BOAT, (IDispenseBehavior) (new DispenserRegistry.a(EntityBoat.EnumBoatType.OAK))); - BlockDispenser.a((IMaterial) Items.SPRUCE_BOAT, (IDispenseBehavior) (new DispenserRegistry.a(EntityBoat.EnumBoatType.SPRUCE))); - BlockDispenser.a((IMaterial) Items.BIRCH_BOAT, (IDispenseBehavior) (new DispenserRegistry.a(EntityBoat.EnumBoatType.BIRCH))); - BlockDispenser.a((IMaterial) Items.JUNGLE_BOAT, (IDispenseBehavior) (new DispenserRegistry.a(EntityBoat.EnumBoatType.JUNGLE))); - BlockDispenser.a((IMaterial) Items.DARK_OAK_BOAT, (IDispenseBehavior) (new DispenserRegistry.a(EntityBoat.EnumBoatType.DARK_OAK))); - BlockDispenser.a((IMaterial) Items.ACACIA_BOAT, (IDispenseBehavior) (new DispenserRegistry.a(EntityBoat.EnumBoatType.ACACIA))); - DispenseBehaviorItem dispensebehavioritem1 = new DispenseBehaviorItem() { - private final DispenseBehaviorItem a = new DispenseBehaviorItem(); - - public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - ItemBucket itembucket = (ItemBucket) itemstack.getItem(); - BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); - World world = isourceblock.getWorld(); - - // CraftBukkit start - int x = blockposition.getX(); - int y = blockposition.getY(); - int z = blockposition.getZ(); - IBlockData iblockdata = world.getType(blockposition); - Material material = iblockdata.getMaterial(); - if (world.isEmpty(blockposition) || !material.isBuildable() || material.isReplaceable() || ((iblockdata.getBlock() instanceof IFluidContainer) && ((IFluidContainer) iblockdata.getBlock()).canPlace(world, blockposition, iblockdata, itembucket.fluidType))) { - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); - - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - - itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); - } - // CraftBukkit end - - if (itembucket.a((EntityHuman) null, world, blockposition, (MovingObjectPosition) null)) { - itembucket.a(world, itemstack, blockposition); - // CraftBukkit start - Handle stacked buckets - Item item = Items.BUCKET; - itemstack.subtract(1); - if (itemstack.isEmpty()) { - itemstack.setItem(Items.BUCKET); - itemstack.setCount(1); - } else if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { - this.a.dispense(isourceblock, new ItemStack(item)); - } - // CraftBukkit end - return itemstack; - } else { - return this.a.dispense(isourceblock, itemstack); - } - } - }; - - BlockDispenser.a((IMaterial) Items.LAVA_BUCKET, (IDispenseBehavior) dispensebehavioritem1); - BlockDispenser.a((IMaterial) Items.WATER_BUCKET, (IDispenseBehavior) dispensebehavioritem1); - BlockDispenser.a((IMaterial) Items.SALMON_BUCKET, (IDispenseBehavior) dispensebehavioritem1); - BlockDispenser.a((IMaterial) Items.COD_BUCKET, (IDispenseBehavior) dispensebehavioritem1); - BlockDispenser.a((IMaterial) Items.PUFFERFISH_BUCKET, (IDispenseBehavior) dispensebehavioritem1); - BlockDispenser.a((IMaterial) Items.TROPICAL_FISH_BUCKET, (IDispenseBehavior) dispensebehavioritem1); - BlockDispenser.a((IMaterial) Items.BUCKET, (IDispenseBehavior) (new DispenseBehaviorItem() { - private final DispenseBehaviorItem a = new DispenseBehaviorItem(); - - public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - World world = isourceblock.getWorld(); - BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); - IBlockData iblockdata = world.getType(blockposition); - Block block = iblockdata.getBlock(); - - if (block instanceof IFluidSource) { - FluidType fluidtype = ((IFluidSource) block).removeFluid(DummyGeneratorAccess.INSTANCE, blockposition, iblockdata); // CraftBukkit - - if (!(fluidtype instanceof FluidTypeFlowing)) { - return super.a(isourceblock, itemstack); - } else { - Item item = fluidtype.b(); - - // CraftBukkit start - org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); - - BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - - fluidtype = ((IFluidSource) block).removeFluid(world, blockposition, iblockdata); // From above - // CraftBukkit end - - itemstack.subtract(1); - if (itemstack.isEmpty()) { - return new ItemStack(item); - } else { - if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { - this.a.dispense(isourceblock, new ItemStack(item)); - } - - return itemstack; - } - } - } else { - return super.a(isourceblock, itemstack); - } - } - })); - BlockDispenser.a((IMaterial) Items.FLINT_AND_STEEL, (IDispenseBehavior) (new DispenserRegistry.DispenseBehaviorMaybe() { - protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - World world = isourceblock.getWorld(); - - // CraftBukkit start - org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); - - BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - // CraftBukkit end - - this.a = true; - BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); - - if (ItemFlintAndSteel.a((GeneratorAccess) world, blockposition)) { - // CraftBukkit start - Ignition by dispensing flint and steel - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, isourceblock.getBlockPosition()).isCancelled()) { - world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); - } - // CraftBukkit end - } else { - Block block = world.getType(blockposition).getBlock(); - - if (block instanceof BlockTNT) { - ((BlockTNT) block).a(world, blockposition); - world.setAir(blockposition); - } else { - this.a = false; - } - } - - if (this.a && itemstack.isDamaged(1, world.random, (EntityPlayer) null)) { - itemstack.setCount(0); - } - - return itemstack; - } - })); - BlockDispenser.a((IMaterial) Items.BONE_MEAL, (IDispenseBehavior) (new DispenserRegistry.DispenseBehaviorMaybe() { - protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - this.a = true; - World world = isourceblock.getWorld(); - BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); - // CraftBukkit start - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); - - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - - world.captureTreeGeneration = true; - // CraftBukkit end - - if (!ItemBoneMeal.a(itemstack, world, blockposition) && !ItemBoneMeal.a(itemstack, world, blockposition, (EnumDirection) null)) { - this.a = false; - } else if (!world.isClientSide) { - world.triggerEffect(2005, blockposition, 0); - } - // CraftBukkit start - world.captureTreeGeneration = false; - if (world.capturedBlockStates.size() > 0) { - TreeType treeType = BlockSapling.treeType; - BlockSapling.treeType = null; - Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); - List blocks = (List) world.capturedBlockStates.clone(); - world.capturedBlockStates.clear(); - StructureGrowEvent structureEvent = null; - if (treeType != null) { - structureEvent = new StructureGrowEvent(location, treeType, false, null, blocks); - org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent); - } - if (structureEvent == null || !structureEvent.isCancelled()) { - for (org.bukkit.block.BlockState blockstate : blocks) { - blockstate.update(true); - } - } - } - // CraftBukkit end - - return itemstack; - } - })); - BlockDispenser.a((IMaterial) Blocks.TNT, (IDispenseBehavior) (new DispenseBehaviorItem() { - protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - World world = isourceblock.getWorld(); - BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); - // EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, (EntityLiving) null); - - // CraftBukkit start - ItemStack itemstack1 = itemstack.cloneAndSubtract(1); - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); - - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D)); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - itemstack.add(1); - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - itemstack.add(1); - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - - EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), (EntityLiving) null); - // CraftBukkit end - - world.addEntity(entitytntprimed); - world.a((EntityHuman) null, entitytntprimed.locX, entitytntprimed.locY, entitytntprimed.locZ, SoundEffects.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F); - // itemstack.subtract(1); // CraftBukkit - handled above - return itemstack; - } - })); - DispenserRegistry.DispenseBehaviorMaybe dispenserregistry_dispensebehaviormaybe = new DispenserRegistry.DispenseBehaviorMaybe() { - protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - this.a = !ItemArmor.a(isourceblock, itemstack).isEmpty(); - return itemstack; - } - }; - - BlockDispenser.a((IMaterial) Items.CREEPER_HEAD, (IDispenseBehavior) dispenserregistry_dispensebehaviormaybe); - BlockDispenser.a((IMaterial) Items.ZOMBIE_HEAD, (IDispenseBehavior) dispenserregistry_dispensebehaviormaybe); - BlockDispenser.a((IMaterial) Items.DRAGON_HEAD, (IDispenseBehavior) dispenserregistry_dispensebehaviormaybe); - BlockDispenser.a((IMaterial) Items.SKELETON_SKULL, (IDispenseBehavior) dispenserregistry_dispensebehaviormaybe); - BlockDispenser.a((IMaterial) Items.PLAYER_HEAD, (IDispenseBehavior) dispenserregistry_dispensebehaviormaybe); - BlockDispenser.a((IMaterial) Items.WITHER_SKELETON_SKULL, (IDispenseBehavior) (new DispenserRegistry.DispenseBehaviorMaybe() { - protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - World world = isourceblock.getWorld(); - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); - BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); - - // CraftBukkit start - org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); - - BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - // CraftBukkit end - - this.a = true; - if (world.isEmpty(blockposition) && BlockWitherSkull.b(world, blockposition, itemstack)) { - world.setTypeAndData(blockposition, (IBlockData) Blocks.WITHER_SKELETON_SKULL.getBlockData().set(BlockSkull.a, enumdirection.k() == EnumDirection.EnumAxis.Y ? 0 : enumdirection.opposite().get2DRotationValue() * 4), 3); - TileEntity tileentity = world.getTileEntity(blockposition); - - if (tileentity instanceof TileEntitySkull) { - BlockWitherSkull.a(world, blockposition, (TileEntitySkull) tileentity); - } - - itemstack.subtract(1); - } else if (ItemArmor.a(isourceblock, itemstack).isEmpty()) { - this.a = false; - } - - return itemstack; - } - })); - BlockDispenser.a((IMaterial) Blocks.CARVED_PUMPKIN, (IDispenseBehavior) (new DispenserRegistry.DispenseBehaviorMaybe() { - protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - World world = isourceblock.getWorld(); - BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); - BlockPumpkinCarved blockpumpkincarved = (BlockPumpkinCarved) Blocks.CARVED_PUMPKIN; - - // CraftBukkit start - org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); - - BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - // CraftBukkit end - - this.a = true; - if (world.isEmpty(blockposition) && blockpumpkincarved.a((IWorldReader) world, blockposition)) { - if (!world.isClientSide) { - world.setTypeAndData(blockposition, blockpumpkincarved.getBlockData(), 3); - } - - itemstack.subtract(1); - } else { - ItemStack itemstack1 = ItemArmor.a(isourceblock, itemstack); - - if (itemstack1.isEmpty()) { - this.a = false; - } - } - - return itemstack; - } - })); - BlockDispenser.a((IMaterial) Blocks.SHULKER_BOX.getItem(), (IDispenseBehavior) (new DispenserRegistry.d())); - EnumColor[] aenumcolor = EnumColor.values(); - int i = aenumcolor.length; - - for (int j = 0; j < i; ++j) { - EnumColor enumcolor = aenumcolor[j]; - - BlockDispenser.a((IMaterial) BlockShulkerBox.a(enumcolor).getItem(), (IDispenseBehavior) (new DispenserRegistry.d())); - } - - } - - public static void c() { + public static void init() { if (!DispenserRegistry.b) { DispenserRegistry.b = true; - SoundEffect.b(); - FluidType.l(); - Block.t(); - BlockFire.d(); - MobEffectList.m(); - Enchantment.h(); - if (EntityTypes.getName(EntityTypes.PLAYER) == null) { - throw new IllegalStateException("Failed loading EntityTypes"); + if (IRegistry.f.c()) { + throw new IllegalStateException("Unable to load registries"); } else { - Item.r(); - PotionRegistry.b(); - PotionBrewer.a(); - BiomeBase.t(); - PlayerSelector.a(); - Particle.c(); - b(); - ArgumentRegistry.a(); - BiomeLayout.a(); - TileEntityTypes.a(); - ChunkGeneratorType.a(); - DimensionManager.a(); - Paintings.a(); - StatisticList.a(); - IRegistry.e(); - if (SharedConstants.b) { - a("block", IRegistry.BLOCK, Block::m); - a("biome", IRegistry.BIOME, BiomeBase::k); - a("enchantment", IRegistry.ENCHANTMENT, Enchantment::g); - a("item", IRegistry.ITEM, Item::getName); - a("effect", IRegistry.MOB_EFFECT, MobEffectList::c); - a("entity", IRegistry.ENTITY_TYPE, EntityTypes::d); + BlockFire.d(); + BlockComposter.d(); + if (EntityTypes.getName(EntityTypes.PLAYER) == null) { + throw new IllegalStateException("Failed loading EntityTypes"); + } else { + PotionBrewer.a(); + PlayerSelector.a(); + IDispenseBehavior.c(); + ArgumentRegistry.a(); + d(); } - - d(); // CraftBukkit start - easier than fixing the decompile + DataConverterFlattenData.a(1008, "{Name:'minecraft:oak_sign',Properties:{rotation:'0'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'0'}}"); + DataConverterFlattenData.a(1009, "{Name:'minecraft:oak_sign',Properties:{rotation:'1'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'1'}}"); + DataConverterFlattenData.a(1010, "{Name:'minecraft:oak_sign',Properties:{rotation:'2'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'2'}}"); + DataConverterFlattenData.a(1011, "{Name:'minecraft:oak_sign',Properties:{rotation:'3'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'3'}}"); + DataConverterFlattenData.a(1012, "{Name:'minecraft:oak_sign',Properties:{rotation:'4'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'4'}}"); + DataConverterFlattenData.a(1013, "{Name:'minecraft:oak_sign',Properties:{rotation:'5'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'5'}}"); + DataConverterFlattenData.a(1014, "{Name:'minecraft:oak_sign',Properties:{rotation:'6'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'6'}}"); + DataConverterFlattenData.a(1015, "{Name:'minecraft:oak_sign',Properties:{rotation:'7'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'7'}}"); + DataConverterFlattenData.a(1016, "{Name:'minecraft:oak_sign',Properties:{rotation:'8'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'8'}}"); + DataConverterFlattenData.a(1017, "{Name:'minecraft:oak_sign',Properties:{rotation:'9'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'9'}}"); + DataConverterFlattenData.a(1018, "{Name:'minecraft:oak_sign',Properties:{rotation:'10'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'10'}}"); + DataConverterFlattenData.a(1019, "{Name:'minecraft:oak_sign',Properties:{rotation:'11'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'11'}}"); + DataConverterFlattenData.a(1020, "{Name:'minecraft:oak_sign',Properties:{rotation:'12'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'12'}}"); + DataConverterFlattenData.a(1021, "{Name:'minecraft:oak_sign',Properties:{rotation:'13'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'13'}}"); + DataConverterFlattenData.a(1022, "{Name:'minecraft:oak_sign',Properties:{rotation:'14'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'14'}}"); + DataConverterFlattenData.a(1023, "{Name:'minecraft:oak_sign',Properties:{rotation:'15'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'15'}}"); + DataConverterMaterialId.ID_MAPPING.put(323, "minecraft:oak_sign"); + DataConverterFlattenData.a(1440, "{Name:\'minecraft:portal\',Properties:{axis:\'x\'}}", new String[]{"{Name:\'minecraft:portal\',Properties:{axis:\'x\'}}"}); DataConverterMaterialId.ID_MAPPING.put(409, "minecraft:prismarine_shard"); @@ -749,21 +107,46 @@ public class DispenserRegistry { } } - private static void a(String s, IRegistry iregistry, Function function) { + private static void a(IRegistry iregistry, Function function, Set set) { LocaleLanguage localelanguage = LocaleLanguage.a(); iregistry.iterator().forEachRemaining((object) -> { - String s1 = (String) function.apply(object); + String s = (String) function.apply(object); - if (!localelanguage.b(s1)) { - DispenserRegistry.c.warn("Missing translation for {}: {} (key: '{}')", s, iregistry.getKey(object), s1); + if (!localelanguage.b(s)) { + set.add(s); } }); } + public static Set b() { + Set set = new TreeSet(); + + a(IRegistry.ENTITY_TYPE, EntityTypes::f, set); + a(IRegistry.MOB_EFFECT, MobEffectList::c, set); + a(IRegistry.ITEM, Item::getName, set); + a(IRegistry.ENCHANTMENT, Enchantment::g, set); + a(IRegistry.BIOME, BiomeBase::j, set); + a(IRegistry.BLOCK, Block::l, set); + a(IRegistry.CUSTOM_STAT, (minecraftkey) -> { + return "stat." + minecraftkey.toString().replace(':', '.'); + }, set); + return set; + } + + public static void c() { + if (!DispenserRegistry.b) { + throw new IllegalArgumentException("Not bootstrapped"); + } else if (!SharedConstants.b) { + b().forEach((s) -> { + DispenserRegistry.LOGGER.error("Missing translations: " + s); + }); + } + } + private static void d() { - if (DispenserRegistry.c.isDebugEnabled()) { + if (DispenserRegistry.LOGGER.isDebugEnabled()) { System.setErr(new DebugOutputStream("STDERR", System.err)); System.setOut(new DebugOutputStream("STDOUT", DispenserRegistry.a)); } else { @@ -773,187 +156,7 @@ public class DispenserRegistry { } - static class b extends BlockActionContext { - - private final EnumDirection j; - - public b(World world, BlockPosition blockposition, EnumDirection enumdirection, ItemStack itemstack, EnumDirection enumdirection1) { - super(world, (EntityHuman) null, itemstack, blockposition, enumdirection1, 0.5F, 0.0F, 0.5F); - this.j = enumdirection; - } - - public BlockPosition getClickPosition() { - return this.i; - } - - public boolean b() { - return this.g.getType(this.i).a((BlockActionContext) this); - } - - public boolean c() { - return this.b(); - } - - public EnumDirection d() { - return EnumDirection.DOWN; - } - - public EnumDirection[] e() { - switch (this.j) { - case DOWN: - default: - return new EnumDirection[] { EnumDirection.DOWN, EnumDirection.NORTH, EnumDirection.EAST, EnumDirection.SOUTH, EnumDirection.WEST, EnumDirection.UP}; - case UP: - return new EnumDirection[] { EnumDirection.DOWN, EnumDirection.UP, EnumDirection.NORTH, EnumDirection.EAST, EnumDirection.SOUTH, EnumDirection.WEST}; - case NORTH: - return new EnumDirection[] { EnumDirection.DOWN, EnumDirection.NORTH, EnumDirection.EAST, EnumDirection.WEST, EnumDirection.UP, EnumDirection.SOUTH}; - case SOUTH: - return new EnumDirection[] { EnumDirection.DOWN, EnumDirection.SOUTH, EnumDirection.EAST, EnumDirection.WEST, EnumDirection.UP, EnumDirection.NORTH}; - case WEST: - return new EnumDirection[] { EnumDirection.DOWN, EnumDirection.WEST, EnumDirection.SOUTH, EnumDirection.UP, EnumDirection.NORTH, EnumDirection.EAST}; - case EAST: - return new EnumDirection[] { EnumDirection.DOWN, EnumDirection.EAST, EnumDirection.SOUTH, EnumDirection.UP, EnumDirection.NORTH, EnumDirection.WEST}; - } - } - - public EnumDirection f() { - return this.j.k() == EnumDirection.EnumAxis.Y ? EnumDirection.NORTH : this.j; - } - - public boolean isSneaking() { - return false; - } - - public float h() { - return (float) (this.j.get2DRotationValue() * 90); - } - } - - static class d extends DispenserRegistry.DispenseBehaviorMaybe { - - private d() {} - - protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - this.a = false; - Item item = itemstack.getItem(); - - if (item instanceof ItemBlock) { - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); - BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); - EnumDirection enumdirection1 = isourceblock.getWorld().isEmpty(blockposition.down()) ? enumdirection : EnumDirection.UP; - - // CraftBukkit start - org.bukkit.block.Block bukkitBlock = isourceblock.getWorld().getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); - - BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); - if (!BlockDispenser.eventFired) { - isourceblock.getWorld().getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - // CraftBukkit end - - this.a = ((ItemBlock) item).a((BlockActionContext) (new DispenserRegistry.b(isourceblock.getWorld(), blockposition, enumdirection, itemstack, enumdirection1))) == EnumInteractionResult.SUCCESS; - if (this.a) { - itemstack.subtract(1); - } - } - - return itemstack; - } - } - - public abstract static class DispenseBehaviorMaybe extends DispenseBehaviorItem { - - protected boolean a = true; - - public DispenseBehaviorMaybe() {} - - protected void a(ISourceBlock isourceblock) { - isourceblock.getWorld().triggerEffect(this.a ? 1000 : 1001, isourceblock.getBlockPosition(), 0); - } - } - - public static class a extends DispenseBehaviorItem { - - private final DispenseBehaviorItem a = new DispenseBehaviorItem(); - private final EntityBoat.EnumBoatType b; - - public a(EntityBoat.EnumBoatType entityboat_enumboattype) { - this.b = entityboat_enumboattype; - } - - public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); - World world = isourceblock.getWorld(); - double d0 = isourceblock.getX() + (double) ((float) enumdirection.getAdjacentX() * 1.125F); - double d1 = isourceblock.getY() + (double) ((float) enumdirection.getAdjacentY() * 1.125F); - double d2 = isourceblock.getZ() + (double) ((float) enumdirection.getAdjacentZ() * 1.125F); - BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); - double d3; - - if (world.getFluid(blockposition).a(TagsFluid.WATER)) { - d3 = 1.0D; - } else { - if (!world.getType(blockposition).isAir() || !world.getFluid(blockposition.down()).a(TagsFluid.WATER)) { - return this.a.dispense(isourceblock, itemstack); - } - - d3 = 0.0D; - } - - // EntityBoat entityboat = new EntityBoat(world, d0, d1 + d3, d2); - // CraftBukkit start - ItemStack itemstack1 = itemstack.cloneAndSubtract(1); - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); - - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); - if (!BlockDispenser.eventFired) { - world.getServer().getPluginManager().callEvent(event); - } - - if (event.isCancelled()) { - itemstack.add(1); - return itemstack; - } - - if (!event.getItem().equals(craftItem)) { - itemstack.add(1); - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); - if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { - idispensebehavior.dispense(isourceblock, eventStack); - return itemstack; - } - } - - EntityBoat entityboat = new EntityBoat(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); - // CraftBukkit end - - entityboat.setType(this.b); - entityboat.yaw = enumdirection.l(); - if (!world.addEntity(entityboat)) itemstack.add(1); // CraftBukkit - // itemstack.subtract(1); // CraftBukkit - handled during event processing - return itemstack; - } - - protected void a(ISourceBlock isourceblock) { - isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); - } + public static void a(String s) { + DispenserRegistry.a.println(s); } } diff --git a/src/main/java/net/minecraft/server/DragonControllerLandedFlame.java b/src/main/java/net/minecraft/server/DragonControllerLandedFlame.java index 50d291139..577d1d207 100644 --- a/src/main/java/net/minecraft/server/DragonControllerLandedFlame.java +++ b/src/main/java/net/minecraft/server/DragonControllerLandedFlame.java @@ -10,15 +10,16 @@ public class DragonControllerLandedFlame extends AbstractDragonControllerLanded super(entityenderdragon); } + @Override public void b() { ++this.b; if (this.b % 2 == 0 && this.b < 10) { - Vec3D vec3d = this.a.a(1.0F).a(); + Vec3D vec3d = this.a.u(1.0F).d(); vec3d.b(-0.7853982F); - double d0 = this.a.bD.locX; - double d1 = this.a.bD.locY + (double) (this.a.bD.length / 2.0F); - double d2 = this.a.bD.locZ; + double d0 = this.a.bA.locX; + double d1 = this.a.bA.locY + (double) (this.a.bA.getHeight() / 2.0F); + double d2 = this.a.bA.locZ; for (int i = 0; i < 8; ++i) { double d3 = d0 + this.a.getRandom().nextGaussian() / 2.0D; @@ -26,7 +27,7 @@ public class DragonControllerLandedFlame extends AbstractDragonControllerLanded double d5 = d2 + this.a.getRandom().nextGaussian() / 2.0D; for (int j = 0; j < 6; ++j) { - this.a.world.addParticle(Particles.j, d3, d4, d5, -vec3d.x * 0.07999999821186066D * (double) j, -vec3d.y * 0.6000000238418579D, -vec3d.z * 0.07999999821186066D * (double) j); + this.a.world.addParticle(Particles.DRAGON_BREATH, d3, d4, d5, -vec3d.x * 0.07999999821186066D * (double) j, -vec3d.y * 0.6000000238418579D, -vec3d.z * 0.07999999821186066D * (double) j); } vec3d.b(0.19634955F); @@ -35,6 +36,7 @@ public class DragonControllerLandedFlame extends AbstractDragonControllerLanded } + @Override public void c() { ++this.b; if (this.b >= 200) { @@ -44,16 +46,16 @@ public class DragonControllerLandedFlame extends AbstractDragonControllerLanded this.a.getDragonControllerManager().setControllerPhase(DragonControllerPhase.SITTING_SCANNING); } } else if (this.b == 10) { - Vec3D vec3d = (new Vec3D(this.a.bD.locX - this.a.locX, 0.0D, this.a.bD.locZ - this.a.locZ)).a(); + Vec3D vec3d = (new Vec3D(this.a.bA.locX - this.a.locX, 0.0D, this.a.bA.locZ - this.a.locZ)).d(); float f = 5.0F; - double d0 = this.a.bD.locX + vec3d.x * 5.0D / 2.0D; - double d1 = this.a.bD.locZ + vec3d.z * 5.0D / 2.0D; - double d2 = this.a.bD.locY + (double) (this.a.bD.length / 2.0F); - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(MathHelper.floor(d0), MathHelper.floor(d2), MathHelper.floor(d1)); + double d0 = this.a.bA.locX + vec3d.x * 5.0D / 2.0D; + double d1 = this.a.bA.locZ + vec3d.z * 5.0D / 2.0D; + double d2 = this.a.bA.locY + (double) (this.a.bA.getHeight() / 2.0F); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(d0, d2, d1); while (this.a.world.isEmpty(blockposition_mutableblockposition ) && d2 > 0) { // Paper --d2; - blockposition_mutableblockposition.c(MathHelper.floor(d0), MathHelper.floor(d2), MathHelper.floor(d1)); + blockposition_mutableblockposition.c(d0, d2, d1); } d2 = (double) (MathHelper.floor(d2) + 1); @@ -61,21 +63,25 @@ public class DragonControllerLandedFlame extends AbstractDragonControllerLanded this.d.setSource(this.a); this.d.setRadius(5.0F); this.d.setDuration(200); - this.d.setParticle(Particles.j); - this.d.a(new MobEffect(MobEffects.HARM)); - if (new com.destroystokyo.paper.event.entity.EnderDragonFlameEvent((org.bukkit.entity.EnderDragon) this.a.getBukkitEntity(), (org.bukkit.entity.AreaEffectCloud) this.d.getBukkitEntity()).callEvent()) // Paper + this.d.setParticle(Particles.DRAGON_BREATH); + this.d.addEffect(new MobEffect(MobEffects.HARM)); + if (new com.destroystokyo.paper.event.entity.EnderDragonFlameEvent((org.bukkit.entity.EnderDragon) this.a.getBukkitEntity(), (org.bukkit.entity.AreaEffectCloud) this.d.getBukkitEntity()).callEvent()) { // Paper this.a.world.addEntity(this.d); - else this.removeAreaEffect(); // Paper + } else { + this.removeAreaEffect(); + } } } + @Override public void d() { this.b = 0; ++this.c; } public void removeAreaEffect() { this.e(); } // Paper - OBFHELPER + @Override public void e() { if (this.d != null) { this.d.die(); @@ -84,6 +90,7 @@ public class DragonControllerLandedFlame extends AbstractDragonControllerLanded } + @Override public DragonControllerPhase getControllerPhase() { return DragonControllerPhase.SITTING_FLAMING; } diff --git a/src/main/java/net/minecraft/server/DragonControllerManager.java b/src/main/java/net/minecraft/server/DragonControllerManager.java index 77df77a12..551387dc0 100644 --- a/src/main/java/net/minecraft/server/DragonControllerManager.java +++ b/src/main/java/net/minecraft/server/DragonControllerManager.java @@ -9,7 +9,7 @@ import org.bukkit.event.entity.EnderDragonChangePhaseEvent; public class DragonControllerManager { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private final EntityEnderDragon enderDragon; private final IDragonController[] dragonControllers = new IDragonController[DragonControllerPhase.c()]; private IDragonController currentDragonController; @@ -43,7 +43,7 @@ public class DragonControllerManager { this.enderDragon.getDataWatcher().set(EntityEnderDragon.PHASE, dragoncontrollerphase.b()); } - DragonControllerManager.a.debug("Dragon is now in phase {} on the {}", dragoncontrollerphase, this.enderDragon.world.isClientSide ? "client" : "server"); + DragonControllerManager.LOGGER.debug("Dragon is now in phase {} on the {}", dragoncontrollerphase, this.enderDragon.world.isClientSide ? "client" : "server"); this.currentDragonController.d(); } } diff --git a/src/main/java/net/minecraft/server/DragonControllerStrafe.java b/src/main/java/net/minecraft/server/DragonControllerStrafe.java index 141ba1e5e..0b0815e11 100644 --- a/src/main/java/net/minecraft/server/DragonControllerStrafe.java +++ b/src/main/java/net/minecraft/server/DragonControllerStrafe.java @@ -6,7 +6,7 @@ import org.apache.logging.log4j.Logger; public class DragonControllerStrafe extends AbstractDragonController { - private static final Logger b = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private int c; private PathEntity d; private Vec3D e; @@ -17,9 +17,10 @@ public class DragonControllerStrafe extends AbstractDragonController { super(entityenderdragon); } + @Override public void c() { if (this.f == null) { - DragonControllerStrafe.b.warn("Skipping player strafe phase because no player was found"); + DragonControllerStrafe.LOGGER.warn("Skipping player strafe phase because no player was found"); this.a.getDragonControllerManager().setControllerPhase(DragonControllerPhase.HOLDING_PATTERN); } else { double d0; @@ -44,11 +45,11 @@ public class DragonControllerStrafe extends AbstractDragonController { } d1 = 64.0D; - if (this.f.h(this.a) < 4096.0D) { + if (this.f.h((Entity) this.a) < 4096.0D) { if (this.a.hasLineOfSight(this.f)) { ++this.c; - Vec3D vec3d = (new Vec3D(this.f.locX - this.a.locX, 0.0D, this.f.locZ - this.a.locZ)).a(); - Vec3D vec3d1 = (new Vec3D((double) MathHelper.sin(this.a.yaw * 0.017453292F), 0.0D, (double) (-MathHelper.cos(this.a.yaw * 0.017453292F)))).a(); + Vec3D vec3d = (new Vec3D(this.f.locX - this.a.locX, 0.0D, this.f.locZ - this.a.locZ)).d(); + Vec3D vec3d1 = (new Vec3D((double) MathHelper.sin(this.a.yaw * 0.017453292F), 0.0D, (double) (-MathHelper.cos(this.a.yaw * 0.017453292F)))).d(); float f = (float) vec3d1.b(vec3d); float f1 = (float) (Math.acos((double) f) * 57.2957763671875D); @@ -56,11 +57,11 @@ public class DragonControllerStrafe extends AbstractDragonController { if (this.c >= 5 && f1 >= 0.0F && f1 < 10.0F) { d2 = 1.0D; Vec3D vec3d2 = this.a.f(1.0F); - double d6 = this.a.bD.locX - vec3d2.x * 1.0D; - double d7 = this.a.bD.locY + (double) (this.a.bD.length / 2.0F) + 0.5D; - double d8 = this.a.bD.locZ - vec3d2.z * 1.0D; + double d6 = this.a.bA.locX - vec3d2.x * 1.0D; + double d7 = this.a.bA.locY + (double) (this.a.bA.getHeight() / 2.0F) + 0.5D; + double d8 = this.a.bA.locZ - vec3d2.z * 1.0D; double d9 = this.f.locX - d6; - double d10 = this.f.locY + (double) (this.f.length / 2.0F) - (d7 + (double) (this.a.bD.length / 2.0F)); + double d10 = this.f.locY + (double) (this.f.getHeight() / 2.0F) - (d7 + (double) (this.a.bA.getHeight() / 2.0F)); double d11 = this.f.locZ - d8; this.a.world.a((EntityHuman) null, 1017, new BlockPosition(this.a), 0); @@ -127,7 +128,7 @@ public class DragonControllerStrafe extends AbstractDragonController { private void k() { if (this.d != null && !this.d.b()) { - Vec3D vec3d = this.d.f(); + Vec3D vec3d = this.d.g(); this.d.a(); double d0 = vec3d.x; @@ -144,6 +145,7 @@ public class DragonControllerStrafe extends AbstractDragonController { } + @Override public void d() { this.c = 0; this.e = null; @@ -154,7 +156,7 @@ public class DragonControllerStrafe extends AbstractDragonController { public void a(EntityLiving entityliving) { this.f = entityliving; int i = this.a.l(); - int j = this.a.k(this.f.locX, this.f.locY, this.f.locZ); + int j = this.a.l(this.f.locX, this.f.locY, this.f.locZ); int k = MathHelper.floor(this.f.locX); int l = MathHelper.floor(this.f.locZ); double d0 = (double) k - this.a.locX; @@ -173,10 +175,12 @@ public class DragonControllerStrafe extends AbstractDragonController { } @Nullable + @Override public Vec3D g() { return this.e; } + @Override public DragonControllerPhase getControllerPhase() { return DragonControllerPhase.STRAFE_PLAYER; } diff --git a/src/main/java/net/minecraft/server/EULA.java b/src/main/java/net/minecraft/server/EULA.java index e13e17bdd..cf00f35a5 100644 --- a/src/main/java/net/minecraft/server/EULA.java +++ b/src/main/java/net/minecraft/server/EULA.java @@ -1,62 +1,95 @@ package net.minecraft.server; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; import java.util.Properties; -import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class EULA { - private static final Logger a = LogManager.getLogger(); - private final File b; + private static final Logger LOGGER = LogManager.getLogger(); + private final java.nio.file.Path b; private final boolean c; - public EULA(File file) { - this.b = file; - this.c = SharedConstants.b || this.a(file); + public EULA(java.nio.file.Path java_nio_file_path) { + this.b = java_nio_file_path; + this.c = SharedConstants.b || this.b(); } - private boolean a(File file) { - FileInputStream fileinputstream = null; - boolean flag = false; - + private boolean b() { try { - Properties properties = new Properties(); + InputStream inputstream = Files.newInputStream(this.b); + Throwable throwable = null; - fileinputstream = new FileInputStream(file); - properties.load(fileinputstream); - flag = Boolean.parseBoolean(properties.getProperty("eula", "false")); + boolean flag; + + try { + Properties properties = new Properties(); + + properties.load(inputstream); + flag = Boolean.parseBoolean(properties.getProperty("eula", "false")); + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (inputstream != null) { + if (throwable != null) { + try { + inputstream.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + inputstream.close(); + } + } + + } + + return flag; } catch (Exception exception) { - EULA.a.warn("Failed to load {}", file); - this.b(); - } finally { - IOUtils.closeQuietly(fileinputstream); + EULA.LOGGER.warn("Failed to load {}", this.b); + this.c(); + return false; } - - return flag; } public boolean a() { return this.c; } - public void b() { + private void c() { if (!SharedConstants.b) { - FileOutputStream fileoutputstream = null; - try { - Properties properties = new Properties(); + OutputStream outputstream = Files.newOutputStream(this.b); + Throwable throwable = null; - fileoutputstream = new FileOutputStream(this.b); - properties.setProperty("eula", "false"); - properties.store(fileoutputstream, "By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).\nYou also agree that tacos are tasty, and the best food in the world."); // Paper - fix lag); + try { + Properties properties = new Properties(); + + properties.setProperty("eula", "false"); + properties.store(outputstream, "By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).\nYou also agree that tacos are tasty, and the best food in the world."); // Paper - fix lag; + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (outputstream != null) { + if (throwable != null) { + try { + outputstream.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + outputstream.close(); + } + } + + } } catch (Exception exception) { - EULA.a.warn("Failed to save {}", this.b, exception); - } finally { - IOUtils.closeQuietly(fileoutputstream); + EULA.LOGGER.warn("Failed to save {}", this.b, exception); } } diff --git a/src/main/java/net/minecraft/server/Enchantment.java b/src/main/java/net/minecraft/server/Enchantment.java deleted file mode 100644 index ab730498d..000000000 --- a/src/main/java/net/minecraft/server/Enchantment.java +++ /dev/null @@ -1,181 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import java.util.List; -import javax.annotation.Nullable; - -public abstract class Enchantment { - - private final EnumItemSlot[] a; - private final Enchantment.Rarity d; - @Nullable - public EnchantmentSlotType itemTarget; - @Nullable - protected String c; - - protected Enchantment(Enchantment.Rarity enchantment_rarity, EnchantmentSlotType enchantmentslottype, EnumItemSlot[] aenumitemslot) { - this.d = enchantment_rarity; - this.itemTarget = enchantmentslottype; - this.a = aenumitemslot; - } - - public List a(EntityLiving entityliving) { - List list = Lists.newArrayList(); - EnumItemSlot[] aenumitemslot = this.a; - int i = aenumitemslot.length; - - for (int j = 0; j < i; ++j) { - EnumItemSlot enumitemslot = aenumitemslot[j]; - ItemStack itemstack = entityliving.getEquipment(enumitemslot); - - if (!itemstack.isEmpty()) { - list.add(itemstack); - } - } - - return list; - } - - public Enchantment.Rarity d() { - return this.d; - } - - public int getStartLevel() { - return 1; - } - - public int getMaxLevel() { - return 1; - } - - public int a(int i) { - return 1 + i * 10; - } - - public int b(int i) { - return this.a(i) + 5; - } - - public int a(int i, DamageSource damagesource) { - return 0; - } - - public float a(int i, EnumMonsterType enummonstertype) { - return 0.0F; - } - - public final boolean b(Enchantment enchantment) { - return this.a(enchantment) && enchantment.a(this); - } - - protected boolean a(Enchantment enchantment) { - return this != enchantment; - } - - protected String f() { - if (this.c == null) { - this.c = SystemUtils.a("enchantment", IRegistry.ENCHANTMENT.getKey(this)); - } - - return this.c; - } - - public String g() { - return this.f(); - } - - public IChatBaseComponent d(int i) { - ChatMessage chatmessage = new ChatMessage(this.g(), new Object[0]); - - if (this.c()) { - chatmessage.a(EnumChatFormat.RED); - } else { - chatmessage.a(EnumChatFormat.GRAY); - } - - if (i != 1 || this.getMaxLevel() != 1) { - chatmessage.a(" ").addSibling(new ChatMessage("enchantment.level." + i, new Object[0])); - } - - return chatmessage; - } - - public boolean canEnchant(ItemStack itemstack) { - return this.itemTarget.canEnchant(itemstack.getItem()); - } - - public void a(EntityLiving entityliving, Entity entity, int i) {} - - public void b(EntityLiving entityliving, Entity entity, int i) {} - - public boolean isTreasure() { - return false; - } - - public boolean c() { - return false; - } - - public static void h() { - EnumItemSlot[] aenumitemslot = new EnumItemSlot[] { EnumItemSlot.HEAD, EnumItemSlot.CHEST, EnumItemSlot.LEGS, EnumItemSlot.FEET}; - - a("protection", new EnchantmentProtection(Enchantment.Rarity.COMMON, EnchantmentProtection.DamageType.ALL, aenumitemslot)); - a("fire_protection", new EnchantmentProtection(Enchantment.Rarity.UNCOMMON, EnchantmentProtection.DamageType.FIRE, aenumitemslot)); - a("feather_falling", new EnchantmentProtection(Enchantment.Rarity.UNCOMMON, EnchantmentProtection.DamageType.FALL, aenumitemslot)); - a("blast_protection", new EnchantmentProtection(Enchantment.Rarity.RARE, EnchantmentProtection.DamageType.EXPLOSION, aenumitemslot)); - a("projectile_protection", new EnchantmentProtection(Enchantment.Rarity.UNCOMMON, EnchantmentProtection.DamageType.PROJECTILE, aenumitemslot)); - a("respiration", new EnchantmentOxygen(Enchantment.Rarity.RARE, aenumitemslot)); - a("aqua_affinity", new EnchantmentWaterWorker(Enchantment.Rarity.RARE, aenumitemslot)); - a("thorns", new EnchantmentThorns(Enchantment.Rarity.VERY_RARE, aenumitemslot)); - a("depth_strider", new EnchantmentDepthStrider(Enchantment.Rarity.RARE, aenumitemslot)); - a("frost_walker", new EnchantmentFrostWalker(Enchantment.Rarity.RARE, new EnumItemSlot[] { EnumItemSlot.FEET})); - a("binding_curse", new EnchantmentBinding(Enchantment.Rarity.VERY_RARE, aenumitemslot)); - a("sharpness", new EnchantmentWeaponDamage(Enchantment.Rarity.COMMON, 0, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("smite", new EnchantmentWeaponDamage(Enchantment.Rarity.UNCOMMON, 1, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("bane_of_arthropods", new EnchantmentWeaponDamage(Enchantment.Rarity.UNCOMMON, 2, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("knockback", new EnchantmentKnockback(Enchantment.Rarity.UNCOMMON, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("fire_aspect", new EnchantmentFire(Enchantment.Rarity.RARE, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("looting", new EnchantmentLootBonus(Enchantment.Rarity.RARE, EnchantmentSlotType.WEAPON, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("sweeping", new EnchantmentSweeping(Enchantment.Rarity.RARE, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("efficiency", new EnchantmentDigging(Enchantment.Rarity.COMMON, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("silk_touch", new EnchantmentSilkTouch(Enchantment.Rarity.VERY_RARE, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("unbreaking", new EnchantmentDurability(Enchantment.Rarity.UNCOMMON, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("fortune", new EnchantmentLootBonus(Enchantment.Rarity.RARE, EnchantmentSlotType.DIGGER, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("power", new EnchantmentArrowDamage(Enchantment.Rarity.COMMON, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("punch", new EnchantmentArrowKnockback(Enchantment.Rarity.RARE, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("flame", new EnchantmentFlameArrows(Enchantment.Rarity.RARE, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("infinity", new EnchantmentInfiniteArrows(Enchantment.Rarity.VERY_RARE, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("luck_of_the_sea", new EnchantmentLootBonus(Enchantment.Rarity.RARE, EnchantmentSlotType.FISHING_ROD, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("lure", new EnchantmentLure(Enchantment.Rarity.RARE, EnchantmentSlotType.FISHING_ROD, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("loyalty", new EnchantmentTridentLoyalty(Enchantment.Rarity.UNCOMMON, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("impaling", new EnchantmentTridentImpaling(Enchantment.Rarity.RARE, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("riptide", new EnchantmentTridentRiptide(Enchantment.Rarity.RARE, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("channeling", new EnchantmentTridentChanneling(Enchantment.Rarity.VERY_RARE, new EnumItemSlot[] { EnumItemSlot.MAINHAND})); - a("mending", new EnchantmentMending(Enchantment.Rarity.RARE, EnumItemSlot.values())); - a("vanishing_curse", new EnchantmentVanishing(Enchantment.Rarity.VERY_RARE, EnumItemSlot.values())); - // CraftBukkit start - for (Object enchantment : IRegistry.ENCHANTMENT) { - org.bukkit.enchantments.Enchantment.registerEnchantment(new org.bukkit.craftbukkit.enchantments.CraftEnchantment((Enchantment) enchantment)); - } - // CraftBukkit end - } - - private static void a(String s, Enchantment enchantment) { - IRegistry.ENCHANTMENT.a(new MinecraftKey(s), enchantment); // CraftBukkit - decompile error - } - - public static enum Rarity { - - COMMON(10), UNCOMMON(5), RARE(2), VERY_RARE(1); - - private final int e; - - private Rarity(int i) { - this.e = i; - } - - public int a() { - return this.e; - } - } -} diff --git a/src/main/java/net/minecraft/server/EnchantmentFrostWalker.java b/src/main/java/net/minecraft/server/EnchantmentFrostWalker.java index dd6d92e9a..b5de6c740 100644 --- a/src/main/java/net/minecraft/server/EnchantmentFrostWalker.java +++ b/src/main/java/net/minecraft/server/EnchantmentFrostWalker.java @@ -12,18 +12,22 @@ public class EnchantmentFrostWalker extends Enchantment { super(enchantment_rarity, EnchantmentSlotType.ARMOR_FEET, aenumitemslot); } + @Override public int a(int i) { return i * 10; } + @Override public int b(int i) { return this.a(i) + 15; } + @Override public boolean isTreasure() { return true; } + @Override public int getMaxLevel() { return 2; } @@ -32,23 +36,23 @@ public class EnchantmentFrostWalker extends Enchantment { if (entityliving.onGround) { IBlockData iblockdata = Blocks.FROSTED_ICE.getBlockData(); float f = (float) Math.min(16, 2 + i); - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(0, 0, 0); - Iterator iterator = BlockPosition.b(blockposition.a((double) (-f), -1.0D, (double) (-f)), blockposition.a((double) f, -1.0D, (double) f)).iterator(); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + Iterator iterator = BlockPosition.a(blockposition.a((double) (-f), -1.0D, (double) (-f)), blockposition.a((double) f, -1.0D, (double) f)).iterator(); while (iterator.hasNext()) { - BlockPosition.MutableBlockPosition blockposition_mutableblockposition1 = (BlockPosition.MutableBlockPosition) iterator.next(); + BlockPosition blockposition1 = (BlockPosition) iterator.next(); - if (blockposition_mutableblockposition1.g(entityliving.locX, entityliving.locY, entityliving.locZ) <= (double) (f * f)) { - blockposition_mutableblockposition.c(blockposition_mutableblockposition1.getX(), blockposition_mutableblockposition1.getY() + 1, blockposition_mutableblockposition1.getZ()); + if (blockposition1.a((IPosition) entityliving.getPositionVector(), (double) f)) { + blockposition_mutableblockposition.d(blockposition1.getX(), blockposition1.getY() + 1, blockposition1.getZ()); IBlockData iblockdata1 = world.getType(blockposition_mutableblockposition); if (iblockdata1.isAir()) { - IBlockData iblockdata2 = world.getType(blockposition_mutableblockposition1); + IBlockData iblockdata2 = world.getType(blockposition1); - if (iblockdata2.getMaterial() == Material.WATER && (Integer) iblockdata2.get(BlockFluids.LEVEL) == 0 && iblockdata.canPlace(world, blockposition_mutableblockposition1) && world.a(iblockdata, (BlockPosition) blockposition_mutableblockposition1)) { + if (iblockdata2.getMaterial() == Material.WATER && (Integer) iblockdata2.get(BlockFluids.LEVEL) == 0 && iblockdata.canPlace(world, blockposition1) && world.a(iblockdata, blockposition1, VoxelShapeCollision.a())) { // CraftBukkit Start - Call EntityBlockFormEvent for Frost Walker - if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, blockposition_mutableblockposition1, iblockdata, entityliving)) { - world.getBlockTickList().a(blockposition_mutableblockposition1.h(), Blocks.FROSTED_ICE, MathHelper.nextInt(entityliving.getRandom(), 60, 120)); + if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, blockposition1, iblockdata, entityliving)) { + world.getBlockTickList().a(blockposition1, Blocks.FROSTED_ICE, MathHelper.nextInt(entityliving.getRandom(), 60, 120)); } // CraftBukkit End } @@ -59,6 +63,7 @@ public class EnchantmentFrostWalker extends Enchantment { } } + @Override public boolean a(Enchantment enchantment) { return super.a(enchantment) && enchantment != Enchantments.DEPTH_STRIDER; } diff --git a/src/main/java/net/minecraft/server/EnchantmentManager.java b/src/main/java/net/minecraft/server/EnchantmentManager.java index 72f0bec4e..1d16919e6 100644 --- a/src/main/java/net/minecraft/server/EnchantmentManager.java +++ b/src/main/java/net/minecraft/server/EnchantmentManager.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Map.Entry; +import javax.annotation.Nullable; import org.apache.commons.lang3.mutable.MutableFloat; import org.apache.commons.lang3.mutable.MutableInt; @@ -39,11 +40,10 @@ public class EnchantmentManager { for (int i = 0; i < nbttaglist.size(); ++i) { NBTTagCompound nbttagcompound = nbttaglist.getCompound(i); - Enchantment enchantment = (Enchantment) IRegistry.ENCHANTMENT.get(MinecraftKey.a(nbttagcompound.getString("id"))); - if (enchantment != null) { - map.put(enchantment, nbttagcompound.getInt("lvl")); - } + IRegistry.ENCHANTMENT.getOptional(MinecraftKey.a(nbttagcompound.getString("id"))).ifPresent((enchantment) -> { + Integer integer = (Integer) map.put(enchantment, nbttagcompound.getInt("lvl")); + }); } return map; @@ -63,7 +63,7 @@ public class EnchantmentManager { nbttagcompound.setString("id", String.valueOf(IRegistry.ENCHANTMENT.getKey(enchantment))); nbttagcompound.setShort("lvl", (short) i); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); if (itemstack.getItem() == Items.ENCHANTED_BOOK) { ItemEnchantedBook.a(itemstack, new WeightedRandomEnchant(enchantment, i)); } @@ -71,7 +71,7 @@ public class EnchantmentManager { } if (nbttaglist.isEmpty()) { - itemstack.c("Enchantments"); + itemstack.removeTag("Enchantments"); } else if (itemstack.getItem() != Items.ENCHANTED_BOOK) { itemstack.a("Enchantments", (NBTBase) nbttaglist); } @@ -85,11 +85,10 @@ public class EnchantmentManager { for (int i = 0; i < nbttaglist.size(); ++i) { String s = nbttaglist.getCompound(i).getString("id"); int j = nbttaglist.getCompound(i).getInt("lvl"); - Enchantment enchantment = (Enchantment) IRegistry.ENCHANTMENT.get(MinecraftKey.a(s)); - if (enchantment != null) { + IRegistry.ENCHANTMENT.getOptional(MinecraftKey.a(s)).ifPresent((enchantment) -> { enchantmentmanager_a.accept(enchantment, j); - } + }); } } @@ -136,7 +135,7 @@ public class EnchantmentManager { }; if (entityliving != null) { - a(enchantmentmanager_a, entityliving.aU()); + a(enchantmentmanager_a, entityliving.bb()); } if (entity instanceof EntityHuman) { @@ -151,7 +150,7 @@ public class EnchantmentManager { }; if (entityliving != null) { - a(enchantmentmanager_a, entityliving.aU()); + a(enchantmentmanager_a, entityliving.bb()); } if (entityliving instanceof EntityHuman) { @@ -161,7 +160,7 @@ public class EnchantmentManager { } public static int a(Enchantment enchantment, EntityLiving entityliving) { - Iterable iterable = enchantment.a(entityliving); + Iterable iterable = enchantment.a(entityliving).values(); if (iterable == null) { return 0; @@ -242,25 +241,31 @@ public class EnchantmentManager { return getEnchantmentLevel(Enchantments.CHANNELING, itemstack) > 0; } - public static ItemStack getRandomEquippedItemWithEnchant(Enchantment enchantment, EntityLiving entityliving) { return b(enchantment, entityliving); } // Paper - OBFHELPER - public static ItemStack b(Enchantment enchantment, EntityLiving entityliving) { - List list = enchantment.a(entityliving); + // Paper - OBFHELPER + public static @Nullable ItemStack getRandomEquippedItemWithEnchant(Enchantment enchantment, EntityLiving entityliving) { + Entry entry = b(enchantment, entityliving); + return entry != null ? entry.getValue() : null; + } + @Nullable + public static Entry b(Enchantment enchantment, EntityLiving entityliving) { + Map map = enchantment.a(entityliving); - if (list.isEmpty()) { - return ItemStack.a; + if (map.isEmpty()) { + return null; } else { - List list1 = Lists.newArrayList(); - Iterator iterator = list.iterator(); + List> list = Lists.newArrayList(); + Iterator iterator = map.entrySet().iterator(); while (iterator.hasNext()) { - ItemStack itemstack = (ItemStack) iterator.next(); + Entry entry = (Entry) iterator.next(); + ItemStack itemstack = (ItemStack) entry.getValue(); if (!itemstack.isEmpty() && getEnchantmentLevel(enchantment, itemstack) > 0) { - list1.add(itemstack); + list.add(entry); } } - return list1.isEmpty() ? ItemStack.a : (ItemStack) list1.get(entityliving.getRandom().nextInt(list1.size())); + return list.isEmpty() ? null : (Entry) list.get(entityliving.getRandom().nextInt(list.size())); } } @@ -340,7 +345,7 @@ public class EnchantmentManager { Iterator iterator = list.iterator(); while (iterator.hasNext()) { - if (!weightedrandomenchant.enchantment.b(((WeightedRandomEnchant) iterator.next()).enchantment)) { + if (!weightedrandomenchant.enchantment.isCompatible(((WeightedRandomEnchant) iterator.next()).enchantment)) { iterator.remove(); } } @@ -358,7 +363,7 @@ public class EnchantmentManager { } enchantment1 = (Enchantment) iterator.next(); - } while (enchantment1.b(enchantment)); + } while (enchantment1.isCompatible(enchantment)); return false; } diff --git a/src/main/java/net/minecraft/server/EnchantmentThorns.java b/src/main/java/net/minecraft/server/EnchantmentThorns.java index 44e649304..62dd5367e 100644 --- a/src/main/java/net/minecraft/server/EnchantmentThorns.java +++ b/src/main/java/net/minecraft/server/EnchantmentThorns.java @@ -1,6 +1,7 @@ package net.minecraft.server; import java.util.Random; +import java.util.Map.Entry; public class EnchantmentThorns extends Enchantment { @@ -8,36 +9,45 @@ public class EnchantmentThorns extends Enchantment { super(enchantment_rarity, EnchantmentSlotType.ARMOR_CHEST, aenumitemslot); } + @Override public int a(int i) { return 10 + 20 * (i - 1); } + @Override public int b(int i) { return super.a(i) + 50; } + @Override public int getMaxLevel() { return 3; } + @Override public boolean canEnchant(ItemStack itemstack) { return itemstack.getItem() instanceof ItemArmor ? true : super.canEnchant(itemstack); } + @Override public void b(EntityLiving entityliving, Entity entity, int i) { Random random = entityliving.getRandom(); - ItemStack itemstack = EnchantmentManager.b(Enchantments.THORNS, entityliving); + Entry entry = EnchantmentManager.b(Enchantments.THORNS, entityliving); if (entity != null && a(i, random)) { // CraftBukkit if (entity != null) { entity.damageEntity(DamageSource.a(entityliving), (float) b(i, random)); } - if (!itemstack.isEmpty()) { - itemstack.damage(3, entityliving); + if (entry != null) { + ((ItemStack) entry.getValue()).damage(3, entityliving, (entityliving1) -> { + entityliving1.c((EnumItemSlot) entry.getKey()); + }); } - } else if (!itemstack.isEmpty()) { - itemstack.damage(1, entityliving); + } else if (entry != null) { + ((ItemStack) entry.getValue()).damage(1, entityliving, (entityliving1) -> { + entityliving1.c((EnumItemSlot) entry.getKey()); + }); } } diff --git a/src/main/java/net/minecraft/server/EnchantmentWeaponDamage.java b/src/main/java/net/minecraft/server/EnchantmentWeaponDamage.java index de82728b9..4571cdf02 100644 --- a/src/main/java/net/minecraft/server/EnchantmentWeaponDamage.java +++ b/src/main/java/net/minecraft/server/EnchantmentWeaponDamage.java @@ -2,10 +2,10 @@ package net.minecraft.server; public class EnchantmentWeaponDamage extends Enchantment { - private static final String[] d = new String[] { "all", "undead", "arthropods"}; - private static final int[] e = new int[] { 1, 5, 5}; - private static final int[] f = new int[] { 11, 8, 8}; - private static final int[] g = new int[] { 20, 20, 20}; + private static final String[] d = new String[]{"all", "undead", "arthropods"}; + private static final int[] e = new int[]{1, 5, 5}; + private static final int[] f = new int[]{11, 8, 8}; + private static final int[] g = new int[]{20, 20, 20}; public final int a; public EnchantmentWeaponDamage(Enchantment.Rarity enchantment_rarity, int i, EnumItemSlot... aenumitemslot) { @@ -13,30 +13,37 @@ public class EnchantmentWeaponDamage extends Enchantment { this.a = i; } + @Override public int a(int i) { return EnchantmentWeaponDamage.e[this.a] + (i - 1) * EnchantmentWeaponDamage.f[this.a]; } + @Override public int b(int i) { return this.a(i) + EnchantmentWeaponDamage.g[this.a]; } + @Override public int getMaxLevel() { return 5; } + @Override public float a(int i, EnumMonsterType enummonstertype) { return this.a == 0 ? 1.0F + (float) Math.max(0, i - 1) * 0.5F : (this.a == 1 && enummonstertype == EnumMonsterType.UNDEAD ? (float) i * 2.5F : (this.a == 2 && enummonstertype == EnumMonsterType.ARTHROPOD ? (float) i * 2.5F : 0.0F)); } + @Override public boolean a(Enchantment enchantment) { return !(enchantment instanceof EnchantmentWeaponDamage); } + @Override public boolean canEnchant(ItemStack itemstack) { return itemstack.getItem() instanceof ItemAxe ? true : super.canEnchant(itemstack); } + @Override public void a(EntityLiving entityliving, Entity entity, int i) { if (entity instanceof EntityLiving) { EntityLiving entityliving1 = (EntityLiving) entity; diff --git a/src/main/java/net/minecraft/server/Enchantments.java b/src/main/java/net/minecraft/server/Enchantments.java new file mode 100644 index 000000000..1105c6c5b --- /dev/null +++ b/src/main/java/net/minecraft/server/Enchantments.java @@ -0,0 +1,55 @@ +package net.minecraft.server; + +public class Enchantments { + + private static final EnumItemSlot[] L = new EnumItemSlot[]{EnumItemSlot.HEAD, EnumItemSlot.CHEST, EnumItemSlot.LEGS, EnumItemSlot.FEET}; + public static final Enchantment PROTECTION_ENVIRONMENTAL = a("protection", new EnchantmentProtection(Enchantment.Rarity.COMMON, EnchantmentProtection.DamageType.ALL, Enchantments.L)); + public static final Enchantment PROTECTION_FIRE = a("fire_protection", new EnchantmentProtection(Enchantment.Rarity.UNCOMMON, EnchantmentProtection.DamageType.FIRE, Enchantments.L)); + public static final Enchantment PROTECTION_FALL = a("feather_falling", new EnchantmentProtection(Enchantment.Rarity.UNCOMMON, EnchantmentProtection.DamageType.FALL, Enchantments.L)); + public static final Enchantment PROTECTION_EXPLOSIONS = a("blast_protection", new EnchantmentProtection(Enchantment.Rarity.RARE, EnchantmentProtection.DamageType.EXPLOSION, Enchantments.L)); + public static final Enchantment PROTECTION_PROJECTILE = a("projectile_protection", new EnchantmentProtection(Enchantment.Rarity.UNCOMMON, EnchantmentProtection.DamageType.PROJECTILE, Enchantments.L)); + public static final Enchantment OXYGEN = a("respiration", new EnchantmentOxygen(Enchantment.Rarity.RARE, Enchantments.L)); + public static final Enchantment WATER_WORKER = a("aqua_affinity", new EnchantmentWaterWorker(Enchantment.Rarity.RARE, Enchantments.L)); + public static final Enchantment THORNS = a("thorns", new EnchantmentThorns(Enchantment.Rarity.VERY_RARE, Enchantments.L)); + public static final Enchantment DEPTH_STRIDER = a("depth_strider", new EnchantmentDepthStrider(Enchantment.Rarity.RARE, Enchantments.L)); + public static final Enchantment FROST_WALKER = a("frost_walker", new EnchantmentFrostWalker(Enchantment.Rarity.RARE, new EnumItemSlot[]{EnumItemSlot.FEET})); + public static final Enchantment BINDING_CURSE = a("binding_curse", new EnchantmentBinding(Enchantment.Rarity.VERY_RARE, Enchantments.L)); + public static final Enchantment DAMAGE_ALL = a("sharpness", new EnchantmentWeaponDamage(Enchantment.Rarity.COMMON, 0, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment DAMAGE_UNDEAD = a("smite", new EnchantmentWeaponDamage(Enchantment.Rarity.UNCOMMON, 1, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment DAMAGE_ARTHROPODS = a("bane_of_arthropods", new EnchantmentWeaponDamage(Enchantment.Rarity.UNCOMMON, 2, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment KNOCKBACK = a("knockback", new EnchantmentKnockback(Enchantment.Rarity.UNCOMMON, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment FIRE_ASPECT = a("fire_aspect", new EnchantmentFire(Enchantment.Rarity.RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment LOOT_BONUS_MOBS = a("looting", new EnchantmentLootBonus(Enchantment.Rarity.RARE, EnchantmentSlotType.WEAPON, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment SWEEPING = a("sweeping", new EnchantmentSweeping(Enchantment.Rarity.RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment DIG_SPEED = a("efficiency", new EnchantmentDigging(Enchantment.Rarity.COMMON, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment SILK_TOUCH = a("silk_touch", new EnchantmentSilkTouch(Enchantment.Rarity.VERY_RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment DURABILITY = a("unbreaking", new EnchantmentDurability(Enchantment.Rarity.UNCOMMON, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment LOOT_BONUS_BLOCKS = a("fortune", new EnchantmentLootBonus(Enchantment.Rarity.RARE, EnchantmentSlotType.DIGGER, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment ARROW_DAMAGE = a("power", new EnchantmentArrowDamage(Enchantment.Rarity.COMMON, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment ARROW_KNOCKBACK = a("punch", new EnchantmentArrowKnockback(Enchantment.Rarity.RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment ARROW_FIRE = a("flame", new EnchantmentFlameArrows(Enchantment.Rarity.RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment ARROW_INFINITE = a("infinity", new EnchantmentInfiniteArrows(Enchantment.Rarity.VERY_RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment LUCK = a("luck_of_the_sea", new EnchantmentLootBonus(Enchantment.Rarity.RARE, EnchantmentSlotType.FISHING_ROD, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment LURE = a("lure", new EnchantmentLure(Enchantment.Rarity.RARE, EnchantmentSlotType.FISHING_ROD, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment LOYALTY = a("loyalty", new EnchantmentTridentLoyalty(Enchantment.Rarity.UNCOMMON, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment IMPALING = a("impaling", new EnchantmentTridentImpaling(Enchantment.Rarity.RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment RIPTIDE = a("riptide", new EnchantmentTridentRiptide(Enchantment.Rarity.RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment CHANNELING = a("channeling", new EnchantmentTridentChanneling(Enchantment.Rarity.VERY_RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment MULTISHOT = a("multishot", new EnchantmentMultishot(Enchantment.Rarity.RARE, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment QUICK_CHARGE = a("quick_charge", new EnchantmentQuickCharge(Enchantment.Rarity.UNCOMMON, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment PIERCING = a("piercing", new EnchantmentPiercing(Enchantment.Rarity.COMMON, new EnumItemSlot[]{EnumItemSlot.MAINHAND})); + public static final Enchantment MENDING = a("mending", new EnchantmentMending(Enchantment.Rarity.RARE, EnumItemSlot.values())); + public static final Enchantment VANISHING_CURSE = a("vanishing_curse", new EnchantmentVanishing(Enchantment.Rarity.VERY_RARE, EnumItemSlot.values())); + + // CraftBukkit start + static { + for (Object enchantment : IRegistry.ENCHANTMENT) { + org.bukkit.enchantments.Enchantment.registerEnchantment(new org.bukkit.craftbukkit.enchantments.CraftEnchantment((Enchantment) enchantment)); + } + } + // CraftBukkit end + + private static Enchantment a(String s, Enchantment enchantment) { + return (Enchantment) IRegistry.a(IRegistry.ENCHANTMENT, s, enchantment); // CraftBukkit - decompile error + } +} diff --git a/src/main/java/net/minecraft/server/EnderDragonBattle.java b/src/main/java/net/minecraft/server/EnderDragonBattle.java index 09eabf123..6700c8c65 100644 --- a/src/main/java/net/minecraft/server/EnderDragonBattle.java +++ b/src/main/java/net/minecraft/server/EnderDragonBattle.java @@ -18,7 +18,7 @@ import org.apache.logging.log4j.Logger; public class EnderDragonBattle { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final Predicate b = IEntitySelector.a.and(IEntitySelector.a(0.0D, 128.0D, 0.0D, 192.0D)); public final BossBattleServer bossBattle; private final WorldServer d; @@ -69,7 +69,7 @@ public class EnderDragonBattle { NBTTagList nbttaglist = nbttagcompound.getList("Gateways", 3); for (int i = 0; i < nbttaglist.size(); ++i) { - this.e.add(nbttaglist.h(i)); + this.e.add(nbttaglist.e(i)); } } else { this.e.addAll(ContiguousSet.create(Range.closedOpen(0, 20), DiscreteDomain.integers())); @@ -98,7 +98,7 @@ public class EnderDragonBattle { while (iterator.hasNext()) { int i = (Integer) iterator.next(); - nbttaglist.add((NBTBase) (new NBTTagInt(i))); + nbttaglist.add(new NBTTagInt(i)); } nbttagcompound.set("Gateways", nbttaglist); @@ -108,20 +108,21 @@ public class EnderDragonBattle { public void b() { this.bossBattle.setVisible(!this.k); if (++this.j >= 20) { - this.k(); + this.l(); this.j = 0; } - EnderDragonBattle.b enderdragonbattle_b = new EnderDragonBattle.b(); - if (!this.bossBattle.getPlayers().isEmpty()) { - if (this.n && enderdragonbattle_b.a()) { + this.d.getChunkProvider().addTicket(TicketType.DRAGON, new ChunkCoordIntPair(0, 0), 9, Unit.INSTANCE); + boolean flag = this.k(); + + if (this.n && flag) { this.g(); this.n = false; } if (this.p != null) { - if (this.r == null && enderdragonbattle_b.a()) { + if (this.r == null && flag) { this.p = null; this.e(); } @@ -130,34 +131,36 @@ public class EnderDragonBattle { } if (!this.k) { - if ((this.m == null || ++this.g >= 1200) && enderdragonbattle_b.a()) { + if ((this.m == null || ++this.g >= 1200) && flag) { this.h(); this.g = 0; } - if (++this.i >= 100 && enderdragonbattle_b.a()) { - this.l(); + if (++this.i >= 100 && flag) { + this.m(); this.i = 0; } } + } else { + this.d.getChunkProvider().removeTicket(TicketType.DRAGON, new ChunkCoordIntPair(0, 0), 9, Unit.INSTANCE); } } private void g() { - EnderDragonBattle.a.info("Scanning for legacy world dragon fight..."); + EnderDragonBattle.LOGGER.info("Scanning for legacy world dragon fight..."); boolean flag = this.i(); if (flag) { - EnderDragonBattle.a.info("Found that the dragon has been killed in this world already."); + EnderDragonBattle.LOGGER.info("Found that the dragon has been killed in this world already."); this.l = true; } else { - EnderDragonBattle.a.info("Found that the dragon has not yet been killed in this world."); + EnderDragonBattle.LOGGER.info("Found that the dragon has not yet been killed in this world."); this.l = false; this.a(false); } - List list = this.d.a(EntityEnderDragon.class, IEntitySelector.a); + List list = this.d.j(); if (list.isEmpty()) { this.k = true; @@ -165,10 +168,10 @@ public class EnderDragonBattle { EntityEnderDragon entityenderdragon = (EntityEnderDragon) list.get(0); this.m = entityenderdragon.getUniqueID(); - EnderDragonBattle.a.info("Found that there's a dragon still alive ({})", entityenderdragon); + EnderDragonBattle.LOGGER.info("Found that there's a dragon still alive ({})", entityenderdragon); this.k = false; if (!flag) { - EnderDragonBattle.a.info("But we didn't have a portal, let's remove it."); + EnderDragonBattle.LOGGER.info("But we didn't have a portal, let's remove it."); entityenderdragon.die(); this.m = null; } @@ -181,13 +184,13 @@ public class EnderDragonBattle { } private void h() { - List list = this.d.a(EntityEnderDragon.class, IEntitySelector.a); + List list = this.d.j(); if (list.isEmpty()) { - EnderDragonBattle.a.debug("Haven't seen the dragon, respawning it"); - this.n(); + EnderDragonBattle.LOGGER.debug("Haven't seen the dragon, respawning it"); + this.o(); } else { - EnderDragonBattle.a.debug("Haven't seen our dragon, but found another one to use."); + EnderDragonBattle.LOGGER.debug("Haven't seen our dragon, but found another one to use."); this.m = ((EntityEnderDragon) list.get(0)).getUniqueID(); } @@ -201,7 +204,7 @@ public class EnderDragonBattle { if (enumdragonrespawn == EnumDragonRespawn.END) { this.p = null; this.k = false; - EntityEnderDragon entityenderdragon = this.n(); + EntityEnderDragon entityenderdragon = this.o(); Iterator iterator = this.bossBattle.getPlayers().iterator(); while (iterator.hasNext()) { @@ -290,47 +293,29 @@ public class EnderDragonBattle { return null; } - private boolean a(int i, int j, int k, int l) { - if (this.b(i, j, k, l)) { - return true; - } else { - this.c(i, j, k, l); - return false; - } - } + private boolean k() { + for (int i = -8; i <= 8; ++i) { + for (int j = 8; j <= 8; ++j) { + IChunkAccess ichunkaccess = this.d.getChunkAt(i, j, ChunkStatus.FULL, false); - private boolean b(int i, int j, int k, int l) { - boolean flag = true; + if (!(ichunkaccess instanceof Chunk)) { + return false; + } - for (int i1 = i; i1 <= j; ++i1) { - for (int j1 = k; j1 <= l; ++j1) { - Chunk chunk = this.d.getChunkAt(i1, j1); + PlayerChunk.State playerchunk_state = ((Chunk) ichunkaccess).getState(); - flag &= chunk.i() == ChunkStatus.POSTPROCESSED; + if (!playerchunk_state.isAtLeast(PlayerChunk.State.TICKING)) { + return false; + } } } - return flag; + return true; } - private void c(int i, int j, int k, int l) { - int i1; - - for (i1 = i - 1; i1 <= j + 1; ++i1) { - this.d.getChunkAt(i1, k - 1); - this.d.getChunkAt(i1, l + 1); - } - - for (i1 = k - 1; i1 <= l + 1; ++i1) { - this.d.getChunkAt(i - 1, i1); - this.d.getChunkAt(j + 1, i1); - } - - } - - private void k() { + private void l() { Set set = Sets.newHashSet(); - Iterator iterator = this.d.b(EntityPlayer.class, EnderDragonBattle.b).iterator(); + Iterator iterator = this.d.a(EnderDragonBattle.b).iterator(); while (iterator.hasNext()) { EntityPlayer entityplayer = (EntityPlayer) iterator.next(); @@ -352,19 +337,17 @@ public class EnderDragonBattle { } - private void l() { + private void m() { this.i = 0; this.h = 0; - WorldGenEnder.Spike[] aworldgenender_spike = WorldGenDecoratorSpike.a(this.d); - int i = aworldgenender_spike.length; - for (int j = 0; j < i; ++j) { - WorldGenEnder.Spike worldgenender_spike = aworldgenender_spike[j]; + WorldGenEnder.Spike worldgenender_spike; - this.h += this.d.a(EntityEnderCrystal.class, worldgenender_spike.f()).size(); + for (Iterator iterator = WorldGenEnder.a((GeneratorAccess) this.d).iterator(); iterator.hasNext(); this.h += this.d.a(EntityEnderCrystal.class, worldgenender_spike.f()).size()) { + worldgenender_spike = (WorldGenEnder.Spike) iterator.next(); } - EnderDragonBattle.a.debug("Found {} end crystals still alive", this.h); + EnderDragonBattle.LOGGER.debug("Found {} end crystals still alive", this.h); } public void a(EntityEnderDragon entityenderdragon) { @@ -372,7 +355,7 @@ public class EnderDragonBattle { this.bossBattle.setProgress(0.0F); this.bossBattle.setVisible(false); this.a(true); - this.m(); + this.n(); if (!this.l) { this.d.setTypeUpdate(this.d.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, WorldGenEndTrophy.a), Blocks.DRAGON_EGG.getBlockData()); } @@ -383,11 +366,11 @@ public class EnderDragonBattle { } - private void m() { + private void n() { if (!this.e.isEmpty()) { int i = (Integer) this.e.remove(this.e.size() - 1); - int j = (int) (96.0D * Math.cos(2.0D * (-3.141592653589793D + 0.15707963267948966D * (double) i))); - int k = (int) (96.0D * Math.sin(2.0D * (-3.141592653589793D + 0.15707963267948966D * (double) i))); + int j = MathHelper.floor(96.0D * Math.cos(2.0D * (-3.141592653589793D + 0.15707963267948966D * (double) i))); + int k = MathHelper.floor(96.0D * Math.sin(2.0D * (-3.141592653589793D + 0.15707963267948966D * (double) i))); this.a(new BlockPosition(j, 75, k)); } @@ -395,7 +378,7 @@ public class EnderDragonBattle { private void a(BlockPosition blockposition) { this.d.triggerEffect(3000, blockposition, 0); - WorldGenerator.ax.generate(this.d, this.d.getChunkProvider().getChunkGenerator(), new Random(), blockposition, new WorldGenEndGatewayConfiguration(false)); + WorldGenerator.END_GATEWAY.generate(this.d, this.d.getChunkProvider().getChunkGenerator(), new Random(), blockposition, WorldGenEndGatewayConfiguration.a()); } private void a(boolean flag) { @@ -410,9 +393,9 @@ public class EnderDragonBattle { worldgenendtrophy.a(this.d, this.d.getChunkProvider().getChunkGenerator(), new Random(), this.o, WorldGenFeatureConfiguration.e); } - private EntityEnderDragon n() { + private EntityEnderDragon o() { this.d.getChunkAtWorldCoords(new BlockPosition(0, 128, 0)); - EntityEnderDragon entityenderdragon = EntityTypes.ENDER_DRAGON.create(this.d); // Paper + EntityEnderDragon entityenderdragon = (EntityEnderDragon) EntityTypes.ENDER_DRAGON.a((World) this.d); entityenderdragon.getDragonControllerManager().setControllerPhase(DragonControllerPhase.HOLDING_PATTERN); entityenderdragon.setPositionRotation(0.0D, 128.0D, 0.0D, this.d.random.nextFloat() * 360.0F, 0.0F); @@ -438,13 +421,13 @@ public class EnderDragonBattle { public void a(EntityEnderCrystal entityendercrystal, DamageSource damagesource) { if (this.p != null && this.r.contains(entityendercrystal)) { - EnderDragonBattle.a.debug("Aborting respawn sequence"); + EnderDragonBattle.LOGGER.debug("Aborting respawn sequence"); this.p = null; this.q = 0; this.f(); this.a(true); } else { - this.l(); + this.m(); Entity entity = this.d.getEntity(this.m); if (entity instanceof EntityEnderDragon) { @@ -463,14 +446,14 @@ public class EnderDragonBattle { BlockPosition blockposition = this.o; if (blockposition == null) { - EnderDragonBattle.a.debug("Tried to respawn, but need to find the portal first."); + EnderDragonBattle.LOGGER.debug("Tried to respawn, but need to find the portal first."); ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = this.j(); if (shapedetector_shapedetectorcollection == null) { - EnderDragonBattle.a.debug("Couldn't find a portal, so we made one."); + EnderDragonBattle.LOGGER.debug("Couldn't find a portal, so we made one."); this.a(true); } else { - EnderDragonBattle.a.debug("Found the exit portal & temporarily using it."); + EnderDragonBattle.LOGGER.debug("Found the exit portal & temporarily using it."); } blockposition = this.o; @@ -491,7 +474,7 @@ public class EnderDragonBattle { list.addAll(list1); } - EnderDragonBattle.a.debug("Found all crystals, respawning dragon."); + EnderDragonBattle.LOGGER.debug("Found all crystals, respawning dragon."); this.a((List) list); } @@ -522,16 +505,15 @@ public class EnderDragonBattle { } public void f() { - WorldGenEnder.Spike[] aworldgenender_spike = WorldGenDecoratorSpike.a(this.d); - int i = aworldgenender_spike.length; + Iterator iterator = WorldGenEnder.a((GeneratorAccess) this.d).iterator(); - for (int j = 0; j < i; ++j) { - WorldGenEnder.Spike worldgenender_spike = aworldgenender_spike[j]; + while (iterator.hasNext()) { + WorldGenEnder.Spike worldgenender_spike = (WorldGenEnder.Spike) iterator.next(); List list = this.d.a(EntityEnderCrystal.class, worldgenender_spike.f()); - Iterator iterator = list.iterator(); + Iterator iterator1 = list.iterator(); - while (iterator.hasNext()) { - EntityEnderCrystal entityendercrystal = (EntityEnderCrystal) iterator.next(); + while (iterator1.hasNext()) { + EntityEnderCrystal entityendercrystal = (EntityEnderCrystal) iterator1.next(); entityendercrystal.setInvulnerable(false); entityendercrystal.setBeamTarget((BlockPosition) null); @@ -539,28 +521,4 @@ public class EnderDragonBattle { } } - - class b { - - private EnderDragonBattle.LoadState b; - - private b() { - this.b = EnderDragonBattle.LoadState.UNKNOWN; - } - - private boolean a() { - if (this.b == EnderDragonBattle.LoadState.UNKNOWN) { - this.b = EnderDragonBattle.this.a(-8, 8, -8, 8) ? EnderDragonBattle.LoadState.LOADED : EnderDragonBattle.LoadState.NOT_LOADED; - } - - return this.b == EnderDragonBattle.LoadState.LOADED; - } - } - - static enum LoadState { - - UNKNOWN, NOT_LOADED, LOADED; - - private LoadState() {} - } } diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index af8620e45..e8def7f81 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -13,6 +14,8 @@ import java.util.Optional; import java.util.Random; import java.util.Set; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -21,17 +24,13 @@ import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Server; -import org.bukkit.TravelAgent; import org.bukkit.block.BlockFace; import org.bukkit.command.CommandSender; import org.bukkit.entity.Hanging; import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; import org.bukkit.entity.Vehicle; import co.aikar.timings.MinecraftTimings; // Paper import co.aikar.timings.Timing; // Paper -import io.akarin.server.core.AkarinAsyncExecutor; - import org.bukkit.event.entity.EntityCombustByEntityEvent; import org.bukkit.event.hanging.HangingBreakByEntityEvent; import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; @@ -41,10 +40,13 @@ import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.Pose; import org.bukkit.event.entity.EntityAirChangeEvent; import org.bukkit.event.entity.EntityCombustEvent; import org.bukkit.event.entity.EntityDropItemEvent; import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.entity.EntityPoseChangeEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.plugin.PluginManager; // CraftBukkit end @@ -73,9 +75,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper - protected CraftEntity bukkitEntity; + private CraftEntity bukkitEntity; - EntityTrackerEntry tracker; // Paper + PlayerChunkMap.EntityTracker tracker; // Paper Throwable addedToWorldStack; // Paper - entity debug public CraftEntity getBukkitEntity() { if (bukkitEntity == null) { @@ -90,16 +92,16 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } // CraftBukkit end - protected static final Logger i = LogManager.getLogger(); - private static final List a = Collections.emptyList(); - private static final AxisAlignedBB b = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); - private static double c = 1.0D; - private static int entityCount = 1; // Paper - MC-111480 - ID 0 is treated as special for DataWatchers, start 1 - private final EntityTypes g; public EntityTypes getEntityType() { return g; } // Paper - OBFHELPER + protected static final Logger LOGGER = LogManager.getLogger(); + private static final AtomicInteger entityCount = new AtomicInteger(1); // paper - start entity count from 1 + private static final List c = Collections.emptyList(); + private static final AxisAlignedBB d = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + private static double e = 1.0D; + private final EntityTypes f; private int id; - public boolean j; public boolean blocksEntitySpawning() { return j; } // Paper - OBFHELPER + public boolean i; public final boolean blocksEntitySpawning() { return this.i; } // Paper - OBFHELPER public final List passengers; - protected int k; + protected int j; private Entity vehicle; public boolean attachedToPlayer; public World world; @@ -109,9 +111,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public double locX; public double locY; public double locZ; - public double motX; - public double motY; - public double motZ; + private Vec3D mot; public float yaw; public float pitch; public float lastYaw; @@ -119,65 +119,64 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke private AxisAlignedBB boundingBox; public boolean onGround; public boolean positionChanged; - public boolean C; - public boolean D; + public boolean y; + public boolean z; public boolean velocityChanged; - protected boolean F; - private boolean az; + protected Vec3D B; public boolean dead; + public float D; + public float E; + public float F; public boolean shouldBeRemoved; // Paper - public boolean hasBeenCounted = false; // Paper - public float width; - public float length; - public float J; - public float K; - public float L; public float fallDistance; - private float aA; - private float aB; - public double N; - public double O; - public double P; - public float Q; + private float av; + private float aw; + public double H; + public double I; + public double J; + public float K; public boolean noclip; - public float S; - protected Random random; + public float M; + protected final Random random; public int ticksLived; public int fireTicks; public boolean inWater; - protected double W; - protected boolean X; + protected double Q; + protected boolean R; + protected boolean inLava; public int noDamageTicks; protected boolean justCreated; - protected boolean fireProof; - protected DataWatcher datawatcher; - protected static final DataWatcherObject ac = DataWatcher.a(Entity.class, DataWatcherRegistry.a); - private static final DataWatcherObject aD = DataWatcher.a(Entity.class, DataWatcherRegistry.b); - private static final DataWatcherObject> aE = DataWatcher.a(Entity.class, DataWatcherRegistry.f); - private static final DataWatcherObject aF = DataWatcher.a(Entity.class, DataWatcherRegistry.i); - private static final DataWatcherObject aG = DataWatcher.a(Entity.class, DataWatcherRegistry.i); - private static final DataWatcherObject aH = DataWatcher.a(Entity.class, DataWatcherRegistry.i); + protected final DataWatcher datawatcher; + protected static final DataWatcherObject W = DataWatcher.a(Entity.class, DataWatcherRegistry.a); + private static final DataWatcherObject AIR_TICKS = DataWatcher.a(Entity.class, DataWatcherRegistry.b); + private static final DataWatcherObject> az = DataWatcher.a(Entity.class, DataWatcherRegistry.f); + private static final DataWatcherObject aA = DataWatcher.a(Entity.class, DataWatcherRegistry.i); + private static final DataWatcherObject aB = DataWatcher.a(Entity.class, DataWatcherRegistry.i); + private static final DataWatcherObject aC = DataWatcher.a(Entity.class, DataWatcherRegistry.i); + protected static final DataWatcherObject POSE = DataWatcher.a(Entity.class, DataWatcherRegistry.s); public boolean inChunk; public boolean isAddedToChunk() { return inChunk; } // Paper - OBFHELPER public int chunkX; public int getChunkX() { return chunkX; } // Paper - OBFHELPER public int chunkY; public int getChunkY() { return chunkY; } // Paper - OBFHELPER public int chunkZ; public int getChunkZ() { return chunkZ; } // Paper - OBFHELPER - public boolean ak; + public boolean af; public boolean impulse; public int portalCooldown; - protected boolean an; public boolean inPortal() { return an; } // Paper - OBFHELPER - protected int ao; + protected boolean ai; public final boolean inPortal() { return this.ai; } // Paper - OBFHELPER + protected int aj; public DimensionManager dimension; - protected BlockPosition aq; - protected Vec3D ar; - protected EnumDirection as; + protected BlockPosition al; + protected Vec3D am; + protected EnumDirection an; private boolean invulnerable; protected UUID uniqueID; - protected String au; + protected String ap; public boolean glowing; - private final Set aJ; - private boolean aK; - private final double[] aL; - private long aM; + private final Set aE; + private boolean aF; + private final double[] aG; + private long aH; + private EntitySize size; + private float headHeight; // CraftBukkit start public boolean persist = true; public boolean valid; @@ -186,40 +185,42 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public Timing tickTimer = MinecraftTimings.getEntityTimings(this); // Paper public Location origin; // Paper // Spigot start - public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); + public final org.spigotmc.ActivationRange.ActivationType activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); public final boolean defaultActivationState; public long activatedTick = Integer.MIN_VALUE; public boolean fromMobSpawner; public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one protected int numCollisions = 0; // Paper - // Akarin start - public boolean enderTeleport; - // Akarin end public void inactiveTick() { } // Spigot end public float getBukkitYaw() { return this.yaw; } + + public boolean isChunkLoaded() { + return world.getChunkIfLoadedImmediately((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4) != null; // Paper + } // CraftBukkit end public Entity(EntityTypes entitytypes, World world) { - this.id = Entity.entityCount++; + this.id = Entity.entityCount.incrementAndGet(); this.passengers = Lists.newArrayList(); - this.boundingBox = Entity.b; - this.width = 0.6F; - this.length = 1.8F; - this.aA = 1.0F; - this.aB = 1.0F; + this.mot = Vec3D.a; + this.boundingBox = Entity.d; + this.B = Vec3D.a; + this.av = 1.0F; + this.aw = 1.0F; this.random = SHARED_RANDOM; // Paper this.fireTicks = -this.getMaxFireTicks(); this.justCreated = true; - this.uniqueID = MathHelper.a(java.util.concurrent.ThreadLocalRandom.current()); // Paper - this.au = this.uniqueID.toString(); - this.aJ = Collections.synchronizedSet(Sets.newHashSet()); // Akarin - synchronized to protect plugins - this.aL = new double[] { 0.0D, 0.0D, 0.0D}; - this.g = entitytypes; + this.uniqueID = MathHelper.a(this.random); + this.ap = this.uniqueID.toString(); + this.aE = Sets.newHashSet(); + this.aG = new double[]{0.0D, 0.0D, 0.0D}; + this.f = entitytypes; this.world = world; + this.size = entitytypes.k(); this.setPosition(0.0D, 0.0D, 0.0D); if (world != null) { this.dimension = world.worldProvider.getDimensionManager(); @@ -231,17 +232,35 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke // Spigot end this.datawatcher = new DataWatcher(this); - this.datawatcher.register(Entity.ac, (byte) 0); - this.datawatcher.register(Entity.aD, this.bf()); - this.datawatcher.register(Entity.aF, false); - this.datawatcher.register(Entity.aE, Optional.empty()); - this.datawatcher.register(Entity.aG, false); - this.datawatcher.register(Entity.aH, false); - this.x_(); + this.datawatcher.register(Entity.W, (byte) 0); + this.datawatcher.register(Entity.AIR_TICKS, this.bp()); + this.datawatcher.register(Entity.aA, false); + this.datawatcher.register(Entity.az, Optional.empty()); + this.datawatcher.register(Entity.aB, false); + this.datawatcher.register(Entity.aC, false); + this.datawatcher.register(Entity.POSE, EntityPose.STANDING); + this.initDatawatcher(); + this.datawatcher.registrationLocked = true; // Spigot + this.headHeight = this.getHeadHeight(EntityPose.STANDING, this.size); } - public EntityTypes P() { - return this.g; + public boolean isSpectator() { + return false; + } + + public final void decouple() { + if (this.isVehicle()) { + this.ejectPassengers(); + } + + if (this.isPassenger()) { + this.stopRiding(); + } + + } + + public EntityTypes getEntityType() { + return this.f; } public int getId() { @@ -253,26 +272,22 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public Set getScoreboardTags() { - return this.aJ; + return this.aE; } public boolean addScoreboardTag(String s) { - synchronized (this.aJ) { // Akarin - return this.aJ.size() >= 1024 ? false : this.aJ.add(s); - } // Akarin + return this.aE.size() >= 1024 ? false : this.aE.add(s); } public boolean removeScoreboardTag(String s) { - synchronized (this.aJ) { // Akarin - return this.aJ.remove(s); - } // Akarin + return this.aE.remove(s); } public void killEntity() { this.die(); } - protected abstract void x_(); + protected abstract void initDatawatcher(); public DataWatcher getDataWatcher() { return this.datawatcher; @@ -290,29 +305,18 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.dead = true; } - public void b(boolean flag) {} - - public void setSize(float f, float f1) { - if (f != this.width || f1 != this.length) { - float f2 = this.width; - - this.width = f; - this.length = f1; - if (this.width < f2) { - double d0 = (double) f / 2.0D; - - this.a(new AxisAlignedBB(this.locX - d0, this.locY, this.locZ - d0, this.locX + d0, this.locY + (double) this.length, this.locZ + d0)); - return; - } - - AxisAlignedBB axisalignedbb = this.getBoundingBox(); - - this.a(new AxisAlignedBB(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ, axisalignedbb.minX + (double) this.width, axisalignedbb.minY + (double) this.length, axisalignedbb.minZ + (double) this.width)); - if (this.width > f2 && !this.justCreated && !this.world.isClientSide) { - this.move(EnumMoveType.SELF, (double) (f2 - this.width), 0.0D, (double) (f2 - this.width)); - } + protected void setPose(EntityPose entitypose) { + // CraftBukkit start + if (entitypose == this.getPose()) { + return; } + this.world.getServer().getPluginManager().callEvent(new EntityPoseChangeEvent(this.getBukkitEntity(), Pose.values()[entitypose.ordinal()])); + // CraftBukkit end + this.datawatcher.set(Entity.POSE, entitypose); + } + public EntityPose getPose() { + return (EntityPose) this.datawatcher.get(Entity.POSE); } protected void setYawPitch(float f, float f1) { @@ -351,131 +355,53 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.locX = d0; this.locY = d1; this.locZ = d2; - float f = this.width / 2.0F; - float f1 = this.length; + float f = this.size.width / 2.0F; + float f1 = this.size.height; this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); - if (valid) world.entityJoinedWorld(this, false); // CraftBukkit + if (valid) ((WorldServer) world).chunkCheck(this); // CraftBukkit } public void tick() { if (!this.world.isClientSide) { - this.setFlag(6, this.bc()); + this.setFlag(6, this.bm()); } - this.W(); + this.entityBaseTick(); } // CraftBukkit start public void postTick() { // No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle - if (!this.world.isClientSide && this.world instanceof WorldServer) { - //this.world.methodProfiler.enter("portal"); // Akarin - remove caller - if (this.an) { - MinecraftServer minecraftserver = this.world.getMinecraftServer(); - - if (true || minecraftserver.getAllowNether()) { // CraftBukkit - if (!this.isPassenger()) { - int i = this.X(); - - if (this.ao++ >= i) { - this.ao = i; - this.portalCooldown = this.aQ(); - DimensionManager dimensionmanager; - - if (this.world.worldProvider.getDimensionManager() == DimensionManager.NETHER) { - dimensionmanager = DimensionManager.OVERWORLD; - } else { - dimensionmanager = DimensionManager.NETHER; - } - - this.a(dimensionmanager); - } - } - - this.an = false; - } - } else { - if (this.ao > 0) { - this.ao -= 4; - } - - if (this.ao < 0) { - this.ao = 0; - } - } - - this.E(); - //this.world.methodProfiler.exit(); // Akarin - remove caller + if (!(this instanceof EntityPlayer)) { + this.doPortalTick(); } } // CraftBukkit end - public void W() { - //this.world.methodProfiler.enter("entityBaseTick"); // Akarin - remove caller + public void entityBaseTick() { + this.world.getMethodProfiler().enter("entityBaseTick"); if (this.isPassenger() && this.getVehicle().dead) { this.stopRiding(); } - if (this.k > 0) { - --this.k; + if (this.j > 0) { + --this.j; } - this.J = this.K; + this.D = this.E; this.lastX = this.locX; this.lastY = this.locY; this.lastZ = this.locZ; this.lastPitch = this.pitch; this.lastYaw = this.yaw; - // Moved up to postTick - /* - if (!this.world.isClientSide && this.world instanceof WorldServer) { - this.world.methodProfiler.enter("portal"); - if (this.an) { - MinecraftServer minecraftserver = this.world.getMinecraftServer(); - - if (minecraftserver.getAllowNether()) { - if (!this.isPassenger()) { - int i = this.X(); - - if (this.ao++ >= i) { - this.ao = i; - this.portalCooldown = this.aQ(); - DimensionManager dimensionmanager; - - if (this.world.worldProvider.getDimensionManager() == DimensionManager.NETHER) { - dimensionmanager = DimensionManager.OVERWORLD; - } else { - dimensionmanager = DimensionManager.NETHER; - } - - this.a(dimensionmanager); - } - } - - this.an = false; - } - } else { - if (this.ao > 0) { - this.ao -= 4; - } - - if (this.ao < 0) { - this.ao = 0; - } - } - - this.E(); - //this.world.methodProfiler.exit(); // Akarin - remove caller - } - */ - - //this.av(); // Akarin - this handle by the client - this.r(); + if (this instanceof EntityPlayer) this.doPortalTick(); // CraftBukkit - // Moved up to postTick + this.aA(); + this.m(); if (this.world.isClientSide) { this.extinguish(); } else if (this.fireTicks > 0) { - if (this.fireProof) { + if (this.isFireProof()) { this.fireTicks -= 4; if (this.fireTicks < 0) { this.extinguish(); @@ -489,7 +415,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } } - if (this.ax()) { + if (this.aD()) { this.burnFromLava(); this.fallDistance *= 0.5F; } @@ -498,7 +424,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke // Extracted to own function /* if (this.locY < -64.0D) { - this.aa(); + this.af(); } */ this.performVoidDamage(); @@ -509,7 +435,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } this.justCreated = false; - //this.world.methodProfiler.exit(); // Akarin - remove caller + this.world.getMethodProfiler().exit(); } // Paper start @@ -530,12 +456,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } - public int X() { + public int ab() { return 1; } protected void burnFromLava() { - if (!this.fireProof) { + if (!this.isFireProof()) { // CraftBukkit start - Fallen in lava TODO: this event spams! if (this instanceof EntityLiving && fireTicks <= 0) { // not on fire yet @@ -586,16 +512,24 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } + public void g(int i) { + this.fireTicks = i; + } + + public int ad() { + return this.fireTicks; + } + public void extinguish() { this.fireTicks = 0; } - protected final void doVoidDamage() { this.aa(); } // Paper - OBFHELPER - protected void aa() { + protected final void doVoidDamage() { this.af(); } // Paper - OBFHELPER + protected void af() { this.die(); } - public boolean c(double d0, double d1, double d2) { + public boolean d(double d0, double d1, double d2) { return this.b(this.getBoundingBox().d(d0, d1, d2)); } @@ -603,233 +537,43 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.world.getCubes(this, axisalignedbb) && !this.world.containsLiquid(axisalignedbb); } - public void move(EnumMoveType enummovetype, double d0, double d1, double d2) { + public void move(EnumMoveType enummovetype, Vec3D vec3d) { if (this.noclip) { - this.a(this.getBoundingBox().d(d0, d1, d2)); + this.a(this.getBoundingBox().b(vec3d)); this.recalcPosition(); } else { if (enummovetype == EnumMoveType.PISTON) { - this.activatedTick = MinecraftServer.currentTick + 20; // Paper - long i = this.world.getTime(); - - if (i != this.aM) { - Arrays.fill(this.aL, 0.0D); - this.aM = i; - } - - int j; - double d3; - - if (d0 != 0.0D) { - j = EnumDirection.EnumAxis.X.ordinal(); - d3 = MathHelper.a(d0 + this.aL[j], -0.51D, 0.51D); - d0 = d3 - this.aL[j]; - this.aL[j] = d3; - if (Math.abs(d0) <= 9.999999747378752E-6D) { - return; - } - } else if (d1 != 0.0D) { - j = EnumDirection.EnumAxis.Y.ordinal(); - d3 = MathHelper.a(d1 + this.aL[j], -0.51D, 0.51D); - d1 = d3 - this.aL[j]; - this.aL[j] = d3; - if (Math.abs(d1) <= 9.999999747378752E-6D) { - return; - } - } else { - if (d2 == 0.0D) { - return; - } - - j = EnumDirection.EnumAxis.Z.ordinal(); - d3 = MathHelper.a(d2 + this.aL[j], -0.51D, 0.51D); - d2 = d3 - this.aL[j]; - this.aL[j] = d3; - if (Math.abs(d2) <= 9.999999747378752E-6D) { - return; - } + vec3d = this.a(vec3d); + if (vec3d.equals(Vec3D.a)) { + return; } } - //this.world.methodProfiler.enter("move"); // Akarin - remove caller - double d4 = this.locX; - double d5 = this.locY; - double d6 = this.locZ; - - if (this.F) { - this.F = false; - d0 *= 0.25D; - d1 *= 0.05000000074505806D; - d2 *= 0.25D; - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; + this.world.getMethodProfiler().enter("move"); + if (this.B.g() > 1.0E-7D) { + vec3d = vec3d.h(this.B); + this.B = Vec3D.a; + this.setMot(Vec3D.a); } - double d7 = d0; - double d8 = d1; - double d9 = d2; + vec3d = this.a(vec3d, enummovetype); + Vec3D vec3d1 = this.e(vec3d); - if ((enummovetype == EnumMoveType.SELF || enummovetype == EnumMoveType.PLAYER) && this.onGround && this.isSneaking() && this instanceof EntityHuman) { - for (double d10 = 0.05D; d0 != 0.0D && this.world.getCubes(this, this.getBoundingBox().d(d0, (double) (-this.Q), 0.0D)); d7 = d0) { - if (d0 < 0.05D && d0 >= -0.05D) { - d0 = 0.0D; - } else if (d0 > 0.0D) { - d0 -= 0.05D; - } else { - d0 += 0.05D; - } - } - - for (; d2 != 0.0D && this.world.getCubes(this, this.getBoundingBox().d(0.0D, (double) (-this.Q), d2)); d9 = d2) { - if (d2 < 0.05D && d2 >= -0.05D) { - d2 = 0.0D; - } else if (d2 > 0.0D) { - d2 -= 0.05D; - } else { - d2 += 0.05D; - } - } - - for (; d0 != 0.0D && d2 != 0.0D && this.world.getCubes(this, this.getBoundingBox().d(d0, (double) (-this.Q), d2)); d9 = d2) { - if (d0 < 0.05D && d0 >= -0.05D) { - d0 = 0.0D; - } else if (d0 > 0.0D) { - d0 -= 0.05D; - } else { - d0 += 0.05D; - } - - d7 = d0; - if (d2 < 0.05D && d2 >= -0.05D) { - d2 = 0.0D; - } else if (d2 > 0.0D) { - d2 -= 0.05D; - } else { - d2 += 0.05D; - } - } + if (vec3d1.g() > 1.0E-7D) { + this.a(this.getBoundingBox().b(vec3d1)); + this.recalcPosition(); } - AxisAlignedBB axisalignedbb = this.getBoundingBox(); - - if (d0 != 0.0D || d1 != 0.0D || d2 != 0.0D) { - StreamAccumulator streamaccumulator = new StreamAccumulator<>(this.world.a(this, this.getBoundingBox(), d0, d1, d2)); - - if (d1 != 0.0D) { - d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, this.getBoundingBox(), streamaccumulator.a(), d1); - this.a(this.getBoundingBox().d(0.0D, d1, 0.0D)); - } - - if (d0 != 0.0D) { - d0 = VoxelShapes.a(EnumDirection.EnumAxis.X, this.getBoundingBox(), streamaccumulator.a(), d0); - if (d0 != 0.0D) { - this.a(this.getBoundingBox().d(d0, 0.0D, 0.0D)); - } - } - - if (d2 != 0.0D) { - d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, this.getBoundingBox(), streamaccumulator.a(), d2); - if (d2 != 0.0D) { - this.a(this.getBoundingBox().d(0.0D, 0.0D, d2)); - } - } - } - - boolean flag = this.onGround || d1 != d8 && d1 < 0.0D; // CraftBukkit - decompile error - double d11; - - if (this.Q > 0.0F && flag && (d7 != d0 || d9 != d2)) { - double d12 = d0; - double d13 = d1; - double d14 = d2; - AxisAlignedBB axisalignedbb1 = this.getBoundingBox(); - - this.a(axisalignedbb); - d0 = d7; - d1 = (double) this.Q; - d2 = d9; - if (d7 != 0.0D || d1 != 0.0D || d9 != 0.0D) { - StreamAccumulator streamaccumulator1 = new StreamAccumulator<>(this.world.a(this, this.getBoundingBox(), d7, d1, d9)); - AxisAlignedBB axisalignedbb2 = this.getBoundingBox(); - AxisAlignedBB axisalignedbb3 = axisalignedbb2.b(d7, 0.0D, d9); - - d11 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb3, streamaccumulator1.a(), d1); - if (d11 != 0.0D) { - axisalignedbb2 = axisalignedbb2.d(0.0D, d11, 0.0D); - } - - double d15 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb2, streamaccumulator1.a(), d7); - - if (d15 != 0.0D) { - axisalignedbb2 = axisalignedbb2.d(d15, 0.0D, 0.0D); - } - - double d16 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb2, streamaccumulator1.a(), d9); - - if (d16 != 0.0D) { - axisalignedbb2 = axisalignedbb2.d(0.0D, 0.0D, d16); - } - - AxisAlignedBB axisalignedbb4 = this.getBoundingBox(); - double d17 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb4, streamaccumulator1.a(), d1); - - if (d17 != 0.0D) { - axisalignedbb4 = axisalignedbb4.d(0.0D, d17, 0.0D); - } - - double d18 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb4, streamaccumulator1.a(), d7); - - if (d18 != 0.0D) { - axisalignedbb4 = axisalignedbb4.d(d18, 0.0D, 0.0D); - } - - double d19 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb4, streamaccumulator1.a(), d9); - - if (d19 != 0.0D) { - axisalignedbb4 = axisalignedbb4.d(0.0D, 0.0D, d19); - } - - double d20 = d15 * d15 + d16 * d16; - double d21 = d18 * d18 + d19 * d19; - - if (d20 > d21) { - d0 = d15; - d2 = d16; - d1 = -d11; - this.a(axisalignedbb2); - } else { - d0 = d18; - d2 = d19; - d1 = -d17; - this.a(axisalignedbb4); - } - - d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, this.getBoundingBox(), streamaccumulator1.a(), d1); - if (d1 != 0.0D) { - this.a(this.getBoundingBox().d(0.0D, d1, 0.0D)); - } - } - - if (d12 * d12 + d14 * d14 >= d0 * d0 + d2 * d2) { - d0 = d12; - d1 = d13; - d2 = d14; - this.a(axisalignedbb1); - } - } - - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.enter("rest"); // Akarin - remove caller - this.recalcPosition(); - this.positionChanged = d7 != d0 || d9 != d2; - this.C = d1 != d8; // CraftBukkit - decompile error - this.onGround = this.C && d8 < 0.0D; - this.D = this.positionChanged || this.C; - int k = MathHelper.floor(this.locX); - int l = MathHelper.floor(this.locY - 0.20000000298023224D); - int i1 = MathHelper.floor(this.locZ); - BlockPosition blockposition = new BlockPosition(k, l, i1); + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("rest"); + this.positionChanged = !MathHelper.b(vec3d.x, vec3d1.x) || !MathHelper.b(vec3d.z, vec3d1.z); + this.y = vec3d.y != vec3d1.y; + this.onGround = this.y && vec3d.y < 0.0D; + this.z = this.positionChanged || this.y; + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY - 0.20000000298023224D); + int k = MathHelper.floor(this.locZ); + BlockPosition blockposition = new BlockPosition(i, j, k); IBlockData iblockdata = this.world.getType(blockposition); if (iblockdata.isAir()) { @@ -837,24 +581,26 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke IBlockData iblockdata1 = this.world.getType(blockposition1); Block block = iblockdata1.getBlock(); - if (block instanceof BlockFence || block instanceof BlockCobbleWall || block instanceof BlockFenceGate) { + if (block.a(TagsBlock.FENCES) || block.a(TagsBlock.WALLS) || block instanceof BlockFenceGate) { iblockdata = iblockdata1; blockposition = blockposition1; } } - this.a(d1, this.onGround, iblockdata, blockposition); - if (d7 != d0) { - this.motX = 0.0D; + this.a(vec3d1.y, this.onGround, iblockdata, blockposition); + Vec3D vec3d2 = this.getMot(); + + if (vec3d.x != vec3d1.x) { + this.setMot(0.0D, vec3d2.y, vec3d2.z); } - if (d9 != d2) { - this.motZ = 0.0D; + if (vec3d.z != vec3d1.z) { + this.setMot(vec3d2.x, vec3d2.y, 0.0D); } Block block1 = iblockdata.getBlock(); - if (d8 != d1) { + if (vec3d.y != vec3d1.y) { block1.a((IBlockAccess) this.world, this); } @@ -863,13 +609,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke Vehicle vehicle = (Vehicle) this.getBukkitEntity(); org.bukkit.block.Block bl = this.world.getWorld().getBlockAt(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)); - if (d7 > d0) { + if (vec3d1.x > vec3d.x) { bl = bl.getRelative(BlockFace.EAST); - } else if (d7 < d0) { + } else if (vec3d.x < vec3d.x) { bl = bl.getRelative(BlockFace.WEST); - } else if (d9 > d2) { + } else if (vec3d1.z > vec3d.z) { bl = bl.getRelative(BlockFace.SOUTH); - } else if (d9 < d2) { + } else if (vec3d1.z < vec3d.z) { bl = bl.getRelative(BlockFace.NORTH); } @@ -881,26 +627,27 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke // CraftBukkit end if (this.playStepSound() && (!this.onGround || !this.isSneaking() || !(this instanceof EntityHuman)) && !this.isPassenger()) { - double d22 = this.locX - d4; - double d23 = this.locY - d5; + double d0 = vec3d1.x; + double d1 = vec3d1.y; + double d2 = vec3d1.z; - d11 = this.locZ - d6; - if (block1 != Blocks.LADDER) { - d23 = 0.0D; + if (block1 != Blocks.LADDER && block1 != Blocks.SCAFFOLDING) { + d1 = 0.0D; } - if (block1 != null && this.onGround) { + if (this.onGround) { block1.stepOn(this.world, blockposition, this); } - this.K = (float) ((double) this.K + (double) MathHelper.sqrt(d22 * d22 + d11 * d11) * 0.6D); - this.L = (float) ((double) this.L + (double) MathHelper.sqrt(d22 * d22 + d23 * d23 + d11 * d11) * 0.6D); - if (this.L > this.aA && !iblockdata.isAir()) { - this.aA = this.ab(); + this.E = (float) ((double) this.E + (double) MathHelper.sqrt(b(vec3d1)) * 0.6D); + this.F = (float) ((double) this.F + (double) MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2) * 0.6D); + if (this.F > this.av && !iblockdata.isAir()) { + this.av = this.ag(); if (this.isInWater()) { - Entity entity = this.isVehicle() && this.bO() != null ? this.bO() : this; + Entity entity = this.isVehicle() && this.getRidingPassenger() != null ? this.getRidingPassenger() : this; float f = entity == this ? 0.35F : 0.4F; - float f1 = MathHelper.sqrt(entity.motX * entity.motX * 0.20000000298023224D + entity.motY * entity.motY + entity.motZ * entity.motZ * 0.20000000298023224D) * f; + Vec3D vec3d3 = entity.getMot(); + float f1 = MathHelper.sqrt(vec3d3.x * vec3d3.x * 0.20000000298023224D + vec3d3.y * vec3d3.y + vec3d3.z * vec3d3.z * 0.20000000298023224D) * f; if (f1 > 1.0F) { f1 = 1.0F; @@ -910,12 +657,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } else { this.a(blockposition, iblockdata); } - } else if (this.L > this.aB && this.ah() && iblockdata.isAir()) { - this.aB = this.e(this.L); + } else if (this.F > this.aw && this.am() && iblockdata.isAir()) { + this.aw = this.e(this.F); } } try { + this.inLava = false; this.checkBlockCollisions(); } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Checking entity block collision"); @@ -925,10 +673,10 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke throw new ReportedException(crashreport); } - boolean flag1 = this.ap(); + boolean flag = this.au(); if (this.world.b(this.getBoundingBox().shrink(0.001D))) { - if (!flag1) { + if (!flag) { ++this.fireTicks; if (this.fireTicks == 0) { // CraftBukkit start @@ -947,17 +695,225 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.fireTicks = -this.getMaxFireTicks(); } - if (flag1 && this.isBurning()) { + if (flag && this.isBurning()) { this.a(SoundEffects.ENTITY_GENERIC_EXTINGUISH_FIRE, 0.7F, 1.6F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); this.fireTicks = -this.getMaxFireTicks(); } - //this.world.methodProfiler.exit(); // Akarin - remove caller + this.world.getMethodProfiler().exit(); } } - protected float ab() { - return (float) ((int) this.L + 1); + protected Vec3D a(Vec3D vec3d, EnumMoveType enummovetype) { + if (this instanceof EntityHuman && (enummovetype == EnumMoveType.SELF || enummovetype == EnumMoveType.PLAYER) && this.onGround && this.isSneaking()) { + double d0 = vec3d.x; + double d1 = vec3d.z; + double d2 = 0.05D; + + while (d0 != 0.0D && this.world.getCubes(this, this.getBoundingBox().d(d0, (double) (-this.K), 0.0D))) { + if (d0 < 0.05D && d0 >= -0.05D) { + d0 = 0.0D; + } else if (d0 > 0.0D) { + d0 -= 0.05D; + } else { + d0 += 0.05D; + } + } + + while (d1 != 0.0D && this.world.getCubes(this, this.getBoundingBox().d(0.0D, (double) (-this.K), d1))) { + if (d1 < 0.05D && d1 >= -0.05D) { + d1 = 0.0D; + } else if (d1 > 0.0D) { + d1 -= 0.05D; + } else { + d1 += 0.05D; + } + } + + while (d0 != 0.0D && d1 != 0.0D && this.world.getCubes(this, this.getBoundingBox().d(d0, (double) (-this.K), d1))) { + if (d0 < 0.05D && d0 >= -0.05D) { + d0 = 0.0D; + } else if (d0 > 0.0D) { + d0 -= 0.05D; + } else { + d0 += 0.05D; + } + + if (d1 < 0.05D && d1 >= -0.05D) { + d1 = 0.0D; + } else if (d1 > 0.0D) { + d1 -= 0.05D; + } else { + d1 += 0.05D; + } + } + + vec3d = new Vec3D(d0, vec3d.y, d1); + } + + return vec3d; + } + + protected Vec3D a(Vec3D vec3d) { + if (vec3d.g() <= 1.0E-7D) { + return vec3d; + } else { + long i = this.world.getTime(); + + if (i != this.aH) { + Arrays.fill(this.aG, 0.0D); + this.aH = i; + } + + double d0; + + if (vec3d.x != 0.0D) { + d0 = this.a(EnumDirection.EnumAxis.X, vec3d.x); + return Math.abs(d0) <= 9.999999747378752E-6D ? Vec3D.a : new Vec3D(d0, 0.0D, 0.0D); + } else if (vec3d.y != 0.0D) { + d0 = this.a(EnumDirection.EnumAxis.Y, vec3d.y); + return Math.abs(d0) <= 9.999999747378752E-6D ? Vec3D.a : new Vec3D(0.0D, d0, 0.0D); + } else if (vec3d.z != 0.0D) { + d0 = this.a(EnumDirection.EnumAxis.Z, vec3d.z); + return Math.abs(d0) <= 9.999999747378752E-6D ? Vec3D.a : new Vec3D(0.0D, 0.0D, d0); + } else { + return Vec3D.a; + } + } + } + + private double a(EnumDirection.EnumAxis enumdirection_enumaxis, double d0) { + int i = enumdirection_enumaxis.ordinal(); + double d1 = MathHelper.a(d0 + this.aG[i], -0.51D, 0.51D); + + d0 = d1 - this.aG[i]; + this.aG[i] = d1; + return d0; + } + + private Vec3D e(Vec3D vec3d) { + AxisAlignedBB axisalignedbb = this.getBoundingBox(); + VoxelShapeCollision voxelshapecollision = VoxelShapeCollision.a(this); + VoxelShape voxelshape = this.world.getWorldBorder().a(); + Stream stream = VoxelShapes.c(voxelshape, VoxelShapes.a(axisalignedbb.shrink(1.0E-7D)), OperatorBoolean.AND) ? Stream.empty() : Stream.of(voxelshape); + Stream stream1 = this.world.a(this, axisalignedbb.a(vec3d), (Set) ImmutableSet.of()); + StreamAccumulator streamaccumulator = new StreamAccumulator<>(Stream.concat(stream1, stream)); + Vec3D vec3d1 = vec3d.g() == 0.0D ? vec3d : a(this, vec3d, axisalignedbb, this.world, voxelshapecollision, streamaccumulator); + boolean flag = vec3d.x != vec3d1.x; + boolean flag1 = vec3d.y != vec3d1.y; + boolean flag2 = vec3d.z != vec3d1.z; + boolean flag3 = this.onGround || flag1 && vec3d.y < 0.0D; + + if (this.K > 0.0F && flag3 && (flag || flag2)) { + Vec3D vec3d2 = a(this, new Vec3D(vec3d.x, (double) this.K, vec3d.z), axisalignedbb, this.world, voxelshapecollision, streamaccumulator); + Vec3D vec3d3 = a(this, new Vec3D(0.0D, (double) this.K, 0.0D), axisalignedbb.b(vec3d.x, 0.0D, vec3d.z), this.world, voxelshapecollision, streamaccumulator); + + if (vec3d3.y < (double) this.K) { + Vec3D vec3d4 = a(this, new Vec3D(vec3d.x, 0.0D, vec3d.z), axisalignedbb.b(vec3d3), this.world, voxelshapecollision, streamaccumulator).e(vec3d3); + + if (b(vec3d4) > b(vec3d2)) { + vec3d2 = vec3d4; + } + } + + if (b(vec3d2) > b(vec3d1)) { + return vec3d2.e(a(this, new Vec3D(0.0D, -vec3d2.y + vec3d.y, 0.0D), axisalignedbb.b(vec3d2), this.world, voxelshapecollision, streamaccumulator)); + } + } + + return vec3d1; + } + + public static double b(Vec3D vec3d) { + return vec3d.x * vec3d.x + vec3d.z * vec3d.z; + } + + public static Vec3D a(@Nullable Entity entity, Vec3D vec3d, AxisAlignedBB axisalignedbb, World world, VoxelShapeCollision voxelshapecollision, StreamAccumulator streamaccumulator) { + boolean flag = vec3d.x == 0.0D; + boolean flag1 = vec3d.y == 0.0D; + boolean flag2 = vec3d.z == 0.0D; + + if ((!flag || !flag1) && (!flag || !flag2) && (!flag1 || !flag2)) { + StreamAccumulator streamaccumulator1 = new StreamAccumulator<>(Stream.concat(streamaccumulator.a(), world.b(entity, axisalignedbb.a(vec3d)))); + + return a(vec3d, axisalignedbb, streamaccumulator1); + } else { + return a(vec3d, axisalignedbb, world, voxelshapecollision, streamaccumulator); + } + } + + public static Vec3D a(Vec3D vec3d, AxisAlignedBB axisalignedbb, StreamAccumulator streamaccumulator) { + double d0 = vec3d.x; + double d1 = vec3d.y; + double d2 = vec3d.z; + + if (d1 != 0.0D) { + d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb, streamaccumulator.a(), d1); + if (d1 != 0.0D) { + axisalignedbb = axisalignedbb.d(0.0D, d1, 0.0D); + } + } + + boolean flag = Math.abs(d0) < Math.abs(d2); + + if (flag && d2 != 0.0D) { + d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb, streamaccumulator.a(), d2); + if (d2 != 0.0D) { + axisalignedbb = axisalignedbb.d(0.0D, 0.0D, d2); + } + } + + if (d0 != 0.0D) { + d0 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb, streamaccumulator.a(), d0); + if (!flag && d0 != 0.0D) { + axisalignedbb = axisalignedbb.d(d0, 0.0D, 0.0D); + } + } + + if (!flag && d2 != 0.0D) { + d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb, streamaccumulator.a(), d2); + } + + return new Vec3D(d0, d1, d2); + } + + public static Vec3D a(Vec3D vec3d, AxisAlignedBB axisalignedbb, IWorldReader iworldreader, VoxelShapeCollision voxelshapecollision, StreamAccumulator streamaccumulator) { + double d0 = vec3d.x; + double d1 = vec3d.y; + double d2 = vec3d.z; + + if (d1 != 0.0D) { + d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb, iworldreader, d1, voxelshapecollision, streamaccumulator.a()); + if (d1 != 0.0D) { + axisalignedbb = axisalignedbb.d(0.0D, d1, 0.0D); + } + } + + boolean flag = Math.abs(d0) < Math.abs(d2); + + if (flag && d2 != 0.0D) { + d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb, iworldreader, d2, voxelshapecollision, streamaccumulator.a()); + if (d2 != 0.0D) { + axisalignedbb = axisalignedbb.d(0.0D, 0.0D, d2); + } + } + + if (d0 != 0.0D) { + d0 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb, iworldreader, d0, voxelshapecollision, streamaccumulator.a()); + if (!flag && d0 != 0.0D) { + axisalignedbb = axisalignedbb.d(d0, 0.0D, 0.0D); + } + } + + if (!flag && d2 != 0.0D) { + d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb, iworldreader, d2, voxelshapecollision, streamaccumulator.a()); + } + + return new Vec3D(d0, d1, d2); + } + + protected float ag() { + return (float) ((int) this.F + 1); } public void recalcPosition() { @@ -966,18 +922,18 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.locX = (axisalignedbb.minX + axisalignedbb.maxX) / 2.0D; this.locY = axisalignedbb.minY; this.locZ = (axisalignedbb.minZ + axisalignedbb.maxZ) / 2.0D; - if (valid) world.entityJoinedWorld(this, false); // CraftBukkit + if (valid) ((WorldServer) world).chunkCheck(this); // CraftBukkit } - protected SoundEffect ad() { + protected SoundEffect getSoundSwim() { return SoundEffects.ENTITY_GENERIC_SWIM; } - protected SoundEffect ae() { + protected SoundEffect getSoundSplash() { return SoundEffects.ENTITY_GENERIC_SPLASH; } - protected SoundEffect af() { + protected SoundEffect getSoundSplashHighSpeed() { return SoundEffects.ENTITY_GENERIC_SPLASH; } @@ -999,7 +955,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke for (int i = blockposition_pooledblockposition.getX(); i <= blockposition_pooledblockposition1.getX(); ++i) { for (int j = blockposition_pooledblockposition.getY(); j <= blockposition_pooledblockposition1.getY(); ++j) { for (int k = blockposition_pooledblockposition.getZ(); k <= blockposition_pooledblockposition1.getZ(); ++k) { - blockposition_pooledblockposition2.c(i, j, k); + blockposition_pooledblockposition2.d(i, j, k); IBlockData iblockdata = this.world.getType(blockposition_pooledblockposition2); try { @@ -1074,45 +1030,46 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke protected void a(BlockPosition blockposition, IBlockData iblockdata) { if (!iblockdata.getMaterial().isLiquid()) { - SoundEffectType soundeffecttype = this.world.getType(blockposition.up()).getBlock() == Blocks.SNOW ? Blocks.SNOW.getStepSound() : iblockdata.getBlock().getStepSound(); + IBlockData iblockdata1 = this.world.getType(blockposition.up()); + SoundEffectType soundeffecttype = iblockdata1.getBlock() == Blocks.SNOW ? iblockdata1.r() : iblockdata.r(); this.a(soundeffecttype.d(), soundeffecttype.a() * 0.15F, soundeffecttype.b()); } } protected void d(float f) { - this.a(this.ad(), f, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); + this.a(this.getSoundSwim(), f, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); } protected float e(float f) { return 0.0F; } - protected boolean ah() { + protected boolean am() { return false; } public void a(SoundEffect soundeffect, float f, float f1) { if (!this.isSilent()) { - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, soundeffect, this.bV(), f, f1); + this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, soundeffect, this.getSoundCategory(), f, f1); } } public boolean isSilent() { - return (Boolean) this.datawatcher.get(Entity.aG); + return (Boolean) this.datawatcher.get(Entity.aB); } public void setSilent(boolean flag) { - this.datawatcher.set(Entity.aG, flag); + this.datawatcher.set(Entity.aB, flag); } public boolean isNoGravity() { - return (Boolean) this.datawatcher.get(Entity.aH); + return (Boolean) this.datawatcher.get(Entity.aC); } public void setNoGravity(boolean flag) { - this.datawatcher.set(Entity.aH, flag); + this.datawatcher.set(Entity.aC, flag); } protected boolean playStepSound() { @@ -1133,29 +1090,29 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } @Nullable - public AxisAlignedBB al() { + public AxisAlignedBB aq() { return null; } protected void burn(float i) { // CraftBukkit - int -> float - if (!this.fireProof) { + if (!this.isFireProof()) { this.damageEntity(DamageSource.FIRE, (float) i); } } public final boolean isFireProof() { - return this.fireProof; + return this.getEntityType().c(); } - public void c(float f, float f1) { + public void b(float f, float f1) { if (this.isVehicle()) { - Iterator iterator = this.bP().iterator(); + Iterator iterator = this.getPassengers().iterator(); while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); - entity.c(f, f1); + entity.b(f, f1); } } @@ -1165,14 +1122,14 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.inWater; } - private boolean p() { + private boolean isInRain() { BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.b(this); Throwable throwable = null; boolean flag; try { - flag = this.world.isRainingAt(blockposition_pooledblockposition) || this.world.isRainingAt(blockposition_pooledblockposition.c(this.locX, this.locY + (double) this.length, this.locZ)); + flag = this.world.isRainingAt(blockposition_pooledblockposition) || this.world.isRainingAt(blockposition_pooledblockposition.c(this.locX, this.locY + (double) this.size.height, this.locZ)); } catch (Throwable throwable1) { throwable = throwable1; throw throwable1; @@ -1194,53 +1151,47 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return flag; } - private boolean q() { + private boolean l() { return this.world.getType(new BlockPosition(this)).getBlock() == Blocks.BUBBLE_COLUMN; } - public boolean ao() { - return this.isInWater() || this.p(); + public boolean isInWaterOrRain() { + return this.isInWater() || this.isInRain(); } - public boolean ap() { - return this.isInWater() || this.p() || this.q(); + public boolean au() { + return this.isInWater() || this.isInRain() || this.l(); } - public boolean aq() { - // Paper start - return this.doWaterMovement(); + public boolean av() { + return this.isInWater() || this.l(); } - public boolean doWaterMovement() { - // Paper end - return this.isInWater() || this.q(); + public boolean aw() { + return this.R && this.isInWater(); } - public boolean ar() { - return this.X && this.isInWater(); + private void m() { + this.ay(); + this.n(); + this.ax(); } - private void r() { - this.at(); - this.s(); - this.as(); - } - - public void as() { + public void ax() { if (this.isSwimming()) { this.setSwimming(this.isSprinting() && this.isInWater() && !this.isPassenger()); } else { - this.setSwimming(this.isSprinting() && this.ar() && !this.isPassenger()); + this.setSwimming(this.isSprinting() && this.aw() && !this.isPassenger()); } } - public boolean at() { + public boolean ay() { if (this.getVehicle() instanceof EntityBoat) { this.inWater = false; } else if (this.b(TagsFluid.WATER)) { if (!this.inWater && !this.justCreated) { - this.au(); + this.az(); } this.fallDistance = 0.0F; @@ -1253,121 +1204,123 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.inWater; } - private void s() { - this.X = this.a(TagsFluid.WATER); + private void n() { + this.R = this.a(TagsFluid.WATER, true); } - protected void au() { - Entity entity = this.isVehicle() && this.bO() != null ? this.bO() : this; + protected void az() { + Entity entity = this.isVehicle() && this.getRidingPassenger() != null ? this.getRidingPassenger() : this; float f = entity == this ? 0.2F : 0.9F; - float f1 = MathHelper.sqrt(entity.motX * entity.motX * 0.20000000298023224D + entity.motY * entity.motY + entity.motZ * entity.motZ * 0.20000000298023224D) * f; + Vec3D vec3d = entity.getMot(); + float f1 = MathHelper.sqrt(vec3d.x * vec3d.x * 0.20000000298023224D + vec3d.y * vec3d.y + vec3d.z * vec3d.z * 0.20000000298023224D) * f; if (f1 > 1.0F) { f1 = 1.0F; } if ((double) f1 < 0.25D) { - this.a(this.ae(), f1, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); + this.a(this.getSoundSplash(), f1, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); } else { - this.a(this.af(), f1, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); + this.a(this.getSoundSplashHighSpeed(), f1, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); } - // Akarin start - this handle by client - /* float f2 = (float) MathHelper.floor(this.getBoundingBox().minY); float f3; float f4; int i; - for (i = 0; (float) i < 1.0F + this.width * 20.0F; ++i) { - f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width; - f4 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width; - this.world.addParticle(Particles.e, this.locX + (double) f3, (double) (f2 + 1.0F), this.locZ + (double) f4, this.motX, this.motY - (double) (this.random.nextFloat() * 0.2F), this.motZ); + for (i = 0; (float) i < 1.0F + this.size.width * 20.0F; ++i) { + f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.size.width; + f4 = (this.random.nextFloat() * 2.0F - 1.0F) * this.size.width; + this.world.addParticle(Particles.BUBBLE, this.locX + (double) f3, (double) (f2 + 1.0F), this.locZ + (double) f4, vec3d.x, vec3d.y - (double) (this.random.nextFloat() * 0.2F), vec3d.z); } - for (i = 0; (float) i < 1.0F + this.width * 20.0F; ++i) { - f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width; - f4 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width; - this.world.addParticle(Particles.R, this.locX + (double) f3, (double) (f2 + 1.0F), this.locZ + (double) f4, this.motX, this.motY, this.motZ); + for (i = 0; (float) i < 1.0F + this.size.width * 20.0F; ++i) { + f3 = (this.random.nextFloat() * 2.0F - 1.0F) * this.size.width; + f4 = (this.random.nextFloat() * 2.0F - 1.0F) * this.size.width; + this.world.addParticle(Particles.SPLASH, this.locX + (double) f3, (double) (f2 + 1.0F), this.locZ + (double) f4, vec3d.x, vec3d.y, vec3d.z); } - */ - // Akarin end } - public void av() { - // Akarin start - this handle by client - /* + public void aA() { if (this.isSprinting() && !this.isInWater()) { - this.aw(); + this.aB(); } - */ - // Akarin end } - protected void aw() { - // Akarin start - this handle by client - /* + protected void aB() { int i = MathHelper.floor(this.locX); int j = MathHelper.floor(this.locY - 0.20000000298023224D); int k = MathHelper.floor(this.locZ); BlockPosition blockposition = new BlockPosition(i, j, k); IBlockData iblockdata = this.world.getType(blockposition); - if (iblockdata.i() != EnumRenderType.INVISIBLE) { - this.world.addParticle(new ParticleParamBlock(Particles.d, iblockdata), this.locX + ((double) this.random.nextFloat() - 0.5D) * (double) this.width, this.getBoundingBox().minY + 0.1D, this.locZ + ((double) this.random.nextFloat() - 0.5D) * (double) this.width, -this.motX * 4.0D, 1.5D, -this.motZ * 4.0D); + if (iblockdata.k() != EnumRenderType.INVISIBLE) { + Vec3D vec3d = this.getMot(); + + this.world.addParticle(new ParticleParamBlock(Particles.BLOCK, iblockdata), this.locX + ((double) this.random.nextFloat() - 0.5D) * (double) this.size.width, this.locY + 0.1D, this.locZ + ((double) this.random.nextFloat() - 0.5D) * (double) this.size.width, vec3d.x * -4.0D, 1.5D, vec3d.z * -4.0D); } - */ - // Akarin end } public boolean a(Tag tag) { + return this.a(tag, false); + } + + public boolean a(Tag tag, boolean flag) { if (this.getVehicle() instanceof EntityBoat) { return false; } else { double d0 = this.locY + (double) this.getHeadHeight(); BlockPosition blockposition = new BlockPosition(this.locX, d0, this.locZ); - Fluid fluid = this.world.getFluid(blockposition); - return fluid.a(tag) && d0 < (double) ((float) blockposition.getY() + fluid.getHeight() + 0.11111111F); - } - } + if (flag && !this.world.isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4)) { + return false; + } else { + Fluid fluid = this.world.getFluid(blockposition); - public boolean ax() { - return this.world.a(this.getBoundingBox().f(0.10000000149011612D, 0.4000000059604645D, 0.10000000149011612D), Material.LAVA); - } - - public void a(float f, float f1, float f2, float f3) { - float f4 = f * f + f1 * f1 + f2 * f2; - - if (f4 >= 1.0E-4F) { - f4 = MathHelper.c(f4); - if (f4 < 1.0F) { - f4 = 1.0F; + return fluid.a(tag) && d0 < (double) ((float) blockposition.getY() + fluid.getHeight(this.world, blockposition) + 0.11111111F); } - - f4 = f3 / f4; - f *= f4; - f1 *= f4; - f2 *= f4; - float f5 = MathHelper.sin(this.yaw * 0.017453292F); - float f6 = MathHelper.cos(this.yaw * 0.017453292F); - - this.motX += (double) (f * f6 - f2 * f5); - this.motY += (double) f1; - this.motZ += (double) (f2 * f6 + f * f5); } } - public float az() { - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(MathHelper.floor(this.locX), 0, MathHelper.floor(this.locZ)); + public void aC() { + this.inLava = true; + } + + public boolean aD() { + return this.inLava; + } + + public void a(float f, Vec3D vec3d) { + Vec3D vec3d1 = a(vec3d, f, this.yaw); + + this.setMot(this.getMot().e(vec3d1)); + } + + protected static Vec3D a(Vec3D vec3d, float f, float f1) { + double d0 = vec3d.g(); + + if (d0 < 1.0E-7D) { + return Vec3D.a; + } else { + Vec3D vec3d1 = (d0 > 1.0D ? vec3d.d() : vec3d).a((double) f); + float f2 = MathHelper.sin(f1 * 0.017453292F); + float f3 = MathHelper.cos(f1 * 0.017453292F); + + return new Vec3D(vec3d1.x * (double) f3 - vec3d1.z * (double) f2, vec3d1.y, vec3d1.z * (double) f3 + vec3d1.x * (double) f2); + } + } + + public float aF() { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(this.locX, 0.0D, this.locZ); if (this.world.isLoaded(blockposition_mutableblockposition)) { blockposition_mutableblockposition.p(MathHelper.floor(this.locY + (double) this.getHeadHeight())); - return this.world.A(blockposition_mutableblockposition); + return this.world.v(blockposition_mutableblockposition); } else { return 0.0F; } @@ -1422,9 +1375,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.lastX = this.locX; this.lastY = this.locY; this.lastZ = this.locZ; - this.N = this.locX; - this.O = this.locY; - this.P = this.locZ; + this.H = this.locX; + this.I = this.locY; + this.J = this.locZ; this.yaw = f; this.pitch = f1; this.setPosition(this.locX, this.locY, this.locZ); @@ -1438,7 +1391,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return MathHelper.c(f * f + f1 * f1 + f2 * f2); } - public double d(double d0, double d1, double d2) { + public double e(double d0, double d1, double d2) { double d3 = this.locX - d0; double d4 = this.locY - d1; double d5 = this.locZ - d2; @@ -1446,31 +1399,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return d3 * d3 + d4 * d4 + d5 * d5; } - public double c(BlockPosition blockposition) { - return blockposition.distanceSquared(this.locX, this.locY, this.locZ); - } - - public double d(BlockPosition blockposition) { - return blockposition.g(this.locX, this.locY, this.locZ); - } - - public double e(double d0, double d1, double d2) { - double d3 = this.locX - d0; - double d4 = this.locY - d1; - double d5 = this.locZ - d2; - - return (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); - } - public double h(Entity entity) { - double d0 = this.locX - entity.locX; - double d1 = this.locY - entity.locY; - double d2 = this.locZ - entity.locZ; - - return d0 * d0 + d1 * d1 + d2 * d2; + return this.c(entity.getPositionVector()); } - public double a(Vec3D vec3d) { + public double c(Vec3D vec3d) { double d0 = this.locX - vec3d.x; double d1 = this.locY - vec3d.y; double d2 = this.locZ - vec3d.z; @@ -1478,7 +1411,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return d0 * d0 + d1 * d1 + d2 * d2; } - public void d(EntityHuman entityhuman) {} + public void pickup(EntityHuman entityhuman) {} public void collide(Entity entity) { if (!this.x(entity)) { @@ -1501,8 +1434,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke d1 *= d3; d0 *= 0.05000000074505806D; d1 *= 0.05000000074505806D; - d0 *= (double) (1.0F - this.S); - d1 *= (double) (1.0F - this.S); + d0 *= (double) (1.0F - this.M); + d1 *= (double) (1.0F - this.M); if (!this.isVehicle()) { this.f(-d0, 0.0D, -d1); } @@ -1517,13 +1450,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public void f(double d0, double d1, double d2) { - this.motX += d0; - this.motY += d1; - this.motZ += d2; + this.setMot(this.getMot().add(d0, d1, d2)); this.impulse = true; } - protected void aA() { + protected void velocityChanged() { this.velocityChanged = true; } @@ -1531,24 +1462,24 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke if (this.isInvulnerable(damagesource)) { return false; } else { - this.aA(); + this.velocityChanged(); return false; } } public final Vec3D f(float f) { - return this.d(this.g(f), this.h(f)); + return this.c(this.g(f), this.h(f)); } public float g(float f) { - return f == 1.0F ? this.pitch : this.lastPitch + (this.pitch - this.lastPitch) * f; + return f == 1.0F ? this.pitch : MathHelper.g(f, this.lastPitch, this.pitch); } public float h(float f) { - return f == 1.0F ? this.yaw : this.lastYaw + (this.yaw - this.lastYaw) * f; + return f == 1.0F ? this.yaw : MathHelper.g(f, this.lastYaw, this.yaw); } - protected final Vec3D d(float f, float f1) { + protected final Vec3D c(float f, float f1) { float f2 = f * 0.017453292F; float f3 = -f1 * 0.017453292F; float f4 = MathHelper.cos(f3); @@ -1559,14 +1490,22 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return new Vec3D((double) (f5 * f6), (double) (-f7), (double) (f4 * f6)); } - public Vec3D getEyePosition(float partialTicks) { return i(partialTicks); } // Paper - OBFHELPER - public Vec3D i(float f) { + public final Vec3D i(float f) { + return this.d(this.g(f), this.h(f)); + } + + protected final Vec3D d(float f, float f1) { + return this.c(f - 90.0F, f1); + } + + public final Vec3D getEyePosition(float partialTicks) { return j(partialTicks); } // Paper - OBFHELPER + public Vec3D j(float f) { if (f == 1.0F) { return new Vec3D(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ); } else { - double d0 = this.lastX + (this.locX - this.lastX) * (double) f; - double d1 = this.lastY + (this.locY - this.lastY) * (double) f + (double) this.getHeadHeight(); - double d2 = this.lastZ + (this.locZ - this.lastZ) * (double) f; + double d0 = MathHelper.d((double) f, this.lastX, this.locX); + double d1 = MathHelper.d((double) f, this.lastY, this.locY) + (double) this.getHeadHeight(); + double d2 = MathHelper.d((double) f, this.lastZ, this.locZ); return new Vec3D(d0, d1, d2); } @@ -1607,7 +1546,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public NBTTagCompound save(NBTTagCompound nbttagcompound) { try { nbttagcompound.set("Pos", this.a(this.locX, this.locY, this.locZ)); - nbttagcompound.set("Motion", this.a(this.motX, this.motY, this.motZ)); + Vec3D vec3d = this.getMot(); + + nbttagcompound.set("Motion", this.a(vec3d.x, vec3d.y, vec3d.z)); // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero // TODO: make sure this is the best way to address this. @@ -1625,14 +1566,14 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke nbttagcompound.setShort("Fire", (short) this.fireTicks); nbttagcompound.setShort("Air", (short) this.getAirTicks()); nbttagcompound.setBoolean("OnGround", this.onGround); - nbttagcompound.setInt("Dimension", this.dimension.getDimensionID()); + nbttagcompound.setInt("Dimension", this.dimension.getType().getDimensionID()); // CraftBukkit - preserve Vanilla compat nbttagcompound.setBoolean("Invulnerable", this.invulnerable); nbttagcompound.setInt("PortalCooldown", this.portalCooldown); nbttagcompound.a("UUID", this.getUniqueID()); // CraftBukkit start // PAIL: Check above UUID reads 1.8 properly, ie: UUIDMost / UUIDLeast - nbttagcompound.setLong("WorldUUIDLeast", this.world.getDataManager().getUUID().getLeastSignificantBits()); - nbttagcompound.setLong("WorldUUIDMost", this.world.getDataManager().getUUID().getMostSignificantBits()); + nbttagcompound.setLong("WorldUUIDLeast", ((WorldServer) this.world).getDataManager().getUUID().getLeastSignificantBits()); + nbttagcompound.setLong("WorldUUIDMost", ((WorldServer) this.world).getDataManager().getUUID().getMostSignificantBits()); nbttagcompound.setInt("Bukkit.updateLevel", CURRENT_LEVEL); nbttagcompound.setInt("Spigot.ticksLived", this.ticksLived); // CraftBukkit end @@ -1661,32 +1602,30 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke NBTTagList nbttaglist; Iterator iterator; - synchronized (this.aJ) { // Akarin - if (!this.aJ.isEmpty()) { + if (!this.aE.isEmpty()) { nbttaglist = new NBTTagList(); - iterator = this.aJ.iterator(); + iterator = this.aE.iterator(); while (iterator.hasNext()) { String s = (String) iterator.next(); - nbttaglist.add((NBTBase) (new NBTTagString(s))); + nbttaglist.add(new NBTTagString(s)); } nbttagcompound.set("Tags", nbttaglist); } - } // Akarin this.b(nbttagcompound); if (this.isVehicle()) { nbttaglist = new NBTTagList(); - iterator = this.bP().iterator(); + iterator = this.getPassengers().iterator(); while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); NBTTagCompound nbttagcompound1 = new NBTTagCompound(); if (entity.c(nbttagcompound1)) { - nbttaglist.add((NBTBase) nbttagcompound1); + nbttaglist.add(nbttagcompound1); } } @@ -1695,8 +1634,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } } + // CraftBukkit start - stores eventually existing bukkit values + if (this.bukkitEntity != null) { + this.bukkitEntity.storeBukkitValues(nbttagcompound); + } + // CraftBukkit end // Paper start - Save the entity's origin location - if (origin != null) { + if (this.origin != null) { nbttagcompound.set("Paper.Origin", this.createList(origin.getX(), origin.getY(), origin.getZ())); } if (spawnReason != null) { @@ -1722,80 +1666,73 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke NBTTagList nbttaglist = nbttagcompound.getList("Pos", 6); NBTTagList nbttaglist1 = nbttagcompound.getList("Motion", 6); NBTTagList nbttaglist2 = nbttagcompound.getList("Rotation", 5); + double d0 = nbttaglist1.h(0); + double d1 = nbttaglist1.h(1); + double d2 = nbttaglist1.h(2); - this.motX = nbttaglist1.k(0); - this.motY = nbttaglist1.k(1); - this.motZ = nbttaglist1.k(2); - - /* CraftBukkit start - Moved section down - if (Math.abs(this.motX) > 10.0D) { - this.motX = 0.0D; - } - - if (Math.abs(this.motY) > 10.0D) { - this.motY = 0.0D; - } - - if (Math.abs(this.motZ) > 10.0D) { - this.motZ = 0.0D; - } - // CraftBukkit end */ - - this.locX = nbttaglist.k(0); - this.locY = nbttaglist.k(1); - this.locZ = nbttaglist.k(2); - this.N = this.locX; - this.O = this.locY; - this.P = this.locZ; + this.setMot(Math.abs(d0) > 10.0D ? 0.0D : d0, Math.abs(d1) > 10.0D ? 0.0D : d1, Math.abs(d2) > 10.0D ? 0.0D : d2); + this.locX = nbttaglist.h(0); + this.locY = nbttaglist.h(1); + this.locZ = nbttaglist.h(2); + this.H = this.locX; + this.I = this.locY; + this.J = this.locZ; this.lastX = this.locX; this.lastY = this.locY; this.lastZ = this.locZ; - this.yaw = nbttaglist2.l(0); - this.pitch = nbttaglist2.l(1); + this.yaw = nbttaglist2.i(0); + this.pitch = nbttaglist2.i(1); this.lastYaw = this.yaw; this.lastPitch = this.pitch; this.setHeadRotation(this.yaw); - this.k(this.yaw); + this.l(this.yaw); this.fallDistance = nbttagcompound.getFloat("FallDistance"); this.fireTicks = nbttagcompound.getShort("Fire"); this.setAirTicks(nbttagcompound.getShort("Air")); this.onGround = nbttagcompound.getBoolean("OnGround"); if (nbttagcompound.hasKey("Dimension")) { - //this.dimension = DimensionManager.a(nbttagcompound.getInt("Dimension")); // Paper - always controlled by world + // this.dimension = DimensionManager.a(nbttagcompound.getInt("Dimension")); // CraftBukkit - redundant } this.invulnerable = nbttagcompound.getBoolean("Invulnerable"); this.portalCooldown = nbttagcompound.getInt("PortalCooldown"); if (nbttagcompound.b("UUID")) { this.uniqueID = nbttagcompound.a("UUID"); - this.au = this.uniqueID.toString(); + this.ap = this.uniqueID.toString(); } - this.setPosition(this.locX, this.locY, this.locZ); - this.setYawPitch(this.yaw, this.pitch); - if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.setCustomName(MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound)); // Paper - Catch ParseException - } + if (Double.isFinite(this.locX) && Double.isFinite(this.locY) && Double.isFinite(this.locZ)) { + if (Double.isFinite((double) this.yaw) && Double.isFinite((double) this.pitch)) { + this.setPosition(this.locX, this.locY, this.locZ); + this.setYawPitch(this.yaw, this.pitch); + if (nbttagcompound.hasKeyOfType("CustomName", 8)) { + this.setCustomName(MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound)); // Paper - Catch ParseException + } - this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible")); - this.setSilent(nbttagcompound.getBoolean("Silent")); - this.setNoGravity(nbttagcompound.getBoolean("NoGravity")); - this.h(nbttagcompound.getBoolean("Glowing")); - if (nbttagcompound.hasKeyOfType("Tags", 9)) { - synchronized (this.aJ) { // Akarin - this.aJ.clear(); - NBTTagList nbttaglist3 = nbttagcompound.getList("Tags", 8); - int i = Math.min(nbttaglist3.size(), 1024); + this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible")); + this.setSilent(nbttagcompound.getBoolean("Silent")); + this.setNoGravity(nbttagcompound.getBoolean("NoGravity")); + this.h(nbttagcompound.getBoolean("Glowing")); + if (nbttagcompound.hasKeyOfType("Tags", 9)) { + this.aE.clear(); + NBTTagList nbttaglist3 = nbttagcompound.getList("Tags", 8); + int i = Math.min(nbttaglist3.size(), 1024); - for (int j = 0; j < i; ++j) { - this.aJ.add(nbttaglist3.getString(j)); + for (int j = 0; j < i; ++j) { + this.aE.add(nbttaglist3.getString(j)); + } + } + + this.a(nbttagcompound); + if (this.aJ()) { + this.setPosition(this.locX, this.locY, this.locZ); + } + + } else { + throw new IllegalStateException("Entity has invalid rotation"); } - } // Akarin - } - - this.a(nbttagcompound); - if (this.aD()) { - this.setPosition(this.locX, this.locY, this.locZ); + } else { + throw new IllegalStateException("Entity has invalid position"); } // CraftBukkit start @@ -1807,26 +1744,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke // Reset the persistence for tamed animals if (entity instanceof EntityTameableAnimal && !isLevelAtLeast(nbttagcompound, 2) && !nbttagcompound.getBoolean("PersistenceRequired")) { EntityInsentient entityinsentient = (EntityInsentient) entity; - entityinsentient.persistent = !entityinsentient.isTypeNotPersistent(); + entityinsentient.persistent = !entityinsentient.isTypeNotPersistent(0); } } // CraftBukkit end - // CraftBukkit start - double limit = getBukkitEntity() instanceof Vehicle ? 100.0D : 10.0D; - if (Math.abs(this.motX) > limit) { - this.motX = 0.0D; - } - - if (Math.abs(this.motY) > limit) { - this.motY = 0.0D; - } - - if (Math.abs(this.motZ) > limit) { - this.motZ = 0.0D; - } - // CraftBukkit end - // CraftBukkit start - Reset world if (this instanceof EntityPlayer) { Server server = Bukkit.getServer(); @@ -1846,8 +1768,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(DimensionManager.OVERWORLD).getWorld(); } - spawnIn(bworld == null? null : ((CraftWorld) bworld).getHandle()); + spawnIn(bworld == null ? null : ((CraftWorld) bworld).getHandle()); } + this.getBukkitEntity().readBukkitValues(nbttagcompound); // CraftBukkit end // Paper start - Restore the entity's origin location @@ -1868,7 +1791,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke if (spawnReason == null) { if (spawnedViaMobSpawner) { spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; - } else if (this instanceof EntityInsentient && this instanceof IAnimal && !((EntityInsentient) this).isTypeNotPersistent()) { + } else if (this instanceof EntityInsentient && (this instanceof EntityAnimal || this instanceof EntityFish) && !((EntityInsentient) this).isTypeNotPersistent(0.0)) { if (!nbttagcompound.getBoolean("PersistenceRequired")) { spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL; } @@ -1888,7 +1811,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } } - protected boolean aD() { + protected boolean aJ() { return true; } @@ -1945,8 +1868,10 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } @Nullable public final String getSaveID() { - EntityTypes type = this.getEntityType(); - return type != null && type.isPersistable() ? getMinecraftKeyString() : null; + EntityTypes entitytypes = this.getEntityType(); + MinecraftKey minecraftkey = EntityTypes.getName(entitytypes); + + return entitytypes != null && entitytypes.isPersistable() ? getMinecraftKeyString() : null; // Paper end } @@ -1963,7 +1888,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke for (int j = 0; j < i; ++j) { double d0 = adouble1[j]; - nbttaglist.add((NBTBase) (new NBTTagDouble(d0))); + nbttaglist.add(new NBTTagDouble(d0)); } return nbttaglist; @@ -1977,7 +1902,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke for (int j = 0; j < i; ++j) { float f = afloat1[j]; - nbttaglist.add((NBTBase) (new NBTTagFloat(f))); + nbttaglist.add(new NBTTagFloat(f)); } return nbttaglist; @@ -1994,7 +1919,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } @Nullable - public EntityItem a_(ItemStack itemstack) { + public EntityItem a(ItemStack itemstack) { return this.a(itemstack, 0.0F); } @@ -2003,6 +1928,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public EntityItem a(ItemStack itemstack, float f) { if (itemstack.isEmpty()) { return null; + } else if (this.world.isClientSide) { + return null; } else { // CraftBukkit start - Capture drops for death event if (this instanceof EntityLiving && !((EntityLiving) this).forceDrops) { @@ -2012,7 +1939,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke // CraftBukkit end EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY + (double) f, this.locZ, itemstack); - entityitem.n(); + entityitem.defaultPickupDelay(); // CraftBukkit start EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); @@ -2038,13 +1965,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke try { for (int i = 0; i < 8; ++i) { - int j = MathHelper.floor(this.locY + (double) (((float) ((i >> 0) % 2) - 0.5F) * 0.1F) + (double) this.getHeadHeight()); - int k = MathHelper.floor(this.locX + (double) (((float) ((i >> 1) % 2) - 0.5F) * this.width * 0.8F)); - int l = MathHelper.floor(this.locZ + (double) (((float) ((i >> 2) % 2) - 0.5F) * this.width * 0.8F)); + int j = MathHelper.floor(this.locY + (double) (((float) ((i >> 0) % 2) - 0.5F) * 0.1F) + (double) this.headHeight); + int k = MathHelper.floor(this.locX + (double) (((float) ((i >> 1) % 2) - 0.5F) * this.size.width * 0.8F)); + int l = MathHelper.floor(this.locZ + (double) (((float) ((i >> 2) % 2) - 0.5F) * this.size.width * 0.8F)); if (blockposition_pooledblockposition.getX() != k || blockposition_pooledblockposition.getY() != j || blockposition_pooledblockposition.getZ() != l) { - blockposition_pooledblockposition.c(k, j, l); - if (this.world.getType(blockposition_pooledblockposition).r()) { + blockposition_pooledblockposition.d(k, j, l); + if (this.world.getType(blockposition_pooledblockposition).m(this.world, blockposition_pooledblockposition)) { boolean flag = true; return flag; @@ -2082,34 +2009,26 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return null; } - public void aH() { - Entity entity = this.getVehicle(); - - if (this.isPassenger() && entity.dead) { - this.stopRiding(); - } else { - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; - this.tick(); - if (this.isPassenger()) { - entity.k(this); - } + public void passengerTick() { + this.setMot(Vec3D.a); + this.tick(); + if (this.isPassenger()) { + this.getVehicle().k(this); } } public void k(Entity entity) { if (this.w(entity)) { - entity.setPosition(this.locX, this.locY + this.aJ() + entity.aI(), this.locZ); + entity.setPosition(this.locX, this.locY + this.aP() + entity.aO(), this.locZ); } } - public double aI() { + public double aO() { return 0.0D; } - public double aJ() { - return (double) this.length * 0.75D; + public double aP() { + return (double) this.size.height * 0.75D; } public boolean startRiding(Entity entity) { @@ -2137,7 +2056,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } protected boolean n(Entity entity) { - return this.k <= 0; + return this.j <= 0; + } + + protected boolean c(EntityPose entitypose) { + return this.world.getCubes(this, this.d(entitypose)); } public void ejectPassengers() { @@ -2170,12 +2093,15 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle(); Entity orig = craft == null ? null : craft.getHandle(); - if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity && entity.world.isChunkLoaded((int) entity.locX >> 4, (int) entity.locZ >> 4, false)) { // Boolean not used + if (getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) { VehicleEnterEvent event = new VehicleEnterEvent( (Vehicle) getBukkitEntity(), entity.getBukkitEntity() ); - Bukkit.getPluginManager().callEvent(event); + // Suppress during worldgen + if (this.valid) { + Bukkit.getPluginManager().callEvent(event); + } CraftEntity craftn = (CraftEntity) entity.getBukkitEntity().getVehicle(); Entity n = craftn == null ? null : craftn.getHandle(); if (event.isCancelled() || n != orig) { @@ -2185,12 +2111,15 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke // CraftBukkit end // Spigot start org.spigotmc.event.entity.EntityMountEvent event = new org.spigotmc.event.entity.EntityMountEvent(entity.getBukkitEntity(), this.getBukkitEntity()); - Bukkit.getPluginManager().callEvent(event); + // Suppress during worldgen + if (this.valid) { + Bukkit.getPluginManager().callEvent(event); + } if (event.isCancelled()) { return false; } // Spigot end - if (!this.world.isClientSide && entity instanceof EntityHuman && !(this.bO() instanceof EntityHuman)) { + if (!this.world.isClientSide && entity instanceof EntityHuman && !(this.getRidingPassenger() instanceof EntityHuman)) { this.passengers.add(0, entity); } else { this.passengers.add(entity); @@ -2231,64 +2160,95 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } // Spigot end this.passengers.remove(entity); - entity.k = 60; + entity.j = 60; } return true; // CraftBukkit } protected boolean q(Entity entity) { - return this.bP().size() < 1; + return this.getPassengers().size() < 1; } - public float getCollisionBorderSize() { return aM(); } // Paper - OBFHELPER - public float aM() { + public final float getCollisionBorderSize() { return aS(); } // Paper - OBFHELPER + public float aS() { return 0.0F; } - public Vec3D getLookVec() { return aN(); } // Paper - OBFHELPER - public Vec3D aN() { - return this.d(this.pitch, this.yaw); + public Vec3D getLookDirection() { + return this.c(this.pitch, this.yaw); } - public Vec2F aO() { + public Vec2F aU() { return new Vec2F(this.pitch, this.yaw); } - public void e(BlockPosition blockposition) { + public void c(BlockPosition blockposition) { if (this.portalCooldown > 0) { - this.portalCooldown = this.aQ(); + this.portalCooldown = this.aX(); } else { - if (!this.world.isClientSide && !blockposition.equals(this.aq)) { - this.aq = new BlockPosition(blockposition); - ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = ((BlockPortal) Blocks.NETHER_PORTAL).c((GeneratorAccess) this.world, this.aq); + if (!this.world.isClientSide && !blockposition.equals(this.al)) { + this.al = new BlockPosition(blockposition); + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = ((BlockPortal) Blocks.NETHER_PORTAL).c((GeneratorAccess) this.world, this.al); double d0 = shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? (double) shapedetector_shapedetectorcollection.a().getZ() : (double) shapedetector_shapedetectorcollection.a().getX(); - double d1 = shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? this.locZ : this.locX; - - d1 = Math.abs(MathHelper.c(d1 - (double) (shapedetector_shapedetectorcollection.getFacing().e().c() == EnumDirection.EnumAxisDirection.NEGATIVE ? 1 : 0), d0, d0 - (double) shapedetector_shapedetectorcollection.d())); + double d1 = Math.abs(MathHelper.c((shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? this.locZ : this.locX) - (double) (shapedetector_shapedetectorcollection.getFacing().e().c() == EnumDirection.EnumAxisDirection.NEGATIVE ? 1 : 0), d0, d0 - (double) shapedetector_shapedetectorcollection.d())); double d2 = MathHelper.c(this.locY - 1.0D, (double) shapedetector_shapedetectorcollection.a().getY(), (double) (shapedetector_shapedetectorcollection.a().getY() - shapedetector_shapedetectorcollection.e())); - this.ar = new Vec3D(d1, d2, 0.0D); - this.as = shapedetector_shapedetectorcollection.getFacing(); + this.am = new Vec3D(d1, d2, 0.0D); + this.an = shapedetector_shapedetectorcollection.getFacing(); } - this.an = true; + this.ai = true; } } - public int aQ() { + protected void doPortalTick() { + if (this.world instanceof WorldServer) { + int i = this.ab(); + + if (this.ai) { + if ((true || this.world.getMinecraftServer().getAllowNether()) && !this.isPassenger() && this.aj++ >= i) { // CraftBukkit + this.world.getMethodProfiler().enter("portal"); + this.aj = i; + this.portalCooldown = this.aX(); + // CraftBukkit start + if (this instanceof EntityPlayer) { + ((EntityPlayer) this).a(this.world.worldProvider.getDimensionManager().getType() == DimensionManager.NETHER ? DimensionManager.OVERWORLD : DimensionManager.NETHER, PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); + } else { + this.a(this.world.worldProvider.getDimensionManager().getType() == DimensionManager.NETHER ? DimensionManager.OVERWORLD : DimensionManager.NETHER); + } + // CraftBukkit end + this.world.getMethodProfiler().exit(); + } + + this.ai = false; + } else { + if (this.aj > 0) { + this.aj -= 4; + } + + if (this.aj < 0) { + this.aj = 0; + } + } + + this.E(); + } + } + + public int aX() { return 300; } - public Iterable aS() { - return Entity.a; + public Iterable aZ() { + return Entity.c; } public Iterable getArmorItems() { - return Entity.a; + return Entity.c; } - public Iterable aU() { - return Iterables.concat(this.aS(), this.getArmorItems()); + public Iterable bb() { + return Iterables.concat(this.aZ(), this.getArmorItems()); } public void setEquipment(EnumItemSlot enumitemslot, ItemStack itemstack) {} @@ -2296,7 +2256,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public boolean isBurning() { boolean flag = this.world != null && this.world.isClientSide; - return !this.fireProof && (this.fireTicks > 0 || flag && this.getFlag(0)); + return !this.isFireProof() && (this.fireTicks > 0 || flag && this.getFlag(0)); } public boolean isPassenger() { @@ -2304,10 +2264,10 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public boolean isVehicle() { - return !this.bP().isEmpty(); + return !this.getPassengers().isEmpty(); } - public boolean aY() { + public boolean bf() { return true; } @@ -2331,6 +2291,10 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.getFlag(4); } + public boolean bk() { + return this.getPose() == EntityPose.SWIMMING; + } + public void setSwimming(boolean flag) { // CraftBukkit start if (this.isSwimming() != flag && this instanceof EntityLiving) { @@ -2342,7 +2306,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke this.setFlag(4, flag); } - public boolean bc() { + public boolean bm() { return this.glowing || this.world.isClientSide && this.getFlag(6); } @@ -2377,36 +2341,40 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public boolean getFlag(int i) { - return ((Byte) this.datawatcher.get(Entity.ac) & 1 << i) != 0; + return ((Byte) this.datawatcher.get(Entity.W) & 1 << i) != 0; } public void setFlag(int i, boolean flag) { - byte b0 = (Byte) this.datawatcher.get(Entity.ac); + byte b0 = (Byte) this.datawatcher.get(Entity.W); if (flag) { - this.datawatcher.set(Entity.ac, (byte) (b0 | 1 << i)); + this.datawatcher.set(Entity.W, (byte) (b0 | 1 << i)); } else { - this.datawatcher.set(Entity.ac, (byte) (b0 & ~(1 << i))); + this.datawatcher.set(Entity.W, (byte) (b0 & ~(1 << i))); } } - public int getMaxAirTicks() { return bf(); } public int bf() { // Paper - OBF HELPER + public int getMaxAirTicks() { return bp(); } // Paper - OBFHELPER + public int bp() { return 300; } public int getAirTicks() { - return (Integer) this.datawatcher.get(Entity.aD); + return (Integer) this.datawatcher.get(Entity.AIR_TICKS); } public void setAirTicks(int i) { // CraftBukkit start EntityAirChangeEvent event = new EntityAirChangeEvent(this.getBukkitEntity(), i); - event.getEntity().getServer().getPluginManager().callEvent(event); + // Suppress during worldgen + if (this.valid) { + event.getEntity().getServer().getPluginManager().callEvent(event); + } if (event.isCancelled()) { return; } - this.datawatcher.set(Entity.aD, event.getAmount()); + this.datawatcher.set(Entity.AIR_TICKS, event.getAmount()); // CraftBukkit end } @@ -2438,7 +2406,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } } - if (this.fireProof) { + if (this.isFireProof()) { return; } CraftEventFactory.entityDamage = entitylightning; @@ -2450,96 +2418,85 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public void j(boolean flag) { + Vec3D vec3d = this.getMot(); + double d0; + if (flag) { - this.motY = Math.max(-0.9D, this.motY - 0.03D); + d0 = Math.max(-0.9D, vec3d.y - 0.03D); } else { - this.motY = Math.min(1.8D, this.motY + 0.1D); + d0 = Math.min(1.8D, vec3d.y + 0.1D); } + this.setMot(vec3d.x, d0, vec3d.z); } public void k(boolean flag) { + Vec3D vec3d = this.getMot(); + double d0; + if (flag) { - this.motY = Math.max(-0.3D, this.motY - 0.03D); + d0 = Math.max(-0.3D, vec3d.y - 0.03D); } else { - this.motY = Math.min(0.7D, this.motY + 0.06D); + d0 = Math.min(0.7D, vec3d.y + 0.06D); } + this.setMot(vec3d.x, d0, vec3d.z); this.fallDistance = 0.0F; } public void onKill(EntityLiving entityLiving) { this.b(entityLiving); } // Paper - OBFHELPER public void b(EntityLiving entityliving) {} - protected boolean i(double d0, double d1, double d2) { + protected void i(double d0, double d1, double d2) { BlockPosition blockposition = new BlockPosition(d0, d1, d2); - double d3 = d0 - (double) blockposition.getX(); - double d4 = d1 - (double) blockposition.getY(); - double d5 = d2 - (double) blockposition.getZ(); + Vec3D vec3d = new Vec3D(d0 - (double) blockposition.getX(), d1 - (double) blockposition.getY(), d2 - (double) blockposition.getZ()); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + EnumDirection enumdirection = EnumDirection.UP; + double d3 = Double.MAX_VALUE; + EnumDirection[] aenumdirection = new EnumDirection[]{EnumDirection.NORTH, EnumDirection.SOUTH, EnumDirection.WEST, EnumDirection.EAST, EnumDirection.UP}; + int i = aenumdirection.length; - if (this.world.getCubes((Entity) null, this.getBoundingBox())) { - return false; - } else { - EnumDirection enumdirection = EnumDirection.UP; - double d6 = Double.MAX_VALUE; + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection1 = aenumdirection[j]; - if (!this.world.o(blockposition.west()) && d3 < d6) { - d6 = d3; - enumdirection = EnumDirection.WEST; + blockposition_mutableblockposition.g(blockposition).c(enumdirection1); + if (!this.world.getType(blockposition_mutableblockposition).o(this.world, blockposition_mutableblockposition)) { + double d4 = vec3d.a(enumdirection1.k()); + double d5 = enumdirection1.c() == EnumDirection.EnumAxisDirection.POSITIVE ? 1.0D - d4 : d4; + + if (d5 < d3) { + d3 = d5; + enumdirection = enumdirection1; + } } - - if (!this.world.o(blockposition.east()) && 1.0D - d3 < d6) { - d6 = 1.0D - d3; - enumdirection = EnumDirection.EAST; - } - - if (!this.world.o(blockposition.north()) && d5 < d6) { - d6 = d5; - enumdirection = EnumDirection.NORTH; - } - - if (!this.world.o(blockposition.south()) && 1.0D - d5 < d6) { - d6 = 1.0D - d5; - enumdirection = EnumDirection.SOUTH; - } - - if (!this.world.o(blockposition.up()) && 1.0D - d4 < d6) { - d6 = 1.0D - d4; - enumdirection = EnumDirection.UP; - } - - float f = this.random.nextFloat() * 0.2F + 0.1F; - float f1 = (float) enumdirection.c().a(); - - if (enumdirection.k() == EnumDirection.EnumAxis.X) { - this.motX = (double) (f1 * f); - this.motY *= 0.75D; - this.motZ *= 0.75D; - } else if (enumdirection.k() == EnumDirection.EnumAxis.Y) { - this.motX *= 0.75D; - this.motY = (double) (f1 * f); - this.motZ *= 0.75D; - } else if (enumdirection.k() == EnumDirection.EnumAxis.Z) { - this.motX *= 0.75D; - this.motY *= 0.75D; - this.motZ = (double) (f1 * f); - } - - return true; } + + float f = this.random.nextFloat() * 0.2F + 0.1F; + float f1 = (float) enumdirection.c().a(); + Vec3D vec3d1 = this.getMot().a(0.75D); + + if (enumdirection.k() == EnumDirection.EnumAxis.X) { + this.setMot((double) (f1 * f), vec3d1.y, vec3d1.z); + } else if (enumdirection.k() == EnumDirection.EnumAxis.Y) { + this.setMot(vec3d1.x, (double) (f1 * f), vec3d1.z); + } else if (enumdirection.k() == EnumDirection.EnumAxis.Z) { + this.setMot(vec3d1.x, vec3d1.y, (double) (f1 * f)); + } + } - public void bh() { - this.F = true; + public void a(IBlockData iblockdata, Vec3D vec3d) { this.fallDistance = 0.0F; + this.B = vec3d; } private static void c(IChatBaseComponent ichatbasecomponent) { ichatbasecomponent.a((chatmodifier) -> { chatmodifier.setChatClickable((ChatClickable) null); - }).a().forEach(Entity::c); + }).getSiblings().forEach(Entity::c); } + @Override public IChatBaseComponent getDisplayName() { IChatBaseComponent ichatbasecomponent = this.getCustomName(); @@ -2549,15 +2506,10 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke c(ichatbasecomponent1); return ichatbasecomponent1; } else { - return this.g.e(); + return this.f.g(); } } - @Nullable - public Entity[] bi() { - return null; - } - public boolean s(Entity entity) { return this == entity; } @@ -2568,9 +2520,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public void setHeadRotation(float f) {} - public void k(float f) {} + public void l(float f) {} - public boolean bk() { + public boolean bs() { return true; } @@ -2586,7 +2538,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.invulnerable && damagesource != DamageSource.OUT_OF_WORLD && !damagesource.v(); } - public boolean bl() { + public boolean isInvulnerable() { return this.invulnerable; } @@ -2604,137 +2556,108 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke nbttagcompound.remove("Dimension"); this.f(nbttagcompound); this.portalCooldown = entity.portalCooldown; - this.aq = entity.aq; - this.ar = entity.ar; - this.as = entity.as; + this.al = entity.al; + this.am = entity.am; + this.an = entity.an; } @Nullable public Entity a(DimensionManager dimensionmanager) { - if (!this.world.isClientSide && !this.dead) { - //this.world.methodProfiler.enter("changeDimension"); // Akarin - remove caller - MinecraftServer minecraftserver = this.bK(); - // CraftBukkit start - Move logic into new function "teleportTo(Location,boolean)" - // DimensionManager dimensionmanager1 = this.dimension; - // WorldServer worldserver = minecraftserver.getWorldServer(dimensionmanager1); - // WorldServer worldserver1 = minecraftserver.getWorldServer(dimensionmanager); - WorldServer exitWorld = null; - if (this.dimension.getDimensionID() < CraftWorld.CUSTOM_DIMENSION_OFFSET) { // Plugins must specify exit from custom Bukkit worlds - exitWorld = minecraftserver.getWorldServer(dimensionmanager); - } - - BlockPosition blockposition = null; // PAIL: CHECK - Location enter = this.getBukkitEntity().getLocation(); - Location exit; - if (exitWorld != null) { - if (blockposition != null) { - exit = new Location(exitWorld.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); - } else { - exit = minecraftserver.getPlayerList().calculateTarget(enter, exitWorld); - } - } - else { - exit = null; - } - boolean useTravelAgent = exitWorld != null && !(this.dimension == DimensionManager.THE_END && exitWorld.dimension == DimensionManager.THE_END); // don't use agent for custom worlds or return from THE_END - - TravelAgent agent = exit != null ? (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().getTravelAgent() : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins - boolean oldCanCreate = agent.getCanCreatePortal(); - agent.setCanCreatePortal(false); // General entities cannot create portals - - EntityPortalEvent event = new EntityPortalEvent(this.getBukkitEntity(), enter, exit, agent); - event.useTravelAgent(useTravelAgent); - event.getEntity().getServer().getPluginManager().callEvent(event); - if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !this.isAlive()) { - agent.setCanCreatePortal(oldCanCreate); - return null; - } - exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo(); - agent.setCanCreatePortal(oldCanCreate); - - // Need to make sure the profiler state is reset afterwards (but we still want to time the call) - Entity entity = this.teleportTo(exit, true); - //this.world.methodProfiler.exit(); // Akarin - remove caller - return entity; - } else { - return null; - } + // CraftBukkit start + return teleportTo(dimensionmanager, null); } - public Entity teleportTo(Location exit, boolean portal) { - if (!this.dead) { // Paper - WorldServer worldserver = ((CraftWorld) getBukkitEntity().getLocation().getWorld()).getHandle(); - WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); - DimensionManager dimensionmanager = worldserver1.dimension; - // CraftBukkit end - - this.dimension = dimensionmanager; - /* CraftBukkit start - TODO: Check if we need this - if (dimensionmanager1 == DimensionManager.THE_END && dimensionmanager == DimensionManager.THE_END) { - worldserver1 = minecraftserver.getWorldServer(DimensionManager.OVERWORLD); - this.dimension = DimensionManager.OVERWORLD; + @Nullable + public Entity teleportTo(DimensionManager dimensionmanager, BlockPosition location) { + // CraftBukkit end + if (!this.world.isClientSide && !this.dead) { + this.world.getMethodProfiler().enter("changeDimension"); + MinecraftServer minecraftserver = this.getMinecraftServer(); + DimensionManager dimensionmanager1 = this.dimension; + WorldServer worldserver = minecraftserver.getWorldServer(dimensionmanager1); + WorldServer worldserver1 = minecraftserver.getWorldServer(dimensionmanager); + // CraftBukkit start + if (worldserver1 == null){ + return null; } - // CraftBukkit end */ - this.world.removeEntity(this); // Paper - Fully remove entity, can't have dupes in the UUID map - this.dead = false; - //this.world.methodProfiler.enter("reposition"); // Akarin - remove caller - /* CraftBukkit start - Handled in calculateTarget - BlockPosition blockposition; + // this.dimension = dimensionmanager; + // this.decouple(); + // CraftBukkit end + this.world.getMethodProfiler().enter("reposition"); + Vec3D vec3d = this.getMot(); + float f = 0.0F; + BlockPosition blockposition = location; // CraftBukkit - if (dimensionmanager == DimensionManager.THE_END) { + if (blockposition == null) { // CraftBukkit + if (dimensionmanager1.getType() == DimensionManager.THE_END && dimensionmanager == DimensionManager.OVERWORLD) { // CraftBukkit + blockposition = worldserver1.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver1.getSpawn()); + } else if (dimensionmanager.getType() == DimensionManager.THE_END) { // CraftBukkit blockposition = worldserver1.getDimensionSpawn(); } else { double d0 = this.locX; double d1 = this.locZ; double d2 = 8.0D; - if (dimensionmanager == DimensionManager.NETHER) { - d0 = MathHelper.a(d0 / 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); - d1 = MathHelper.a(d1 / 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); - } else if (dimensionmanager == DimensionManager.OVERWORLD) { - d0 = MathHelper.a(d0 * 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); - d1 = MathHelper.a(d1 * 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); + if (dimensionmanager1.getType() == DimensionManager.OVERWORLD && dimensionmanager.getType() == DimensionManager.NETHER) { // CraftBukkit + d0 /= 8.0D; + d1 /= 8.0D; + } else if (dimensionmanager1.getType() == DimensionManager.NETHER && dimensionmanager.getType() == DimensionManager.OVERWORLD) { // CraftBukkit + d0 *= 8.0D; + d1 *= 8.0D; } - d0 = (double) MathHelper.clamp((int) d0, -29999872, 29999872); - d1 = (double) MathHelper.clamp((int) d1, -29999872, 29999872); - float f = this.yaw; + double d3 = Math.min(-2.9999872E7D, worldserver1.getWorldBorder().c() + 16.0D); + double d4 = Math.min(-2.9999872E7D, worldserver1.getWorldBorder().d() + 16.0D); + double d5 = Math.min(2.9999872E7D, worldserver1.getWorldBorder().e() - 16.0D); + double d6 = Math.min(2.9999872E7D, worldserver1.getWorldBorder().f() - 16.0D); - this.setPositionRotation(d0, this.locY, d1, 90.0F, 0.0F); - PortalTravelAgent portaltravelagent = worldserver1.getTravelAgent(); + d0 = MathHelper.a(d0, d3, d5); + d1 = MathHelper.a(d1, d4, d6); + Vec3D vec3d1 = this.getPortalOffset(); - portaltravelagent.b(this, f); - blockposition = new BlockPosition(this); + blockposition = new BlockPosition(d0, this.locY, d1); + ShapeDetector.Shape shapedetector_shape = worldserver1.getTravelAgent().a(blockposition, vec3d, this.getPortalDirection(), vec3d1.x, vec3d1.y, this instanceof EntityHuman); + + if (shapedetector_shape == null) { + return null; + } + + blockposition = new BlockPosition(shapedetector_shape.position); + vec3d = shapedetector_shape.velocity; + f = (float) shapedetector_shape.yaw; + } + } // CraftBukkit + + // CraftBukkit start + // SPIGOT-5136 - don't fire event for CraftEntity.teleport + if (location == null) { + Location enter = this.getBukkitEntity().getLocation(); + Location exit = new Location(worldserver1.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + EntityPortalEvent event = new EntityPortalEvent(this.getBukkitEntity(), enter, exit); + event.getEntity().getServer().getPluginManager().callEvent(event); + if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !this.isAlive()) { + return null; + } + + exit = event.getTo(); + worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); + blockposition = new BlockPosition(exit.getX(), exit.getY(), exit.getZ()); } - // CraftBukkit end */ - // CraftBukkit start - Ensure chunks are loaded in case TravelAgent is not used which would initially cause chunks to load during find/create - // minecraftserver.getPlayerList().changeWorld(this, j, worldserver, worldserver1); - worldserver1.getMinecraftServer().getPlayerList().repositionEntity(this, exit, portal); - // worldserver.entityJoinedWorld(this, false); // Handled in repositionEntity + this.dimension = dimensionmanager; + this.decouple(); // CraftBukkit end - //this.world.methodProfiler.exitEnter("reloading"); // Akarin - remove caller - Entity entity = this.P().a((World) worldserver1); + + this.world.getMethodProfiler().exitEnter("reloading"); + Entity entity = this.getEntityType().a((World) worldserver1); if (entity != null) { entity.v(this); - /* CraftBukkit start - We need to do this... - if (dimensionmanager1 == DimensionManager.THE_END && dimensionmanager == DimensionManager.THE_END) { - BlockPosition blockposition1 = worldserver1.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver1.getSpawn()); - - entity.setPositionRotation(blockposition1, entity.yaw, entity.pitch); - } else { - entity.setPositionRotation(blockposition, entity.yaw, entity.pitch); - } - // CraftBukkit end */ - - boolean flag = entity.attachedToPlayer; - - entity.attachedToPlayer = true; - worldserver1.addEntity(entity); - entity.attachedToPlayer = flag; - worldserver1.entityJoinedWorld(entity, false); + entity.setPositionRotation(blockposition, entity.yaw + f, entity.pitch); + entity.setMot(vec3d); + worldserver1.addEntityTeleport(entity); // CraftBukkit start - Forward the CraftEntity to the new entity this.getBukkitEntity().setHandle(entity); entity.bukkitEntity = this.getBukkitEntity(); @@ -2746,17 +2669,17 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } this.dead = true; - //this.world.methodProfiler.exit(); // Akarin - remove caller - worldserver.p(); - worldserver1.p(); - // this.world.methodProfiler.exit(); // CraftBukkit: Moved up to keep balanced + this.world.getMethodProfiler().exit(); + worldserver.resetEmptyTime(); + worldserver1.resetEmptyTime(); + this.world.getMethodProfiler().exit(); return entity; } else { return null; } } - public boolean bm() { + public boolean canPortal() { return true; } @@ -2768,16 +2691,16 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return true; } - public int bn() { + public int bv() { return 3; } public Vec3D getPortalOffset() { - return this.ar; + return this.am; } public EnumDirection getPortalDirection() { - return this.as; + return this.an; } public boolean isIgnoreBlockTrigger() { @@ -2786,7 +2709,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public void appendEntityCrashDetails(CrashReportSystemDetails crashreportsystemdetails) { crashreportsystemdetails.a("Entity Type", () -> { - return EntityTypes.getName(this.P()) + " (" + this.getClass().getCanonicalName() + ")"; + return EntityTypes.getName(this.getEntityType()) + " (" + this.getClass().getCanonicalName() + ")"; }); crashreportsystemdetails.a("Entity ID", (Object) this.id); crashreportsystemdetails.a("Entity Name", () -> { @@ -2794,9 +2717,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke }); crashreportsystemdetails.a("Entity's Exact location", (Object) String.format(Locale.ROOT, "%.2f, %.2f, %.2f", this.locX, this.locY, this.locZ)); crashreportsystemdetails.a("Entity's Block location", (Object) CrashReportSystemDetails.a(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ))); - crashreportsystemdetails.a("Entity's Momentum", (Object) String.format(Locale.ROOT, "%.2f, %.2f, %.2f", this.motX, this.motY, this.motZ)); + Vec3D vec3d = this.getMot(); + + crashreportsystemdetails.a("Entity's Momentum", (Object) String.format(Locale.ROOT, "%.2f, %.2f, %.2f", vec3d.x, vec3d.y, vec3d.z)); crashreportsystemdetails.a("Entity's Passengers", () -> { - return this.bP().toString(); + return this.getPassengers().toString(); }); crashreportsystemdetails.a("Entity's Vehicle", () -> { return this.getVehicle().toString(); @@ -2806,22 +2731,23 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public void setUUID(UUID uuid) { a(uuid); } // Paper - OBFHELPER public void a(UUID uuid) { this.uniqueID = uuid; - this.au = this.uniqueID.toString(); + this.ap = this.uniqueID.toString(); } public UUID getUniqueID() { return this.uniqueID; } - public String bu() { - return this.au; + public String getUniqueIDString() { + return this.ap; } public String getName() { - return this.au; + return this.ap; } - public boolean bw() { + public boolean bE() { + // Paper start return this.pushedByWater(); } @@ -2830,42 +2756,84 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return true; } + @Override public IChatBaseComponent getScoreboardDisplayName() { return ScoreboardTeam.a(this.getScoreboardTeam(), this.getDisplayName()).a((chatmodifier) -> { - chatmodifier.setChatHoverable(this.bC()).setInsertion(this.bu()); + chatmodifier.setChatHoverable(this.bK()).setInsertion(this.getUniqueIDString()); }); } public void setCustomName(@Nullable IChatBaseComponent ichatbasecomponent) { - this.datawatcher.set(Entity.aE, Optional.ofNullable(ichatbasecomponent)); + this.datawatcher.set(Entity.az, Optional.ofNullable(ichatbasecomponent)); } @Nullable + @Override public IChatBaseComponent getCustomName() { - return (IChatBaseComponent) ((Optional) this.datawatcher.get(Entity.aE)).orElse((Object) null); + return (IChatBaseComponent) ((Optional) this.datawatcher.get(Entity.az)).orElse((Object) null); } + @Override public boolean hasCustomName() { - return ((Optional) this.datawatcher.get(Entity.aE)).isPresent(); + return ((Optional) this.datawatcher.get(Entity.az)).isPresent(); } public void setCustomNameVisible(boolean flag) { - this.datawatcher.set(Entity.aF, flag); + this.datawatcher.set(Entity.aA, flag); } public boolean getCustomNameVisible() { - return (Boolean) this.datawatcher.get(Entity.aF); + return (Boolean) this.datawatcher.get(Entity.aA); + } + + public final void enderTeleportAndLoad(double d0, double d1, double d2) { + if (this.world instanceof WorldServer) { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(d0, d1, d2)); + + ((WorldServer) this.world).getChunkProvider().addTicket(TicketType.POST_TELEPORT, chunkcoordintpair, 0, this.getId()); + this.world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z); + this.enderTeleportTo(d0, d1, d2); + } } public void enderTeleportTo(double d0, double d1, double d2) { - this.enderTeleport = true; // Akarin - this.aK = true; - this.setPositionRotation(d0, d1, d2, this.yaw, this.pitch); - this.world.entityJoinedWorld(this, false); - this.enderTeleport = false; // Akarin + if (this.world instanceof WorldServer) { + this.aF = true; + this.setPositionRotation(d0, d1, d2, this.yaw, this.pitch); + ((WorldServer) this.world).chunkCheck(this); + } } - public void a(DataWatcherObject datawatcherobject) {} + public void a(DataWatcherObject datawatcherobject) { + if (Entity.POSE.equals(datawatcherobject)) { + this.updateSize(); + } + + } + + public void updateSize() { + EntitySize entitysize = this.size; + EntityPose entitypose = this.getPose(); + EntitySize entitysize1 = this.a(entitypose); + + this.size = entitysize1; + this.headHeight = this.getHeadHeight(entitypose, entitysize1); + if (entitysize1.width < entitysize.width) { + double d0 = (double) entitysize1.width / 2.0D; + + this.a(new AxisAlignedBB(this.locX - d0, this.locY, this.locZ - d0, this.locX + d0, this.locY + (double) entitysize1.height, this.locZ + d0)); + } else { + AxisAlignedBB axisalignedbb = this.getBoundingBox(); + + this.a(new AxisAlignedBB(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ, axisalignedbb.minX + (double) entitysize1.width, axisalignedbb.minY + (double) entitysize1.height, axisalignedbb.minZ + (double) entitysize1.width)); + if (entitysize1.width > entitysize.width && !this.justCreated && !this.world.isClientSide) { + float f = entitysize.width - entitysize1.width; + + this.move(EnumMoveType.SELF, new Vec3D((double) f, 0.0D, (double) f)); + } + + } + } public EnumDirection getDirection() { return EnumDirection.fromAngle((double) this.yaw); @@ -2875,11 +2843,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.getDirection(); } - protected ChatHoverable bC() { + protected ChatHoverable bK() { NBTTagCompound nbttagcompound = new NBTTagCompound(); - MinecraftKey minecraftkey = EntityTypes.getName(this.P()); + MinecraftKey minecraftkey = EntityTypes.getName(this.getEntityType()); - nbttagcompound.setString("id", this.bu()); + nbttagcompound.setString("id", this.getUniqueIDString()); if (minecraftkey != null) { nbttagcompound.setString("type", minecraftkey.toString()); } @@ -2896,6 +2864,15 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.boundingBox; } + protected AxisAlignedBB d(EntityPose entitypose) { + EntitySize entitysize = this.a(entitypose); + float f = entitysize.width / 2.0F; + Vec3D vec3d = new Vec3D(this.locX - (double) f, this.locY, this.locZ - (double) f); + Vec3D vec3d1 = new Vec3D(this.locX + (double) f, this.locY + (double) entitysize.height, this.locZ + (double) f); + + return new AxisAlignedBB(vec3d, vec3d1); + } + public void a(AxisAlignedBB axisalignedbb) { // CraftBukkit start - block invalid bounding boxes double minX = axisalignedbb.minX, @@ -2919,29 +2896,26 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke // CraftBukkit end } - public float getHeadHeight() { - return this.length * 0.85F; + protected float getHeadHeight(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height * 0.85F; } - public boolean bG() { - return this.az; + public final float getHeadHeight() { + return this.headHeight; } - public void n(boolean flag) { - this.az = flag; - } - - public boolean c(int i, ItemStack itemstack) { + public boolean a_(int i, ItemStack itemstack) { return false; } + @Override public void sendMessage(IChatBaseComponent ichatbasecomponent) {} public BlockPosition getChunkCoordinates() { return new BlockPosition(this); } - public Vec3D bI() { + public Vec3D bP() { return new Vec3D(this.locX, this.locY, this.locZ); } @@ -2950,7 +2924,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } @Nullable - public MinecraftServer bK() { + public MinecraftServer getMinecraftServer() { return this.world.getMinecraftServer(); } @@ -2958,7 +2932,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return EnumInteractionResult.PASS; } - public boolean bL() { + public boolean bS() { return false; } @@ -2978,14 +2952,14 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke float f = MathHelper.g(this.yaw); switch (enumblockrotation) { - case CLOCKWISE_180: - return f + 180.0F; - case COUNTERCLOCKWISE_90: - return f + 270.0F; - case CLOCKWISE_90: - return f + 90.0F; - default: - return f; + case CLOCKWISE_180: + return f + 180.0F; + case COUNTERCLOCKWISE_90: + return f + 270.0F; + case CLOCKWISE_90: + return f + 90.0F; + default: + return f; } } @@ -2993,37 +2967,37 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke float f = MathHelper.g(this.yaw); switch (enumblockmirror) { - case LEFT_RIGHT: - return -f; - case FRONT_BACK: - return 180.0F - f; - default: - return f; + case LEFT_RIGHT: + return -f; + case FRONT_BACK: + return 180.0F - f; + default: + return f; } } - public boolean bM() { + public boolean bT() { return false; } - public boolean bN() { - boolean flag = this.aK; + public boolean bU() { + boolean flag = this.aF; - this.aK = false; + this.aF = false; return flag; } @Nullable - public Entity bO() { + public Entity getRidingPassenger() { return null; } - public List bP() { + public List getPassengers() { return (List) (this.passengers.isEmpty() ? Collections.emptyList() : Lists.newArrayList(this.passengers)); } public boolean w(Entity entity) { - Iterator iterator = this.bP().iterator(); + Iterator iterator = this.getPassengers().iterator(); Entity entity1; @@ -3039,7 +3013,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public boolean a(Class oclass) { - Iterator iterator = this.bP().iterator(); + Iterator iterator = this.getPassengers().iterator(); Entity entity; @@ -3056,7 +3030,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public Collection getAllPassengers() { Set set = Sets.newHashSet(); - Iterator iterator = this.bP().iterator(); + Iterator iterator = this.getPassengers().iterator(); while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); @@ -3068,7 +3042,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return set; } - public boolean bR() { + public boolean hasSinglePlayerPassenger() { Set set = Sets.newHashSet(); this.a(true, set); @@ -3078,7 +3052,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke private void a(boolean flag, Set set) { Entity entity; - for (Iterator iterator = this.bP().iterator(); iterator.hasNext(); entity.a(flag, set)) { + for (Iterator iterator = this.getPassengers().iterator(); iterator.hasNext(); entity.a(flag, set)) { entity = (Entity) iterator.next(); if (!flag || EntityPlayer.class.isAssignableFrom(entity.getClass())) { set.add(entity); @@ -3102,7 +3076,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public boolean y(Entity entity) { - Iterator iterator = this.bP().iterator(); + Iterator iterator = this.getPassengers().iterator(); Entity entity1; @@ -3120,10 +3094,10 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return true; } - public boolean bT() { - Entity entity = this.bO(); + public boolean ca() { + Entity entity = this.getRidingPassenger(); - return entity instanceof EntityHuman ? ((EntityHuman) entity).dn() : !this.world.isClientSide; + return entity instanceof EntityHuman ? ((EntityHuman) entity).dG() : !this.world.isClientSide; } @Nullable @@ -3135,8 +3109,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return EnumPistonReaction.NORMAL; } - public SoundCategory getDeathSoundCategory() { return bV();} // Paper - OBFHELPER - public SoundCategory bV() { + public SoundCategory getSoundCategory() { return SoundCategory.NEUTRAL; } @@ -3145,26 +3118,29 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } public CommandListenerWrapper getCommandListener() { - return new CommandListenerWrapper(this, new Vec3D(this.locX, this.locY, this.locZ), this.aO(), this.world instanceof WorldServer ? (WorldServer) this.world : null, this.y(), this.getDisplayName().getString(), this.getScoreboardDisplayName(), this.world.getMinecraftServer(), this); + return new CommandListenerWrapper(this, new Vec3D(this.locX, this.locY, this.locZ), this.aU(), this.world instanceof WorldServer ? (WorldServer) this.world : null, this.y(), this.getDisplayName().getString(), this.getScoreboardDisplayName(), this.world.getMinecraftServer(), this); } protected int y() { return 0; } - public boolean j(int i) { + public boolean k(int i) { return this.y() >= i; } - public boolean a() { - return this.world.getGameRules().getBoolean("sendCommandFeedback"); + @Override + public boolean shouldSendSuccess() { + return this.world.getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK); } - public boolean b() { + @Override + public boolean shouldSendFailure() { return true; } - public boolean B_() { + @Override + public boolean shouldBroadcastCommands() { return true; } @@ -3175,8 +3151,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke double d2 = vec3d.z - vec3d1.z; double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2); - this.pitch = MathHelper.g((float) (-(MathHelper.c(d1, d3) * 57.2957763671875D))); - this.yaw = MathHelper.g((float) (MathHelper.c(d2, d0) * 57.2957763671875D) - 90.0F); + this.pitch = MathHelper.g((float) (-(MathHelper.d(d1, d3) * 57.2957763671875D))); + this.yaw = MathHelper.g((float) (MathHelper.d(d2, d0) * 57.2957763671875D) - 90.0F); this.setHeadRotation(this.yaw); this.lastPitch = this.pitch; this.lastYaw = this.yaw; @@ -3191,11 +3167,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke int i1 = MathHelper.floor(axisalignedbb.minZ); int j1 = MathHelper.f(axisalignedbb.maxZ); - if (!this.world.isAreaLoaded(i, k, i1, j, l, j1, true)) { + if (!this.world.isAreaLoaded(i, k, i1, j, l, j1)) { return false; } else { double d0 = 0.0D; - boolean flag = this.bw(); + boolean flag = this.bE(); boolean flag1 = false; Vec3D vec3d = Vec3D.a; int k1 = 0; @@ -3206,17 +3182,17 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke for (int l1 = i; l1 < j; ++l1) { for (int i2 = k; i2 < l; ++i2) { for (int j2 = i1; j2 < j1; ++j2) { - blockposition_pooledblockposition.c(l1, i2, j2); + blockposition_pooledblockposition.d(l1, i2, j2); Fluid fluid = this.world.getFluid(blockposition_pooledblockposition); if (fluid.a(tag)) { - double d1 = (double) ((float) i2 + fluid.getHeight()); + double d1 = (double) ((float) i2 + fluid.getHeight(this.world, blockposition_pooledblockposition)); if (d1 >= axisalignedbb.minY) { flag1 = true; d0 = Math.max(d1 - axisalignedbb.minY, d0); if (flag) { - Vec3D vec3d1 = fluid.a((IWorldReader) this.world, (BlockPosition) blockposition_pooledblockposition); + Vec3D vec3d1 = fluid.c(this.world, blockposition_pooledblockposition); if (d0 < 0.4D) { vec3d1 = vec3d1.a(d0); @@ -3248,28 +3224,54 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } - if (vec3d.b() > 0.0D) { + if (vec3d.f() > 0.0D) { if (k1 > 0) { vec3d = vec3d.a(1.0D / (double) k1); } if (!(this instanceof EntityHuman)) { - vec3d = vec3d.a(); + vec3d = vec3d.d(); } - double d2 = 0.014D; - - this.motX += vec3d.x * 0.014D; - this.motY += vec3d.y * 0.014D; - this.motZ += vec3d.z * 0.014D; + this.setMot(this.getMot().e(vec3d.a(0.014D))); } - this.W = d0; + this.Q = d0; return flag1; } } - public double bY() { - return this.W; + public double cf() { + return this.Q; + } + + public final float getWidth() { + return this.size.width; + } + + public final float getHeight() { + return this.size.height; + } + + public abstract Packet N(); + + public EntitySize a(EntityPose entitypose) { + return this.f.k(); + } + + public Vec3D getPositionVector() { + return new Vec3D(this.locX, this.locY, this.locZ); + } + + public Vec3D getMot() { + return this.mot; + } + + public void setMot(Vec3D vec3d) { + this.mot = vec3d; + } + + public void setMot(double d0, double d1, double d2) { + this.setMot(new Vec3D(d0, d1, d2)); } } diff --git a/src/main/java/net/minecraft/server/EntityAgeable.java b/src/main/java/net/minecraft/server/EntityAgeable.java index 87db1bc2d..e87754ef3 100644 --- a/src/main/java/net/minecraft/server/EntityAgeable.java +++ b/src/main/java/net/minecraft/server/EntityAgeable.java @@ -4,15 +4,13 @@ import javax.annotation.Nullable; public abstract class EntityAgeable extends EntityCreature { - private static final DataWatcherObject bC = DataWatcher.a(EntityAgeable.class, DataWatcherRegistry.i); - protected int a; + private static final DataWatcherObject bz = DataWatcher.a(EntityAgeable.class, DataWatcherRegistry.i); protected int b; protected int c; - private float bD = -1.0F; - private float bE; + protected int d; public boolean ageLocked; // CraftBukkit - protected EntityAgeable(EntityTypes entitytypes, World world) { + protected EntityAgeable(EntityTypes entitytypes, World world) { super(entitytypes, world); } @@ -23,7 +21,7 @@ public abstract class EntityAgeable extends EntityCreature { super.inactiveTick(); if ( this.world.isClientSide || this.ageLocked ) { // CraftBukkit - this.a( this.isBaby() ); + this.updateSize(); } else { int i = this.getAge(); @@ -44,11 +42,14 @@ public abstract class EntityAgeable extends EntityCreature { @Nullable public abstract EntityAgeable createChild(EntityAgeable entityageable); + protected void a(EntityHuman entityhuman, EntityAgeable entityageable) {} + + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); Item item = itemstack.getItem(); - if (item instanceof ItemMonsterEgg && ((ItemMonsterEgg) item).a(itemstack.getTag(), this.P())) { + if (item instanceof ItemMonsterEgg && ((ItemMonsterEgg) item).a(itemstack.getTag(), this.getEntityType())) { if (!this.world.isClientSide) { EntityAgeable entityageable = this.createChild(this); @@ -60,6 +61,7 @@ public abstract class EntityAgeable extends EntityCreature { entityageable.setCustomName(itemstack.getName()); } + this.a(entityhuman, entityageable); if (!entityhuman.abilities.canInstantlyBuild) { itemstack.subtract(1); } @@ -72,13 +74,14 @@ public abstract class EntityAgeable extends EntityCreature { } } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityAgeable.bC, false); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityAgeable.bz, false); } public int getAge() { - return this.world.isClientSide ? ((Boolean) this.datawatcher.get(EntityAgeable.bC) ? -1 : 1) : this.a; + return this.world.isClientSide ? ((Boolean) this.datawatcher.get(EntityAgeable.bz) ? -1 : 1) : this.b; } public void setAge(int i, boolean flag) { @@ -89,23 +92,20 @@ public abstract class EntityAgeable extends EntityCreature { j += i * 20; if (j > 0) { j = 0; - if (k < 0) { - this.l(); - } } int l = j - k; this.setAgeRaw(j); if (flag) { - this.b += l; - if (this.c == 0) { - this.c = 40; + this.c += l; + if (this.d == 0) { + this.d = 40; } } if (this.getAge() == 0) { - this.setAgeRaw(this.b); + this.setAgeRaw(this.c); } } @@ -115,56 +115,58 @@ public abstract class EntityAgeable extends EntityCreature { } public void setAgeRaw(int i) { - this.datawatcher.set(EntityAgeable.bC, i < 0); - this.a = i; - this.a(this.isBaby()); + int j = this.b; + + this.b = i; + if (j < 0 && i >= 0 || j >= 0 && i < 0) { + this.datawatcher.set(EntityAgeable.bz, i < 0); + this.l(); + } + } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setInt("Age", this.getAge()); - nbttagcompound.setInt("ForcedAge", this.b); + nbttagcompound.setInt("ForcedAge", this.c); nbttagcompound.setBoolean("AgeLocked", this.ageLocked); // CraftBukkit } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setAgeRaw(nbttagcompound.getInt("Age")); - this.b = nbttagcompound.getInt("ForcedAge"); + this.c = nbttagcompound.getInt("ForcedAge"); this.ageLocked = nbttagcompound.getBoolean("AgeLocked"); // CraftBukkit } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntityAgeable.bC.equals(datawatcherobject)) { - this.a(this.isBaby()); + if (EntityAgeable.bz.equals(datawatcherobject)) { + this.updateSize(); } super.a(datawatcherobject); } + @Override public void movementTick() { super.movementTick(); if (this.world.isClientSide || ageLocked) { // CraftBukkit - if (this.c > 0) { - // Akarin start - this handle by client - /* - if (this.c % 4 == 0) { - this.world.addParticle(Particles.z, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, 0.0D, 0.0D, 0.0D); + if (this.d > 0) { + if (this.d % 4 == 0) { + this.world.addParticle(Particles.HAPPY_VILLAGER, this.locX + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), this.locY + 0.5D + (double) (this.random.nextFloat() * this.getHeight()), this.locZ + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), 0.0D, 0.0D, 0.0D); } - */ - // Akarin end - --this.c; + --this.d; } - } else { + } else if (this.isAlive()) { int i = this.getAge(); if (i < 0) { ++i; this.setAgeRaw(i); - if (i == 0) { - this.l(); - } } else if (i > 0) { --i; this.setAgeRaw(i); @@ -175,21 +177,8 @@ public abstract class EntityAgeable extends EntityCreature { protected void l() {} + @Override public boolean isBaby() { return this.getAge() < 0; } - - public void a(boolean flag) { - this.a(flag ? 0.5F : 1.0F); - } - - public final void setSize(float f, float f1) { - this.bD = f; - this.bE = f1; - this.a(1.0F); - } - - protected final void a(float f) { - super.setSize(this.bD * f, this.bE * f); - } } diff --git a/src/main/java/net/minecraft/server/EntityAnimal.java b/src/main/java/net/minecraft/server/EntityAnimal.java index 3298a7e03..3e627ea08 100644 --- a/src/main/java/net/minecraft/server/EntityAnimal.java +++ b/src/main/java/net/minecraft/server/EntityAnimal.java @@ -1,47 +1,44 @@ package net.minecraft.server; +import java.util.Random; import java.util.UUID; import javax.annotation.Nullable; -public abstract class EntityAnimal extends EntityAgeable implements IAnimal { +public abstract class EntityAnimal extends EntityAgeable { - protected Block bF; - public int bC; // CraftBukkit - private -> public + public int loveTicks; public UUID breedCause; public ItemStack breedItem; // CraftBukkit - Add breedItem variable - protected EntityAnimal(EntityTypes entitytypes, World world) { + protected EntityAnimal(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.bF = Blocks.GRASS_BLOCK; } + @Override protected void mobTick() { if (this.getAge() != 0) { - this.bC = 0; + this.loveTicks = 0; } super.mobTick(); } + @Override public void movementTick() { super.movementTick(); if (this.getAge() != 0) { - this.bC = 0; + this.loveTicks = 0; } - if (this.bC > 0) { - --this.bC; - // Akarin start - this handle by client - /* - if (this.bC % 10 == 0) { + if (this.loveTicks > 0) { + --this.loveTicks; + if (this.loveTicks % 10 == 0) { double d0 = this.random.nextGaussian() * 0.02D; double d1 = this.random.nextGaussian() * 0.02D; double d2 = this.random.nextGaussian() * 0.02D; - this.world.addParticle(Particles.A, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2); + this.world.addParticle(Particles.HEART, this.locX + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), this.locY + 0.5D + (double) (this.random.nextFloat() * this.getHeight()), this.locZ + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), d0, d1, d2); } - */ - // Akarin end } } @@ -49,69 +46,73 @@ public abstract class EntityAnimal extends EntityAgeable implements IAnimal { /* CraftBukkit start // Function disabled as it has no special function anymore after // setSitting is disabled. + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; } else { - this.bC = 0; + this.loveTicks = 0; return super.damageEntity(damagesource, f); } } // CraftBukkit end */ + @Override public float a(BlockPosition blockposition, IWorldReader iworldreader) { - return iworldreader.getType(blockposition.down()).getBlock() == this.bF ? 10.0F : iworldreader.A(blockposition) - 0.5F; + return iworldreader.getType(blockposition.down()).getBlock() == Blocks.GRASS_BLOCK ? 10.0F : iworldreader.v(blockposition) - 0.5F; } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setInt("InLove", this.bC); + nbttagcompound.setInt("InLove", this.loveTicks); if (this.breedCause != null) { nbttagcompound.a("LoveCause", this.breedCause); } } - public double aI() { + @Override + public double aO() { return 0.14D; } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.bC = nbttagcompound.getInt("InLove"); + this.loveTicks = nbttagcompound.getInt("InLove"); this.breedCause = nbttagcompound.b("LoveCause") ? nbttagcompound.a("LoveCause") : null; } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - int i = MathHelper.floor(this.locX); - int j = MathHelper.floor(this.getBoundingBox().minY); - int k = MathHelper.floor(this.locZ); - BlockPosition blockposition = new BlockPosition(i, j, k); - - return generatoraccess.getType(blockposition.down()).getBlock() == this.bF && generatoraccess.getLightLevel(blockposition, 0) > 8 && super.a(generatoraccess, flag); + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return generatoraccess.getType(blockposition.down()).getBlock() == Blocks.GRASS_BLOCK && generatoraccess.getLightLevel(blockposition, 0) > 8; } - public int z() { + @Override + public int A() { return 120; } - public boolean isTypeNotPersistent() { + @Override + public boolean isTypeNotPersistent(double d0) { return false; } + @Override protected int getExpValue(EntityHuman entityhuman) { return 1 + this.world.random.nextInt(3); } - public boolean f(ItemStack itemstack) { + public boolean i(ItemStack itemstack) { return itemstack.getItem() == Items.WHEAT; } + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); - if (this.f(itemstack)) { - if (this.getAge() == 0 && this.dD()) { + if (this.i(itemstack)) { + if (this.getAge() == 0 && this.ea()) { this.a(entityhuman, itemstack); this.f(entityhuman); return true; @@ -134,12 +135,12 @@ public abstract class EntityAnimal extends EntityAgeable implements IAnimal { } - public boolean dD() { - return this.bC <= 0; + public boolean ea() { + return this.loveTicks <= 0; } public void f(@Nullable EntityHuman entityhuman) { - this.bC = 600; + this.loveTicks = 600; if (entityhuman != null) { this.breedCause = entityhuman.getUniqueID(); } @@ -148,8 +149,8 @@ public abstract class EntityAnimal extends EntityAgeable implements IAnimal { this.world.broadcastEntityEffect(this, (byte) 18); } - public void d(int i) { - this.bC = i; + public void setLoveTicks(int i) { + this.loveTicks = i; } @Nullable @@ -164,11 +165,11 @@ public abstract class EntityAnimal extends EntityAgeable implements IAnimal { } public boolean isInLove() { - return this.bC > 0; + return this.loveTicks > 0; } public void resetLove() { - this.bC = 0; + this.loveTicks = 0; } public boolean mate(EntityAnimal entityanimal) { diff --git a/src/main/java/net/minecraft/server/EntityAreaEffectCloud.java b/src/main/java/net/minecraft/server/EntityAreaEffectCloud.java index b2814c0e7..fe527aba5 100644 --- a/src/main/java/net/minecraft/server/EntityAreaEffectCloud.java +++ b/src/main/java/net/minecraft/server/EntityAreaEffectCloud.java @@ -20,87 +20,91 @@ import org.bukkit.entity.LivingEntity; public class EntityAreaEffectCloud extends Entity { - private static final Logger a = LogManager.getLogger(); - private static final DataWatcherObject b = DataWatcher.a(EntityAreaEffectCloud.class, DataWatcherRegistry.c); - private static final DataWatcherObject c = DataWatcher.a(EntityAreaEffectCloud.class, DataWatcherRegistry.b); - private static final DataWatcherObject d = DataWatcher.a(EntityAreaEffectCloud.class, DataWatcherRegistry.i); - private static final DataWatcherObject e = DataWatcher.a(EntityAreaEffectCloud.class, DataWatcherRegistry.j); + private static final Logger LOGGER = LogManager.getLogger(); + private static final DataWatcherObject c = DataWatcher.a(EntityAreaEffectCloud.class, DataWatcherRegistry.c); + private static final DataWatcherObject COLOR = DataWatcher.a(EntityAreaEffectCloud.class, DataWatcherRegistry.b); + private static final DataWatcherObject e = DataWatcher.a(EntityAreaEffectCloud.class, DataWatcherRegistry.i); + private static final DataWatcherObject f = DataWatcher.a(EntityAreaEffectCloud.class, DataWatcherRegistry.j); private PotionRegistry potionRegistry; public List effects; - private final Map h; - private int aw; + private final Map affectedEntities; + private int at; public int waitTime; public int reapplicationDelay; private boolean hasColor; public int durationOnUse; public float radiusOnUse; public float radiusPerTick; - private EntityLiving aD; - private UUID aE; + private EntityLiving aA; + private UUID aB; - public EntityAreaEffectCloud(World world) { - super(EntityTypes.AREA_EFFECT_CLOUD, world); + public EntityAreaEffectCloud(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.potionRegistry = Potions.EMPTY; this.effects = Lists.newArrayList(); - this.h = Maps.newHashMap(); - this.aw = 600; + this.affectedEntities = Maps.newHashMap(); + this.at = 600; this.waitTime = 20; this.reapplicationDelay = 20; this.noclip = true; - this.fireProof = true; this.setRadius(3.0F); } public EntityAreaEffectCloud(World world, double d0, double d1, double d2) { - this(world); + this(EntityTypes.AREA_EFFECT_CLOUD, world); this.setPosition(d0, d1, d2); } - protected void x_() { - this.getDataWatcher().register(EntityAreaEffectCloud.c, 0); - this.getDataWatcher().register(EntityAreaEffectCloud.b, 0.5F); - this.getDataWatcher().register(EntityAreaEffectCloud.d, false); - this.getDataWatcher().register(EntityAreaEffectCloud.e, Particles.s); + @Override + protected void initDatawatcher() { + this.getDataWatcher().register(EntityAreaEffectCloud.COLOR, 0); + this.getDataWatcher().register(EntityAreaEffectCloud.c, 0.5F); + this.getDataWatcher().register(EntityAreaEffectCloud.e, false); + this.getDataWatcher().register(EntityAreaEffectCloud.f, Particles.ENTITY_EFFECT); } public void setRadius(float f) { - double d0 = this.locX; - double d1 = this.locY; - double d2 = this.locZ; - - this.setSize(f * 2.0F, 0.5F); - this.setPosition(d0, d1, d2); if (!this.world.isClientSide) { - this.getDataWatcher().set(EntityAreaEffectCloud.b, f); + this.getDataWatcher().set(EntityAreaEffectCloud.c, f); } } + @Override + public void updateSize() { + double d0 = this.locX; + double d1 = this.locY; + double d2 = this.locZ; + + super.updateSize(); + this.setPosition(d0, d1, d2); + } + public float getRadius() { - return (Float) this.getDataWatcher().get(EntityAreaEffectCloud.b); + return (Float) this.getDataWatcher().get(EntityAreaEffectCloud.c); } public void a(PotionRegistry potionregistry) { this.potionRegistry = potionregistry; if (!this.hasColor) { - this.x(); + this.z(); } } - private void x() { + private void z() { if (this.potionRegistry == Potions.EMPTY && this.effects.isEmpty()) { - this.getDataWatcher().set(EntityAreaEffectCloud.c, 0); + this.getDataWatcher().set(EntityAreaEffectCloud.COLOR, 0); } else { - this.getDataWatcher().set(EntityAreaEffectCloud.c, PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects))); + this.getDataWatcher().set(EntityAreaEffectCloud.COLOR, PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects))); } } - public void a(MobEffect mobeffect) { + public void addEffect(MobEffect mobeffect) { this.effects.add(mobeffect); if (!this.hasColor) { - this.x(); + this.z(); } } @@ -108,7 +112,7 @@ public class EntityAreaEffectCloud extends Entity { // CraftBukkit start accessor methods public void refreshEffects() { if (!this.hasColor) { - this.getDataWatcher().set(EntityAreaEffectCloud.c, Integer.valueOf(PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects)))); // PAIL: rename + this.getDataWatcher().set(EntityAreaEffectCloud.COLOR, PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects))); // PAIL: rename } } @@ -122,42 +126,61 @@ public class EntityAreaEffectCloud extends Entity { // CraftBukkit end public int getColor() { - return (Integer) this.getDataWatcher().get(EntityAreaEffectCloud.c); + return (Integer) this.getDataWatcher().get(EntityAreaEffectCloud.COLOR); } public void setColor(int i) { this.hasColor = true; - this.getDataWatcher().set(EntityAreaEffectCloud.c, i); + this.getDataWatcher().set(EntityAreaEffectCloud.COLOR, i); } public ParticleParam getParticle() { - return (ParticleParam) this.getDataWatcher().get(EntityAreaEffectCloud.e); + return (ParticleParam) this.getDataWatcher().get(EntityAreaEffectCloud.f); } public void setParticle(ParticleParam particleparam) { - this.getDataWatcher().set(EntityAreaEffectCloud.e, particleparam); + this.getDataWatcher().set(EntityAreaEffectCloud.f, particleparam); } protected void a(boolean flag) { - this.getDataWatcher().set(EntityAreaEffectCloud.d, flag); + this.getDataWatcher().set(EntityAreaEffectCloud.e, flag); } public boolean l() { - return (Boolean) this.getDataWatcher().get(EntityAreaEffectCloud.d); + return (Boolean) this.getDataWatcher().get(EntityAreaEffectCloud.e); } public int getDuration() { - return this.aw; + return this.at; } public void setDuration(int i) { - this.aw = i; + this.at = i; } + // Spigot start - copied from below + @Override + public void inactiveTick() { + super.inactiveTick(); + + if (this.ticksLived >= this.waitTime + this.at) { + this.die(); + return; + } + } + // Spigot end + + @Override public void tick() { super.tick(); boolean flag = this.l(); float f = this.getRadius(); + // Paper start - fix MC-114618 + if (f < 0.0F) { + this.die(); + return; + } + // Paper end if (this.world.isClientSide) { ParticleParam particleparam = this.getParticle(); @@ -176,7 +199,7 @@ public class EntityAreaEffectCloud extends Entity { f1 = MathHelper.c(this.random.nextFloat()) * 0.2F; f2 = MathHelper.cos(f4) * f1; f3 = MathHelper.sin(f4) * f1; - if (particleparam.b() == Particles.s) { + if (particleparam.getParticle() == Particles.ENTITY_EFFECT) { int i1 = this.random.nextBoolean() ? 16777215 : this.getColor(); i = i1 >> 16 & 255; @@ -197,7 +220,7 @@ public class EntityAreaEffectCloud extends Entity { f3 = MathHelper.cos(f1) * f2; float f6 = MathHelper.sin(f1) * f2; - if (particleparam.b() == Particles.s) { + if (particleparam.getParticle() == Particles.ENTITY_EFFECT) { i = this.getColor(); j = i >> 16 & 255; k = i >> 8 & 255; @@ -210,7 +233,7 @@ public class EntityAreaEffectCloud extends Entity { } } } else { - if (this.ticksLived >= this.waitTime + this.aw) { + if (this.ticksLived >= this.waitTime + this.at) { this.die(); return; } @@ -236,7 +259,7 @@ public class EntityAreaEffectCloud extends Entity { } if (this.ticksLived % 5 == 0) { - Iterator iterator = this.h.entrySet().iterator(); + Iterator iterator = this.affectedEntities.entrySet().iterator(); while (iterator.hasNext()) { Entry entry = (Entry) iterator.next(); @@ -257,7 +280,7 @@ public class EntityAreaEffectCloud extends Entity { list.addAll(this.effects); if (list.isEmpty()) { - this.h.clear(); + this.affectedEntities.clear(); } else { List list1 = this.world.a(EntityLiving.class, this.getBoundingBox()); @@ -268,7 +291,7 @@ public class EntityAreaEffectCloud extends Entity { while (iterator2.hasNext()) { EntityLiving entityliving = (EntityLiving) iterator2.next(); - if (!this.h.containsKey(entityliving) && entityliving.de()) { + if (!this.affectedEntities.containsKey(entityliving) && entityliving.dt()) { double d0 = entityliving.locX - this.locX; double d1 = entityliving.locZ - this.locZ; double d2 = d0 * d0 + d1 * d1; @@ -285,7 +308,7 @@ public class EntityAreaEffectCloud extends Entity { if (entity instanceof CraftLivingEntity) { EntityLiving entityliving = ((CraftLivingEntity) entity).getHandle(); // CraftBukkit end - this.h.put(entityliving, this.ticksLived + this.reapplicationDelay); + this.affectedEntities.put(entityliving, this.ticksLived + this.reapplicationDelay); Iterator iterator3 = list.iterator(); while (iterator3.hasNext()) { @@ -309,8 +332,8 @@ public class EntityAreaEffectCloud extends Entity { } if (this.durationOnUse != 0) { - this.aw += this.durationOnUse; - if (this.aw <= 0) { + this.at += this.durationOnUse; + if (this.at <= 0) { this.die(); return; } @@ -338,38 +361,39 @@ public class EntityAreaEffectCloud extends Entity { } public void setSource(@Nullable EntityLiving entityliving) { - this.aD = entityliving; - this.aE = entityliving == null ? null : entityliving.getUniqueID(); + this.aA = entityliving; + this.aB = entityliving == null ? null : entityliving.getUniqueID(); } @Nullable public EntityLiving getSource() { - if (this.aD == null && this.aE != null && this.world instanceof WorldServer) { - Entity entity = ((WorldServer) this.world).getEntity(this.aE); + if (this.aA == null && this.aB != null && this.world instanceof WorldServer) { + Entity entity = ((WorldServer) this.world).getEntity(this.aB); if (entity instanceof EntityLiving) { - this.aD = (EntityLiving) entity; + this.aA = (EntityLiving) entity; } } - return this.aD; + return this.aA; } + @Override protected void a(NBTTagCompound nbttagcompound) { this.ticksLived = nbttagcompound.getInt("Age"); - this.aw = nbttagcompound.getInt("Duration"); + this.at = nbttagcompound.getInt("Duration"); this.waitTime = nbttagcompound.getInt("WaitTime"); this.reapplicationDelay = nbttagcompound.getInt("ReapplicationDelay"); this.durationOnUse = nbttagcompound.getInt("DurationOnUse"); this.radiusOnUse = nbttagcompound.getFloat("RadiusOnUse"); this.radiusPerTick = nbttagcompound.getFloat("RadiusPerTick"); this.setRadius(nbttagcompound.getFloat("Radius")); - this.aE = nbttagcompound.a("OwnerUUID"); + this.aB = nbttagcompound.a("OwnerUUID"); if (nbttagcompound.hasKeyOfType("Particle", 8)) { try { this.setParticle(ArgumentParticle.b(new StringReader(nbttagcompound.getString("Particle")))); } catch (CommandSyntaxException commandsyntaxexception) { - EntityAreaEffectCloud.a.warn("Couldn't load custom particle {}", nbttagcompound.getString("Particle"), commandsyntaxexception); + EntityAreaEffectCloud.LOGGER.warn("Couldn't load custom particle {}", nbttagcompound.getString("Particle"), commandsyntaxexception); } } @@ -390,16 +414,17 @@ public class EntityAreaEffectCloud extends Entity { MobEffect mobeffect = MobEffect.b(nbttaglist.getCompound(i)); if (mobeffect != null) { - this.a(mobeffect); + this.addEffect(mobeffect); } } } } + @Override protected void b(NBTTagCompound nbttagcompound) { nbttagcompound.setInt("Age", this.ticksLived); - nbttagcompound.setInt("Duration", this.aw); + nbttagcompound.setInt("Duration", this.at); nbttagcompound.setInt("WaitTime", this.waitTime); nbttagcompound.setInt("ReapplicationDelay", this.reapplicationDelay); nbttagcompound.setInt("DurationOnUse", this.durationOnUse); @@ -407,8 +432,8 @@ public class EntityAreaEffectCloud extends Entity { nbttagcompound.setFloat("RadiusPerTick", this.radiusPerTick); nbttagcompound.setFloat("Radius", this.getRadius()); nbttagcompound.setString("Particle", this.getParticle().a()); - if (this.aE != null) { - nbttagcompound.a("OwnerUUID", this.aE); + if (this.aB != null) { + nbttagcompound.a("OwnerUUID", this.aB); } if (this.hasColor) { @@ -426,7 +451,7 @@ public class EntityAreaEffectCloud extends Entity { while (iterator.hasNext()) { MobEffect mobeffect = (MobEffect) iterator.next(); - nbttaglist.add((NBTBase) mobeffect.a(new NBTTagCompound())); + nbttaglist.add(mobeffect.a(new NBTTagCompound())); } nbttagcompound.set("Effects", nbttaglist); @@ -434,15 +459,27 @@ public class EntityAreaEffectCloud extends Entity { } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntityAreaEffectCloud.b.equals(datawatcherobject)) { - this.setRadius(this.getRadius()); + if (EntityAreaEffectCloud.c.equals(datawatcherobject)) { + this.updateSize(); } super.a(datawatcherobject); } + @Override public EnumPistonReaction getPushReaction() { return EnumPistonReaction.IGNORE; } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); + } + + @Override + public EntitySize a(EntityPose entitypose) { + return EntitySize.b(this.getRadius() * 2.0F, 0.5F); + } } diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java index a5cc5e284..02595cfcc 100644 --- a/src/main/java/net/minecraft/server/EntityArmorStand.java +++ b/src/main/java/net/minecraft/server/EntityArmorStand.java @@ -16,28 +16,27 @@ import org.bukkit.event.player.PlayerArmorStandManipulateEvent; public class EntityArmorStand extends EntityLiving { - private static final Vector3f bx = new Vector3f(0.0F, 0.0F, 0.0F); - private static final Vector3f by = new Vector3f(0.0F, 0.0F, 0.0F); - private static final Vector3f bz = new Vector3f(-10.0F, 0.0F, -10.0F); - private static final Vector3f bA = new Vector3f(-15.0F, 0.0F, 10.0F); - private static final Vector3f bB = new Vector3f(-1.0F, 0.0F, -1.0F); - private static final Vector3f bC = new Vector3f(1.0F, 0.0F, 1.0F); - public static final DataWatcherObject a = DataWatcher.a(EntityArmorStand.class, DataWatcherRegistry.a); - public static final DataWatcherObject b = DataWatcher.a(EntityArmorStand.class, DataWatcherRegistry.k); + private static final Vector3f bu = new Vector3f(0.0F, 0.0F, 0.0F); + private static final Vector3f bv = new Vector3f(0.0F, 0.0F, 0.0F); + private static final Vector3f bw = new Vector3f(-10.0F, 0.0F, -10.0F); + private static final Vector3f bx = new Vector3f(-15.0F, 0.0F, 10.0F); + private static final Vector3f by = new Vector3f(-1.0F, 0.0F, -1.0F); + private static final Vector3f bz = new Vector3f(1.0F, 0.0F, 1.0F); + public static final DataWatcherObject b = DataWatcher.a(EntityArmorStand.class, DataWatcherRegistry.a); public static final DataWatcherObject c = DataWatcher.a(EntityArmorStand.class, DataWatcherRegistry.k); public static final DataWatcherObject d = DataWatcher.a(EntityArmorStand.class, DataWatcherRegistry.k); public static final DataWatcherObject e = DataWatcher.a(EntityArmorStand.class, DataWatcherRegistry.k); public static final DataWatcherObject f = DataWatcher.a(EntityArmorStand.class, DataWatcherRegistry.k); public static final DataWatcherObject g = DataWatcher.a(EntityArmorStand.class, DataWatcherRegistry.k); - private static final Predicate bD = (entity) -> { - return entity instanceof EntityMinecartAbstract && ((EntityMinecartAbstract) entity).v() == EntityMinecartAbstract.EnumMinecartType.RIDEABLE; + public static final DataWatcherObject bs = DataWatcher.a(EntityArmorStand.class, DataWatcherRegistry.k); + private static final Predicate bA = (entity) -> { + return entity instanceof EntityMinecartAbstract && ((EntityMinecartAbstract) entity).getMinecartType() == EntityMinecartAbstract.EnumMinecartType.RIDEABLE; }; - private final NonNullList bE; - private final NonNullList bF; - private boolean bG; - public long h; - private int bH;public void setDisabledSlots(int i) { bH = i;} public int getDisabledSlots() { return bH ;} // Paper - OBFHELPER - private boolean bI; + private final NonNullList handItems; + private final NonNullList armorItems; + private boolean bD; + public long bt; + private int bE; public void setDisabledSlots(int i) { bE = i;} public int getDisabledSlots() { return bE ;} // Paper - OBFHELPER public Vector3f headPose; public Vector3f bodyPose; public Vector3f leftArmPose; @@ -47,28 +46,27 @@ public class EntityArmorStand extends EntityLiving { public boolean canMove = true; // Paper // Paper start - Allow ArmorStands not to tick public boolean canTick = true; + public boolean canTickSetByAPI = false; private boolean noTickPoseDirty = false; private boolean noTickEquipmentDirty = false; // Paper end - public EntityArmorStand(World world) { - super(EntityTypes.ARMOR_STAND, world); - this.bE = NonNullList.a(2, ItemStack.a); - this.bF = NonNullList.a(4, ItemStack.a); - this.headPose = EntityArmorStand.bx; - this.bodyPose = EntityArmorStand.by; - this.leftArmPose = EntityArmorStand.bz; - this.rightArmPose = EntityArmorStand.bA; - this.leftLegPose = EntityArmorStand.bB; - this.rightLegPose = EntityArmorStand.bC; - this.noclip = this.isNoGravity(); + public EntityArmorStand(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.handItems = NonNullList.a(2, ItemStack.a); + this.armorItems = NonNullList.a(4, ItemStack.a); + this.headPose = EntityArmorStand.bu; + this.bodyPose = EntityArmorStand.bv; + this.leftArmPose = EntityArmorStand.bw; + this.rightArmPose = EntityArmorStand.bx; + this.leftLegPose = EntityArmorStand.by; + this.rightLegPose = EntityArmorStand.bz; if (world != null) this.canTick = world.paperConfig.armorStandTick; // Paper - armour stand ticking - this.setSize(0.5F, 1.975F); - this.Q = 0.0F; + this.K = 0.0F; } public EntityArmorStand(World world, double d0, double d1, double d2) { - this(world); + this(EntityTypes.ARMOR_STAND, world); this.setPosition(d0, d1, d2); } @@ -79,65 +77,76 @@ public class EntityArmorStand extends EntityLiving { } // CraftBukkit end - public final void setSize(float f, float f1) { + @Override + public void updateSize() { double d0 = this.locX; double d1 = this.locY; double d2 = this.locZ; - float f2 = this.isMarker() ? 0.0F : (this.isBaby() ? 0.5F : 1.0F); - super.setSize(f * f2, f1 * f2); + super.updateSize(); this.setPosition(d0, d1, d2); } - public boolean cP() { - return super.cP() && !this.isNoGravity(); + private boolean A() { + return !this.isMarker() && !this.isNoGravity(); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityArmorStand.a, (byte) 0); - this.datawatcher.register(EntityArmorStand.b, EntityArmorStand.bx); - this.datawatcher.register(EntityArmorStand.c, EntityArmorStand.by); - this.datawatcher.register(EntityArmorStand.d, EntityArmorStand.bz); - this.datawatcher.register(EntityArmorStand.e, EntityArmorStand.bA); - this.datawatcher.register(EntityArmorStand.f, EntityArmorStand.bB); - this.datawatcher.register(EntityArmorStand.g, EntityArmorStand.bC); + @Override + public boolean df() { + return super.df() && this.A(); } - public Iterable aS() { - return this.bE; + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityArmorStand.b, (byte) 0); + this.datawatcher.register(EntityArmorStand.c, EntityArmorStand.bu); + this.datawatcher.register(EntityArmorStand.d, EntityArmorStand.bv); + this.datawatcher.register(EntityArmorStand.e, EntityArmorStand.bw); + this.datawatcher.register(EntityArmorStand.f, EntityArmorStand.bx); + this.datawatcher.register(EntityArmorStand.g, EntityArmorStand.by); + this.datawatcher.register(EntityArmorStand.bs, EntityArmorStand.bz); } + @Override + public Iterable aZ() { + return this.handItems; + } + + @Override public Iterable getArmorItems() { - return this.bF; + return this.armorItems; } + @Override public ItemStack getEquipment(EnumItemSlot enumitemslot) { switch (enumitemslot.a()) { - case HAND: - return (ItemStack) this.bE.get(enumitemslot.b()); - case ARMOR: - return (ItemStack) this.bF.get(enumitemslot.b()); - default: - return ItemStack.a; + case HAND: + return (ItemStack) this.handItems.get(enumitemslot.b()); + case ARMOR: + return (ItemStack) this.armorItems.get(enumitemslot.b()); + default: + return ItemStack.a; } } + @Override public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) { switch (enumitemslot.a()) { - case HAND: - this.b(itemstack); - this.bE.set(enumitemslot.b(), itemstack); - break; - case ARMOR: - this.b(itemstack); - this.bF.set(enumitemslot.b(), itemstack); + case HAND: + this.b(itemstack); + this.handItems.set(enumitemslot.b(), itemstack); + break; + case ARMOR: + this.b(itemstack); + this.armorItems.set(enumitemslot.b(), itemstack); } this.noTickEquipmentDirty = true; // Paper - Allow equipment to be updated even when tick disabled } - public boolean c(int i, ItemStack itemstack) { + @Override + public boolean a_(int i, ItemStack itemstack) { EnumItemSlot enumitemslot; if (i == 98) { @@ -166,13 +175,21 @@ public class EntityArmorStand extends EntityLiving { } } + @Override + public boolean e(ItemStack itemstack) { + EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); + + return this.getEquipment(enumitemslot).isEmpty() && !this.d(enumitemslot); + } + + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); NBTTagList nbttaglist = new NBTTagList(); NBTTagCompound nbttagcompound1; - for (Iterator iterator = this.bF.iterator(); iterator.hasNext(); nbttaglist.add((NBTBase) nbttagcompound1)) { + for (Iterator iterator = this.armorItems.iterator(); iterator.hasNext(); nbttaglist.add(nbttagcompound1)) { ItemStack itemstack = (ItemStack) iterator.next(); nbttagcompound1 = new NBTTagCompound(); @@ -186,7 +203,7 @@ public class EntityArmorStand extends EntityLiving { NBTTagCompound nbttagcompound2; - for (Iterator iterator1 = this.bE.iterator(); iterator1.hasNext(); nbttaglist1.add((NBTBase) nbttagcompound2)) { + for (Iterator iterator1 = this.handItems.iterator(); iterator1.hasNext(); nbttaglist1.add(nbttagcompound2)) { ItemStack itemstack1 = (ItemStack) iterator1.next(); nbttagcompound2 = new NBTTagCompound(); @@ -199,16 +216,17 @@ public class EntityArmorStand extends EntityLiving { nbttagcompound.setBoolean("Invisible", this.isInvisible()); nbttagcompound.setBoolean("Small", this.isSmall()); nbttagcompound.setBoolean("ShowArms", this.hasArms()); - nbttagcompound.setInt("DisabledSlots", this.bH); + nbttagcompound.setInt("DisabledSlots", this.bE); nbttagcompound.setBoolean("NoBasePlate", this.hasBasePlate()); if (this.isMarker()) { nbttagcompound.setBoolean("Marker", this.isMarker()); } - nbttagcompound.set("Pose", this.z()); - nbttagcompound.setBoolean("Paper.CanTick", this.canTick); // Paper - persist no tick setting + nbttagcompound.set("Pose", this.B()); + if (this.canTickSetByAPI) nbttagcompound.setBoolean("Paper.CanTickOverride", this.canTick); // Paper - persist no tick setting } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); NBTTagList nbttaglist; @@ -217,30 +235,30 @@ public class EntityArmorStand extends EntityLiving { if (nbttagcompound.hasKeyOfType("ArmorItems", 9)) { nbttaglist = nbttagcompound.getList("ArmorItems", 10); - for (i = 0; i < this.bF.size(); ++i) { - this.bF.set(i, ItemStack.a(nbttaglist.getCompound(i))); + for (i = 0; i < this.armorItems.size(); ++i) { + this.armorItems.set(i, ItemStack.a(nbttaglist.getCompound(i))); } } if (nbttagcompound.hasKeyOfType("HandItems", 9)) { nbttaglist = nbttagcompound.getList("HandItems", 10); - for (i = 0; i < this.bE.size(); ++i) { - this.bE.set(i, ItemStack.a(nbttaglist.getCompound(i))); + for (i = 0; i < this.handItems.size(); ++i) { + this.handItems.set(i, ItemStack.a(nbttaglist.getCompound(i))); } } this.setInvisible(nbttagcompound.getBoolean("Invisible")); this.setSmall(nbttagcompound.getBoolean("Small")); this.setArms(nbttagcompound.getBoolean("ShowArms")); - this.bH = nbttagcompound.getInt("DisabledSlots"); + this.bE = nbttagcompound.getInt("DisabledSlots"); this.setBasePlate(nbttagcompound.getBoolean("NoBasePlate")); this.setMarker(nbttagcompound.getBoolean("Marker")); - this.bI = !this.isMarker(); - this.noclip = this.isNoGravity(); + this.noclip = !this.A(); // Paper start - persist no tick - if (nbttagcompound.hasKey("Paper.CanTick")) { - this.canTick = nbttagcompound.getBoolean("Paper.CanTick"); + if (nbttagcompound.hasKey("Paper.CanTickOverride")) { + this.canTick = nbttagcompound.getBoolean("Paper.CanTickOverride"); + this.canTickSetByAPI = true; } // Paper end NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Pose"); @@ -251,62 +269,65 @@ public class EntityArmorStand extends EntityLiving { private void g(NBTTagCompound nbttagcompound) { NBTTagList nbttaglist = nbttagcompound.getList("Head", 5); - this.setHeadPose(nbttaglist.isEmpty() ? EntityArmorStand.bx : new Vector3f(nbttaglist)); + this.setHeadPose(nbttaglist.isEmpty() ? EntityArmorStand.bu : new Vector3f(nbttaglist)); NBTTagList nbttaglist1 = nbttagcompound.getList("Body", 5); - this.setBodyPose(nbttaglist1.isEmpty() ? EntityArmorStand.by : new Vector3f(nbttaglist1)); + this.setBodyPose(nbttaglist1.isEmpty() ? EntityArmorStand.bv : new Vector3f(nbttaglist1)); NBTTagList nbttaglist2 = nbttagcompound.getList("LeftArm", 5); - this.setLeftArmPose(nbttaglist2.isEmpty() ? EntityArmorStand.bz : new Vector3f(nbttaglist2)); + this.setLeftArmPose(nbttaglist2.isEmpty() ? EntityArmorStand.bw : new Vector3f(nbttaglist2)); NBTTagList nbttaglist3 = nbttagcompound.getList("RightArm", 5); - this.setRightArmPose(nbttaglist3.isEmpty() ? EntityArmorStand.bA : new Vector3f(nbttaglist3)); + this.setRightArmPose(nbttaglist3.isEmpty() ? EntityArmorStand.bx : new Vector3f(nbttaglist3)); NBTTagList nbttaglist4 = nbttagcompound.getList("LeftLeg", 5); - this.setLeftLegPose(nbttaglist4.isEmpty() ? EntityArmorStand.bB : new Vector3f(nbttaglist4)); + this.setLeftLegPose(nbttaglist4.isEmpty() ? EntityArmorStand.by : new Vector3f(nbttaglist4)); NBTTagList nbttaglist5 = nbttagcompound.getList("RightLeg", 5); - this.setRightLegPose(nbttaglist5.isEmpty() ? EntityArmorStand.bC : new Vector3f(nbttaglist5)); + this.setRightLegPose(nbttaglist5.isEmpty() ? EntityArmorStand.bz : new Vector3f(nbttaglist5)); } - private NBTTagCompound z() { + private NBTTagCompound B() { NBTTagCompound nbttagcompound = new NBTTagCompound(); - if (!EntityArmorStand.bx.equals(this.headPose)) { + if (!EntityArmorStand.bu.equals(this.headPose)) { nbttagcompound.set("Head", this.headPose.a()); } - if (!EntityArmorStand.by.equals(this.bodyPose)) { + if (!EntityArmorStand.bv.equals(this.bodyPose)) { nbttagcompound.set("Body", this.bodyPose.a()); } - if (!EntityArmorStand.bz.equals(this.leftArmPose)) { + if (!EntityArmorStand.bw.equals(this.leftArmPose)) { nbttagcompound.set("LeftArm", this.leftArmPose.a()); } - if (!EntityArmorStand.bA.equals(this.rightArmPose)) { + if (!EntityArmorStand.bx.equals(this.rightArmPose)) { nbttagcompound.set("RightArm", this.rightArmPose.a()); } - if (!EntityArmorStand.bB.equals(this.leftLegPose)) { + if (!EntityArmorStand.by.equals(this.leftLegPose)) { nbttagcompound.set("LeftLeg", this.leftLegPose.a()); } - if (!EntityArmorStand.bC.equals(this.rightLegPose)) { + if (!EntityArmorStand.bz.equals(this.rightLegPose)) { nbttagcompound.set("RightLeg", this.rightLegPose.a()); } return nbttagcompound; } + @Override public boolean isCollidable() { return false; } - protected void C(Entity entity) {} + @Override + protected void D(Entity entity) {} - protected void cN() { - List list = this.world.getEntities(this, this.getBoundingBox(), EntityArmorStand.bD); + @Override + protected void collideNearby() { + List list = this.world.getEntities(this, this.getBoundingBox(), EntityArmorStand.bA); for (int i = 0; i < list.size(); ++i) { Entity entity = (Entity) list.get(i); @@ -318,22 +339,23 @@ public class EntityArmorStand extends EntityLiving { } + @Override public EnumInteractionResult a(EntityHuman entityhuman, Vec3D vec3d, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); if (!this.isMarker() && itemstack.getItem() != Items.NAME_TAG) { if (!this.world.isClientSide && !entityhuman.isSpectator()) { - EnumItemSlot enumitemslot = EntityInsentient.e(itemstack); + EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); if (itemstack.isEmpty()) { - EnumItemSlot enumitemslot1 = this.b(vec3d); - EnumItemSlot enumitemslot2 = this.c(enumitemslot1) ? enumitemslot : enumitemslot1; + EnumItemSlot enumitemslot1 = this.f(vec3d); + EnumItemSlot enumitemslot2 = this.d(enumitemslot1) ? enumitemslot : enumitemslot1; if (this.a(enumitemslot2)) { this.a(entityhuman, enumitemslot2, itemstack, enumhand); } } else { - if (this.c(enumitemslot)) { + if (this.d(enumitemslot)) { return EnumInteractionResult.FAIL; } @@ -353,7 +375,7 @@ public class EntityArmorStand extends EntityLiving { } } - protected EnumItemSlot b(Vec3D vec3d) { + protected EnumItemSlot f(Vec3D vec3d) { EnumItemSlot enumitemslot = EnumItemSlot.MAINHAND; boolean flag = this.isSmall(); double d0 = flag ? vec3d.y * 2.0D : vec3d.y; @@ -374,16 +396,16 @@ public class EntityArmorStand extends EntityLiving { return enumitemslot; } - public boolean isSlotDisabled(EnumItemSlot slot) { return this.c(slot); } // Paper - OBFHELPER - public boolean c(EnumItemSlot enumitemslot) { - return (this.bH & 1 << enumitemslot.c()) != 0 || enumitemslot.a() == EnumItemSlot.Function.HAND && !this.hasArms(); + public boolean isSlotDisabled(EnumItemSlot slot) { return this.d(slot); } // Paper - OBFHELPER + public boolean d(EnumItemSlot enumitemslot) { + return (this.bE & 1 << enumitemslot.c()) != 0 || enumitemslot.a() == EnumItemSlot.Function.HAND && !this.hasArms(); } private void a(EntityHuman entityhuman, EnumItemSlot enumitemslot, ItemStack itemstack, EnumHand enumhand) { ItemStack itemstack1 = this.getEquipment(enumitemslot); - if (itemstack1.isEmpty() || (this.bH & 1 << enumitemslot.c() + 8) == 0) { - if (!itemstack1.isEmpty() || (this.bH & 1 << enumitemslot.c() + 16) == 0) { + if (itemstack1.isEmpty() || (this.bE & 1 << enumitemslot.c() + 8) == 0) { + if (!itemstack1.isEmpty() || (this.bE & 1 << enumitemslot.c() + 16) == 0) { ItemStack itemstack2; // CraftBukkit start org.bukkit.inventory.ItemStack armorStandItem = CraftItemStack.asCraftMirror(itemstack1); @@ -420,55 +442,62 @@ public class EntityArmorStand extends EntityLiving { } } + @Override public boolean damageEntity(DamageSource damagesource, float f) { - // CraftBukkit start - if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { - return false; - } - // CraftBukkit end if (!this.world.isClientSide && !this.dead) { if (DamageSource.OUT_OF_WORLD.equals(damagesource)) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { + return false; + } + // CraftBukkit end this.killEntity(); // CraftBukkit - this.die() -> this.killEntity() return false; - } else if (!this.isInvulnerable(damagesource) && !this.bG && !this.isMarker()) { + } else if (!this.isInvulnerable(damagesource) && (true || !this.bD) && !this.isMarker()) { // CraftBukkit + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f, true, this.bD)) { // PAIL: armorStandInvisible + return false; + } + // CraftBukkit end if (damagesource.isExplosion()) { - this.D(); + this.g(damagesource); this.killEntity(); // CraftBukkit - this.die() -> this.killEntity() return false; } else if (DamageSource.FIRE.equals(damagesource)) { if (this.isBurning()) { - this.a(0.15F); + this.e(damagesource, 0.15F); } else { this.setOnFire(5); } return false; } else if (DamageSource.BURN.equals(damagesource) && this.getHealth() > 0.5F) { - this.a(4.0F); + this.e(damagesource, 4.0F); return false; } else { boolean flag = damagesource.j() instanceof EntityArrow; - boolean flag1 = "player".equals(damagesource.q()); + boolean flag1 = flag && ((EntityArrow) damagesource.j()).getPierceLevel() > 0; + boolean flag2 = "player".equals(damagesource.q()); - if (!flag1 && !flag) { + if (!flag2 && !flag) { return false; } else if (damagesource.getEntity() instanceof EntityHuman && !((EntityHuman) damagesource.getEntity()).abilities.mayBuild) { return false; } else if (damagesource.v()) { this.F(); - this.A(); + this.D(); this.killEntity(); // CraftBukkit - this.die() -> this.killEntity() - return false; + return flag1; } else { long i = this.world.getTime(); - if (i - this.h > 5L && !flag) { + if (i - this.bt > 5L && !flag) { this.world.broadcastEntityEffect(this, (byte) 32); - this.h = i; + this.bt = i; } else { - this.B(); - this.A(); - this.killEntity(); // CraftBukkit - this.die() -> this.killEntity() + this.f(damagesource); + this.D(); + this.die(); // CraftBukkit - SPIGOT-4890: remain as this.die() since above damagesource method will call death event } return true; @@ -482,19 +511,19 @@ public class EntityArmorStand extends EntityLiving { } } - private void A() { + private void D() { if (this.world instanceof WorldServer) { - ((WorldServer) this.world).a(new ParticleParamBlock(Particles.d, Blocks.OAK_PLANKS.getBlockData()), this.locX, this.locY + (double) this.length / 1.5D, this.locZ, 10, (double) (this.width / 4.0F), (double) (this.length / 4.0F), (double) (this.width / 4.0F), 0.05D); + ((WorldServer) this.world).a(new ParticleParamBlock(Particles.BLOCK, Blocks.OAK_PLANKS.getBlockData()), this.locX, this.locY + (double) this.getHeight() / 1.5D, this.locZ, 10, (double) (this.getWidth() / 4.0F), (double) (this.getHeight() / 4.0F), (double) (this.getWidth() / 4.0F), 0.05D); } } - private void a(float f) { + private void e(DamageSource damagesource, float f) { float f1 = this.getHealth(); f1 -= f; if (f1 <= 0.5F) { - this.D(); + this.g(damagesource); this.killEntity(); // CraftBukkit - this.die() -> this.killEntity() } else { this.setHealth(f1); @@ -502,69 +531,78 @@ public class EntityArmorStand extends EntityLiving { } - private void B() { + private void f(DamageSource damagesource) { drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(new ItemStack(Items.ARMOR_STAND))); // CraftBukkit - add to drops - this.D(); + this.g(damagesource); } - private void D() { + private void g(DamageSource damagesource) { this.F(); + // this.d(damagesource); // CraftBukkit - moved down ItemStack itemstack; int i; - for (i = 0; i < this.bE.size(); ++i) { - itemstack = (ItemStack) this.bE.get(i); + for (i = 0; i < this.handItems.size(); ++i) { + itemstack = (ItemStack) this.handItems.get(i); if (!itemstack.isEmpty()) { drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops - this.bE.set(i, ItemStack.a); + this.handItems.set(i, ItemStack.a); } } - for (i = 0; i < this.bF.size(); ++i) { - itemstack = (ItemStack) this.bF.get(i); + for (i = 0; i < this.armorItems.size(); ++i) { + itemstack = (ItemStack) this.armorItems.get(i); if (!itemstack.isEmpty()) { drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops - this.bF.set(i, ItemStack.a); + this.armorItems.set(i, ItemStack.a); } } + this.d(damagesource); // CraftBukkit - moved from above } private void F() { - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_ARMOR_STAND_BREAK, this.bV(), 1.0F, 1.0F); + this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_ARMOR_STAND_BREAK, this.getSoundCategory(), 1.0F, 1.0F); } + @Override protected float e(float f, float f1) { - this.aR = this.lastYaw; - this.aQ = this.yaw; + this.aL = this.lastYaw; + this.aK = this.yaw; return 0.0F; } - public float getHeadHeight() { - return this.isBaby() ? this.length * 0.5F : this.length * 0.9F; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height * (this.isBaby() ? 0.5F : 0.9F); } - public double aI() { + @Override + public double aO() { return this.isMarker() ? 0.0D : 0.10000000149011612D; } - public void a(float f, float f1, float f2) { - if (!this.isNoGravity()) { - super.a(f, f1, f2); + @Override + public void e(Vec3D vec3d) { + if (this.A()) { + super.e(vec3d); } } - public void k(float f) { - this.aR = this.lastYaw = f; - this.aT = this.aS = f; + @Override + public void l(float f) { + this.aL = this.lastYaw = f; + this.aN = this.aM = f; } + @Override public void setHeadRotation(float f) { - this.aR = this.lastYaw = f; - this.aT = this.aS = f; + this.aL = this.lastYaw = f; + this.aN = this.aM = f; } + @Override public void tick() { // Paper start if (!this.canTick) { @@ -583,127 +621,120 @@ public class EntityArmorStand extends EntityLiving { // Paper end super.tick(); - // Paper start - Split into separate method updatePose(); } public void updatePose() { // Paper end - Vector3f vector3f = (Vector3f) this.datawatcher.get(EntityArmorStand.b); + Vector3f vector3f = (Vector3f) this.datawatcher.get(EntityArmorStand.c); if (!this.headPose.equals(vector3f)) { this.setHeadPose(vector3f); } - Vector3f vector3f1 = (Vector3f) this.datawatcher.get(EntityArmorStand.c); + Vector3f vector3f1 = (Vector3f) this.datawatcher.get(EntityArmorStand.d); if (!this.bodyPose.equals(vector3f1)) { this.setBodyPose(vector3f1); } - Vector3f vector3f2 = (Vector3f) this.datawatcher.get(EntityArmorStand.d); + Vector3f vector3f2 = (Vector3f) this.datawatcher.get(EntityArmorStand.e); if (!this.leftArmPose.equals(vector3f2)) { this.setLeftArmPose(vector3f2); } - Vector3f vector3f3 = (Vector3f) this.datawatcher.get(EntityArmorStand.e); + Vector3f vector3f3 = (Vector3f) this.datawatcher.get(EntityArmorStand.f); if (!this.rightArmPose.equals(vector3f3)) { this.setRightArmPose(vector3f3); } - Vector3f vector3f4 = (Vector3f) this.datawatcher.get(EntityArmorStand.f); + Vector3f vector3f4 = (Vector3f) this.datawatcher.get(EntityArmorStand.g); if (!this.leftLegPose.equals(vector3f4)) { this.setLeftLegPose(vector3f4); } - Vector3f vector3f5 = (Vector3f) this.datawatcher.get(EntityArmorStand.g); + Vector3f vector3f5 = (Vector3f) this.datawatcher.get(EntityArmorStand.bs); if (!this.rightLegPose.equals(vector3f5)) { this.setRightLegPose(vector3f5); } - boolean flag = this.isMarker(); - - if (this.bI != flag) { - this.a(flag); - this.j = !flag; - this.bI = flag; - } - - } - - private void a(boolean flag) { - if (flag) { - this.setSize(0.0F, 0.0F); - } else { - this.setSize(0.5F, 1.975F); - } - } + @Override protected void C() { - this.setInvisible(this.bG); + this.setInvisible(this.bD); } + @Override public void setInvisible(boolean flag) { - this.bG = flag; + this.bD = flag; super.setInvisible(flag); } + @Override public boolean isBaby() { return this.isSmall(); } + // CraftBukkit start + @Override + protected boolean isDropExperience() { + return true; // MC-157395, SPIGOT-5193 even baby (small) armor stands should drop + } + // CraftBukkit end + + @Override public void killEntity() { org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, drops); // CraftBukkit - call event // Paper - make cancellable if (event.isCancelled()) return; // Paper - make cancellable this.die(); } - public boolean bL() { + @Override + public boolean bS() { return this.isInvisible(); } + @Override public EnumPistonReaction getPushReaction() { return this.isMarker() ? EnumPistonReaction.IGNORE : super.getPushReaction(); } public void setSmall(boolean flag) { - this.datawatcher.set(EntityArmorStand.a, this.a((Byte) this.datawatcher.get(EntityArmorStand.a), 1, flag)); - this.setSize(0.5F, 1.975F); + this.datawatcher.set(EntityArmorStand.b, this.a((Byte) this.datawatcher.get(EntityArmorStand.b), 1, flag)); } public boolean isSmall() { - return ((Byte) this.datawatcher.get(EntityArmorStand.a) & 1) != 0; + return ((Byte) this.datawatcher.get(EntityArmorStand.b) & 1) != 0; } public void setArms(boolean flag) { - this.datawatcher.set(EntityArmorStand.a, this.a((Byte) this.datawatcher.get(EntityArmorStand.a), 4, flag)); + this.datawatcher.set(EntityArmorStand.b, this.a((Byte) this.datawatcher.get(EntityArmorStand.b), 4, flag)); } public boolean hasArms() { - return ((Byte) this.datawatcher.get(EntityArmorStand.a) & 4) != 0; + return ((Byte) this.datawatcher.get(EntityArmorStand.b) & 4) != 0; } public void setBasePlate(boolean flag) { - this.datawatcher.set(EntityArmorStand.a, this.a((Byte) this.datawatcher.get(EntityArmorStand.a), 8, flag)); + this.datawatcher.set(EntityArmorStand.b, this.a((Byte) this.datawatcher.get(EntityArmorStand.b), 8, flag)); } public boolean hasBasePlate() { - return ((Byte) this.datawatcher.get(EntityArmorStand.a) & 8) != 0; + return ((Byte) this.datawatcher.get(EntityArmorStand.b) & 8) != 0; } public void setMarker(boolean flag) { - this.datawatcher.set(EntityArmorStand.a, this.a((Byte) this.datawatcher.get(EntityArmorStand.a), 16, flag)); - this.setSize(0.5F, 1.975F); + this.datawatcher.set(EntityArmorStand.b, this.a((Byte) this.datawatcher.get(EntityArmorStand.b), 16, flag)); } public boolean isMarker() { - return ((Byte) this.datawatcher.get(EntityArmorStand.a) & 16) != 0; + return ((Byte) this.datawatcher.get(EntityArmorStand.b) & 16) != 0; } private byte a(byte b0, int i, boolean flag) { @@ -718,37 +749,37 @@ public class EntityArmorStand extends EntityLiving { public void setHeadPose(Vector3f vector3f) { this.headPose = vector3f; - this.datawatcher.set(EntityArmorStand.b, vector3f); + this.datawatcher.set(EntityArmorStand.c, vector3f); this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setBodyPose(Vector3f vector3f) { this.bodyPose = vector3f; - this.datawatcher.set(EntityArmorStand.c, vector3f); + this.datawatcher.set(EntityArmorStand.d, vector3f); this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setLeftArmPose(Vector3f vector3f) { this.leftArmPose = vector3f; - this.datawatcher.set(EntityArmorStand.d, vector3f); + this.datawatcher.set(EntityArmorStand.e, vector3f); this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setRightArmPose(Vector3f vector3f) { this.rightArmPose = vector3f; - this.datawatcher.set(EntityArmorStand.e, vector3f); + this.datawatcher.set(EntityArmorStand.f, vector3f); this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setLeftLegPose(Vector3f vector3f) { this.leftLegPose = vector3f; - this.datawatcher.set(EntityArmorStand.f, vector3f); + this.datawatcher.set(EntityArmorStand.g, vector3f); this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } public void setRightLegPose(Vector3f vector3f) { this.rightLegPose = vector3f; - this.datawatcher.set(EntityArmorStand.g, vector3f); + this.datawatcher.set(EntityArmorStand.bs, vector3f); this.noTickPoseDirty = true; // Paper - Allow updates when not ticking } @@ -760,51 +791,68 @@ public class EntityArmorStand extends EntityLiving { return this.bodyPose; } + @Override public boolean isInteractable() { return super.isInteractable() && !this.isMarker(); } + @Override public EnumMainHand getMainHand() { return EnumMainHand.RIGHT; } - protected SoundEffect m(int i) { + @Override + protected SoundEffect getSoundFall(int i) { return SoundEffects.ENTITY_ARMOR_STAND_FALL; } @Nullable - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_ARMOR_STAND_HIT; } @Nullable - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_ARMOR_STAND_BREAK; } + @Override public void onLightningStrike(EntityLightning entitylightning) {} - public boolean de() { + @Override + public boolean dt() { return false; } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntityArmorStand.a.equals(datawatcherobject)) { - this.setSize(0.5F, 1.975F); + if (EntityArmorStand.b.equals(datawatcherobject)) { + this.updateSize(); + this.i = !this.isMarker(); } super.a(datawatcherobject); } - public boolean df() { + @Override + public boolean du() { return false; } + @Override + public EntitySize a(EntityPose entitypose) { + float f = this.isMarker() ? 0.0F : (this.isBaby() ? 0.5F : 1.0F); + + return this.getEntityType().k().a(f); + } + // Paper start @Override - public void move(EnumMoveType moveType, double x, double y, double z) { + public void move(EnumMoveType moveType, Vec3D vec3d) { if (this.canMove) { - super.move(moveType, x, y, z); + super.move(moveType, vec3d); } } diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java index 3d13c754d..5f3e1ccb4 100644 --- a/src/main/java/net/minecraft/server/EntityArrow.java +++ b/src/main/java/net/minecraft/server/EntityArrow.java @@ -1,10 +1,12 @@ package net.minecraft.server; +import com.google.common.collect.Lists; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.UUID; -import java.util.function.Predicate; import javax.annotation.Nullable; // CraftBukkit start @@ -15,23 +17,23 @@ import org.bukkit.event.player.PlayerPickupArrowEvent; public abstract class EntityArrow extends Entity implements IProjectile { - private static final Predicate g = IEntitySelector.f.and(IEntitySelector.a.and(Entity::isInteractable)); - private static final DataWatcherObject h = DataWatcher.a(EntityArrow.class, DataWatcherRegistry.a); - protected static final DataWatcherObject> a = DataWatcher.a(EntityArrow.class, DataWatcherRegistry.o); - public int tileX; - public int tileY; - public int tileZ; + private static final DataWatcherObject ar = DataWatcher.a(EntityArrow.class, DataWatcherRegistry.a); + protected static final DataWatcherObject> b = DataWatcher.a(EntityArrow.class, DataWatcherRegistry.o); + private static final DataWatcherObject as = DataWatcher.a(EntityArrow.class, DataWatcherRegistry.a); @Nullable - private IBlockData az; + private IBlockData at; public boolean inGround; - protected int c; + protected int d; public EntityArrow.PickupStatus fromPlayer; public int shake; public UUID shooter; - public int despawnCounter; // PAIL - private int aB; + public int despawnCounter; + private int av; private double damage; public int knockbackStrength; + private SoundEffect ay; + private IntOpenHashSet az; + private List aA; // Spigot Start @Override @@ -45,22 +47,19 @@ public abstract class EntityArrow extends Entity implements IProjectile { } // Spigot End - protected EntityArrow(EntityTypes entitytypes, World world) { + protected EntityArrow(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.tileX = -1; - this.tileY = -1; - this.tileZ = -1; this.fromPlayer = EntityArrow.PickupStatus.DISALLOWED; this.damage = 2.0D; - this.setSize(0.5F, 0.5F); + this.ay = this.k(); } - protected EntityArrow(EntityTypes entitytypes, double d0, double d1, double d2, World world) { + protected EntityArrow(EntityTypes entitytypes, double d0, double d1, double d2, World world) { this(entitytypes, world); this.setPosition(d0, d1, d2); } - protected EntityArrow(EntityTypes entitytypes, EntityLiving entityliving, World world) { + protected EntityArrow(EntityTypes entitytypes, EntityLiving entityliving, World world) { this(entitytypes, entityliving.locX, entityliving.locY + (double) entityliving.getHeadHeight() - 0.10000000149011612D, entityliving.locZ, world); this.setShooter(entityliving); if (entityliving instanceof EntityHuman) { @@ -69,9 +68,15 @@ public abstract class EntityArrow extends Entity implements IProjectile { } - protected void x_() { - this.datawatcher.register(EntityArrow.h, (byte) 0); - this.datawatcher.register(EntityArrow.a, Optional.empty()); + public void a(SoundEffect soundeffect) { + this.ay = soundeffect; + } + + @Override + protected void initDatawatcher() { + this.datawatcher.register(EntityArrow.ar, (byte) 0); + this.datawatcher.register(EntityArrow.b, Optional.empty()); + this.datawatcher.register(EntityArrow.as, (byte) 0); } public void a(Entity entity, float f, float f1, float f2, float f3, float f4) { @@ -80,52 +85,39 @@ public abstract class EntityArrow extends Entity implements IProjectile { float f7 = MathHelper.cos(f1 * 0.017453292F) * MathHelper.cos(f * 0.017453292F); this.shoot((double) f5, (double) f6, (double) f7, f3, f4); - this.motX += entity.motX; - this.motZ += entity.motZ; - if (!entity.onGround) { - this.motY += entity.motY; - } - + if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(entity.getMot().x, entity.onGround ? 0.0D : entity.getMot().y, entity.getMot().z)); // Paper - allow disabling relative velocity } + @Override public void shoot(double d0, double d1, double d2, float f, float f1) { - float f2 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + Vec3D vec3d = (new Vec3D(d0, d1, d2)).d().add(this.random.nextGaussian() * 0.007499999832361937D * (double) f1, this.random.nextGaussian() * 0.007499999832361937D * (double) f1, this.random.nextGaussian() * 0.007499999832361937D * (double) f1).a((double) f); - d0 /= (double) f2; - d1 /= (double) f2; - d2 /= (double) f2; - d0 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; - d1 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; - d2 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; - d0 *= (double) f; - d1 *= (double) f; - d2 *= (double) f; - this.motX = d0; - this.motY = d1; - this.motZ = d2; - float f3 = MathHelper.sqrt(d0 * d0 + d2 * d2); + this.setMot(vec3d); + float f2 = MathHelper.sqrt(b(vec3d)); - this.yaw = (float) (MathHelper.c(d0, d2) * 57.2957763671875D); - this.pitch = (float) (MathHelper.c(d1, (double) f3) * 57.2957763671875D); + this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); + this.pitch = (float) (MathHelper.d(vec3d.y, (double) f2) * 57.2957763671875D); this.lastYaw = this.yaw; this.lastPitch = this.pitch; this.despawnCounter = 0; } + @Override public void tick() { super.tick(); - boolean flag = this.q(); + boolean flag = this.v(); + Vec3D vec3d = this.getMot(); if (this.lastPitch == 0.0F && this.lastYaw == 0.0F) { - float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + float f = MathHelper.sqrt(b(vec3d)); - this.yaw = (float) (MathHelper.c(this.motX, this.motZ) * 57.2957763671875D); - this.pitch = (float) (MathHelper.c(this.motY, (double) f) * 57.2957763671875D); + this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); + this.pitch = (float) (MathHelper.d(vec3d.y, (double) f) * 57.2957763671875D); this.lastYaw = this.yaw; this.lastPitch = this.pitch; } - BlockPosition blockposition = new BlockPosition(this.tileX, this.tileY, this.tileZ); + BlockPosition blockposition = new BlockPosition(this.locX, this.locY, this.locZ); IBlockData iblockdata = this.world.getType(blockposition); if (!iblockdata.isAir() && !flag) { @@ -137,7 +129,7 @@ public abstract class EntityArrow extends Entity implements IProjectile { while (iterator.hasNext()) { AxisAlignedBB axisalignedbb = (AxisAlignedBB) iterator.next(); - if (axisalignedbb.a(blockposition).b(new Vec3D(this.locX, this.locY, this.locZ))) { + if (axisalignedbb.a(blockposition).c(new Vec3D(this.locX, this.locY, this.locZ))) { this.inGround = true; break; } @@ -149,88 +141,95 @@ public abstract class EntityArrow extends Entity implements IProjectile { --this.shake; } - if (this.ao()) { + if (this.isInWaterOrRain()) { this.extinguish(); } if (this.inGround && !flag) { - if (this.az != iblockdata && this.world.getCubes((Entity) null, this.getBoundingBox().g(0.05D))) { + if (this.at != iblockdata && this.world.c(this.getBoundingBox().g(0.06D))) { this.inGround = false; - this.motX *= (double) (this.random.nextFloat() * 0.2F); - this.motY *= (double) (this.random.nextFloat() * 0.2F); - this.motZ *= (double) (this.random.nextFloat() * 0.2F); + this.setMot(vec3d.d((double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F))); this.despawnCounter = 0; - this.aB = 0; - } else { - this.f(); + this.av = 0; + } else if (!this.world.isClientSide) { + this.i(); } - ++this.c; + ++this.d; } else { - this.c = 0; - ++this.aB; - Vec3D vec3d = new Vec3D(this.locX, this.locY, this.locZ); - Vec3D vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); - MovingObjectPosition movingobjectposition = this.world.rayTrace(vec3d, vec3d1, FluidCollisionOption.NEVER, true, false); + this.d = 0; + ++this.av; + Vec3D vec3d1 = new Vec3D(this.locX, this.locY, this.locZ); + Vec3D vec3d2 = vec3d1.e(vec3d); + Object object = this.world.rayTrace(new RayTrace(vec3d1, vec3d2, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this)); - vec3d = new Vec3D(this.locX, this.locY, this.locZ); - vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); - if (movingobjectposition != null) { - vec3d1 = new Vec3D(movingobjectposition.pos.x, movingobjectposition.pos.y, movingobjectposition.pos.z); + if (((MovingObjectPosition) object).getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { + vec3d2 = ((MovingObjectPosition) object).getPos(); } - Entity entity = this.a(vec3d, vec3d1); + while (!this.dead) { + MovingObjectPositionEntity movingobjectpositionentity = this.a(vec3d1, vec3d2); - if (entity != null) { - movingobjectposition = new MovingObjectPosition(entity); - } - - if (movingobjectposition != null && movingobjectposition.entity instanceof EntityHuman) { - EntityHuman entityhuman = (EntityHuman) movingobjectposition.entity; - Entity entity1 = this.getShooter(); - - if (entity1 instanceof EntityHuman && !((EntityHuman) entity1).a(entityhuman)) { - movingobjectposition = null; + if (movingobjectpositionentity != null) { + object = movingobjectpositionentity; } - } - // Paper start - Call ProjectileCollideEvent - // TODO: flag - noclip - call cancelled? - if (movingobjectposition != null && movingobjectposition.entity != null) { - com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, movingobjectposition); - if (event.isCancelled()) { - movingobjectposition = null; + if (object != null && ((MovingObjectPosition) object).getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + Entity entity = ((MovingObjectPositionEntity) object).getEntity(); + Entity entity1 = this.getShooter(); + + if (entity instanceof EntityHuman && entity1 instanceof EntityHuman && !((EntityHuman) entity1).a((EntityHuman) entity)) { + object = null; + movingobjectpositionentity = null; + } } - } - // Paper end - if (movingobjectposition != null && !flag) { - this.a(movingobjectposition); - this.impulse = true; + // Paper start - Call ProjectileCollideEvent + // TODO: flag - noclip - call cancelled? + if (object instanceof MovingObjectPositionEntity) { + com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, (MovingObjectPositionEntity)object); + if (event.isCancelled()) { + object = null; + movingobjectpositionentity = null; + } + } + // Paper end + + if (object != null && !flag) { + this.a((MovingObjectPosition) object); + this.impulse = true; + } + + if (movingobjectpositionentity == null || this.getPierceLevel() <= 0) { + break; + } + + object = null; } - // Akarin start - this handle by client - /* + vec3d = this.getMot(); + double d0 = vec3d.x; + double d1 = vec3d.y; + double d2 = vec3d.z; + if (this.isCritical()) { for (int i = 0; i < 4; ++i) { - this.world.addParticle(Particles.h, this.locX + this.motX * (double) i / 4.0D, this.locY + this.motY * (double) i / 4.0D, this.locZ + this.motZ * (double) i / 4.0D, -this.motX, -this.motY + 0.2D, -this.motZ); + this.world.addParticle(Particles.CRIT, this.locX + d0 * (double) i / 4.0D, this.locY + d1 * (double) i / 4.0D, this.locZ + d2 * (double) i / 4.0D, -d0, -d1 + 0.2D, -d2); } } - */ - // Akarin end - this.locX += this.motX; - this.locY += this.motY; - this.locZ += this.motZ; - float f1 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + this.locX += d0; + this.locY += d1; + this.locZ += d2; + float f1 = MathHelper.sqrt(b(vec3d)); if (flag) { - this.yaw = (float) (MathHelper.c(-this.motX, -this.motZ) * 57.2957763671875D); + this.yaw = (float) (MathHelper.d(-d0, -d2) * 57.2957763671875D); } else { - this.yaw = (float) (MathHelper.c(this.motX, this.motZ) * 57.2957763671875D); + this.yaw = (float) (MathHelper.d(d0, d2) * 57.2957763671875D); } - for (this.pitch = (float) (MathHelper.c(this.motY, (double) f1) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + for (this.pitch = (float) (MathHelper.d(d1, (double) f1) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { ; } @@ -246,30 +245,26 @@ public abstract class EntityArrow extends Entity implements IProjectile { this.lastYaw += 360.0F; } - this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; - this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; + this.pitch = MathHelper.g(0.2F, this.lastPitch, this.pitch); + this.yaw = MathHelper.g(0.2F, this.lastYaw, this.yaw); float f2 = 0.99F; float f3 = 0.05F; if (this.isInWater()) { - // Akarin start - this handle by client - /* for (int j = 0; j < 4; ++j) { float f4 = 0.25F; - this.world.addParticle(Particles.e, this.locX - this.motX * 0.25D, this.locY - this.motY * 0.25D, this.locZ - this.motZ * 0.25D, this.motX, this.motY, this.motZ); + this.world.addParticle(Particles.BUBBLE, this.locX - d0 * 0.25D, this.locY - d1 * 0.25D, this.locZ - d2 * 0.25D, d0, d1, d2); } - */ - // Akarin end - f2 = this.p(); + f2 = this.u(); } - this.motX *= (double) f2; - this.motY *= (double) f2; - this.motZ *= (double) f2; + this.setMot(vec3d.a((double) f2)); if (!this.isNoGravity() && !flag) { - this.motY -= 0.05000000074505806D; + Vec3D vec3d3 = this.getMot(); + + this.setMot(vec3d3.x, vec3d3.y - 0.05000000074505806D, vec3d3.z); } this.setPosition(this.locX, this.locY, this.locZ); @@ -277,7 +272,7 @@ public abstract class EntityArrow extends Entity implements IProjectile { } } - protected void f() { + protected void i() { ++this.despawnCounter; if (this.despawnCounter >= (fromPlayer == PickupStatus.CREATIVE_ONLY ? world.paperConfig.creativeArrowDespawnRate : (fromPlayer == PickupStatus.DISALLOWED ? world.paperConfig.nonPlayerArrowDespawnRate : world.spigotConfig.arrowDespawnRate))) { // Spigot // Paper this.die(); @@ -287,40 +282,68 @@ public abstract class EntityArrow extends Entity implements IProjectile { protected void a(MovingObjectPosition movingobjectposition) { org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition); // CraftBukkit - Call event - if (movingobjectposition.entity != null) { - this.b(movingobjectposition); - } else { - BlockPosition blockposition = movingobjectposition.getBlockPosition(); + MovingObjectPosition.EnumMovingObjectType movingobjectposition_enummovingobjecttype = movingobjectposition.getType(); - this.tileX = blockposition.getX(); - this.tileY = blockposition.getY(); - this.tileZ = blockposition.getZ(); - IBlockData iblockdata = this.world.getType(blockposition); + if (movingobjectposition_enummovingobjecttype == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + this.a((MovingObjectPositionEntity) movingobjectposition); + } else if (movingobjectposition_enummovingobjecttype == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + MovingObjectPositionBlock movingobjectpositionblock = (MovingObjectPositionBlock) movingobjectposition; + IBlockData iblockdata = this.world.getType(movingobjectpositionblock.getBlockPosition()); - this.az = iblockdata; - this.motX = (double) ((float) (movingobjectposition.pos.x - this.locX)); - this.motY = (double) ((float) (movingobjectposition.pos.y - this.locY)); - this.motZ = (double) ((float) (movingobjectposition.pos.z - this.locZ)); - float f = MathHelper.sqrt(this.motX * this.motX + this.motY * this.motY + this.motZ * this.motZ) * 20.0F; + this.at = iblockdata; + Vec3D vec3d = movingobjectpositionblock.getPos().a(this.locX, this.locY, this.locZ); - this.locX -= this.motX / (double) f; - this.locY -= this.motY / (double) f; - this.locZ -= this.motZ / (double) f; - this.a(this.i(), 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F)); + this.setMot(vec3d); + Vec3D vec3d1 = vec3d.d().a(0.05000000074505806D); + + this.locX -= vec3d1.x; + this.locY -= vec3d1.y; + this.locZ -= vec3d1.z; + this.a(this.getSoundHit(), 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F)); this.inGround = true; this.shake = 7; this.setCritical(false); - if (!iblockdata.isAir()) { - this.az.a(this.world, blockposition, (Entity) this); - } + this.setPierceLevel((byte) 0); + this.a(SoundEffects.ENTITY_ARROW_HIT); + this.o(false); + this.w(); + iblockdata.a(this.world, iblockdata, movingobjectpositionblock, this); } } - protected void b(MovingObjectPosition movingobjectposition) { - Entity entity = movingobjectposition.entity; - float f = MathHelper.sqrt(this.motX * this.motX + this.motY * this.motY + this.motZ * this.motZ); - int i = MathHelper.f((double) f * this.damage); + private void w() { + if (this.aA != null) { + this.aA.clear(); + } + + if (this.az != null) { + this.az.clear(); + } + + } + + protected void a(MovingObjectPositionEntity movingobjectpositionentity) { + Entity entity = movingobjectpositionentity.getEntity(); + float f = (float) this.getMot().f(); + int i = MathHelper.f(Math.max((double) f * this.damage, 0.0D)); + + if (this.getPierceLevel() > 0) { + if (this.az == null) { + this.az = new IntOpenHashSet(5); + } + + if (this.aA == null) { + this.aA = Lists.newArrayListWithCapacity(5); + } + + if (this.az.size() >= this.getPierceLevel() + 1) { + this.die(); + return; + } + + this.az.add(entity.getId()); + } if (this.isCritical()) { i += this.random.nextInt(i / 2 + 2); @@ -333,8 +356,13 @@ public abstract class EntityArrow extends Entity implements IProjectile { damagesource = DamageSource.arrow(this, this); } else { damagesource = DamageSource.arrow(this, entity1); + if (entity1 instanceof EntityLiving) { + ((EntityLiving) entity1).z(entity); + } } + int j = entity.ad(); + if (this.isBurning() && !(entity instanceof EntityEnderman)) { // CraftBukkit start EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 5); @@ -349,19 +377,19 @@ public abstract class EntityArrow extends Entity implements IProjectile { if (entity instanceof EntityLiving) { EntityLiving entityliving = (EntityLiving) entity; - if (!this.world.isClientSide) { + if (!this.world.isClientSide && this.getPierceLevel() <= 0) { entityliving.setArrowCount(entityliving.getArrowCount() + 1); } if (this.knockbackStrength > 0) { - float f1 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + Vec3D vec3d = this.getMot().d(1.0D, 0.0D, 1.0D).d().a((double) this.knockbackStrength * 0.6D); - if (f1 > 0.0F) { - entityliving.f(this.motX * (double) this.knockbackStrength * 0.6000000238418579D / (double) f1, 0.1D, this.motZ * (double) this.knockbackStrength * 0.6000000238418579D / (double) f1); + if (vec3d.g() > 0.0D) { + entityliving.f(vec3d.x, 0.1D, vec3d.z); } } - if (entity1 instanceof EntityLiving) { + if (!this.world.isClientSide && entity1 instanceof EntityLiving) { EnchantmentManager.a(entityliving, entity1); EnchantmentManager.b((EntityLiving) entity1, (Entity) entityliving); } @@ -370,20 +398,33 @@ public abstract class EntityArrow extends Entity implements IProjectile { if (entity1 != null && entityliving != entity1 && entityliving instanceof EntityHuman && entity1 instanceof EntityPlayer) { ((EntityPlayer) entity1).playerConnection.sendPacket(new PacketPlayOutGameStateChange(6, 0.0F)); } + + if (!entity.isAlive() && this.aA != null) { + this.aA.add(entityliving); + } + + if (!this.world.isClientSide && entity1 instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entity1; + + if (this.aA != null && this.r()) { + CriterionTriggers.G.a(entityplayer, this.aA, this.aA.size()); + } else if (!entity.isAlive() && this.r()) { + CriterionTriggers.G.a(entityplayer, Arrays.asList(entity), 0); + } + } } - this.a(SoundEffects.ENTITY_ARROW_HIT, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F)); - if (!(entity instanceof EntityEnderman)) { + this.a(this.ay, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F)); + if (this.getPierceLevel() <= 0 && !(entity instanceof EntityEnderman)) { this.die(); } } else { - this.motX *= -0.10000000149011612D; - this.motY *= -0.10000000149011612D; - this.motZ *= -0.10000000149011612D; + entity.g(j); + this.setMot(this.getMot().a(-0.1D)); this.yaw += 180.0F; this.lastYaw += 180.0F; - this.aB = 0; - if (!this.world.isClientSide && this.motX * this.motX + this.motY * this.motY + this.motZ * this.motZ < 0.0010000000474974513D) { + this.av = 0; + if (!this.world.isClientSide && this.getMot().g() < 1.0E-7D) { if (this.fromPlayer == EntityArrow.PickupStatus.ALLOWED) { this.a(this.getItemStack(), 0.1F); } @@ -394,56 +435,28 @@ public abstract class EntityArrow extends Entity implements IProjectile { } - protected SoundEffect i() { + protected SoundEffect k() { return SoundEffects.ENTITY_ARROW_HIT; } - public void move(EnumMoveType enummovetype, double d0, double d1, double d2) { - super.move(enummovetype, d0, d1, d2); - if (this.inGround) { - this.tileX = MathHelper.floor(this.locX); - this.tileY = MathHelper.floor(this.locY); - this.tileZ = MathHelper.floor(this.locZ); - } - + protected final SoundEffect getSoundHit() { + return this.ay; } protected void a(EntityLiving entityliving) {} @Nullable - protected Entity a(Vec3D vec3d, Vec3D vec3d1) { - Entity entity = null; - List list = this.world.getEntities(this, this.getBoundingBox().b(this.motX, this.motY, this.motZ).g(1.0D), EntityArrow.g); - double d0 = 0.0D; - - for (int i = 0; i < list.size(); ++i) { - Entity entity1 = (Entity) list.get(i); - - if (entity1 != this.getShooter() || this.aB >= 5) { - AxisAlignedBB axisalignedbb = entity1.getBoundingBox().g(0.30000001192092896D); - MovingObjectPosition movingobjectposition = axisalignedbb.b(vec3d, vec3d1); - - if (movingobjectposition != null) { - double d1 = vec3d.distanceSquared(movingobjectposition.pos); - - if (d1 < d0 || d0 == 0.0D) { - entity = entity1; - d0 = d1; - } - } - } - } - - return entity; + protected MovingObjectPositionEntity a(Vec3D vec3d, Vec3D vec3d1) { + return ProjectileHelper.a(this.world, this, vec3d, vec3d1, this.getBoundingBox().a(this.getMot()).g(1.0D), (entity) -> { + return !entity.isSpectator() && entity.isAlive() && entity.isInteractable() && (entity != this.getShooter() || this.av >= 5) && (this.az == null || !this.az.contains(entity.getId())); + }); } + @Override public void b(NBTTagCompound nbttagcompound) { - nbttagcompound.setInt("xTile", this.tileX); - nbttagcompound.setInt("yTile", this.tileY); - nbttagcompound.setInt("zTile", this.tileZ); nbttagcompound.setShort("life", (short) this.despawnCounter); - if (this.az != null) { - nbttagcompound.set("inBlockState", GameProfileSerializer.a(this.az)); + if (this.at != null) { + nbttagcompound.set("inBlockState", GameProfileSerializer.a(this.at)); } nbttagcompound.setByte("shake", (byte) this.shake); @@ -451,19 +464,20 @@ public abstract class EntityArrow extends Entity implements IProjectile { nbttagcompound.setByte("pickup", (byte) this.fromPlayer.ordinal()); nbttagcompound.setDouble("damage", this.damage); nbttagcompound.setBoolean("crit", this.isCritical()); + nbttagcompound.setByte("PierceLevel", this.getPierceLevel()); if (this.shooter != null) { nbttagcompound.a("OwnerUUID", this.shooter); } + nbttagcompound.setString("SoundEvent", IRegistry.SOUND_EVENT.getKey(this.ay).toString()); + nbttagcompound.setBoolean("ShotFromCrossbow", this.r()); } + @Override public void a(NBTTagCompound nbttagcompound) { - this.tileX = nbttagcompound.getInt("xTile"); - this.tileY = nbttagcompound.getInt("yTile"); - this.tileZ = nbttagcompound.getInt("zTile"); this.despawnCounter = nbttagcompound.getShort("life"); if (nbttagcompound.hasKeyOfType("inBlockState", 10)) { - this.az = GameProfileSerializer.d(nbttagcompound.getCompound("inBlockState")); + this.at = GameProfileSerializer.d(nbttagcompound.getCompound("inBlockState")); } this.shake = nbttagcompound.getByte("shake") & 255; @@ -479,15 +493,25 @@ public abstract class EntityArrow extends Entity implements IProjectile { } this.setCritical(nbttagcompound.getBoolean("crit")); + this.setPierceLevel(nbttagcompound.getByte("PierceLevel")); if (nbttagcompound.b("OwnerUUID")) { this.shooter = nbttagcompound.a("OwnerUUID"); } + if (nbttagcompound.hasKeyOfType("SoundEvent", 8)) { + this.ay = (SoundEffect) IRegistry.SOUND_EVENT.getOptional(new MinecraftKey(nbttagcompound.getString("SoundEvent"))).orElse(this.k()); + } + + this.o(nbttagcompound.getBoolean("ShotFromCrossbow")); } public void setShooter(@Nullable Entity entity) { this.shooter = entity == null ? null : entity.getUniqueID(); this.projectileSource = entity == null ? null : (LivingEntity) entity.getBukkitEntity(); // CraftBukkit + if (entity instanceof EntityHuman) { + this.fromPlayer = ((EntityHuman) entity).abilities.canInstantlyBuild ? EntityArrow.PickupStatus.CREATIVE_ONLY : EntityArrow.PickupStatus.ALLOWED; + } + } @Nullable @@ -495,13 +519,14 @@ public abstract class EntityArrow extends Entity implements IProjectile { return this.shooter != null && this.world instanceof WorldServer ? ((WorldServer) this.world).getEntity(this.shooter) : null; } - public void d(EntityHuman entityhuman) { - if (!this.world.isClientSide && (this.inGround || this.q()) && this.shake <= 0) { + @Override + public void pickup(EntityHuman entityhuman) { + if (!this.world.isClientSide && (this.inGround || this.v()) && this.shake <= 0) { // CraftBukkit start ItemStack itemstack = this.getItemStack(); if (this.fromPlayer == PickupStatus.ALLOWED && !itemstack.isEmpty() && entityhuman.inventory.canHold(itemstack) > 0) { EntityItem item = new EntityItem(this.world, this.locX, this.locY, this.locZ, itemstack); - PlayerPickupArrowEvent event = new PlayerPickupArrowEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), new org.bukkit.craftbukkit.entity.CraftItem(this.world.getServer(), this, item), (org.bukkit.entity.Arrow) this.getBukkitEntity()); + PlayerPickupArrowEvent event = new PlayerPickupArrowEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), new org.bukkit.craftbukkit.entity.CraftItem(this.world.getServer(), this, item), (org.bukkit.entity.AbstractArrow) this.getBukkitEntity()); // event.setCancelled(!entityhuman.canPickUpLoot); TODO this.world.getServer().getPluginManager().callEvent(event); @@ -510,7 +535,7 @@ public abstract class EntityArrow extends Entity implements IProjectile { } itemstack = item.getItemStack(); } - boolean flag = this.fromPlayer == EntityArrow.PickupStatus.ALLOWED || this.fromPlayer == EntityArrow.PickupStatus.CREATIVE_ONLY && entityhuman.abilities.canInstantlyBuild || this.q() && this.getShooter().getUniqueID() == entityhuman.getUniqueID(); + boolean flag = this.fromPlayer == EntityArrow.PickupStatus.ALLOWED || this.fromPlayer == EntityArrow.PickupStatus.CREATIVE_ONLY && entityhuman.abilities.canInstantlyBuild || this.v() && this.getShooter().getUniqueID() == entityhuman.getUniqueID(); if (this.fromPlayer == EntityArrow.PickupStatus.ALLOWED && !entityhuman.inventory.pickup(itemstack)) { // CraftBukkit end @@ -527,6 +552,7 @@ public abstract class EntityArrow extends Entity implements IProjectile { protected abstract ItemStack getItemStack(); + @Override protected boolean playStepSound() { return false; } @@ -543,11 +569,13 @@ public abstract class EntityArrow extends Entity implements IProjectile { this.knockbackStrength = i; } - public boolean bk() { + @Override + public boolean bs() { return false; } - public float getHeadHeight() { + @Override + protected float getHeadHeight(EntityPose entitypose, EntitySize entitysize) { return 0.0F; } @@ -555,23 +583,37 @@ public abstract class EntityArrow extends Entity implements IProjectile { this.a(1, flag); } + public void setPierceLevel(byte b0) { + this.datawatcher.set(EntityArrow.as, b0); + } + private void a(int i, boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntityArrow.h); + byte b0 = (Byte) this.datawatcher.get(EntityArrow.ar); if (flag) { - this.datawatcher.set(EntityArrow.h, (byte) (b0 | i)); + this.datawatcher.set(EntityArrow.ar, (byte) (b0 | i)); } else { - this.datawatcher.set(EntityArrow.h, (byte) (b0 & ~i)); + this.datawatcher.set(EntityArrow.ar, (byte) (b0 & ~i)); } } public boolean isCritical() { - byte b0 = (Byte) this.datawatcher.get(EntityArrow.h); + byte b0 = (Byte) this.datawatcher.get(EntityArrow.ar); return (b0 & 1) != 0; } + public boolean r() { + byte b0 = (Byte) this.datawatcher.get(EntityArrow.ar); + + return (b0 & 4) != 0; + } + + public byte getPierceLevel() { + return (Byte) this.datawatcher.get(EntityArrow.as); + } + public void a(EntityLiving entityliving, float f) { int i = EnchantmentManager.a(Enchantments.ARROW_DAMAGE, entityliving); int j = EnchantmentManager.a(Enchantments.ARROW_KNOCKBACK, entityliving); @@ -591,17 +633,28 @@ public abstract class EntityArrow extends Entity implements IProjectile { } - protected float p() { + protected float u() { return 0.6F; } - public void o(boolean flag) { + public void n(boolean flag) { this.noclip = flag; this.a(2, flag); } - public boolean q() { - return !this.world.isClientSide ? this.noclip : ((Byte) this.datawatcher.get(EntityArrow.h) & 2) != 0; + public boolean v() { + return !this.world.isClientSide ? this.noclip : ((Byte) this.datawatcher.get(EntityArrow.ar) & 2) != 0; + } + + public void o(boolean flag) { + this.a(4, flag); + } + + @Override + public Packet N() { + Entity entity = this.getShooter(); + + return new PacketPlayOutSpawnEntity(this, entity == null ? 0 : entity.getId()); } public static enum PickupStatus { diff --git a/src/main/java/net/minecraft/server/EntityBat.java b/src/main/java/net/minecraft/server/EntityBat.java index 766154435..72474211b 100644 --- a/src/main/java/net/minecraft/server/EntityBat.java +++ b/src/main/java/net/minecraft/server/EntityBat.java @@ -2,99 +2,110 @@ package net.minecraft.server; import java.time.LocalDate; import java.time.temporal.ChronoField; +import java.util.Random; import javax.annotation.Nullable; import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class EntityBat extends EntityAmbient { - private static final DataWatcherObject a = DataWatcher.a(EntityBat.class, DataWatcherRegistry.a); - private BlockPosition b; + private static final DataWatcherObject b = DataWatcher.a(EntityBat.class, DataWatcherRegistry.a); + private static final PathfinderTargetCondition c = (new PathfinderTargetCondition()).a(4.0D).b(); + private BlockPosition d; - public EntityBat(World world) { - super(EntityTypes.BAT, world); - this.setSize(0.5F, 0.9F); + public EntityBat(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.setAsleep(true); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityBat.a, (byte) 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityBat.b, (byte) 0); } - protected float cD() { + @Override + protected float getSoundVolume() { return 0.1F; } - protected float cE() { - return super.cE() * 0.95F; + @Override + protected float cV() { + return super.cV() * 0.95F; } @Nullable - public SoundEffect D() { + @Override + public SoundEffect getSoundAmbient() { return this.isAsleep() && this.random.nextInt(4) != 0 ? null : SoundEffects.ENTITY_BAT_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_BAT_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_BAT_DEATH; } + @Override public boolean isCollidable() { return false; } - protected void C(Entity entity) {} + @Override + protected void D(Entity entity) {} - protected void cN() {} + @Override + protected void collideNearby() {} + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(6.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(6.0D); } public boolean isAsleep() { - return ((Byte) this.datawatcher.get(EntityBat.a) & 1) != 0; + return ((Byte) this.datawatcher.get(EntityBat.b) & 1) != 0; } public void setAsleep(boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntityBat.a); + byte b0 = (Byte) this.datawatcher.get(EntityBat.b); if (flag) { - this.datawatcher.set(EntityBat.a, (byte) (b0 | 1)); + this.datawatcher.set(EntityBat.b, (byte) (b0 | 1)); } else { - this.datawatcher.set(EntityBat.a, (byte) (b0 & -2)); + this.datawatcher.set(EntityBat.b, (byte) (b0 & -2)); } } + @Override public void tick() { super.tick(); if (this.isAsleep()) { - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; - this.locY = (double) MathHelper.floor(this.locY) + 1.0D - (double) this.length; + this.setMot(Vec3D.a); + this.locY = (double) MathHelper.floor(this.locY) + 1.0D - (double) this.getHeight(); } else { - this.motY *= 0.6000000238418579D; + this.setMot(this.getMot().d(1.0D, 0.6D, 1.0D)); } } + @Override protected void mobTick() { super.mobTick(); BlockPosition blockposition = new BlockPosition(this); BlockPosition blockposition1 = blockposition.up(); if (this.isAsleep()) { - if (this.world.getType(blockposition1).isOccluding()) { + if (this.world.getType(blockposition1).isOccluding(this.world, blockposition)) { if (this.random.nextInt(200) == 0) { - this.aS = (float) this.random.nextInt(360); + this.aM = (float) this.random.nextInt(360); } - if (this.world.b(this, 4.0D) != null) { + if (this.world.a(EntityBat.c, (EntityLiving) this) != null) { // CraftBukkit Start - Call BatToggleSleepEvent if (CraftEventFactory.handleBatToggleSleepEvent(this, true)) { this.setAsleep(false); @@ -111,27 +122,27 @@ public class EntityBat extends EntityAmbient { // CraftBukkit End - Call BatToggleSleepEvent } } else { - if (this.b != null && (!this.world.isEmpty(this.b) || this.b.getY() < 1)) { - this.b = null; + if (this.d != null && (!this.world.isEmpty(this.d) || this.d.getY() < 1)) { + this.d = null; } - if (this.b == null || this.random.nextInt(30) == 0 || this.b.distanceSquared((double) ((int) this.locX), (double) ((int) this.locY), (double) ((int) this.locZ)) < 4.0D) { - this.b = new BlockPosition((int) this.locX + this.random.nextInt(7) - this.random.nextInt(7), (int) this.locY + this.random.nextInt(6) - 2, (int) this.locZ + this.random.nextInt(7) - this.random.nextInt(7)); + if (this.d == null || this.random.nextInt(30) == 0 || this.d.a((IPosition) this.getPositionVector(), 2.0D)) { + this.d = new BlockPosition(this.locX + (double) this.random.nextInt(7) - (double) this.random.nextInt(7), this.locY + (double) this.random.nextInt(6) - 2.0D, this.locZ + (double) this.random.nextInt(7) - (double) this.random.nextInt(7)); } - double d0 = (double) this.b.getX() + 0.5D - this.locX; - double d1 = (double) this.b.getY() + 0.1D - this.locY; - double d2 = (double) this.b.getZ() + 0.5D - this.locZ; + double d0 = (double) this.d.getX() + 0.5D - this.locX; + double d1 = (double) this.d.getY() + 0.1D - this.locY; + double d2 = (double) this.d.getZ() + 0.5D - this.locZ; + Vec3D vec3d = this.getMot(); + Vec3D vec3d1 = vec3d.add((Math.signum(d0) * 0.5D - vec3d.x) * 0.10000000149011612D, (Math.signum(d1) * 0.699999988079071D - vec3d.y) * 0.10000000149011612D, (Math.signum(d2) * 0.5D - vec3d.z) * 0.10000000149011612D); - this.motX += (Math.signum(d0) * 0.5D - this.motX) * 0.10000000149011612D; - this.motY += (Math.signum(d1) * 0.699999988079071D - this.motY) * 0.10000000149011612D; - this.motZ += (Math.signum(d2) * 0.5D - this.motZ) * 0.10000000149011612D; - float f = (float) (MathHelper.c(this.motZ, this.motX) * 57.2957763671875D) - 90.0F; + this.setMot(vec3d1); + float f = (float) (MathHelper.d(vec3d1.z, vec3d1.x) * 57.2957763671875D) - 90.0F; float f1 = MathHelper.g(f - this.yaw); - this.bj = 0.5F; + this.bd = 0.5F; this.yaw += f1; - if (this.random.nextInt(100) == 0 && this.world.getType(blockposition1).isOccluding()) { + if (this.random.nextInt(100) == 0 && this.world.getType(blockposition1).isOccluding(this.world, blockposition1)) { // CraftBukkit Start - Call BatToggleSleepEvent if (CraftEventFactory.handleBatToggleSleepEvent(this, false)) { this.setAsleep(true); @@ -142,18 +153,23 @@ public class EntityBat extends EntityAmbient { } + @Override protected boolean playStepSound() { return false; } - public void c(float f, float f1) {} + @Override + public void b(float f, float f1) {} + @Override protected void a(double d0, boolean flag, IBlockData iblockdata, BlockPosition blockposition) {} + @Override public boolean isIgnoreBlockTrigger() { return true; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -170,36 +186,36 @@ public class EntityBat extends EntityAmbient { } } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.datawatcher.set(EntityBat.a, nbttagcompound.getByte("BatFlags")); + this.datawatcher.set(EntityBat.b, nbttagcompound.getByte("BatFlags")); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setByte("BatFlags", (Byte) this.datawatcher.get(EntityBat.a)); + nbttagcompound.setByte("BatFlags", (Byte) this.datawatcher.get(EntityBat.b)); } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - BlockPosition blockposition = new BlockPosition(this.locX, this.getBoundingBox().minY, this.locZ); - + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { if (blockposition.getY() >= generatoraccess.getSeaLevel()) { return false; } else { int i = generatoraccess.getLightLevel(blockposition); byte b0 = 4; - if (this.dr()) { + if (dT()) { b0 = 7; - } else if (this.random.nextBoolean()) { + } else if (random.nextBoolean()) { return false; } - return i > this.random.nextInt(b0) ? false : super.a(generatoraccess, flag); + return i > random.nextInt(b0) ? false : a(entitytypes, generatoraccess, enummobspawn, blockposition, random); } } - private boolean dr() { + private static boolean dT() { LocalDate localdate = LocalDate.now(); int i = localdate.get(ChronoField.DAY_OF_MONTH); int j = localdate.get(ChronoField.MONTH_OF_YEAR); @@ -207,12 +223,8 @@ public class EntityBat extends EntityAmbient { return j == 10 && i >= 20 || j == 11 && i <= 3; } - public float getHeadHeight() { - return this.length / 2.0F; - } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.an; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height / 2.0F; } } diff --git a/src/main/java/net/minecraft/server/EntityBoat.java b/src/main/java/net/minecraft/server/EntityBoat.java index e4e3ef87d..32b7f7805 100644 --- a/src/main/java/net/minecraft/server/EntityBoat.java +++ b/src/main/java/net/minecraft/server/EntityBoat.java @@ -14,37 +14,37 @@ import org.bukkit.event.vehicle.VehicleMoveEvent; public class EntityBoat extends Entity { - private static final DataWatcherObject a = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.b); private static final DataWatcherObject b = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.b); - private static final DataWatcherObject c = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.c); - private static final DataWatcherObject d = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.b); - private static final DataWatcherObject e = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.i); + private static final DataWatcherObject c = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.b); + private static final DataWatcherObject d = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.c); + private static final DataWatcherObject e = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.b); private static final DataWatcherObject f = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.i); - private static final DataWatcherObject g = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.b); - private final float[] h; - private float aw; - private float ax; - private float ay; - private int az; + private static final DataWatcherObject g = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.i); + private static final DataWatcherObject ar = DataWatcher.a(EntityBoat.class, DataWatcherRegistry.b); + private final float[] as; + private float at; + private float au; + private float av; + private int aw; + private double ax; + private double ay; + private double az; private double aA; private double aB; - private double aC; - private double aD; - private double aE; + private boolean aC; + private boolean aD; + private boolean aE; private boolean aF; - private boolean aG; - private boolean aH; - private boolean aI; - private double aJ; - private float aK; - private EntityBoat.EnumStatus aL; - private EntityBoat.EnumStatus aM; - private double aN; - private boolean aO; - private boolean aP; - private float aQ; - private float aR; - private float aS; + private double aG; + private float aH; + private EntityBoat.EnumStatus aI; + private EntityBoat.EnumStatus aJ; + private double aK; + private boolean aL; + private boolean aM; + private float aN; + private float aO; + private float aP; // CraftBukkit start // PAIL: Some of these haven't worked since a few updates, and since 1.9 they are less and less applicable. @@ -54,56 +54,60 @@ public class EntityBoat extends Entity { public boolean landBoats = false; // CraftBukkit end - public EntityBoat(World world) { - super(EntityTypes.BOAT, world); - this.h = new float[2]; - this.j = true; - this.setSize(1.375F, 0.5625F); + public EntityBoat(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.as = new float[2]; + this.i = true; } public EntityBoat(World world, double d0, double d1, double d2) { - this(world); + this(EntityTypes.BOAT, world); this.setPosition(d0, d1, d2); - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; + this.setMot(Vec3D.a); this.lastX = d0; this.lastY = d1; this.lastZ = d2; } + @Override protected boolean playStepSound() { return false; } - protected void x_() { - this.datawatcher.register(EntityBoat.a, 0); - this.datawatcher.register(EntityBoat.b, 1); - this.datawatcher.register(EntityBoat.c, 0.0F); - this.datawatcher.register(EntityBoat.d, EntityBoat.EnumBoatType.OAK.ordinal()); - this.datawatcher.register(EntityBoat.e, false); + @Override + protected void initDatawatcher() { + this.datawatcher.register(EntityBoat.b, 0); + this.datawatcher.register(EntityBoat.c, 1); + this.datawatcher.register(EntityBoat.d, 0.0F); + this.datawatcher.register(EntityBoat.e, EntityBoat.EnumBoatType.OAK.ordinal()); this.datawatcher.register(EntityBoat.f, false); - this.datawatcher.register(EntityBoat.g, 0); + this.datawatcher.register(EntityBoat.g, false); + this.datawatcher.register(EntityBoat.ar, 0); } @Nullable + @Override public AxisAlignedBB j(Entity entity) { return entity.isCollidable() ? entity.getBoundingBox() : null; } @Nullable - public AxisAlignedBB al() { + @Override + public AxisAlignedBB aq() { return this.getBoundingBox(); } + @Override public boolean isCollidable() { return true; } - public double aJ() { + @Override + public double aP() { return -0.1D; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -126,11 +130,11 @@ public class EntityBoat extends Entity { this.c(-this.o()); this.b(10); - this.setDamage(this.m() + f * 10.0F); - this.aA(); + this.setDamage(this.getDamage() + f * 10.0F); + this.velocityChanged(); boolean flag = damagesource.getEntity() instanceof EntityHuman && ((EntityHuman) damagesource.getEntity()).abilities.canInstantlyBuild; - if (flag || this.m() > 40.0F) { + if (flag || this.getDamage() > 40.0F) { // CraftBukkit start VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker); this.world.getServer().getPluginManager().callEvent(destroyEvent); @@ -140,7 +144,7 @@ public class EntityBoat extends Entity { return true; } // CraftBukkit end - if (!flag && this.world.getGameRules().getBoolean("doEntityDrops")) { + if (!flag && this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { this.a((IMaterial) this.f()); } @@ -154,22 +158,24 @@ public class EntityBoat extends Entity { } } + @Override public void j(boolean flag) { if (!this.world.isClientSide) { - this.aO = true; - this.aP = flag; - if (this.z() == 0) { + this.aL = true; + this.aM = flag; + if (this.A() == 0) { this.d(60); } } - //this.world.addParticle(Particles.R, this.locX + (double) this.random.nextFloat(), this.locY + 0.7D, this.locZ + (double) this.random.nextFloat(), 0.0D, 0.0D, 0.0D); // Akarin - this handle by client + this.world.addParticle(Particles.SPLASH, this.locX + (double) this.random.nextFloat(), this.locY + 0.7D, this.locZ + (double) this.random.nextFloat(), 0.0D, 0.0D, 0.0D); if (this.random.nextInt(20) == 0) { - this.world.a(this.locX, this.locY, this.locZ, this.ae(), this.bV(), 1.0F, 0.8F + 0.4F * this.random.nextFloat(), false); + this.world.a(this.locX, this.locY, this.locZ, this.getSoundSplash(), this.getSoundCategory(), 1.0F, 0.8F + 0.4F * this.random.nextFloat(), false); } } + @Override public void collide(Entity entity) { if (entity instanceof EntityBoat) { if (entity.getBoundingBox().minY < this.getBoundingBox().maxY) { @@ -199,41 +205,44 @@ public class EntityBoat extends Entity { public Item f() { switch (this.getType()) { - case OAK: - default: - return Items.OAK_BOAT; - case SPRUCE: - return Items.SPRUCE_BOAT; - case BIRCH: - return Items.BIRCH_BOAT; - case JUNGLE: - return Items.JUNGLE_BOAT; - case ACACIA: - return Items.ACACIA_BOAT; - case DARK_OAK: - return Items.DARK_OAK_BOAT; + case OAK: + default: + return Items.OAK_BOAT; + case SPRUCE: + return Items.SPRUCE_BOAT; + case BIRCH: + return Items.BIRCH_BOAT; + case JUNGLE: + return Items.JUNGLE_BOAT; + case ACACIA: + return Items.ACACIA_BOAT; + case DARK_OAK: + return Items.DARK_OAK_BOAT; } } + @Override public boolean isInteractable() { return !this.dead; } + @Override public EnumDirection getAdjustedDirection() { return this.getDirection().e(); } private Location lastLocation; // CraftBukkit + @Override public void tick() { - this.aM = this.aL; - this.aL = this.s(); - if (this.aL != EntityBoat.EnumStatus.UNDER_WATER && this.aL != EntityBoat.EnumStatus.UNDER_FLOWING_WATER) { - this.ax = 0.0F; + this.aJ = this.aI; + this.aI = this.s(); + if (this.aI != EntityBoat.EnumStatus.UNDER_WATER && this.aI != EntityBoat.EnumStatus.UNDER_FLOWING_WATER) { + this.au = 0.0F; } else { - ++this.ax; + ++this.au; } - if (!this.world.isClientSide && this.ax >= 60.0F) { + if (!this.world.isClientSide && this.au >= 60.0F) { this.ejectPassengers(); } @@ -241,8 +250,8 @@ public class EntityBoat extends Entity { this.b(this.n() - 1); } - if (this.m() > 0.0F) { - this.setDamage(this.m() - 1.0F); + if (this.getDamage() > 0.0F) { + this.setDamage(this.getDamage() - 1.0F); } this.lastX = this.locX; @@ -250,22 +259,20 @@ public class EntityBoat extends Entity { this.lastZ = this.locZ; super.tick(); this.r(); - if (this.bT()) { - if (this.bP().isEmpty() || !(this.bP().get(0) instanceof EntityHuman)) { + if (this.ca()) { + if (this.getPassengers().isEmpty() || !(this.getPassengers().get(0) instanceof EntityHuman)) { this.a(false, false); } - this.v(); + this.w(); if (this.world.isClientSide) { - this.x(); + this.z(); this.world.a((Packet) (new PacketPlayInBoatMove(this.a(0), this.a(1)))); } - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); + this.move(EnumMoveType.SELF, this.getMot()); } else { - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; + this.setMot(Vec3D.a); } // CraftBukkit start @@ -288,7 +295,7 @@ public class EntityBoat extends Entity { for (int i = 0; i <= 1; ++i) { if (this.a(i)) { - if (!this.isSilent() && (double) (this.h[i] % 6.2831855F) <= 0.7853981852531433D && ((double) this.h[i] + 0.39269909262657166D) % 6.2831854820251465D >= 0.7853981852531433D) { + if (!this.isSilent() && (double) (this.as[i] % 6.2831855F) <= 0.7853981852531433D && ((double) this.as[i] + 0.39269909262657166D) % 6.2831854820251465D >= 0.7853981852531433D) { SoundEffect soundeffect = this.i(); if (soundeffect != null) { @@ -296,13 +303,13 @@ public class EntityBoat extends Entity { double d0 = i == 1 ? -vec3d.z : vec3d.z; double d1 = i == 1 ? vec3d.x : -vec3d.x; - this.world.a((EntityHuman) null, this.locX + d0, this.locY, this.locZ + d1, soundeffect, this.bV(), 1.0F, 0.8F + 0.4F * this.random.nextFloat()); + this.world.playSound((EntityHuman) null, this.locX + d0, this.locY, this.locZ + d1, soundeffect, this.getSoundCategory(), 1.0F, 0.8F + 0.4F * this.random.nextFloat()); } } - this.h[i] = (float) ((double) this.h[i] + 0.39269909262657166D); + this.as[i] = (float) ((double) this.as[i] + 0.39269909262657166D); } else { - this.h[i] = 0.0F; + this.as[i] = 0.0F; } } @@ -310,13 +317,13 @@ public class EntityBoat extends Entity { List list = this.world.getEntities(this, this.getBoundingBox().grow(0.20000000298023224D, -0.009999999776482582D, 0.20000000298023224D), IEntitySelector.a(this)); if (!list.isEmpty()) { - boolean flag = !this.world.isClientSide && !(this.bO() instanceof EntityHuman); + boolean flag = !this.world.isClientSide && !(this.getRidingPassenger() instanceof EntityHuman); for (int j = 0; j < list.size(); ++j) { Entity entity = (Entity) list.get(j); if (!entity.w(this)) { - if (flag && this.bP().size() < 2 && !entity.isPassenger() && entity.width < this.width && entity instanceof EntityLiving && !(entity instanceof EntityWaterAnimal) && !(entity instanceof EntityHuman)) { + if (flag && this.getPassengers().size() < 2 && !entity.isPassenger() && entity.getWidth() < this.getWidth() && entity instanceof EntityLiving && !(entity instanceof EntityWaterAnimal) && !(entity instanceof EntityHuman)) { entity.startRiding(this); } else { this.collide(entity); @@ -331,22 +338,22 @@ public class EntityBoat extends Entity { int i; if (this.world.isClientSide) { - i = this.z(); + i = this.A(); if (i > 0) { - this.aQ += 0.05F; + this.aN += 0.05F; } else { - this.aQ -= 0.1F; + this.aN -= 0.1F; } - this.aQ = MathHelper.a(this.aQ, 0.0F, 1.0F); - this.aS = this.aR; - this.aR = 10.0F * (float) Math.sin((double) (0.5F * (float) this.world.getTime())) * this.aQ; + this.aN = MathHelper.a(this.aN, 0.0F, 1.0F); + this.aP = this.aO; + this.aO = 10.0F * (float) Math.sin((double) (0.5F * (float) this.world.getTime())) * this.aN; } else { - if (!this.aO) { + if (!this.aL) { this.d(0); } - i = this.z(); + i = this.A(); if (i > 0) { --i; this.d(i); @@ -354,15 +361,17 @@ public class EntityBoat extends Entity { if (j > 0 && i == 0) { this.d(0); - if (this.aP) { - this.motY -= 0.7D; + Vec3D vec3d = this.getMot(); + + if (this.aM) { + this.setMot(vec3d.add(0.0D, -0.7D, 0.0D)); this.ejectPassengers(); } else { - this.motY = this.a(EntityHuman.class) ? 2.7D : 0.6D; + this.setMot(vec3d.x, this.a(EntityHuman.class) ? 2.7D : 0.6D, vec3d.z); } } - this.aO = false; + this.aL = false; } } @@ -371,51 +380,51 @@ public class EntityBoat extends Entity { @Nullable protected SoundEffect i() { switch (this.s()) { - case IN_WATER: - case UNDER_WATER: - case UNDER_FLOWING_WATER: - return SoundEffects.ENTITY_BOAT_PADDLE_WATER; - case ON_LAND: - return SoundEffects.ENTITY_BOAT_PADDLE_LAND; - case IN_AIR: - default: - return null; + case IN_WATER: + case UNDER_WATER: + case UNDER_FLOWING_WATER: + return SoundEffects.ENTITY_BOAT_PADDLE_WATER; + case ON_LAND: + return SoundEffects.ENTITY_BOAT_PADDLE_LAND; + case IN_AIR: + default: + return null; } } private void r() { - if (this.az > 0 && !this.bT()) { - double d0 = this.locX + (this.aA - this.locX) / (double) this.az; - double d1 = this.locY + (this.aB - this.locY) / (double) this.az; - double d2 = this.locZ + (this.aC - this.locZ) / (double) this.az; - double d3 = MathHelper.g(this.aD - (double) this.yaw); + if (this.aw > 0 && !this.ca()) { + double d0 = this.locX + (this.ax - this.locX) / (double) this.aw; + double d1 = this.locY + (this.ay - this.locY) / (double) this.aw; + double d2 = this.locZ + (this.az - this.locZ) / (double) this.aw; + double d3 = MathHelper.g(this.aA - (double) this.yaw); - this.yaw = (float) ((double) this.yaw + d3 / (double) this.az); - this.pitch = (float) ((double) this.pitch + (this.aE - (double) this.pitch) / (double) this.az); - --this.az; + this.yaw = (float) ((double) this.yaw + d3 / (double) this.aw); + this.pitch = (float) ((double) this.pitch + (this.aB - (double) this.pitch) / (double) this.aw); + --this.aw; this.setPosition(d0, d1, d2); this.setYawPitch(this.yaw, this.pitch); } } public void a(boolean flag, boolean flag1) { - this.datawatcher.set(EntityBoat.e, flag); - this.datawatcher.set(EntityBoat.f, flag1); + this.datawatcher.set(EntityBoat.f, flag); + this.datawatcher.set(EntityBoat.g, flag1); } private EntityBoat.EnumStatus s() { - EntityBoat.EnumStatus entityboat_enumstatus = this.u(); + EntityBoat.EnumStatus entityboat_enumstatus = this.v(); if (entityboat_enumstatus != null) { - this.aJ = this.getBoundingBox().maxY; + this.aG = this.getBoundingBox().maxY; return entityboat_enumstatus; - } else if (this.t()) { + } else if (this.u()) { return EntityBoat.EnumStatus.IN_WATER; } else { float f = this.l(); if (f > 0.0F) { - this.aK = f; + this.aH = f; return EntityBoat.EnumStatus.ON_LAND; } else { return EntityBoat.EnumStatus.IN_AIR; @@ -428,7 +437,7 @@ public class EntityBoat extends Entity { int i = MathHelper.floor(axisalignedbb.minX); int j = MathHelper.f(axisalignedbb.maxX); int k = MathHelper.floor(axisalignedbb.maxY); - int l = MathHelper.f(axisalignedbb.maxY - this.aN); + int l = MathHelper.f(axisalignedbb.maxY - this.aK); int i1 = MathHelper.floor(axisalignedbb.minZ); int j1 = MathHelper.f(axisalignedbb.maxZ); BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); @@ -441,11 +450,11 @@ public class EntityBoat extends Entity { for (int l1 = i; l1 < j; ++l1) { for (int i2 = i1; i2 < j1; ++i2) { - blockposition_pooledblockposition.c(l1, k1, i2); + blockposition_pooledblockposition.d(l1, k1, i2); Fluid fluid = this.world.getFluid(blockposition_pooledblockposition); if (fluid.a(TagsFluid.WATER)) { - f = Math.max(f, (float) k1 + fluid.getHeight()); + f = Math.max(f, fluid.getHeight(this.world, blockposition_pooledblockposition)); } if (f >= 1.0F) { @@ -506,11 +515,11 @@ public class EntityBoat extends Entity { if (j2 != 2) { for (int k2 = k; k2 < l; ++k2) { if (j2 <= 0 || k2 != k && k2 != l - 1) { - blockposition_pooledblockposition.c(l1, k2, i2); + blockposition_pooledblockposition.d(l1, k2, i2); IBlockData iblockdata = this.world.getType(blockposition_pooledblockposition); if (!(iblockdata.getBlock() instanceof BlockWaterLily) && VoxelShapes.c(iblockdata.getCollisionShape(this.world, blockposition_pooledblockposition).a((double) l1, (double) k2, (double) i2), voxelshape, OperatorBoolean.AND)) { - f += iblockdata.getBlock().n(); + f += iblockdata.getBlock().m(); ++k1; } } @@ -539,7 +548,7 @@ public class EntityBoat extends Entity { return f / (float) k1; } - private boolean t() { + private boolean u() { AxisAlignedBB axisalignedbb = this.getBoundingBox(); int i = MathHelper.floor(axisalignedbb.minX); int j = MathHelper.f(axisalignedbb.maxX); @@ -549,7 +558,7 @@ public class EntityBoat extends Entity { int j1 = MathHelper.f(axisalignedbb.maxZ); boolean flag = false; - this.aJ = Double.MIN_VALUE; + this.aG = Double.MIN_VALUE; BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); Throwable throwable = null; @@ -557,13 +566,13 @@ public class EntityBoat extends Entity { for (int k1 = i; k1 < j; ++k1) { for (int l1 = k; l1 < l; ++l1) { for (int i2 = i1; i2 < j1; ++i2) { - blockposition_pooledblockposition.c(k1, l1, i2); + blockposition_pooledblockposition.d(k1, l1, i2); Fluid fluid = this.world.getFluid(blockposition_pooledblockposition); if (fluid.a(TagsFluid.WATER)) { - float f = (float) l1 + fluid.getHeight(); + float f = (float) l1 + fluid.getHeight(this.world, blockposition_pooledblockposition); - this.aJ = Math.max((double) f, this.aJ); + this.aG = Math.max((double) f, this.aG); flag |= axisalignedbb.minY < (double) f; } } @@ -591,7 +600,7 @@ public class EntityBoat extends Entity { } @Nullable - private EntityBoat.EnumStatus u() { + private EntityBoat.EnumStatus v() { AxisAlignedBB axisalignedbb = this.getBoundingBox(); double d0 = axisalignedbb.maxY + 0.001D; int i = MathHelper.floor(axisalignedbb.minX); @@ -608,11 +617,11 @@ public class EntityBoat extends Entity { for (int k1 = i; k1 < j; ++k1) { for (int l1 = k; l1 < l; ++l1) { for (int i2 = i1; i2 < j1; ++i2) { - blockposition_pooledblockposition.c(k1, l1, i2); + blockposition_pooledblockposition.d(k1, l1, i2); Fluid fluid = this.world.getFluid(blockposition_pooledblockposition); - if (fluid.a(TagsFluid.WATER) && d0 < (double) ((float) blockposition_pooledblockposition.getY() + fluid.getHeight())) { - if (!fluid.d()) { + if (fluid.a(TagsFluid.WATER) && d0 < (double) ((float) blockposition_pooledblockposition.getY() + fluid.getHeight(this.world, blockposition_pooledblockposition))) { + if (!fluid.isSource()) { EntityBoat.EnumStatus entityboat_enumstatus = EntityBoat.EnumStatus.UNDER_FLOWING_WATER; return entityboat_enumstatus; @@ -644,91 +653,88 @@ public class EntityBoat extends Entity { } } - private void v() { + private void w() { double d0 = -0.03999999910593033D; double d1 = this.isNoGravity() ? 0.0D : -0.03999999910593033D; double d2 = 0.0D; - this.aw = 0.05F; - if (this.aM == EntityBoat.EnumStatus.IN_AIR && this.aL != EntityBoat.EnumStatus.IN_AIR && this.aL != EntityBoat.EnumStatus.ON_LAND) { - this.aJ = this.getBoundingBox().minY + (double) this.length; - this.setPosition(this.locX, (double) (this.k() - this.length) + 0.101D, this.locZ); - this.motY = 0.0D; - this.aN = 0.0D; - this.aL = EntityBoat.EnumStatus.IN_WATER; + this.at = 0.05F; + if (this.aJ == EntityBoat.EnumStatus.IN_AIR && this.aI != EntityBoat.EnumStatus.IN_AIR && this.aI != EntityBoat.EnumStatus.ON_LAND) { + this.aG = this.getBoundingBox().minY + (double) this.getHeight(); + this.setPosition(this.locX, (double) (this.k() - this.getHeight()) + 0.101D, this.locZ); + this.setMot(this.getMot().d(1.0D, 0.0D, 1.0D)); + this.aK = 0.0D; + this.aI = EntityBoat.EnumStatus.IN_WATER; } else { - if (this.aL == EntityBoat.EnumStatus.IN_WATER) { - d2 = (this.aJ - this.getBoundingBox().minY) / (double) this.length; - this.aw = 0.9F; - } else if (this.aL == EntityBoat.EnumStatus.UNDER_FLOWING_WATER) { + if (this.aI == EntityBoat.EnumStatus.IN_WATER) { + d2 = (this.aG - this.getBoundingBox().minY) / (double) this.getHeight(); + this.at = 0.9F; + } else if (this.aI == EntityBoat.EnumStatus.UNDER_FLOWING_WATER) { d1 = -7.0E-4D; - this.aw = 0.9F; - } else if (this.aL == EntityBoat.EnumStatus.UNDER_WATER) { + this.at = 0.9F; + } else if (this.aI == EntityBoat.EnumStatus.UNDER_WATER) { d2 = 0.009999999776482582D; - this.aw = 0.45F; - } else if (this.aL == EntityBoat.EnumStatus.IN_AIR) { - this.aw = 0.9F; - } else if (this.aL == EntityBoat.EnumStatus.ON_LAND) { - this.aw = this.aK; - if (this.bO() instanceof EntityHuman) { - this.aK /= 2.0F; + this.at = 0.45F; + } else if (this.aI == EntityBoat.EnumStatus.IN_AIR) { + this.at = 0.9F; + } else if (this.aI == EntityBoat.EnumStatus.ON_LAND) { + this.at = this.aH; + if (this.getRidingPassenger() instanceof EntityHuman) { + this.aH /= 2.0F; } } - this.motX *= (double) this.aw; - this.motZ *= (double) this.aw; - this.ay *= this.aw; - this.motY += d1; + Vec3D vec3d = this.getMot(); + + this.setMot(vec3d.x * (double) this.at, vec3d.y + d1, vec3d.z * (double) this.at); + this.av *= this.at; if (d2 > 0.0D) { - double d3 = 0.65D; + Vec3D vec3d1 = this.getMot(); - this.motY += d2 * 0.06153846016296973D; - double d4 = 0.75D; - - this.motY *= 0.75D; + this.setMot(vec3d1.x, (vec3d1.y + d2 * 0.06153846016296973D) * 0.75D, vec3d1.z); } } } - private void x() { + private void z() { if (this.isVehicle()) { float f = 0.0F; - if (this.aF) { - this.ay += -1.0F; + if (this.aC) { + --this.av; } - if (this.aG) { - ++this.ay; + if (this.aD) { + ++this.av; } - if (this.aG != this.aF && !this.aH && !this.aI) { + if (this.aD != this.aC && !this.aE && !this.aF) { f += 0.005F; } - this.yaw += this.ay; - if (this.aH) { + this.yaw += this.av; + if (this.aE) { f += 0.04F; } - if (this.aI) { + if (this.aF) { f -= 0.005F; } - this.motX += (double) (MathHelper.sin(-this.yaw * 0.017453292F) * f); - this.motZ += (double) (MathHelper.cos(this.yaw * 0.017453292F) * f); - this.a(this.aG && !this.aF || this.aH, this.aF && !this.aG || this.aH); + this.setMot(this.getMot().add((double) (MathHelper.sin(-this.yaw * 0.017453292F) * f), 0.0D, (double) (MathHelper.cos(this.yaw * 0.017453292F) * f))); + this.a(this.aD && !this.aC || this.aE, this.aC && !this.aD || this.aE); } } + @Override public void k(Entity entity) { if (this.w(entity)) { float f = 0.0F; - float f1 = (float) ((this.dead ? 0.009999999776482582D : this.aJ()) + entity.aI()); + float f1 = (float) ((this.dead ? 0.009999999776482582D : this.aP()) + entity.aO()); - if (this.bP().size() > 1) { - int i = this.bP().indexOf(entity); + if (this.getPassengers().size() > 1) { + int i = this.getPassengers().indexOf(entity); if (i == 0) { f = 0.2F; @@ -744,13 +750,13 @@ public class EntityBoat extends Entity { Vec3D vec3d = (new Vec3D((double) f, 0.0D, 0.0D)).b(-this.yaw * 0.017453292F - 1.5707964F); entity.setPosition(this.locX + vec3d.x, this.locY + (double) f1, this.locZ + vec3d.z); - entity.yaw += this.ay; - entity.setHeadRotation(entity.getHeadRotation() + this.ay); + entity.yaw += this.av; + entity.setHeadRotation(entity.getHeadRotation() + this.av); this.a(entity); - if (entity instanceof EntityAnimal && this.bP().size() > 1) { + if (entity instanceof EntityAnimal && this.getPassengers().size() > 1) { int j = entity.getId() % 2 == 0 ? 90 : 270; - entity.k(((EntityAnimal) entity).aQ + (float) j); + entity.l(((EntityAnimal) entity).aK + (float) j); entity.setHeadRotation(entity.getHeadRotation() + (float) j); } @@ -758,7 +764,7 @@ public class EntityBoat extends Entity { } protected void a(Entity entity) { - entity.k(this.yaw); + entity.l(this.yaw); float f = MathHelper.g(entity.yaw - this.yaw); float f1 = MathHelper.a(f, -105.0F, 105.0F); @@ -767,10 +773,12 @@ public class EntityBoat extends Entity { entity.setHeadRotation(entity.yaw); } + @Override protected void b(NBTTagCompound nbttagcompound) { nbttagcompound.setString("Type", this.getType().a()); } + @Override protected void a(NBTTagCompound nbttagcompound) { if (nbttagcompound.hasKeyOfType("Type", 8)) { this.setType(EntityBoat.EnumBoatType.a(nbttagcompound.getString("Type"))); @@ -778,11 +786,12 @@ public class EntityBoat extends Entity { } + @Override public boolean b(EntityHuman entityhuman, EnumHand enumhand) { if (entityhuman.isSneaking()) { return false; } else { - if (!this.world.isClientSide && this.ax < 60.0F) { + if (!this.world.isClientSide && this.au < 60.0F) { entityhuman.startRiding(this); } @@ -790,17 +799,18 @@ public class EntityBoat extends Entity { } } + @Override protected void a(double d0, boolean flag, IBlockData iblockdata, BlockPosition blockposition) { - this.aN = this.motY; + this.aK = this.getMot().y; if (!this.isPassenger()) { if (flag) { if (this.fallDistance > 3.0F) { - if (this.aL != EntityBoat.EnumStatus.ON_LAND) { + if (this.aI != EntityBoat.EnumStatus.ON_LAND) { this.fallDistance = 0.0F; return; } - this.c(this.fallDistance, 1.0F); + this.b(this.fallDistance, 1.0F); if (!this.world.isClientSide && !this.dead) { // CraftBukkit start Vehicle vehicle = (Vehicle) this.getBukkitEntity(); @@ -808,7 +818,7 @@ public class EntityBoat extends Entity { this.world.getServer().getPluginManager().callEvent(destroyEvent); if (!destroyEvent.isCancelled()) { this.die(); - if (this.world.getGameRules().getBoolean("doEntityDrops")) { + if (this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { int i; for (i = 0; i < 3; ++i) { @@ -832,60 +842,67 @@ public class EntityBoat extends Entity { } public boolean a(int i) { - return (Boolean) this.datawatcher.get(i == 0 ? EntityBoat.e : EntityBoat.f) && this.bO() != null; + return (Boolean) this.datawatcher.get(i == 0 ? EntityBoat.f : EntityBoat.g) && this.getRidingPassenger() != null; } public void setDamage(float f) { - this.datawatcher.set(EntityBoat.c, f); + this.datawatcher.set(EntityBoat.d, f); } - public float m() { - return (Float) this.datawatcher.get(EntityBoat.c); + public float getDamage() { + return (Float) this.datawatcher.get(EntityBoat.d); } public void b(int i) { - this.datawatcher.set(EntityBoat.a, i); - } - - public int n() { - return (Integer) this.datawatcher.get(EntityBoat.a); - } - - private void d(int i) { - this.datawatcher.set(EntityBoat.g, i); - } - - private int z() { - return (Integer) this.datawatcher.get(EntityBoat.g); - } - - public void c(int i) { this.datawatcher.set(EntityBoat.b, i); } - public int o() { + public int n() { return (Integer) this.datawatcher.get(EntityBoat.b); } + private void d(int i) { + this.datawatcher.set(EntityBoat.ar, i); + } + + private int A() { + return (Integer) this.datawatcher.get(EntityBoat.ar); + } + + public void c(int i) { + this.datawatcher.set(EntityBoat.c, i); + } + + public int o() { + return (Integer) this.datawatcher.get(EntityBoat.c); + } + public void setType(EntityBoat.EnumBoatType entityboat_enumboattype) { - this.datawatcher.set(EntityBoat.d, entityboat_enumboattype.ordinal()); + this.datawatcher.set(EntityBoat.e, entityboat_enumboattype.ordinal()); } public EntityBoat.EnumBoatType getType() { - return EntityBoat.EnumBoatType.a((Integer) this.datawatcher.get(EntityBoat.d)); + return EntityBoat.EnumBoatType.a((Integer) this.datawatcher.get(EntityBoat.e)); } + @Override protected boolean q(Entity entity) { - return this.bP().size() < 2 && !this.a(TagsFluid.WATER); + return this.getPassengers().size() < 2 && !this.a(TagsFluid.WATER); } @Nullable - public Entity bO() { - List list = this.bP(); + @Override + public Entity getRidingPassenger() { + List list = this.getPassengers(); return list.isEmpty() ? null : (Entity) list.get(0); } + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); + } + public static enum EnumBoatType { OAK(Blocks.OAK_PLANKS, "oak"), SPRUCE(Blocks.SPRUCE_PLANKS, "spruce"), BIRCH(Blocks.BIRCH_PLANKS, "birch"), JUNGLE(Blocks.JUNGLE_PLANKS, "jungle"), ACACIA(Blocks.ACACIA_PLANKS, "acacia"), DARK_OAK(Blocks.DARK_OAK_PLANKS, "dark_oak"); diff --git a/src/main/java/net/minecraft/server/EntityCat.java b/src/main/java/net/minecraft/server/EntityCat.java new file mode 100644 index 000000000..f4660233e --- /dev/null +++ b/src/main/java/net/minecraft/server/EntityCat.java @@ -0,0 +1,572 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.function.Predicate; +import javax.annotation.Nullable; + +public class EntityCat extends EntityTameableAnimal { + + private static final RecipeItemStack bD = RecipeItemStack.a(Items.COD, Items.SALMON); + private static final DataWatcherObject bE = DataWatcher.a(EntityCat.class, DataWatcherRegistry.b); + private static final DataWatcherObject bF = DataWatcher.a(EntityCat.class, DataWatcherRegistry.i); + private static final DataWatcherObject bG = DataWatcher.a(EntityCat.class, DataWatcherRegistry.i); + private static final DataWatcherObject bH = DataWatcher.a(EntityCat.class, DataWatcherRegistry.b); + public static final Map bC = (Map) SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // CraftBukkit - decompile error + hashmap.put(0, new MinecraftKey("textures/entity/cat/tabby.png")); + hashmap.put(1, new MinecraftKey("textures/entity/cat/black.png")); + hashmap.put(2, new MinecraftKey("textures/entity/cat/red.png")); + hashmap.put(3, new MinecraftKey("textures/entity/cat/siamese.png")); + hashmap.put(4, new MinecraftKey("textures/entity/cat/british_shorthair.png")); + hashmap.put(5, new MinecraftKey("textures/entity/cat/calico.png")); + hashmap.put(6, new MinecraftKey("textures/entity/cat/persian.png")); + hashmap.put(7, new MinecraftKey("textures/entity/cat/ragdoll.png")); + hashmap.put(8, new MinecraftKey("textures/entity/cat/white.png")); + hashmap.put(9, new MinecraftKey("textures/entity/cat/jellie.png")); + hashmap.put(10, new MinecraftKey("textures/entity/cat/all_black.png")); + }); + private EntityCat.a bI; + private PathfinderGoalTempt bJ; + private float bK; + private float bL; + private float bM; + private float bN; + private float bO; + private float bP; + + public EntityCat(EntityTypes entitytypes, World world) { + super(entitytypes, world); + } + + public MinecraftKey ee() { + return (MinecraftKey) EntityCat.bC.get(this.getCatType()); + } + + @Override + protected void initPathfinder() { + this.goalSit = new PathfinderGoalSit(this); + this.bJ = new EntityCat.PathfinderGoalTemptChance(this, 0.6D, EntityCat.bD, true); + this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new EntityCat.b(this)); + this.goalSelector.a(2, this.goalSit); + this.goalSelector.a(3, this.bJ); + this.goalSelector.a(5, new PathfinderGoalCatSitOnBed(this, 1.1D, 8)); + this.goalSelector.a(6, new PathfinderGoalFollowOwner(this, 1.0D, 10.0F, 5.0F)); + this.goalSelector.a(7, new PathfinderGoalJumpOnBlock(this, 0.8D)); + this.goalSelector.a(8, new PathfinderGoalLeapAtTarget(this, 0.3F)); + this.goalSelector.a(9, new PathfinderGoalOcelotAttack(this)); + this.goalSelector.a(10, new PathfinderGoalBreed(this, 0.8D)); + this.goalSelector.a(11, new PathfinderGoalRandomStrollLand(this, 0.8D, 1.0000001E-5F)); + this.goalSelector.a(12, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); + this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityRabbit.class, false, (Predicate) null)); + this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityTurtle.class, false, EntityTurtle.bz)); + } + + public int getCatType() { + return (Integer) this.datawatcher.get(EntityCat.bE); + } + + public void setCatType(int i) { + if (i < 0 || i >= 11) { + i = this.random.nextInt(10); + } + + this.datawatcher.set(EntityCat.bE, i); + } + + public void u(boolean flag) { + this.datawatcher.set(EntityCat.bF, flag); + } + + public boolean eg() { + return (Boolean) this.datawatcher.get(EntityCat.bF); + } + + public void v(boolean flag) { + this.datawatcher.set(EntityCat.bG, flag); + } + + public boolean eh() { + return (Boolean) this.datawatcher.get(EntityCat.bG); + } + + public EnumColor getCollarColor() { + return EnumColor.fromColorIndex((Integer) this.datawatcher.get(EntityCat.bH)); + } + + public void setCollarColor(EnumColor enumcolor) { + this.datawatcher.set(EntityCat.bH, enumcolor.getColorIndex()); + } + + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityCat.bE, 1); + this.datawatcher.register(EntityCat.bF, false); + this.datawatcher.register(EntityCat.bG, false); + this.datawatcher.register(EntityCat.bH, EnumColor.RED.getColorIndex()); + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("CatType", this.getCatType()); + nbttagcompound.setByte("CollarColor", (byte) this.getCollarColor().getColorIndex()); + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setCatType(nbttagcompound.getInt("CatType")); + if (nbttagcompound.hasKeyOfType("CollarColor", 99)) { + this.setCollarColor(EnumColor.fromColorIndex(nbttagcompound.getInt("CollarColor"))); + } + + } + + @Override + public void mobTick() { + if (this.getControllerMove().b()) { + double d0 = this.getControllerMove().c(); + + if (d0 == 0.6D) { + this.setSneaking(true); + this.setSprinting(false); + } else if (d0 == 1.33D) { + this.setSneaking(false); + this.setSprinting(true); + } else { + this.setSneaking(false); + this.setSprinting(false); + } + } else { + this.setSneaking(false); + this.setSprinting(false); + } + + } + + @Nullable + @Override + protected SoundEffect getSoundAmbient() { + return this.isTamed() ? (this.isInLove() ? SoundEffects.ENTITY_CAT_PURR : (this.random.nextInt(4) == 0 ? SoundEffects.ENTITY_CAT_PURREOW : SoundEffects.ENTITY_CAT_AMBIENT)) : SoundEffects.ENTITY_CAT_STRAY_AMBIENT; + } + + @Override + public int A() { + return 120; + } + + public void ej() { + this.a(SoundEffects.ENTITY_CAT_HISS, this.getSoundVolume(), this.cV()); + } + + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return SoundEffects.ENTITY_CAT_HURT; + } + + @Override + protected SoundEffect getSoundDeath() { + return SoundEffects.ENTITY_CAT_DEATH; + } + + @Override + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); + } + + @Override + public void b(float f, float f1) {} + + @Override + protected void a(EntityHuman entityhuman, ItemStack itemstack) { + if (this.i(itemstack)) { + this.a(SoundEffects.ENTITY_CAT_EAT, 1.0F, 1.0F); + } + + super.a(entityhuman, itemstack); + } + + @Override + public boolean C(Entity entity) { + return entity.damageEntity(DamageSource.mobAttack(this), 3.0F); + } + + @Override + public void tick() { + super.tick(); + if (this.bJ != null && this.bJ.h() && !this.isTamed() && this.ticksLived % 100 == 0) { + this.a(SoundEffects.ENTITY_CAT_BEG_FOR_FOOD, 1.0F, 1.0F); + } + + this.ek(); + } + + private void ek() { + if ((this.eg() || this.eh()) && this.ticksLived % 5 == 0) { + this.a(SoundEffects.ENTITY_CAT_PURR, 0.6F + 0.4F * (this.random.nextFloat() - this.random.nextFloat()), 1.0F); + } + + this.el(); + this.em(); + } + + private void el() { + this.bL = this.bK; + this.bN = this.bM; + if (this.eg()) { + this.bK = Math.min(1.0F, this.bK + 0.15F); + this.bM = Math.min(1.0F, this.bM + 0.08F); + } else { + this.bK = Math.max(0.0F, this.bK - 0.22F); + this.bM = Math.max(0.0F, this.bM - 0.13F); + } + + } + + private void em() { + this.bP = this.bO; + if (this.eh()) { + this.bO = Math.min(1.0F, this.bO + 0.1F); + } else { + this.bO = Math.max(0.0F, this.bO - 0.13F); + } + + } + + @Override + public EntityCat createChild(EntityAgeable entityageable) { + EntityCat entitycat = (EntityCat) EntityTypes.CAT.a(this.world); + + if (entityageable instanceof EntityCat) { + if (this.random.nextBoolean()) { + entitycat.setCatType(this.getCatType()); + } else { + entitycat.setCatType(((EntityCat) entityageable).getCatType()); + } + + if (this.isTamed()) { + entitycat.setOwnerUUID(this.getOwnerUUID()); + entitycat.setTamed(true); + if (this.random.nextBoolean()) { + entitycat.setCollarColor(this.getCollarColor()); + } else { + entitycat.setCollarColor(((EntityCat) entityageable).getCollarColor()); + } + } + } + + return entitycat; + } + + @Override + public boolean mate(EntityAnimal entityanimal) { + if (!this.isTamed()) { + return false; + } else if (!(entityanimal instanceof EntityCat)) { + return false; + } else { + EntityCat entitycat = (EntityCat) entityanimal; + + return entitycat.isTamed() && super.mate(entityanimal); + } + } + + @Nullable + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + groupdataentity = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + if (generatoraccess.aa() > 0.9F) { + this.setCatType(this.random.nextInt(11)); + } else { + this.setCatType(this.random.nextInt(10)); + } + + if (WorldGenerator.SWAMP_HUT.b(generatoraccess, new BlockPosition(this))) { + this.setCatType(10); + this.setPersistent(); + } + + return groupdataentity; + } + + @Override + public boolean a(EntityHuman entityhuman, EnumHand enumhand) { + ItemStack itemstack = entityhuman.b(enumhand); + Item item = itemstack.getItem(); + + if (this.isTamed()) { + if (this.h((EntityLiving) entityhuman)) { + if (item instanceof ItemDye) { + EnumColor enumcolor = ((ItemDye) item).d(); + + if (enumcolor != this.getCollarColor()) { + this.setCollarColor(enumcolor); + if (!entityhuman.abilities.canInstantlyBuild) { + itemstack.subtract(1); + } + + this.setPersistent(); + return true; + } + } else if (this.i(itemstack)) { + if (this.getHealth() < this.getMaxHealth() && item.isFood()) { + this.a(entityhuman, itemstack); + this.heal((float) item.getFoodInfo().getNutrition()); + return true; + } + } else if (!this.world.isClientSide) { + this.goalSit.setSitting(!this.isSitting()); + } + } + } else if (this.i(itemstack)) { + this.a(entityhuman, itemstack); + if (!this.world.isClientSide) { + if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { // CraftBukkit + this.tame(entityhuman); + this.r(true); + this.goalSit.setSitting(true); + this.world.broadcastEntityEffect(this, (byte) 7); + } else { + this.r(false); + this.world.broadcastEntityEffect(this, (byte) 6); + } + } + + this.setPersistent(); + return true; + } + + boolean flag = super.a(entityhuman, enumhand); + + if (flag) { + this.setPersistent(); + } + + return flag; + } + + @Override + public boolean i(ItemStack itemstack) { + return EntityCat.bD.test(itemstack); + } + + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height * 0.5F; + } + + @Override + public boolean isTypeNotPersistent(double d0) { + return !this.isTamed() && this.ticksLived > 2400; + } + + @Override + protected void dW() { + if (this.bI == null) { + this.bI = new EntityCat.a<>(this, EntityHuman.class, 16.0F, 0.8D, 1.33D); + } + + this.goalSelector.a((PathfinderGoal) this.bI); + if (!this.isTamed()) { + this.goalSelector.a(4, this.bI); + } + + } + + static class b extends PathfinderGoal { + + private final EntityCat a; + private EntityHuman b; + private BlockPosition c; + private int d; + + public b(EntityCat entitycat) { + this.a = entitycat; + } + + @Override + public boolean a() { + if (!this.a.isTamed()) { + return false; + } else if (this.a.isSitting()) { + return false; + } else { + EntityLiving entityliving = this.a.getOwner(); + + if (entityliving instanceof EntityHuman) { + this.b = (EntityHuman) entityliving; + if (!entityliving.isSleeping()) { + return false; + } + + if (this.a.h((Entity) this.b) > 100.0D) { + return false; + } + + BlockPosition blockposition = new BlockPosition(this.b); + IBlockData iblockdata = this.a.world.getType(blockposition); + + if (iblockdata.getBlock().a(TagsBlock.BEDS)) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockBed.FACING); + + this.c = new BlockPosition(blockposition.getX() - enumdirection.getAdjacentX(), blockposition.getY(), blockposition.getZ() - enumdirection.getAdjacentZ()); + return !this.g(); + } + } + + return false; + } + } + + private boolean g() { + List list = this.a.world.a(EntityCat.class, (new AxisAlignedBB(this.c)).g(2.0D)); + Iterator iterator = list.iterator(); + + EntityCat entitycat; + + do { + do { + if (!iterator.hasNext()) { + return false; + } + + entitycat = (EntityCat) iterator.next(); + } while (entitycat == this.a); + } while (!entitycat.eg() && !entitycat.eh()); + + return true; + } + + @Override + public boolean b() { + return this.a.isTamed() && !this.a.isSitting() && this.b != null && this.b.isSleeping() && this.c != null && !this.g(); + } + + @Override + public void c() { + if (this.c != null) { + this.a.getGoalSit().setSitting(false); + this.a.getNavigation().a((double) this.c.getX(), (double) this.c.getY(), (double) this.c.getZ(), 1.100000023841858D); + } + + } + + @Override + public void d() { + this.a.u(false); + float f = this.a.world.j(1.0F); + + if (this.b.dJ() >= 100 && (double) f > 0.77D && (double) f < 0.8D && (double) this.a.world.getRandom().nextFloat() < 0.7D) { + this.h(); + } + + this.d = 0; + this.a.v(false); + this.a.getNavigation().o(); + } + + private void h() { + Random random = this.a.getRandom(); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + blockposition_mutableblockposition.a((Entity) this.a); + this.a.a((double) (blockposition_mutableblockposition.getX() + random.nextInt(11) - 5), (double) (blockposition_mutableblockposition.getY() + random.nextInt(5) - 2), (double) (blockposition_mutableblockposition.getZ() + random.nextInt(11) - 5), false); + blockposition_mutableblockposition.a((Entity) this.a); + LootTable loottable = this.a.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.af); + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.a.world)).set(LootContextParameters.POSITION, blockposition_mutableblockposition).set(LootContextParameters.THIS_ENTITY, this.a).a(random); + List list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.GIFT)); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + ItemStack itemstack = (ItemStack) iterator.next(); + + this.a.world.addEntity(new EntityItem(this.a.world, (double) ((float) blockposition_mutableblockposition.getX() - MathHelper.sin(this.a.aK * 0.017453292F)), (double) blockposition_mutableblockposition.getY(), (double) ((float) blockposition_mutableblockposition.getZ() + MathHelper.cos(this.a.aK * 0.017453292F)), itemstack)); + } + + } + + @Override + public void e() { + if (this.b != null && this.c != null) { + this.a.getGoalSit().setSitting(false); + this.a.getNavigation().a((double) this.c.getX(), (double) this.c.getY(), (double) this.c.getZ(), 1.100000023841858D); + if (this.a.h((Entity) this.b) < 2.5D) { + ++this.d; + if (this.d > 16) { + this.a.u(true); + this.a.v(false); + } else { + this.a.a((Entity) this.b, 45.0F, 45.0F); + this.a.v(true); + } + } else { + this.a.u(false); + } + } + + } + } + + static class PathfinderGoalTemptChance extends PathfinderGoalTempt { + + @Nullable + private EntityLiving chosenTarget; // CraftBukkit + private final EntityCat d; + + public PathfinderGoalTemptChance(EntityCat entitycat, double d0, RecipeItemStack recipeitemstack, boolean flag) { + super(entitycat, d0, recipeitemstack, flag); + this.d = entitycat; + } + + @Override + public void e() { + super.e(); + if (this.chosenTarget == null && this.a.getRandom().nextInt(600) == 0) { + this.chosenTarget = this.target; + } else if (this.a.getRandom().nextInt(500) == 0) { + this.chosenTarget = null; + } + + } + + @Override + protected boolean g() { + return this.chosenTarget != null && this.chosenTarget.equals(this.target) ? false : super.g(); + } + + @Override + public boolean a() { + return super.a() && !this.d.isTamed(); + } + } + + static class a extends PathfinderGoalAvoidTarget { + + private final EntityCat i; + + public a(EntityCat entitycat, Class oclass, float f, double d0, double d1) { + // Predicate predicate = IEntitySelector.e; // CraftBukkit - decompile error + + super(entitycat, oclass, f, d0, d1, IEntitySelector.e::test); // CraftBukkit - decompile error + this.i = entitycat; + } + + @Override + public boolean a() { + return !this.i.isTamed() && super.a(); + } + + @Override + public boolean b() { + return !this.i.isTamed() && super.b(); + } + } +} diff --git a/src/main/java/net/minecraft/server/EntityCaveSpider.java b/src/main/java/net/minecraft/server/EntityCaveSpider.java index 480beced8..89c9306df 100644 --- a/src/main/java/net/minecraft/server/EntityCaveSpider.java +++ b/src/main/java/net/minecraft/server/EntityCaveSpider.java @@ -4,18 +4,19 @@ import javax.annotation.Nullable; public class EntityCaveSpider extends EntitySpider { - public EntityCaveSpider(World world) { - super(EntityTypes.CAVE_SPIDER, world); - this.setSize(0.7F, 0.5F); + public EntityCaveSpider(EntityTypes entitytypes, World world) { + super(entitytypes, world); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(12.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(12.0D); } - public boolean B(Entity entity) { - if (super.B(entity)) { + @Override + public boolean C(Entity entity) { + if (super.C(entity)) { if (entity instanceof EntityLiving) { byte b0 = 0; @@ -37,16 +38,13 @@ public class EntityCaveSpider extends EntitySpider { } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { return groupdataentity; } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 0.45F; } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.z; - } } diff --git a/src/main/java/net/minecraft/server/EntityChicken.java b/src/main/java/net/minecraft/server/EntityChicken.java index 070a9e7b1..f1dfdd4ff 100644 --- a/src/main/java/net/minecraft/server/EntityChicken.java +++ b/src/main/java/net/minecraft/server/EntityChicken.java @@ -1,150 +1,160 @@ package net.minecraft.server; -import javax.annotation.Nullable; - public class EntityChicken extends EntityAnimal { - private static final RecipeItemStack bK = RecipeItemStack.a(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS); + private static final RecipeItemStack bG = RecipeItemStack.a(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS); + public float bz; + public float bA; + public float bB; public float bC; - public float bD; - public float bE; - public float bG; - public float bH = 1.0F; - public int bI; - public boolean bJ; + public float bD = 1.0F; + public int eggLayTime; + public boolean bF; - public EntityChicken(World world) { - super(EntityTypes.CHICKEN, world); - this.setSize(0.4F, 0.7F); - this.bI = this.random.nextInt(6000) + 6000; + public EntityChicken(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.eggLayTime = this.random.nextInt(6000) + 6000; this.a(PathType.WATER, 0.0F); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); - this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, EntityChicken.bK)); + this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, EntityChicken.bG)); this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.1D)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); } - public float getHeadHeight() { - return this.length; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return this.isBaby() ? entitysize.height * 0.85F : entitysize.height * 0.92F; } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(4.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(4.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); } + @Override public void movementTick() { // CraftBukkit start if (this.isChickenJockey()) { - this.persistent = !this.isTypeNotPersistent(); + this.persistent = !this.isTypeNotPersistent(0); } // CraftBukkit end super.movementTick(); - this.bG = this.bC; - this.bE = this.bD; - this.bD = (float) ((double) this.bD + (double) (this.onGround ? -1 : 4) * 0.3D); - this.bD = MathHelper.a(this.bD, 0.0F, 1.0F); - if (!this.onGround && this.bH < 1.0F) { - this.bH = 1.0F; + this.bC = this.bz; + this.bB = this.bA; + this.bA = (float) ((double) this.bA + (double) (this.onGround ? -1 : 4) * 0.3D); + this.bA = MathHelper.a(this.bA, 0.0F, 1.0F); + if (!this.onGround && this.bD < 1.0F) { + this.bD = 1.0F; } - this.bH = (float) ((double) this.bH * 0.9D); - if (!this.onGround && this.motY < 0.0D) { - this.motY *= 0.6D; + this.bD = (float) ((double) this.bD * 0.9D); + Vec3D vec3d = this.getMot(); + + if (!this.onGround && vec3d.y < 0.0D) { + this.setMot(vec3d.d(1.0D, 0.6D, 1.0D)); } - this.bC += this.bH * 2.0F; - if (!this.world.isClientSide && !this.isBaby() && !this.isChickenJockey() && --this.bI <= 0) { + this.bz += this.bD * 2.0F; + if (!this.world.isClientSide && this.isAlive() && !this.isBaby() && !this.isChickenJockey() && --this.eggLayTime <= 0) { this.a(SoundEffects.ENTITY_CHICKEN_EGG, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); this.forceDrops = true; // CraftBukkit this.a((IMaterial) Items.EGG); this.forceDrops = false; // CraftBukkit - this.bI = this.random.nextInt(6000) + 6000; + this.eggLayTime = this.random.nextInt(6000) + 6000; } } - public void c(float f, float f1) {} + @Override + public void b(float f, float f1) {} - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_CHICKEN_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_CHICKEN_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_CHICKEN_DEATH; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(SoundEffects.ENTITY_CHICKEN_STEP, 0.15F, 1.0F); } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.J; - } - + @Override public EntityChicken createChild(EntityAgeable entityageable) { - return EntityTypes.CHICKEN.create(world); // Paper + return (EntityChicken) EntityTypes.CHICKEN.a(this.world); } - public boolean f(ItemStack itemstack) { - return EntityChicken.bK.test(itemstack); + @Override + public boolean i(ItemStack itemstack) { + return EntityChicken.bG.test(itemstack); } + @Override protected int getExpValue(EntityHuman entityhuman) { return this.isChickenJockey() ? 10 : super.getExpValue(entityhuman); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.bJ = nbttagcompound.getBoolean("IsChickenJockey"); + this.bF = nbttagcompound.getBoolean("IsChickenJockey"); if (nbttagcompound.hasKey("EggLayTime")) { - this.bI = nbttagcompound.getInt("EggLayTime"); + this.eggLayTime = nbttagcompound.getInt("EggLayTime"); } } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setBoolean("IsChickenJockey", this.bJ); - nbttagcompound.setInt("EggLayTime", this.bI); + nbttagcompound.setBoolean("IsChickenJockey", this.bF); + nbttagcompound.setInt("EggLayTime", this.eggLayTime); } - public boolean isTypeNotPersistent() { + @Override + public boolean isTypeNotPersistent(double d0) { return this.isChickenJockey() && !this.isVehicle(); } + @Override public void k(Entity entity) { super.k(entity); - float f = MathHelper.sin(this.aQ * 0.017453292F); - float f1 = MathHelper.cos(this.aQ * 0.017453292F); + float f = MathHelper.sin(this.aK * 0.017453292F); + float f1 = MathHelper.cos(this.aK * 0.017453292F); float f2 = 0.1F; float f3 = 0.0F; - entity.setPosition(this.locX + (double) (0.1F * f), this.locY + (double) (this.length * 0.5F) + entity.aI() + 0.0D, this.locZ - (double) (0.1F * f1)); + entity.setPosition(this.locX + (double) (0.1F * f), this.locY + (double) (this.getHeight() * 0.5F) + entity.aO() + 0.0D, this.locZ - (double) (0.1F * f1)); if (entity instanceof EntityLiving) { - ((EntityLiving) entity).aQ = this.aQ; + ((EntityLiving) entity).aK = this.aK; } } public boolean isChickenJockey() { - return this.bJ; + return this.bF; } - public void s(boolean flag) { - this.bJ = flag; + public void r(boolean flag) { + this.bF = flag; } } diff --git a/src/main/java/net/minecraft/server/EntityCow.java b/src/main/java/net/minecraft/server/EntityCow.java index cc53e915d..2c8bbf20a 100644 --- a/src/main/java/net/minecraft/server/EntityCow.java +++ b/src/main/java/net/minecraft/server/EntityCow.java @@ -1,6 +1,5 @@ package net.minecraft.server; -import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.inventory.CraftItemStack; @@ -8,16 +7,12 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack; public class EntityCow extends EntityAnimal { - protected EntityCow(EntityTypes entitytypes, World world) { + public EntityCow(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.setSize(0.9F, 1.4F); } - public EntityCow(World world) { - this(EntityTypes.COW, world); - } - - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); this.goalSelector.a(1, new PathfinderGoalPanic(this, 2.0D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); @@ -28,44 +23,45 @@ public class EntityCow extends EntityAnimal { this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.20000000298023224D); } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_COW_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_COW_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_COW_DEATH; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(SoundEffects.ENTITY_COW_STEP, 0.15F, 1.0F); } - protected float cD() { + @Override + protected float getSoundVolume() { return 0.4F; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.S; - } - + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); if (itemstack.getItem() == Items.BUCKET && !entityhuman.abilities.canInstantlyBuild && !this.isBaby()) { // CraftBukkit start - Got milk? - org.bukkit.Location loc = this.getBukkitEntity().getLocation(); - org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), null, itemstack, Items.MILK_BUCKET, enumhand); // Paper - add enumHand + org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman.world, entityhuman, this.getChunkCoordinates(), this.getChunkCoordinates(), null, itemstack, Items.MILK_BUCKET, enumhand); // Paper - add enumHand if (event.isCancelled()) { return false; @@ -87,11 +83,13 @@ public class EntityCow extends EntityAnimal { } } + @Override public EntityCow createChild(EntityAgeable entityageable) { - return EntityTypes.COW.create(world); // Paper + return (EntityCow) EntityTypes.COW.a(this.world); } - public float getHeadHeight() { - return this.isBaby() ? this.length : 1.3F; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return this.isBaby() ? entitysize.height * 0.95F : 1.3F; } } diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java index d659c57db..7dacaa216 100644 --- a/src/main/java/net/minecraft/server/EntityCreature.java +++ b/src/main/java/net/minecraft/server/EntityCreature.java @@ -7,17 +7,12 @@ import org.bukkit.event.entity.EntityUnleashEvent; public abstract class EntityCreature extends EntityInsentient { public org.bukkit.craftbukkit.entity.CraftCreature getBukkitCreature() { return (org.bukkit.craftbukkit.entity.CraftCreature) super.getBukkitEntity(); } // Paper - public BlockPosition movingTarget = null; public BlockPosition getMovingTarget() { return movingTarget; } // Paper - private BlockPosition a; - private float b; - protected EntityCreature(EntityTypes entitytypes, World world) { + protected EntityCreature(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.a = BlockPosition.ZERO; - this.b = -1.0F; } - public float a(BlockPosition blockposition) { + public float f(BlockPosition blockposition) { return this.a(blockposition, (IWorldReader) this.world); } @@ -25,49 +20,22 @@ public abstract class EntityCreature extends EntityInsentient { return 0.0F; } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - return super.a(generatoraccess, flag) && this.a(new BlockPosition(this.locX, this.getBoundingBox().minY, this.locZ), (IWorldReader) generatoraccess) >= 0.0F; + @Override + public boolean a(GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn) { + return this.a(new BlockPosition(this.locX, this.getBoundingBox().minY, this.locZ), (IWorldReader) generatoraccess) >= 0.0F; } - public boolean dr() { - return !this.navigation.p(); + public boolean dT() { + return !this.getNavigation().n(); } - public boolean ds() { - return this.f(new BlockPosition(this)); - } + @Override + protected void dM() { + super.dM(); + Entity entity = this.getLeashHolder(); - public boolean f(BlockPosition blockposition) { - return this.b == -1.0F ? true : this.a.n(blockposition) < (double) (this.b * this.b); - } - - public void a(BlockPosition blockposition, int i) { - this.a = blockposition; - this.b = (float) i; - } - - public BlockPosition dt() { - return this.a; - } - - public float du() { - return this.b; - } - - public void dv() { - this.b = -1.0F; - } - - public boolean dw() { - return this.b != -1.0F; - } - - protected void dl() { - super.dl(); - if (this.isLeashed() && this.getLeashHolder() != null && this.getLeashHolder().world == this.world) { - Entity entity = this.getLeashHolder(); - - this.a(new BlockPosition((int) entity.locX, (int) entity.locY, (int) entity.locZ), 5); + if (entity != null && entity.world == this.world) { + this.a(new BlockPosition(entity), 5); float f = this.g(entity); if (this instanceof EntityTameableAnimal && ((EntityTameableAnimal) this).isSitting()) { @@ -83,27 +51,25 @@ public abstract class EntityCreature extends EntityInsentient { if (f > 10.0F) { this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); // CraftBukkit this.unleash(true, true); - this.goalSelector.c(1); + this.goalSelector.a(PathfinderGoal.Type.MOVE); } else if (f > 6.0F) { double d0 = (entity.locX - this.locX) / (double) f; double d1 = (entity.locY - this.locY) / (double) f; double d2 = (entity.locZ - this.locZ) / (double) f; - this.motX += d0 * Math.abs(d0) * 0.4D; - this.motY += d1 * Math.abs(d1) * 0.4D; - this.motZ += d2 * Math.abs(d2) * 0.4D; + this.setMot(this.getMot().add(Math.copySign(d0 * d0 * 0.4D, d0), Math.copySign(d1 * d1 * 0.4D, d1), Math.copySign(d2 * d2 * 0.4D, d2))); } else { - this.goalSelector.d(1); + this.goalSelector.b(PathfinderGoal.Type.MOVE); float f1 = 2.0F; - Vec3D vec3d = (new Vec3D(entity.locX - this.locX, entity.locY - this.locY, entity.locZ - this.locZ)).a().a((double) Math.max(f - 2.0F, 0.0F)); + Vec3D vec3d = (new Vec3D(entity.locX - this.locX, entity.locY - this.locY, entity.locZ - this.locZ)).d().a((double) Math.max(f - 2.0F, 0.0F)); - this.getNavigation().a(this.locX + vec3d.x, this.locY + vec3d.y, this.locZ + vec3d.z, this.dx()); + this.getNavigation().a(this.locX + vec3d.x, this.locY + vec3d.y, this.locZ + vec3d.z, this.dU()); } } } - protected double dx() { + protected double dU() { return 1.0D; } diff --git a/src/main/java/net/minecraft/server/EntityCreeper.java b/src/main/java/net/minecraft/server/EntityCreeper.java index 945a75dd6..bcb727630 100644 --- a/src/main/java/net/minecraft/server/EntityCreeper.java +++ b/src/main/java/net/minecraft/server/EntityCreeper.java @@ -2,51 +2,55 @@ package net.minecraft.server; import java.util.Collection; import java.util.Iterator; -import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit end public class EntityCreeper extends EntityMonster { - private static final DataWatcherObject a = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.b); - private static final DataWatcherObject b = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.i); - private static final DataWatcherObject c = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.i);private static final DataWatcherObject isIgnitedDW = c; // Paper OBFHELPER - private int bC; + private static final DataWatcherObject b = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.b); + private static final DataWatcherObject POWERED = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.i); + private static final DataWatcherObject d = DataWatcher.a(EntityCreeper.class, DataWatcherRegistry.i); private static final DataWatcherObject isIgnitedDW = d; // Paper OBFHELPER + private int bz; public int fuseTicks; // Paper - public public int maxFuseTicks = 30; public int explosionRadius = 3; - private int bG; + private int bD; - public EntityCreeper(World world) { - super(EntityTypes.CREEPER, world); - this.setSize(0.6F, 1.7F); + public EntityCreeper(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); this.goalSelector.a(2, new PathfinderGoalSwell(this)); this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityOcelot.class, 6.0F, 1.0D, 1.2D)); + this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityCat.class, 6.0F, 1.0D, 1.2D)); this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.8D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0])); } + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); } - public int bn() { + @Override + public int bv() { return this.getGoalTarget() == null ? 3 : 3 + (int) (this.getHealth() - 1.0F); } - public void c(float f, float f1) { - super.c(f, f1); + @Override + public void b(float f, float f1) { + super.b(f, f1); this.fuseTicks = (int) ((float) this.fuseTicks + f * 1.5F); if (this.fuseTicks > this.maxFuseTicks - 5) { this.fuseTicks = this.maxFuseTicks - 5; @@ -54,16 +58,18 @@ public class EntityCreeper extends EntityMonster { } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityCreeper.a, -1); - this.datawatcher.register(EntityCreeper.b, false); - this.datawatcher.register(EntityCreeper.c, false); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityCreeper.b, -1); + this.datawatcher.register(EntityCreeper.POWERED, false); + this.datawatcher.register(EntityCreeper.d, false); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - if ((Boolean) this.datawatcher.get(EntityCreeper.b)) { + if ((Boolean) this.datawatcher.get(EntityCreeper.POWERED)) { nbttagcompound.setBoolean("powered", true); } @@ -72,9 +78,10 @@ public class EntityCreeper extends EntityMonster { nbttagcompound.setBoolean("ignited", this.isIgnited()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.datawatcher.set(EntityCreeper.b, nbttagcompound.getBoolean("powered")); + this.datawatcher.set(EntityCreeper.POWERED, nbttagcompound.getBoolean("powered")); if (nbttagcompound.hasKeyOfType("Fuse", 99)) { this.maxFuseTicks = nbttagcompound.getShort("Fuse"); } @@ -84,19 +91,20 @@ public class EntityCreeper extends EntityMonster { } if (nbttagcompound.getBoolean("ignited")) { - this.dB(); + this.ignite(); } } + @Override public void tick() { if (this.isAlive()) { - this.bC = this.fuseTicks; + this.bz = this.fuseTicks; if (this.isIgnited()) { this.a(1); } - int i = this.dz(); + int i = this.dV(); if (i > 0 && this.fuseTicks == 0) { this.a(SoundEffects.ENTITY_CREEPER_PRIMED, 1.0F, 0.5F); @@ -109,56 +117,57 @@ public class EntityCreeper extends EntityMonster { if (this.fuseTicks >= this.maxFuseTicks) { this.fuseTicks = this.maxFuseTicks; - this.dE(); + this.explode(); } } super.tick(); } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_CREEPER_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_CREEPER_DEATH; } - public void die(DamageSource damagesource) { - // super.die(damagesource); // CraftBukkit - Moved to end - if (this.world.getGameRules().getBoolean("doMobLoot")) { - if (damagesource.getEntity() instanceof EntitySkeleton) { - this.a((IMaterial) ItemRecord.a(this.random)); - } else if (damagesource.getEntity() instanceof EntityCreeper && damagesource.getEntity() != this && ((EntityCreeper) damagesource.getEntity()).isPowered() && ((EntityCreeper) damagesource.getEntity()).canCauseHeadDrop()) { - ((EntityCreeper) damagesource.getEntity()).setCausedHeadDrop(); + @Override + protected void dropDeathLoot(DamageSource damagesource, int i, boolean flag) { + super.dropDeathLoot(damagesource, i, flag); + Entity entity = damagesource.getEntity(); + + if (entity != this && entity instanceof EntityCreeper) { + EntityCreeper entitycreeper = (EntityCreeper) entity; + + if (entitycreeper.canCauseHeadDrop()) { + entitycreeper.setCausedHeadDrop(); this.a((IMaterial) Items.CREEPER_HEAD); } } - super.die(damagesource); // CraftBukkit - Moved from above } - public boolean B(Entity entity) { + @Override + public boolean C(Entity entity) { return true; } public boolean isPowered() { - return (Boolean) this.datawatcher.get(EntityCreeper.b); + return (Boolean) this.datawatcher.get(EntityCreeper.POWERED); } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.x; - } - - public int dz() { - return (Integer) this.datawatcher.get(EntityCreeper.a); + public int dV() { + return (Integer) this.datawatcher.get(EntityCreeper.b); } public void a(int i) { - this.datawatcher.set(EntityCreeper.a, i); + this.datawatcher.set(EntityCreeper.b, i); } + @Override public void onLightningStrike(EntityLightning entitylightning) { super.onLightningStrike(entitylightning); // CraftBukkit start @@ -170,19 +179,22 @@ public class EntityCreeper extends EntityMonster { } public void setPowered(boolean powered) { - this.datawatcher.set(EntityCreeper.b, powered); + this.datawatcher.set(EntityCreeper.POWERED, powered); } // CraftBukkit end + @Override protected boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); if (itemstack.getItem() == Items.FLINT_AND_STEEL) { - this.world.a(entityhuman, this.locX, this.locY, this.locZ, SoundEffects.ITEM_FLINTANDSTEEL_USE, this.bV(), 1.0F, this.random.nextFloat() * 0.4F + 0.8F); + this.world.playSound(entityhuman, this.locX, this.locY, this.locZ, SoundEffects.ITEM_FLINTANDSTEEL_USE, this.getSoundCategory(), 1.0F, this.random.nextFloat() * 0.4F + 0.8F); entityhuman.a(enumhand); if (!this.world.isClientSide) { - this.dB(); - itemstack.damage(1, entityhuman); + this.ignite(); + itemstack.damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(enumhand); + }); return true; } } @@ -190,10 +202,9 @@ public class EntityCreeper extends EntityMonster { return super.a(entityhuman, enumhand); } - public void explode() { this.dE(); } // Paper - OBFHELPER - private void dE() { + public void explode() { if (!this.world.isClientSide) { - boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); + Explosion.Effect explosion_effect = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? Explosion.Effect.DESTROY : Explosion.Effect.NONE; float f = this.isPowered() ? 2.0F : 1.0F; // CraftBukkit start @@ -201,7 +212,7 @@ public class EntityCreeper extends EntityMonster { this.world.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { this.killed = true; - this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), flag); + this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), explosion_effect); this.die(); this.createEffectCloud(); } else { @@ -230,38 +241,38 @@ public class EntityCreeper extends EntityMonster { while (iterator.hasNext()) { MobEffect mobeffect = (MobEffect) iterator.next(); - entityareaeffectcloud.a(new MobEffect(mobeffect)); + entityareaeffectcloud.addEffect(new MobEffect(mobeffect)); } - this.world.addEntity(entityareaeffectcloud); + this.world.addEntity(entityareaeffectcloud, CreatureSpawnEvent.SpawnReason.EXPLOSION); // CraftBukkit } } public boolean isIgnited() { - return (Boolean) this.datawatcher.get(EntityCreeper.c); + return (Boolean) this.datawatcher.get(EntityCreeper.d); + } + + public void ignite() { + // Paper start + setIgnited(true); } - // Paper start public void setIgnited(boolean ignited) { if (isIgnited() != ignited) { com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited); if (event.callEvent()) { - this.datawatcher.set(EntityCreeper.c, event.isIgnited()); + this.datawatcher.set(EntityCreeper.d, event.isIgnited()); } } - } - - public void dB() { - setIgnited(true); // Paper end } public boolean canCauseHeadDrop() { - return this.bG < 1 && this.world.getGameRules().getBoolean("doMobLoot"); + return this.isPowered() && this.bD < 1; } public void setCausedHeadDrop() { - ++this.bG; + ++this.bD; } } diff --git a/src/main/java/net/minecraft/server/EntityDamageSourceIndirect.java b/src/main/java/net/minecraft/server/EntityDamageSourceIndirect.java index 93ca59f3b..509fdf135 100644 --- a/src/main/java/net/minecraft/server/EntityDamageSourceIndirect.java +++ b/src/main/java/net/minecraft/server/EntityDamageSourceIndirect.java @@ -12,22 +12,25 @@ public class EntityDamageSourceIndirect extends EntityDamageSource { } @Nullable + @Override public Entity j() { - return this.w; + return this.x; } @Nullable + @Override public Entity getEntity() { return this.owner; } + @Override public IChatBaseComponent getLocalizedDeathMessage(EntityLiving entityliving) { - IChatBaseComponent ichatbasecomponent = this.owner == null ? this.w.getScoreboardDisplayName() : this.owner.getScoreboardDisplayName(); + IChatBaseComponent ichatbasecomponent = this.owner == null ? this.x.getScoreboardDisplayName() : this.owner.getScoreboardDisplayName(); ItemStack itemstack = this.owner instanceof EntityLiving ? ((EntityLiving) this.owner).getItemInMainHand() : ItemStack.a; String s = "death.attack." + this.translationIndex; String s1 = s + ".item"; - return !itemstack.isEmpty() && itemstack.hasName() ? new ChatMessage(s1, new Object[] { entityliving.getScoreboardDisplayName(), ichatbasecomponent, itemstack.A()}) : new ChatMessage(s, new Object[] { entityliving.getScoreboardDisplayName(), ichatbasecomponent}); + return !itemstack.isEmpty() && itemstack.hasName() ? new ChatMessage(s1, new Object[]{entityliving.getScoreboardDisplayName(), ichatbasecomponent, itemstack.B()}) : new ChatMessage(s, new Object[]{entityliving.getScoreboardDisplayName(), ichatbasecomponent}); } // CraftBukkit start diff --git a/src/main/java/net/minecraft/server/EntityDolphin.java b/src/main/java/net/minecraft/server/EntityDolphin.java index 8bf15a685..063fb7053 100644 --- a/src/main/java/net/minecraft/server/EntityDolphin.java +++ b/src/main/java/net/minecraft/server/EntityDolphin.java @@ -1,79 +1,87 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.List; +import java.util.Random; import java.util.function.Predicate; import javax.annotation.Nullable; public class EntityDolphin extends EntityWaterAnimal { - private static final DataWatcherObject b = DataWatcher.a(EntityDolphin.class, DataWatcherRegistry.l); - private static final DataWatcherObject c = DataWatcher.a(EntityDolphin.class, DataWatcherRegistry.i); - private static final DataWatcherObject bC = DataWatcher.a(EntityDolphin.class, DataWatcherRegistry.b); - public static final Predicate a = (entityitem) -> { + private static final DataWatcherObject c = DataWatcher.a(EntityDolphin.class, DataWatcherRegistry.l); + private static final DataWatcherObject d = DataWatcher.a(EntityDolphin.class, DataWatcherRegistry.i); + private static final DataWatcherObject bz = DataWatcher.a(EntityDolphin.class, DataWatcherRegistry.b); + private static final PathfinderTargetCondition bA = (new PathfinderTargetCondition()).a(10.0D).b().a().c(); + public static final Predicate b = (entityitem) -> { return !entityitem.q() && entityitem.isAlive() && entityitem.isInWater(); }; - public EntityDolphin(World world) { - super(EntityTypes.DOLPHIN, world); - this.setSize(0.9F, 0.6F); + public EntityDolphin(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.moveController = new EntityDolphin.a(this); this.lookController = new ControllerLookDolphin(this, 10); - this.p(true); + this.setCanPickupLoot(true); } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - this.setAirTicks(this.bf()); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.setAirTicks(this.bp()); this.pitch = 0.0F; - return super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } - public boolean ca() { + @Override + public boolean cm() { return false; } + @Override protected void a(int i) {} public void g(BlockPosition blockposition) { - this.datawatcher.set(EntityDolphin.b, blockposition); + this.datawatcher.set(EntityDolphin.c, blockposition); } public BlockPosition l() { - return (BlockPosition) this.datawatcher.get(EntityDolphin.b); + return (BlockPosition) this.datawatcher.get(EntityDolphin.c); } - public boolean dy() { - return (Boolean) this.datawatcher.get(EntityDolphin.c); + public boolean dV() { + return (Boolean) this.datawatcher.get(EntityDolphin.d); } - public void a(boolean flag) { - this.datawatcher.set(EntityDolphin.c, flag); + public void r(boolean flag) { + this.datawatcher.set(EntityDolphin.d, flag); } - public int dz() { - return (Integer) this.datawatcher.get(EntityDolphin.bC); + public int dW() { + return (Integer) this.datawatcher.get(EntityDolphin.bz); } public void b(int i) { - this.datawatcher.set(EntityDolphin.bC, i); + this.datawatcher.set(EntityDolphin.bz, i); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityDolphin.b, BlockPosition.ZERO); - this.datawatcher.register(EntityDolphin.c, false); - this.datawatcher.register(EntityDolphin.bC, 2400); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityDolphin.c, BlockPosition.ZERO); + this.datawatcher.register(EntityDolphin.d, false); + this.datawatcher.register(EntityDolphin.bz, 2400); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setInt("TreasurePosX", this.l().getX()); nbttagcompound.setInt("TreasurePosY", this.l().getY()); nbttagcompound.setInt("TreasurePosZ", this.l().getZ()); - nbttagcompound.setBoolean("GotFish", this.dy()); - nbttagcompound.setInt("Moistness", this.dz()); + nbttagcompound.setBoolean("GotFish", this.dV()); + nbttagcompound.setInt("Moistness", this.dW()); } + @Override public void a(NBTTagCompound nbttagcompound) { int i = nbttagcompound.getInt("TreasurePosX"); int j = nbttagcompound.getInt("TreasurePosY"); @@ -81,11 +89,12 @@ public class EntityDolphin extends EntityWaterAnimal { this.g(new BlockPosition(i, j, k)); super.a(nbttagcompound); - this.a(nbttagcompound.getBoolean("GotFish")); + this.r(nbttagcompound.getBoolean("GotFish")); this.b(nbttagcompound.getInt("Moistness")); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalBreath(this)); this.goalSelector.a(0, new PathfinderGoalWater(this)); this.goalSelector.a(1, new EntityDolphin.b(this)); @@ -98,22 +107,25 @@ public class EntityDolphin extends EntityWaterAnimal { this.goalSelector.a(8, new EntityDolphin.d()); this.goalSelector.a(8, new PathfinderGoalFollowBoat(this)); this.goalSelector.a(9, new PathfinderGoalAvoidTarget<>(this, EntityGuardian.class, 8.0F, 1.0D, 1.0D)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[] { EntityGuardian.class})); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityGuardian.class})).a(new Class[0])); // CraftBukkit - decompile error } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(1.2000000476837158D); this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE); this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D); } + @Override protected NavigationAbstract b(World world) { return new NavigationGuardian(this, world); } - public boolean B(Entity entity) { + @Override + public boolean C(Entity entity) { boolean flag = entity.damageEntity(DamageSource.mobAttack(this), (float) ((int) this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).getValue())); if (flag) { @@ -124,35 +136,54 @@ public class EntityDolphin extends EntityWaterAnimal { return flag; } - public int bf() { + @Override + public int bp() { return 4800; } - protected int l(int i) { - return this.bf(); + @Override + protected int m(int i) { + return this.bp(); } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 0.3F; } - public int K() { + @Override + public int M() { return 1; } - public int L() { + @Override + public int dA() { return 1; } + @Override protected boolean n(Entity entity) { return true; } + @Override + public boolean e(ItemStack itemstack) { + EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); + + return !this.getEquipment(enumitemslot).isEmpty() ? false : enumitemslot == EnumItemSlot.MAINHAND && super.e(itemstack); + } + + @Override protected void a(EntityItem entityitem) { if (this.getEquipment(EnumItemSlot.MAINHAND).isEmpty()) { ItemStack itemstack = entityitem.getItemStack(); - if (this.d(itemstack)) { + if (this.g(itemstack)) { + // CraftBukkit start - call EntityPickupItemEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entityitem, 0, false).isCancelled()) { + return; + } + // CraftBukkit end this.setSlot(EnumItemSlot.MAINHAND, itemstack); this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F; this.receive(entityitem, itemstack.getCount()); @@ -162,42 +193,42 @@ public class EntityDolphin extends EntityWaterAnimal { } + @Override public void tick() { super.tick(); if (!this.isNoAI()) { - if (this.ap()) { + if (this.au()) { this.b(2400); } else { - this.b(this.dz() - 1); - if (this.dz() <= 0) { + this.b(this.dW() - 1); + if (this.dW() <= 0) { this.damageEntity(DamageSource.DRYOUT, 1.0F); } if (this.onGround) { - this.motY += 0.5D; - this.motX += (double) ((this.random.nextFloat() * 2.0F - 1.0F) * 0.2F); - this.motZ += (double) ((this.random.nextFloat() * 2.0F - 1.0F) * 0.2F); + this.setMot(this.getMot().add((double) ((this.random.nextFloat() * 2.0F - 1.0F) * 0.2F), 0.5D, (double) ((this.random.nextFloat() * 2.0F - 1.0F) * 0.2F))); this.yaw = this.random.nextFloat() * 360.0F; this.onGround = false; this.impulse = true; } } - if (this.world.isClientSide && this.isInWater() && this.motX * this.motX + this.motY * this.motY + this.motZ * this.motZ > 0.03D) { + if (this.world.isClientSide && this.isInWater() && this.getMot().g() > 0.03D) { Vec3D vec3d = this.f(0.0F); float f = MathHelper.cos(this.yaw * 0.017453292F) * 0.3F; float f1 = MathHelper.sin(this.yaw * 0.017453292F) * 0.3F; float f2 = 1.2F - this.random.nextFloat() * 0.7F; for (int i = 0; i < 2; ++i) { - this.world.addParticle(Particles.X, this.locX - vec3d.x * (double) f2 + (double) f, this.locY - vec3d.y, this.locZ - vec3d.z * (double) f2 + (double) f1, 0.0D, 0.0D, 0.0D); - this.world.addParticle(Particles.X, this.locX - vec3d.x * (double) f2 - (double) f, this.locY - vec3d.y, this.locZ - vec3d.z * (double) f2 - (double) f1, 0.0D, 0.0D, 0.0D); + this.world.addParticle(Particles.DOLPHIN, this.locX - vec3d.x * (double) f2 + (double) f, this.locY - vec3d.y, this.locZ - vec3d.z * (double) f2 + (double) f1, 0.0D, 0.0D, 0.0D); + this.world.addParticle(Particles.DOLPHIN, this.locX - vec3d.x * (double) f2 - (double) f, this.locY - vec3d.y, this.locZ - vec3d.z * (double) f2 - (double) f1, 0.0D, 0.0D, 0.0D); } } } } + @Override protected boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -206,7 +237,7 @@ public class EntityDolphin extends EntityWaterAnimal { this.a(SoundEffects.ENTITY_DOLPHIN_EAT, 1.0F, 1.0F); } - this.a(true); + this.r(true); if (!entityhuman.abilities.canInstantlyBuild) { itemstack.subtract(1); } @@ -217,84 +248,59 @@ public class EntityDolphin extends EntityWaterAnimal { } } - @Nullable - public EntityItem f(ItemStack itemstack) { - if (itemstack.isEmpty()) { - return null; - } else { - double d0 = this.locY - 0.30000001192092896D + (double) this.getHeadHeight(); - EntityItem entityitem = new EntityItem(this.world, this.locX, d0, this.locZ, itemstack); - - entityitem.a(40); - entityitem.c(this.getUniqueID()); - float f = 0.3F; - - entityitem.motX = (double) (-MathHelper.sin(this.yaw * 0.017453292F) * MathHelper.cos(this.pitch * 0.017453292F) * f); - entityitem.motY = (double) (MathHelper.sin(this.pitch * 0.017453292F) * f * 1.5F); - entityitem.motZ = (double) (MathHelper.cos(this.yaw * 0.017453292F) * MathHelper.cos(this.pitch * 0.017453292F) * f); - float f1 = this.random.nextFloat() * 6.2831855F; - - f = 0.02F * this.random.nextFloat(); - entityitem.motX += (double) (MathHelper.cos(f1) * f); - entityitem.motZ += (double) (MathHelper.sin(f1) * f); - this.world.addEntity(entityitem); - return entityitem; - } + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return blockposition.getY() > 45 && blockposition.getY() < generatoraccess.getSeaLevel() && (generatoraccess.getBiome(blockposition) != Biomes.OCEAN || generatoraccess.getBiome(blockposition) != Biomes.DEEP_OCEAN) && generatoraccess.getFluid(blockposition).a(TagsFluid.WATER); } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - return this.locY > 45.0D && this.locY < (double) generatoraccess.getSeaLevel() && generatoraccess.getBiome(new BlockPosition(this)) != Biomes.OCEAN || generatoraccess.getBiome(new BlockPosition(this)) != Biomes.DEEP_OCEAN && super.a(generatoraccess, flag); - } - - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_DOLPHIN_HURT; } @Nullable - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_DOLPHIN_DEATH; } @Nullable - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return this.isInWater() ? SoundEffects.ENTITY_DOLPHIN_AMBIENT_WATER : SoundEffects.ENTITY_DOLPHIN_AMBIENT; } - protected SoundEffect ae() { + @Override + protected SoundEffect getSoundSplash() { return SoundEffects.ENTITY_DOLPHIN_SPLASH; } - protected SoundEffect ad() { + @Override + protected SoundEffect getSoundSwim() { return SoundEffects.ENTITY_DOLPHIN_SWIM; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aN; + protected boolean dX() { + BlockPosition blockposition = this.getNavigation().h(); + + return blockposition != null ? blockposition.a((IPosition) this.getPositionVector(), 12.0D) : false; } - protected boolean dA() { - BlockPosition blockposition = this.getNavigation().i(); - - return blockposition != null ? this.c(blockposition) < 144.0D : false; - } - - public void a(float f, float f1, float f2) { - if (this.cP() && this.isInWater()) { - this.a(f, f1, f2, this.cK()); - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - this.motX *= 0.8999999761581421D; - this.motY *= 0.8999999761581421D; - this.motZ *= 0.8999999761581421D; + @Override + public void e(Vec3D vec3d) { + if (this.df() && this.isInWater()) { + this.a(this.db(), vec3d); + this.move(EnumMoveType.SELF, this.getMot()); + this.setMot(this.getMot().a(0.9D)); if (this.getGoalTarget() == null) { - this.motY -= 0.005D; + this.setMot(this.getMot().add(0.0D, -0.005D, 0.0D)); } } else { - super.a(f, f1, f2); + super.e(vec3d); } } + @Override public boolean a(EntityHuman entityhuman) { return true; } @@ -306,26 +312,30 @@ public class EntityDolphin extends EntityWaterAnimal { b(EntityDolphin entitydolphin) { this.a = entitydolphin; - this.a(3); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); } - public boolean f() { + @Override + public boolean C_() { return false; } + @Override public boolean a() { - return this.a.dy() && this.a.getAirTicks() >= 100; + return this.a.dV() && this.a.getAirTicks() >= 100; } + @Override public boolean b() { BlockPosition blockposition = this.a.l(); - return this.a.c(new BlockPosition((double) blockposition.getX(), this.a.locY, (double) blockposition.getZ())) > 16.0D && !this.b && this.a.getAirTicks() >= 100; + return !(new BlockPosition((double) blockposition.getX(), this.a.locY, (double) blockposition.getZ())).a((IPosition) this.a.getPositionVector(), 4.0D) && !this.b && this.a.getAirTicks() >= 100; } + @Override public void c() { this.b = false; - this.a.getNavigation().q(); + this.a.getNavigation().o(); World world = this.a.world; BlockPosition blockposition = new BlockPosition(this.a); String s = (double) world.random.nextFloat() >= 0.5D ? "Ocean_Ruin" : "Shipwreck"; @@ -347,20 +357,22 @@ public class EntityDolphin extends EntityWaterAnimal { world.broadcastEntityEffect(this.a, (byte) 38); } + @Override public void d() { BlockPosition blockposition = this.a.l(); - if (this.a.c(new BlockPosition((double) blockposition.getX(), this.a.locY, (double) blockposition.getZ())) <= 16.0D || this.b) { - this.a.a(false); + if ((new BlockPosition((double) blockposition.getX(), this.a.locY, (double) blockposition.getZ())).a((IPosition) this.a.getPositionVector(), 4.0D) || this.b) { + this.a.r(false); } } + @Override public void e() { BlockPosition blockposition = this.a.l(); World world = this.a.world; - if (this.a.dA() || this.a.getNavigation().p()) { + if (this.a.dX() || this.a.getNavigation().n()) { Vec3D vec3d = RandomPositionGenerator.a((EntityCreature) this.a, 16, 1, new Vec3D((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), 0.39269909262657166D); if (vec3d == null) { @@ -380,7 +392,7 @@ public class EntityDolphin extends EntityWaterAnimal { return; } - this.a.getControllerLook().a(vec3d.x, vec3d.y, vec3d.z, (float) (this.a.L() + 20), (float) this.a.K()); + this.a.getControllerLook().a(vec3d.x, vec3d.y, vec3d.z, (float) (this.a.dA() + 20), (float) this.a.M()); this.a.getNavigation().a(vec3d.x, vec3d.y, vec3d.z, 1.3D); if (world.random.nextInt(80) == 0) { world.broadcastEntityEffect(this.a, (byte) 38); @@ -399,31 +411,36 @@ public class EntityDolphin extends EntityWaterAnimal { c(EntityDolphin entitydolphin, double d0) { this.a = entitydolphin; this.b = d0; - this.a(3); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); } + @Override public boolean a() { - this.c = this.a.world.findNearbyPlayer(this.a, 10.0D); + this.c = this.a.world.a(EntityDolphin.bA, (EntityLiving) this.a); return this.c == null ? false : this.c.isSwimming(); } + @Override public boolean b() { - return this.c != null && this.c.isSwimming() && this.a.h(this.c) < 256.0D; + return this.c != null && this.c.isSwimming() && this.a.h((Entity) this.c) < 256.0D; } + @Override public void c() { this.c.addEffect(new MobEffect(MobEffects.DOLPHINS_GRACE, 100), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.DOLPHIN); // CraftBukkit } + @Override public void d() { this.c = null; - this.a.getNavigation().q(); + this.a.getNavigation().o(); } + @Override public void e() { - this.a.getControllerLook().a(this.c, (float) (this.a.L() + 20), (float) this.a.K()); - if (this.a.h(this.c) < 6.25D) { - this.a.getNavigation().q(); + this.a.getControllerLook().a(this.c, (float) (this.a.dA() + 20), (float) this.a.M()); + if (this.a.h((Entity) this.c) < 6.25D) { + this.a.getNavigation().o(); } else { this.a.getNavigation().a((Entity) this.c, this.b); } @@ -441,18 +458,20 @@ public class EntityDolphin extends EntityWaterAnimal { private d() {} + @Override public boolean a() { if (this.b > EntityDolphin.this.ticksLived) { return false; } else { - List list = EntityDolphin.this.world.a(EntityItem.class, EntityDolphin.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityDolphin.a); + List list = EntityDolphin.this.world.a(EntityItem.class, EntityDolphin.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityDolphin.b); return !list.isEmpty() || !EntityDolphin.this.getEquipment(EnumItemSlot.MAINHAND).isEmpty(); } } + @Override public void c() { - List list = EntityDolphin.this.world.a(EntityItem.class, EntityDolphin.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityDolphin.a); + List list = EntityDolphin.this.world.a(EntityItem.class, EntityDolphin.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityDolphin.b); if (!list.isEmpty()) { EntityDolphin.this.getNavigation().a((Entity) list.get(0), 1.2000000476837158D); @@ -462,29 +481,47 @@ public class EntityDolphin extends EntityWaterAnimal { this.b = 0; } + @Override public void d() { ItemStack itemstack = EntityDolphin.this.getEquipment(EnumItemSlot.MAINHAND); if (!itemstack.isEmpty()) { - EntityDolphin.this.f(itemstack); + this.a(itemstack); EntityDolphin.this.setSlot(EnumItemSlot.MAINHAND, ItemStack.a); this.b = EntityDolphin.this.ticksLived + EntityDolphin.this.random.nextInt(100); } } + @Override public void e() { - List list = EntityDolphin.this.world.a(EntityItem.class, EntityDolphin.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityDolphin.a); + List list = EntityDolphin.this.world.a(EntityItem.class, EntityDolphin.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityDolphin.b); ItemStack itemstack = EntityDolphin.this.getEquipment(EnumItemSlot.MAINHAND); if (!itemstack.isEmpty()) { - EntityDolphin.this.f(itemstack); + this.a(itemstack); EntityDolphin.this.setSlot(EnumItemSlot.MAINHAND, ItemStack.a); } else if (!list.isEmpty()) { EntityDolphin.this.getNavigation().a((Entity) list.get(0), 1.2000000476837158D); } } + + private void a(ItemStack itemstack) { + if (!itemstack.isEmpty()) { + double d0 = EntityDolphin.this.locY - 0.30000001192092896D + (double) EntityDolphin.this.getHeadHeight(); + EntityItem entityitem = new EntityItem(EntityDolphin.this.world, EntityDolphin.this.locX, d0, EntityDolphin.this.locZ, itemstack); + + entityitem.setPickupDelay(40); + entityitem.setThrower(EntityDolphin.this.getUniqueID()); + float f = 0.3F; + float f1 = EntityDolphin.this.random.nextFloat() * 6.2831855F; + float f2 = 0.02F * EntityDolphin.this.random.nextFloat(); + + entityitem.setMot((double) (0.3F * -MathHelper.sin(EntityDolphin.this.yaw * 0.017453292F) * MathHelper.cos(EntityDolphin.this.pitch * 0.017453292F) + MathHelper.cos(f1) * f2), (double) (0.3F * MathHelper.sin(EntityDolphin.this.pitch * 0.017453292F) * 1.5F), (double) (0.3F * MathHelper.cos(EntityDolphin.this.yaw * 0.017453292F) * MathHelper.cos(EntityDolphin.this.pitch * 0.017453292F) + MathHelper.sin(f1) * f2)); + EntityDolphin.this.world.addEntity(entityitem); + } + } } static class a extends ControllerMove { @@ -496,12 +533,13 @@ public class EntityDolphin extends EntityWaterAnimal { this.i = entitydolphin; } + @Override public void a() { if (this.i.isInWater()) { - this.i.motY += 0.005D; + this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); } - if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().p()) { + if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().n()) { double d0 = this.b - this.i.locX; double d1 = this.c - this.i.locY; double d2 = this.d - this.i.locZ; @@ -510,24 +548,24 @@ public class EntityDolphin extends EntityWaterAnimal { if (d3 < 2.500000277905201E-7D) { this.a.r(0.0F); } else { - float f = (float) (MathHelper.c(d2, d0) * 57.2957763671875D) - 90.0F; + float f = (float) (MathHelper.d(d2, d0) * 57.2957763671875D) - 90.0F; this.i.yaw = this.a(this.i.yaw, f, 10.0F); - this.i.aQ = this.i.yaw; - this.i.aS = this.i.yaw; + this.i.aK = this.i.yaw; + this.i.aM = this.i.yaw; float f1 = (float) (this.e * this.i.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); if (this.i.isInWater()) { this.i.o(f1 * 0.02F); - float f2 = -((float) (MathHelper.c(d1, (double) MathHelper.sqrt(d0 * d0 + d2 * d2)) * 57.2957763671875D)); + float f2 = -((float) (MathHelper.d(d1, (double) MathHelper.sqrt(d0 * d0 + d2 * d2)) * 57.2957763671875D)); f2 = MathHelper.a(MathHelper.g(f2), -85.0F, 85.0F); this.i.pitch = this.a(this.i.pitch, f2, 5.0F); float f3 = MathHelper.cos(this.i.pitch * 0.017453292F); float f4 = MathHelper.sin(this.i.pitch * 0.017453292F); - this.i.bj = f3 * f1; - this.i.bi = -f4 * f1; + this.i.bd = f3 * f1; + this.i.bc = -f4 * f1; } else { this.i.o(f1 * 0.1F); } diff --git a/src/main/java/net/minecraft/server/EntityDragonFireball.java b/src/main/java/net/minecraft/server/EntityDragonFireball.java index c0d66a023..547698a2d 100644 --- a/src/main/java/net/minecraft/server/EntityDragonFireball.java +++ b/src/main/java/net/minecraft/server/EntityDragonFireball.java @@ -5,26 +5,27 @@ import java.util.List; public class EntityDragonFireball extends EntityFireball { - public EntityDragonFireball(World world) { - super(EntityTypes.DRAGON_FIREBALL, world, 1.0F, 1.0F); + public EntityDragonFireball(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntityDragonFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) { - super(EntityTypes.DRAGON_FIREBALL, entityliving, d0, d1, d2, world, 1.0F, 1.0F); + super(EntityTypes.DRAGON_FIREBALL, entityliving, d0, d1, d2, world); } + @Override protected void a(MovingObjectPosition movingobjectposition) { - if (movingobjectposition.entity == null || !movingobjectposition.entity.s(this.shooter)) { + if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.ENTITY || !((MovingObjectPositionEntity) movingobjectposition).getEntity().s(this.shooter)) { if (!this.world.isClientSide) { List list = this.world.a(EntityLiving.class, this.getBoundingBox().grow(4.0D, 2.0D, 4.0D)); EntityAreaEffectCloud entityareaeffectcloud = new EntityAreaEffectCloud(this.world, this.locX, this.locY, this.locZ); entityareaeffectcloud.setSource(this.shooter); - entityareaeffectcloud.setParticle(Particles.j); + entityareaeffectcloud.setParticle(Particles.DRAGON_BREATH); entityareaeffectcloud.setRadius(3.0F); entityareaeffectcloud.setDuration(600); entityareaeffectcloud.setRadiusPerTick((7.0F - entityareaeffectcloud.getRadius()) / (float) entityareaeffectcloud.getDuration()); - entityareaeffectcloud.a(new MobEffect(MobEffects.HARM, 1, 1)); + entityareaeffectcloud.addEffect(new MobEffect(MobEffects.HARM, 1, 1)); if (!list.isEmpty()) { Iterator iterator = list.iterator(); @@ -49,19 +50,23 @@ public class EntityDragonFireball extends EntityFireball { } } + @Override public boolean isInteractable() { return false; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { return false; } + @Override protected ParticleParam i() { - return Particles.j; + return Particles.DRAGON_BREATH; } - protected boolean f() { + @Override + protected boolean K_() { return false; } } diff --git a/src/main/java/net/minecraft/server/EntityDrowned.java b/src/main/java/net/minecraft/server/EntityDrowned.java index 0e2b5ee74..6f0094e6d 100644 --- a/src/main/java/net/minecraft/server/EntityDrowned.java +++ b/src/main/java/net/minecraft/server/EntityDrowned.java @@ -1,44 +1,42 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.Random; -import java.util.function.Predicate; import javax.annotation.Nullable; public class EntityDrowned extends EntityZombie implements IRangedEntity { - private boolean bC; - protected final NavigationGuardian a; - protected final Navigation b; + private boolean bz; + protected final NavigationGuardian b; + protected final Navigation c; - public EntityDrowned(World world) { - super(EntityTypes.DROWNED, world); - this.Q = 1.0F; - this.moveController = new EntityDrowned.e(this); + public EntityDrowned(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.K = 1.0F; + this.moveController = new EntityDrowned.d(this); this.a(PathType.WATER, 0.0F); - this.a = new NavigationGuardian(this, world); - this.b = new Navigation(this, world); + this.b = new NavigationGuardian(this, world); + this.c = new Navigation(this, world); } + @Override protected void l() { - this.goalSelector.a(1, new EntityDrowned.d(this, 1.0D)); - this.goalSelector.a(2, new EntityDrowned.g(this, 1.0D, 40, 10.0F)); + this.goalSelector.a(1, new EntityDrowned.c(this, 1.0D)); + this.goalSelector.a(2, new EntityDrowned.f(this, 1.0D, 40, 10.0F)); this.goalSelector.a(2, new EntityDrowned.a(this, 1.0D, false)); - this.goalSelector.a(5, new EntityDrowned.c(this, 1.0D)); - this.goalSelector.a(6, new EntityDrowned.f(this, 1.0D, this.world.getSeaLevel())); + this.goalSelector.a(5, new EntityDrowned.b(this, 1.0D)); + this.goalSelector.a(6, new EntityDrowned.e(this, 1.0D, this.world.getSeaLevel())); this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[] { EntityDrowned.class})); - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, new EntityDrowned.b(this))); - if ( world.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityDrowned.class})).a(EntityPigZombie.class)); + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, this::h)); + if ( world.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)); // Paper this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); - this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, true, false, EntityTurtle.bC)); + this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, true, false, EntityTurtle.bz)); } - protected NavigationAbstract b(World world) { - return super.b(world); - } - - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - groupdataentity = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + groupdataentity = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); if (this.getEquipment(EnumItemSlot.OFFHAND).isEmpty() && this.random.nextFloat() < 0.03F) { this.setSlot(EnumItemSlot.OFFHAND, new ItemStack(Items.NAUTILUS_SHELL)); this.dropChanceHand[EnumItemSlot.OFFHAND.b()] = 2.0F; @@ -47,49 +45,53 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { return groupdataentity; } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this.locX, this.locY, this.locZ)); + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + BiomeBase biomebase = generatoraccess.getBiome(blockposition); + boolean flag = generatoraccess.getDifficulty() != EnumDifficulty.PEACEFUL && a(generatoraccess, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || generatoraccess.getFluid(blockposition).a(TagsFluid.WATER)); - return biomebase != Biomes.RIVER && biomebase != Biomes.FROZEN_RIVER ? this.random.nextInt(40) == 0 && this.dF() && super.a(generatoraccess, flag) : this.random.nextInt(15) == 0 && super.a(generatoraccess, flag); + return biomebase != Biomes.RIVER && biomebase != Biomes.FROZEN_RIVER ? random.nextInt(40) == 0 && a(generatoraccess, blockposition) && flag : random.nextInt(15) == 0 && flag; } - private boolean dF() { - return this.getBoundingBox().minY < (double) (this.world.getSeaLevel() - 5); + private static boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition) { + return blockposition.getY() < generatoraccess.getSeaLevel() - 5; } - protected boolean dz() { + @Override + protected boolean dV() { return false; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aM; - } - - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return this.isInWater() ? SoundEffects.ENTITY_DROWNED_AMBIENT_WATER : SoundEffects.ENTITY_DROWNED_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return this.isInWater() ? SoundEffects.ENTITY_DROWNED_HURT_WATER : SoundEffects.ENTITY_DROWNED_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return this.isInWater() ? SoundEffects.ENTITY_DROWNED_DEATH_WATER : SoundEffects.ENTITY_DROWNED_DEATH; } - protected SoundEffect dA() { + @Override + protected SoundEffect getSoundStep() { return SoundEffects.ENTITY_DROWNED_STEP; } - protected SoundEffect ad() { + @Override + protected SoundEffect getSoundSwim() { return SoundEffects.ENTITY_DROWNED_SWIM; } - protected ItemStack dB() { + @Override + protected ItemStack dX() { return ItemStack.a; } + @Override protected void a(DifficultyDamageScaler difficultydamagescaler) { if ((double) this.random.nextFloat() > 0.9D) { int i = this.random.nextInt(16); @@ -103,28 +105,32 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { } + @Override protected boolean a(ItemStack itemstack, ItemStack itemstack1, EnumItemSlot enumitemslot) { return itemstack1.getItem() == Items.NAUTILUS_SHELL ? false : (itemstack1.getItem() == Items.TRIDENT ? (itemstack.getItem() == Items.TRIDENT ? itemstack.getDamage() < itemstack1.getDamage() : false) : (itemstack.getItem() == Items.TRIDENT ? true : super.a(itemstack, itemstack1, enumitemslot))); } - protected boolean dC() { + @Override + protected boolean dY() { return false; } + @Override public boolean a(IWorldReader iworldreader) { - return iworldreader.a_(this, this.getBoundingBox()) && iworldreader.getCubes(this, this.getBoundingBox()); + return iworldreader.i(this); } - public boolean f(@Nullable EntityLiving entityliving) { - return entityliving != null ? !this.world.L() || entityliving.isInWater() : false; + public boolean h(@Nullable EntityLiving entityliving) { + return entityliving != null ? !this.world.J() || entityliving.isInWater() : false; } - public boolean bw() { + @Override + public boolean bE() { return !this.isSwimming(); } - private boolean dI() { - if (this.bC) { + private boolean ee() { + if (this.bz) { return true; } else { EntityLiving entityliving = this.getGoalTarget(); @@ -133,40 +139,40 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { } } - public void a(float f, float f1, float f2) { - if (this.cP() && this.isInWater() && this.dI()) { - this.a(f, f1, f2, 0.01F); - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - this.motX *= 0.8999999761581421D; - this.motY *= 0.8999999761581421D; - this.motZ *= 0.8999999761581421D; + @Override + public void e(Vec3D vec3d) { + if (this.df() && this.isInWater() && this.ee()) { + this.a(0.01F, vec3d); + this.move(EnumMoveType.SELF, this.getMot()); + this.setMot(this.getMot().a(0.9D)); } else { - super.a(f, f1, f2); + super.e(vec3d); } } - public void as() { + @Override + public void ax() { if (!this.world.isClientSide) { - if (this.cP() && this.isInWater() && this.dI()) { - this.navigation = this.a; + if (this.df() && this.isInWater() && this.ee()) { + this.navigation = this.b; this.setSwimming(true); } else { - this.navigation = this.b; + this.navigation = this.c; this.setSwimming(false); } } } - protected boolean dD() { - PathEntity pathentity = this.getNavigation().m(); + protected boolean dZ() { + PathEntity pathentity = this.getNavigation().l(); if (pathentity != null) { - PathPoint pathpoint = pathentity.i(); + BlockPosition blockposition = pathentity.k(); - if (pathpoint != null) { - double d0 = this.d((double) pathpoint.a, (double) pathpoint.b, (double) pathpoint.c); + if (blockposition != null) { + double d0 = this.e((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); if (d0 < 4.0D) { return true; @@ -177,10 +183,11 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { return false; } + @Override public void a(EntityLiving entityliving, float f) { EntityThrownTrident entitythrowntrident = new EntityThrownTrident(this.world, this, new ItemStack(Items.TRIDENT)); double d0 = entityliving.locX - this.locX; - double d1 = entityliving.getBoundingBox().minY + (double) (entityliving.length / 3.0F) - entitythrowntrident.locY; + double d1 = entityliving.getBoundingBox().minY + (double) (entityliving.getHeight() / 3.0F) - entitythrowntrident.locY; double d2 = entityliving.locZ - this.locZ; double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2); @@ -189,41 +196,29 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { this.world.addEntity(entitythrowntrident); } - public void a(boolean flag) { - this.bC = flag; + public void r(boolean flag) { + this.bz = flag; } - static class b implements Predicate { - - private final EntityDrowned a; - - public b(EntityDrowned entitydrowned) { - this.a = entitydrowned; - } - - public boolean test(@Nullable EntityHuman entityhuman) { - return this.a.f((EntityLiving) entityhuman); - } - } - - static class e extends ControllerMove { + static class d extends ControllerMove { private final EntityDrowned i; - public e(EntityDrowned entitydrowned) { + public d(EntityDrowned entitydrowned) { super(entitydrowned); this.i = entitydrowned; } + @Override public void a() { EntityLiving entityliving = this.i.getGoalTarget(); - if (this.i.dI() && this.i.isInWater()) { - if (entityliving != null && entityliving.locY > this.i.locY || this.i.bC) { - this.i.motY += 0.002D; + if (this.i.ee() && this.i.isInWater()) { + if (entityliving != null && entityliving.locY > this.i.locY || this.i.bz) { + this.i.setMot(this.i.getMot().add(0.0D, 0.002D, 0.0D)); } - if (this.h != ControllerMove.Operation.MOVE_TO || this.i.getNavigation().p()) { + if (this.h != ControllerMove.Operation.MOVE_TO || this.i.getNavigation().n()) { this.i.o(0.0F); return; } @@ -234,19 +229,18 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { double d3 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); d1 /= d3; - float f = (float) (MathHelper.c(d2, d0) * 57.2957763671875D) - 90.0F; + float f = (float) (MathHelper.d(d2, d0) * 57.2957763671875D) - 90.0F; this.i.yaw = this.a(this.i.yaw, f, 90.0F); - this.i.aQ = this.i.yaw; + this.i.aK = this.i.yaw; float f1 = (float) (this.e * this.i.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); + float f2 = MathHelper.g(0.125F, this.i.db(), f1); - this.i.o(this.i.cK() + (f1 - this.i.cK()) * 0.125F); - this.i.motY += (double) this.i.cK() * d1 * 0.1D; - this.i.motX += (double) this.i.cK() * d0 * 0.005D; - this.i.motZ += (double) this.i.cK() * d2 * 0.005D; + this.i.o(f2); + this.i.setMot(this.i.getMot().add((double) f2 * d0 * 0.005D, (double) f2 * d1 * 0.1D, (double) f2 * d2 * 0.005D)); } else { if (!this.i.onGround) { - this.i.motY -= 0.008D; + this.i.setMot(this.i.getMot().add(0.0D, -0.008D, 0.0D)); } super.a(); @@ -264,16 +258,18 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { this.d = entitydrowned; } + @Override public boolean a() { - return super.a() && this.d.f(this.d.getGoalTarget()); + return super.a() && this.d.h(this.d.getGoalTarget()); } + @Override public boolean b() { - return super.b() && this.d.f(this.d.getGoalTarget()); + return super.b() && this.d.h(this.d.getGoalTarget()); } } - static class d extends PathfinderGoal { + static class c extends PathfinderGoal { private final EntityCreature a; private double b; @@ -282,15 +278,16 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { private final double e; private final World f; - public d(EntityCreature entitycreature, double d0) { + public c(EntityCreature entitycreature, double d0) { this.a = entitycreature; this.e = d0; this.f = entitycreature.world; - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); } + @Override public boolean a() { - if (!this.f.L()) { + if (!this.f.J()) { return false; } else if (this.a.isInWater()) { return false; @@ -308,10 +305,12 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { } } + @Override public boolean b() { - return !this.a.getNavigation().p(); + return !this.a.getNavigation().n(); } + @Override public void c() { this.a.getNavigation().a(this.b, this.c, this.d, this.e); } @@ -322,7 +321,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { BlockPosition blockposition = new BlockPosition(this.a.locX, this.a.getBoundingBox().minY, this.a.locZ); for (int i = 0; i < 10; ++i) { - BlockPosition blockposition1 = blockposition.a(random.nextInt(20) - 10, 2 - random.nextInt(8), random.nextInt(20) - 10); + BlockPosition blockposition1 = blockposition.b(random.nextInt(20) - 10, 2 - random.nextInt(8), random.nextInt(20) - 10); if (this.f.getType(blockposition1).getBlock() == Blocks.WATER) { return new Vec3D((double) blockposition1.getX(), (double) blockposition1.getY(), (double) blockposition1.getZ()); @@ -333,63 +332,71 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { } } - static class c extends PathfinderGoalGotoTarget { + static class b extends PathfinderGoalGotoTarget { - private final EntityDrowned f; + private final EntityDrowned g; - public c(EntityDrowned entitydrowned, double d0) { + public b(EntityDrowned entitydrowned, double d0) { super(entitydrowned, d0, 8, 2); - this.f = entitydrowned; + this.g = entitydrowned; } + @Override public boolean a() { - return super.a() && !this.f.world.L() && this.f.isInWater() && this.f.locY >= (double) (this.f.world.getSeaLevel() - 3); + return super.a() && !this.g.world.J() && this.g.isInWater() && this.g.locY >= (double) (this.g.world.getSeaLevel() - 3); } + @Override public boolean b() { return super.b(); } + @Override protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) { BlockPosition blockposition1 = blockposition.up(); - return iworldreader.isEmpty(blockposition1) && iworldreader.isEmpty(blockposition1.up()) ? iworldreader.getType(blockposition).q() : false; + return iworldreader.isEmpty(blockposition1) && iworldreader.isEmpty(blockposition1.up()) ? iworldreader.getType(blockposition).a((IBlockAccess) iworldreader, blockposition, (Entity) this.g) : false; } + @Override public void c() { - this.f.a(false); - this.f.navigation = this.f.b; + this.g.r(false); + this.g.navigation = this.g.c; super.c(); } + @Override public void d() { super.d(); } } - static class f extends PathfinderGoal { + static class e extends PathfinderGoal { private final EntityDrowned a; private final double b; private final int c; private boolean d; - public f(EntityDrowned entitydrowned, double d0, int i) { + public e(EntityDrowned entitydrowned, double d0, int i) { this.a = entitydrowned; this.b = d0; this.c = i; } + @Override public boolean a() { - return !this.a.world.L() && this.a.isInWater() && this.a.locY < (double) (this.c - 2); + return !this.a.world.J() && this.a.isInWater() && this.a.locY < (double) (this.c - 2); } + @Override public boolean b() { return this.a() && !this.d; } + @Override public void e() { - if (this.a.locY < (double) (this.c - 1) && (this.a.getNavigation().p() || this.a.dD())) { + if (this.a.locY < (double) (this.c - 1) && (this.a.getNavigation().n() || this.a.dZ())) { Vec3D vec3d = RandomPositionGenerator.a(this.a, 4, 8, new Vec3D(this.a.locX, (double) (this.c - 1), this.a.locZ)); if (vec3d == null) { @@ -402,37 +409,44 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { } + @Override public void c() { - this.a.a(true); + this.a.r(true); this.d = false; } + @Override public void d() { - this.a.a(false); + this.a.r(false); } } - static class g extends PathfinderGoalArrowAttack { + static class f extends PathfinderGoalArrowAttack { private final EntityDrowned a; - public g(IRangedEntity irangedentity, double d0, int i, float f) { + public f(IRangedEntity irangedentity, double d0, int i, float f) { super(irangedentity, d0, i, f); this.a = (EntityDrowned) irangedentity; } + @Override public boolean a() { return super.a() && this.a.getItemInMainHand().getItem() == Items.TRIDENT; } + @Override public void c() { super.c(); - this.a.s(true); + this.a.q(true); + this.a.c(EnumHand.MAIN_HAND); } + @Override public void d() { super.d(); - this.a.s(false); + this.a.dp(); + this.a.q(false); } } } diff --git a/src/main/java/net/minecraft/server/EntityEgg.java b/src/main/java/net/minecraft/server/EntityEgg.java index 174b87971..aedf2ce17 100644 --- a/src/main/java/net/minecraft/server/EntityEgg.java +++ b/src/main/java/net/minecraft/server/EntityEgg.java @@ -7,10 +7,10 @@ import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerEggThrowEvent; // CraftBukkit end -public class EntityEgg extends EntityProjectile { +public class EntityEgg extends EntityProjectileThrowable { - public EntityEgg(World world) { - super(EntityTypes.EGG, world); + public EntityEgg(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntityEgg(World world, EntityLiving entityliving) { @@ -21,9 +21,10 @@ public class EntityEgg extends EntityProjectile { super(EntityTypes.EGG, d0, d1, d2, world); } + @Override protected void a(MovingObjectPosition movingobjectposition) { - if (movingobjectposition.entity != null) { - movingobjectposition.entity.damageEntity(DamageSource.projectile(this, this.getShooter()), 0.0F); + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + ((MovingObjectPositionEntity) movingobjectposition).getEntity().damageEntity(DamageSource.projectile(this, this.getShooter()), 0.0F); } if (!this.world.isClientSide) { @@ -68,4 +69,9 @@ public class EntityEgg extends EntityProjectile { } } + + @Override + protected Item i() { + return Items.EGG; + } } diff --git a/src/main/java/net/minecraft/server/EntityEnderCrystal.java b/src/main/java/net/minecraft/server/EntityEnderCrystal.java index 79bdb82b3..801552fc6 100644 --- a/src/main/java/net/minecraft/server/EntityEnderCrystal.java +++ b/src/main/java/net/minecraft/server/EntityEnderCrystal.java @@ -10,36 +10,38 @@ import org.bukkit.event.entity.ExplosionPrimeEvent; public class EntityEnderCrystal extends Entity { - private static final DataWatcherObject> b = DataWatcher.a(EntityEnderCrystal.class, DataWatcherRegistry.m); - private static final DataWatcherObject c = DataWatcher.a(EntityEnderCrystal.class, DataWatcherRegistry.i); - public int a; + private static final DataWatcherObject> c = DataWatcher.a(EntityEnderCrystal.class, DataWatcherRegistry.m); + private static final DataWatcherObject d = DataWatcher.a(EntityEnderCrystal.class, DataWatcherRegistry.i); + public int b; - public EntityEnderCrystal(World world) { - super(EntityTypes.END_CRYSTAL, world); - this.j = true; - this.setSize(2.0F, 2.0F); - this.a = this.random.nextInt(100000); + public EntityEnderCrystal(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.i = true; + this.b = this.random.nextInt(100000); } public EntityEnderCrystal(World world, double d0, double d1, double d2) { - this(world); + this(EntityTypes.END_CRYSTAL, world); this.setPosition(d0, d1, d2); } + @Override protected boolean playStepSound() { return false; } - protected void x_() { - this.getDataWatcher().register(EntityEnderCrystal.b, Optional.empty()); - this.getDataWatcher().register(EntityEnderCrystal.c, true); + @Override + protected void initDatawatcher() { + this.getDataWatcher().register(EntityEnderCrystal.c, Optional.empty()); + this.getDataWatcher().register(EntityEnderCrystal.d, true); } + @Override public void tick() { this.lastX = this.locX; this.lastY = this.locY; this.lastZ = this.locZ; - ++this.a; + ++this.b; if (!this.world.isClientSide) { BlockPosition blockposition = new BlockPosition(this); @@ -54,6 +56,7 @@ public class EntityEnderCrystal extends Entity { } + @Override protected void b(NBTTagCompound nbttagcompound) { if (this.getBeamTarget() != null) { nbttagcompound.set("BeamTarget", GameProfileSerializer.a(this.getBeamTarget())); @@ -62,6 +65,7 @@ public class EntityEnderCrystal extends Entity { nbttagcompound.setBoolean("ShowBottom", this.isShowingBottom()); } + @Override protected void a(NBTTagCompound nbttagcompound) { if (nbttagcompound.hasKeyOfType("BeamTarget", 10)) { this.setBeamTarget(GameProfileSerializer.c(nbttagcompound.getCompound("BeamTarget"))); @@ -73,10 +77,12 @@ public class EntityEnderCrystal extends Entity { } + @Override public boolean isInteractable() { return true; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -90,27 +96,26 @@ public class EntityEnderCrystal extends Entity { } // CraftBukkit end this.die(); - if (!this.world.isClientSide) { - if (!damagesource.isExplosion()) { - // CraftBukkit start - ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 6.0F, false); - this.world.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - this.dead = false; - return false; - } - this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), true); - // CraftBukkit end + if (!damagesource.isExplosion()) { + // CraftBukkit start + ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 6.0F, false); + this.world.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + this.dead = false; + return false; } - - this.a(damagesource); + this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), Explosion.Effect.DESTROY); + // CraftBukkit end } + + this.a(damagesource); } return true; } } + @Override public void killEntity() { this.a(DamageSource.GENERIC); super.killEntity(); @@ -119,7 +124,7 @@ public class EntityEnderCrystal extends Entity { private void a(DamageSource damagesource) { if (this.world.worldProvider instanceof WorldProviderTheEnd) { WorldProviderTheEnd worldprovidertheend = (WorldProviderTheEnd) this.world.worldProvider; - EnderDragonBattle enderdragonbattle = worldprovidertheend.r(); + EnderDragonBattle enderdragonbattle = worldprovidertheend.q(); if (enderdragonbattle != null) { enderdragonbattle.a(this, damagesource); @@ -129,19 +134,24 @@ public class EntityEnderCrystal extends Entity { } public void setBeamTarget(@Nullable BlockPosition blockposition) { - this.getDataWatcher().set(EntityEnderCrystal.b, Optional.ofNullable(blockposition)); + this.getDataWatcher().set(EntityEnderCrystal.c, Optional.ofNullable(blockposition)); } @Nullable public BlockPosition getBeamTarget() { - return (BlockPosition) ((Optional) this.getDataWatcher().get(EntityEnderCrystal.b)).orElse((Object) null); + return (BlockPosition) ((Optional) this.getDataWatcher().get(EntityEnderCrystal.c)).orElse((Object) null); } public void setShowingBottom(boolean flag) { - this.getDataWatcher().set(EntityEnderCrystal.c, flag); + this.getDataWatcher().set(EntityEnderCrystal.d, flag); } public boolean isShowingBottom() { - return (Boolean) this.getDataWatcher().get(EntityEnderCrystal.c); + return (Boolean) this.getDataWatcher().get(EntityEnderCrystal.d); + } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); } } diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java index db5041e2f..c8c74f2b3 100644 --- a/src/main/java/net/minecraft/server/EntityEnderDragon.java +++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -1,70 +1,73 @@ package net.minecraft.server; +import com.google.common.collect.Lists; import java.util.Iterator; import java.util.List; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; // CraftBukkit start +import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityRegainHealthEvent; // CraftBukkit end import com.destroystokyo.paper.event.block.TNTPrimeEvent; // Paper - TNTPrimeEvent // PAIL: Fixme -public class EntityEnderDragon extends EntityInsentient implements IComplex, IMonster { +public class EntityEnderDragon extends EntityInsentient implements IMonster { - private static final Logger bQ = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public static final DataWatcherObject PHASE = DataWatcher.a(EntityEnderDragon.class, DataWatcherRegistry.b); - public double[][] b = new double[64][3]; - public int c = -1; - public EntityComplexPart[] children; - public EntityComplexPart bD = new EntityComplexPart(this, "head", 6.0F, 6.0F); - public EntityComplexPart bE = new EntityComplexPart(this, "neck", 6.0F, 6.0F); - public EntityComplexPart bF = new EntityComplexPart(this, "body", 8.0F, 8.0F); - public EntityComplexPart bG = new EntityComplexPart(this, "tail", 4.0F, 4.0F); - public EntityComplexPart bH = new EntityComplexPart(this, "tail", 4.0F, 4.0F); - public EntityComplexPart bI = new EntityComplexPart(this, "tail", 4.0F, 4.0F); - public EntityComplexPart bJ = new EntityComplexPart(this, "wing", 4.0F, 4.0F); - public EntityComplexPart bK = new EntityComplexPart(this, "wing", 4.0F, 4.0F); - public float bL; - public float bM; - public boolean bN; - public int bO; + private static final PathfinderTargetCondition bO = (new PathfinderTargetCondition()).a(64.0D); + public final double[][] c = new double[64][3]; + public int d = -1; + public final EntityComplexPart[] children; + public final EntityComplexPart bA = new EntityComplexPart(this, "head", 1.0F, 1.0F); + public final EntityComplexPart bB = new EntityComplexPart(this, "neck", 3.0F, 3.0F); + public final EntityComplexPart bC = new EntityComplexPart(this, "body", 5.0F, 3.0F); + public final EntityComplexPart bD = new EntityComplexPart(this, "tail", 2.0F, 2.0F); + public final EntityComplexPart bE = new EntityComplexPart(this, "tail", 2.0F, 2.0F); + public final EntityComplexPart bF = new EntityComplexPart(this, "tail", 2.0F, 2.0F); + public final EntityComplexPart bG = new EntityComplexPart(this, "wing", 4.0F, 2.0F); + public final EntityComplexPart bH = new EntityComplexPart(this, "wing", 4.0F, 2.0F); + public float bI; + public float bJ; + public boolean bK; + public int bL; public EntityEnderCrystal currentEnderCrystal; - private final EnderDragonBattle bR; - private final DragonControllerManager bS; - private int bT = 100; - private int bU; - private final PathPoint[] bV = new PathPoint[24]; - private final int[] bW = new int[24]; - private final Path bX = new Path(); - private Explosion explosionSource = new Explosion(null, this, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, true); // CraftBukkit - reusable source for CraftTNTPrimed.getSource() + private final EnderDragonBattle bP; + private final DragonControllerManager bQ; + private int bR = 100; + private int bS; + private final PathPoint[] bT = new PathPoint[24]; + private final int[] bU = new int[24]; + private final Path bV = new Path(); + private Explosion explosionSource = new Explosion(null, this, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.Effect.DESTROY); // CraftBukkit - reusable source for CraftTNTPrimed.getSource() - public EntityEnderDragon(World world) { + public EntityEnderDragon(EntityTypes entitytypes, World world) { super(EntityTypes.ENDER_DRAGON, world); - this.children = new EntityComplexPart[] { this.bD, this.bE, this.bF, this.bG, this.bH, this.bI, this.bJ, this.bK}; + this.children = new EntityComplexPart[]{this.bA, this.bB, this.bC, this.bD, this.bE, this.bF, this.bG, this.bH}; this.setHealth(this.getMaxHealth()); - this.setSize(16.0F, 8.0F); this.noclip = true; - this.fireProof = true; - this.ak = true; + this.af = true; if (!world.isClientSide && world.worldProvider instanceof WorldProviderTheEnd) { - this.bR = ((WorldProviderTheEnd) world.worldProvider).r(); + this.bP = ((WorldProviderTheEnd) world.worldProvider).q(); } else { - this.bR = null; + this.bP = null; } - this.bS = new DragonControllerManager(this); + this.bQ = new DragonControllerManager(this); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(200.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(200.0D); } - protected void x_() { - super.x_(); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); this.getDataWatcher().register(EntityEnderDragon.PHASE, DragonControllerPhase.HOVER.b()); } @@ -74,20 +77,21 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } f = 1.0F - f; - int j = this.c - i & 63; - int k = this.c - i - 1 & 63; + int j = this.d - i & 63; + int k = this.d - i - 1 & 63; double[] adouble = new double[3]; - double d0 = this.b[j][0]; - double d1 = MathHelper.g(this.b[k][0] - d0); + double d0 = this.c[j][0]; + double d1 = MathHelper.g(this.c[k][0] - d0); adouble[0] = d0 + d1 * (double) f; - d0 = this.b[j][1]; - d1 = this.b[k][1] - d0; + d0 = this.c[j][1]; + d1 = this.c[k][1] - d0; adouble[1] = d0 + d1 * (double) f; - adouble[2] = this.b[j][2] + (this.b[k][2] - this.b[j][2]) * (double) f; + adouble[2] = MathHelper.d((double) f, this.c[j][2], this.c[k][2]); return adouble; } + @Override public void movementTick() { float f; float f1; @@ -95,178 +99,164 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo if (this.world.isClientSide) { this.setHealth(this.getHealth()); if (!this.isSilent()) { - f = MathHelper.cos(this.bM * 6.2831855F); - f1 = MathHelper.cos(this.bL * 6.2831855F); + f = MathHelper.cos(this.bJ * 6.2831855F); + f1 = MathHelper.cos(this.bI * 6.2831855F); if (f1 <= -0.3F && f >= -0.3F) { - this.world.a(this.locX, this.locY, this.locZ, SoundEffects.ENTITY_ENDER_DRAGON_FLAP, this.bV(), 5.0F, 0.8F + this.random.nextFloat() * 0.3F, false); + this.world.a(this.locX, this.locY, this.locZ, SoundEffects.ENTITY_ENDER_DRAGON_FLAP, this.getSoundCategory(), 5.0F, 0.8F + this.random.nextFloat() * 0.3F, false); } - if (!this.bS.a().a() && --this.bT < 0) { - this.world.a(this.locX, this.locY, this.locZ, SoundEffects.ENTITY_ENDER_DRAGON_GROWL, this.bV(), 2.5F, 0.8F + this.random.nextFloat() * 0.3F, false); - this.bT = 200 + this.random.nextInt(200); + if (!this.bQ.a().a() && --this.bR < 0) { + this.world.a(this.locX, this.locY, this.locZ, SoundEffects.ENTITY_ENDER_DRAGON_GROWL, this.getSoundCategory(), 2.5F, 0.8F + this.random.nextFloat() * 0.3F, false); + this.bR = 200 + this.random.nextInt(200); } } } - this.bL = this.bM; - float f2; - - if (false && this.getHealth() <= 0.0F) { // Akarin - this handle by client + this.bI = this.bJ; + if (this.getHealth() <= 0.0F) { f = (this.random.nextFloat() - 0.5F) * 8.0F; f1 = (this.random.nextFloat() - 0.5F) * 4.0F; - f2 = (this.random.nextFloat() - 0.5F) * 8.0F; - this.world.addParticle(Particles.u, this.locX + (double) f, this.locY + 2.0D + (double) f1, this.locZ + (double) f2, 0.0D, 0.0D, 0.0D); + float f2 = (this.random.nextFloat() - 0.5F) * 8.0F; + + this.world.addParticle(Particles.EXPLOSION, this.locX + (double) f, this.locY + 2.0D + (double) f1, this.locZ + (double) f2, 0.0D, 0.0D, 0.0D); } else { - this.dt(); - f = 0.2F / (MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ) * 10.0F + 1.0F); - f *= (float) Math.pow(2.0D, this.motY); - if (this.bS.a().a()) { - this.bM += 0.1F; - } else if (this.bN) { - this.bM += f * 0.5F; + this.dW(); + Vec3D vec3d = this.getMot(); + + f1 = 0.2F / (MathHelper.sqrt(b(vec3d)) * 10.0F + 1.0F); + f1 *= (float) Math.pow(2.0D, vec3d.y); + if (this.bQ.a().a()) { + this.bJ += 0.1F; + } else if (this.bK) { + this.bJ += f1 * 0.5F; } else { - this.bM += f; + this.bJ += f1; } this.yaw = MathHelper.g(this.yaw); if (this.isNoAI()) { - this.bM = 0.5F; + this.bJ = 0.5F; } else { - if (this.c < 0) { - for (int i = 0; i < this.b.length; ++i) { - this.b[i][0] = (double) this.yaw; - this.b[i][1] = this.locY; + if (this.d < 0) { + for (int i = 0; i < this.c.length; ++i) { + this.c[i][0] = (double) this.yaw; + this.c[i][1] = this.locY; } } - if (++this.c == this.b.length) { - this.c = 0; + if (++this.d == this.c.length) { + this.d = 0; } - this.b[this.c][0] = (double) this.yaw; - this.b[this.c][1] = this.locY; + this.c[this.d][0] = (double) this.yaw; + this.c[this.d][1] = this.locY; double d0; double d1; double d2; float f3; - float f4; if (this.world.isClientSide) { - if (this.bl > 0) { - double d3 = this.locX + (this.bm - this.locX) / (double) this.bl; + if (this.bf > 0) { + double d3 = this.locX + (this.bg - this.locX) / (double) this.bf; - d0 = this.locY + (this.bn - this.locY) / (double) this.bl; - d1 = this.locZ + (this.bo - this.locZ) / (double) this.bl; - d2 = MathHelper.g(this.bp - (double) this.yaw); - this.yaw = (float) ((double) this.yaw + d2 / (double) this.bl); - this.pitch = (float) ((double) this.pitch + (this.bq - (double) this.pitch) / (double) this.bl); - --this.bl; + d0 = this.locY + (this.bh - this.locY) / (double) this.bf; + d1 = this.locZ + (this.bi - this.locZ) / (double) this.bf; + d2 = MathHelper.g(this.bj - (double) this.yaw); + this.yaw = (float) ((double) this.yaw + d2 / (double) this.bf); + this.pitch = (float) ((double) this.pitch + (this.bk - (double) this.pitch) / (double) this.bf); + --this.bf; this.setPosition(d3, d0, d1); this.setYawPitch(this.yaw, this.pitch); } - this.bS.a().b(); + this.bQ.a().b(); } else { - IDragonController idragoncontroller = this.bS.a(); + IDragonController idragoncontroller = this.bQ.a(); idragoncontroller.c(); - if (this.bS.a() != idragoncontroller) { - idragoncontroller = this.bS.a(); + if (this.bQ.a() != idragoncontroller) { + idragoncontroller = this.bQ.a(); idragoncontroller.c(); } - Vec3D vec3d = idragoncontroller.g(); + Vec3D vec3d1 = idragoncontroller.g(); - if (vec3d != null && idragoncontroller.getControllerPhase() != DragonControllerPhase.HOVER) { // CraftBukkit - Don't move when hovering - d0 = vec3d.x - this.locX; - d1 = vec3d.y - this.locY; - d2 = vec3d.z - this.locZ; + if (vec3d1 != null && idragoncontroller.getControllerPhase() != DragonControllerPhase.HOVER) { // CraftBukkit - Don't move when hovering + d0 = vec3d1.x - this.locX; + d1 = vec3d1.y - this.locY; + d2 = vec3d1.z - this.locZ; double d4 = d0 * d0 + d1 * d1 + d2 * d2; f3 = idragoncontroller.f(); - d1 = MathHelper.a(d1 / (double) MathHelper.sqrt(d0 * d0 + d2 * d2), (double) (-f3), (double) f3); - this.motY += d1 * 0.10000000149011612D; - this.yaw = MathHelper.g(this.yaw); - double d5 = MathHelper.a(MathHelper.g(180.0D - MathHelper.c(d0, d2) * 57.2957763671875D - (double) this.yaw), -50.0D, 50.0D); - Vec3D vec3d1 = (new Vec3D(vec3d.x - this.locX, vec3d.y - this.locY, vec3d.z - this.locZ)).a(); - Vec3D vec3d2 = (new Vec3D((double) MathHelper.sin(this.yaw * 0.017453292F), this.motY, (double) (-MathHelper.cos(this.yaw * 0.017453292F)))).a(); + double d5 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2); - f4 = Math.max(((float) vec3d2.b(vec3d1) + 0.5F) / 1.5F, 0.0F); - this.bk *= 0.8F; - this.bk = (float) ((double) this.bk + d5 * (double) idragoncontroller.h()); - this.yaw += this.bk * 0.1F; + if (d5 > 0.0D) { + d1 = MathHelper.a(d1 / d5, (double) (-f3), (double) f3); + } + + this.setMot(this.getMot().add(0.0D, d1 * 0.01D, 0.0D)); + this.yaw = MathHelper.g(this.yaw); + double d6 = MathHelper.a(MathHelper.g(180.0D - MathHelper.d(d0, d2) * 57.2957763671875D - (double) this.yaw), -50.0D, 50.0D); + Vec3D vec3d2 = vec3d1.a(this.locX, this.locY, this.locZ).d(); + Vec3D vec3d3 = (new Vec3D((double) MathHelper.sin(this.yaw * 0.017453292F), this.getMot().y, (double) (-MathHelper.cos(this.yaw * 0.017453292F)))).d(); + float f4 = Math.max(((float) vec3d3.b(vec3d2) + 0.5F) / 1.5F, 0.0F); + + this.be *= 0.8F; + this.be = (float) ((double) this.be + d6 * (double) idragoncontroller.h()); + this.yaw += this.be * 0.1F; float f5 = (float) (2.0D / (d4 + 1.0D)); float f6 = 0.06F; - this.a(0.0F, 0.0F, -1.0F, 0.06F * (f4 * f5 + (1.0F - f5))); - if (this.bN) { - this.move(EnumMoveType.SELF, this.motX * 0.800000011920929D, this.motY * 0.800000011920929D, this.motZ * 0.800000011920929D); + this.a(0.06F * (f4 * f5 + (1.0F - f5)), new Vec3D(0.0D, 0.0D, -1.0D)); + if (this.bK) { + this.move(EnumMoveType.SELF, this.getMot().a(0.800000011920929D)); } else { - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); + this.move(EnumMoveType.SELF, this.getMot()); } - Vec3D vec3d3 = (new Vec3D(this.motX, this.motY, this.motZ)).a(); - float f7 = ((float) vec3d3.b(vec3d2) + 1.0F) / 2.0F; + Vec3D vec3d4 = this.getMot().d(); + double d7 = 0.8D + 0.15D * (vec3d4.b(vec3d3) + 1.0D) / 2.0D; - f7 = 0.8F + 0.15F * f7; - this.motX *= (double) f7; - this.motZ *= (double) f7; - this.motY *= 0.9100000262260437D; + this.setMot(this.getMot().d(d7, 0.9100000262260437D, d7)); } } - this.aQ = this.yaw; - this.bD.width = 1.0F; - this.bD.length = 1.0F; - this.bE.width = 3.0F; - this.bE.length = 3.0F; - this.bG.width = 2.0F; - this.bG.length = 2.0F; - this.bH.width = 2.0F; - this.bH.length = 2.0F; - this.bI.width = 2.0F; - this.bI.length = 2.0F; - this.bF.length = 3.0F; - this.bF.width = 5.0F; - this.bJ.length = 2.0F; - this.bJ.width = 4.0F; - this.bK.length = 3.0F; - this.bK.width = 4.0F; + this.aK = this.yaw; Vec3D[] avec3d = new Vec3D[this.children.length]; for (int j = 0; j < this.children.length; ++j) { avec3d[j] = new Vec3D(this.children[j].locX, this.children[j].locY, this.children[j].locZ); } - f2 = (float) (this.a(5, 1.0F)[1] - this.a(10, 1.0F)[1]) * 10.0F * 0.017453292F; - float f8 = MathHelper.cos(f2); - float f9 = MathHelper.sin(f2); + float f7 = (float) (this.a(5, 1.0F)[1] - this.a(10, 1.0F)[1]) * 10.0F * 0.017453292F; + float f8 = MathHelper.cos(f7); + float f9 = MathHelper.sin(f7); float f10 = this.yaw * 0.017453292F; float f11 = MathHelper.sin(f10); float f12 = MathHelper.cos(f10); - this.bF.tick(); - this.bF.setPositionRotation(this.locX + (double) (f11 * 0.5F), this.locY, this.locZ - (double) (f12 * 0.5F), 0.0F, 0.0F); - this.bJ.tick(); - this.bJ.setPositionRotation(this.locX + (double) (f12 * 4.5F), this.locY + 2.0D, this.locZ + (double) (f11 * 4.5F), 0.0F, 0.0F); - this.bK.tick(); - this.bK.setPositionRotation(this.locX - (double) (f12 * 4.5F), this.locY + 2.0D, this.locZ - (double) (f11 * 4.5F), 0.0F, 0.0F); + this.bC.tick(); + this.bC.setPositionRotation(this.locX + (double) (f11 * 0.5F), this.locY, this.locZ - (double) (f12 * 0.5F), 0.0F, 0.0F); + this.bG.tick(); + this.bG.setPositionRotation(this.locX + (double) (f12 * 4.5F), this.locY + 2.0D, this.locZ + (double) (f11 * 4.5F), 0.0F, 0.0F); + this.bH.tick(); + this.bH.setPositionRotation(this.locX - (double) (f12 * 4.5F), this.locY + 2.0D, this.locZ - (double) (f11 * 4.5F), 0.0F, 0.0F); if (!this.world.isClientSide && this.hurtTicks == 0) { - this.a(this.world.getEntities(this, this.bJ.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D))); - this.a(this.world.getEntities(this, this.bK.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D))); - this.b(this.world.getEntities(this, this.bD.getBoundingBox().g(1.0D))); - this.b(this.world.getEntities(this, this.bE.getBoundingBox().g(1.0D))); + this.a(this.world.getEntities(this, this.bG.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e)); + this.a(this.world.getEntities(this, this.bH.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e)); + this.b(this.world.getEntities(this, this.bA.getBoundingBox().g(1.0D), IEntitySelector.e)); + this.b(this.world.getEntities(this, this.bB.getBoundingBox().g(1.0D), IEntitySelector.e)); } double[] adouble = this.a(5, 1.0F); - float f13 = MathHelper.sin(this.yaw * 0.017453292F - this.bk * 0.01F); - float f14 = MathHelper.cos(this.yaw * 0.017453292F - this.bk * 0.01F); + float f13 = MathHelper.sin(this.yaw * 0.017453292F - this.be * 0.01F); + float f14 = MathHelper.cos(this.yaw * 0.017453292F - this.be * 0.01F); - this.bD.tick(); - this.bE.tick(); - f3 = this.u(1.0F); - this.bD.setPositionRotation(this.locX + (double) (f13 * 6.5F * f8), this.locY + (double) f3 + (double) (f9 * 6.5F), this.locZ - (double) (f14 * 6.5F * f8), 0.0F, 0.0F); - this.bE.setPositionRotation(this.locX + (double) (f13 * 5.5F * f8), this.locY + (double) f3 + (double) (f9 * 5.5F), this.locZ - (double) (f14 * 5.5F * f8), 0.0F, 0.0F); + this.bA.tick(); + this.bB.tick(); + f3 = this.v(1.0F); + this.bA.setPositionRotation(this.locX + (double) (f13 * 6.5F * f8), this.locY + (double) f3 + (double) (f9 * 6.5F), this.locZ - (double) (f14 * 6.5F * f8), 0.0F, 0.0F); + this.bB.setPositionRotation(this.locX + (double) (f13 * 5.5F * f8), this.locY + (double) f3 + (double) (f9 * 5.5F), this.locZ - (double) (f14 * 5.5F * f8), 0.0F, 0.0F); int k; @@ -274,32 +264,32 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo EntityComplexPart entitycomplexpart = null; if (k == 0) { - entitycomplexpart = this.bG; + entitycomplexpart = this.bD; } if (k == 1) { - entitycomplexpart = this.bH; + entitycomplexpart = this.bE; } if (k == 2) { - entitycomplexpart = this.bI; + entitycomplexpart = this.bF; } double[] adouble1 = this.a(12 + k * 2, 1.0F); - float f15 = this.yaw * 0.017453292F + this.c(adouble1[0] - adouble[0]) * 0.017453292F; + float f15 = this.yaw * 0.017453292F + this.d(adouble1[0] - adouble[0]) * 0.017453292F; float f16 = MathHelper.sin(f15); float f17 = MathHelper.cos(f15); float f18 = 1.5F; + float f19 = (float) (k + 1) * 2.0F; - f4 = (float) (k + 1) * 2.0F; entitycomplexpart.tick(); - entitycomplexpart.setPositionRotation(this.locX - (double) ((f11 * 1.5F + f16 * f4) * f8), this.locY + (adouble1[1] - adouble[1]) - (double) ((f4 + 1.5F) * f9) + 1.5D, this.locZ + (double) ((f12 * 1.5F + f17 * f4) * f8), 0.0F, 0.0F); + entitycomplexpart.setPositionRotation(this.locX - (double) ((f11 * 1.5F + f16 * f19) * f8), this.locY + (adouble1[1] - adouble[1]) - (double) ((f19 + 1.5F) * f9) + 1.5D, this.locZ + (double) ((f12 * 1.5F + f17 * f19) * f8), 0.0F, 0.0F); } if (!this.world.isClientSide) { - this.bN = this.b(this.bD.getBoundingBox()) | this.b(this.bE.getBoundingBox()) | this.b(this.bF.getBoundingBox()); - if (this.bR != null) { - this.bR.b(this); + this.bK = this.b(this.bA.getBoundingBox()) | this.b(this.bB.getBoundingBox()) | this.b(this.bC.getBoundingBox()); + if (this.bP != null) { + this.bP.b(this); } } @@ -313,10 +303,10 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } } - private float u(float f) { + private float v(float f) { double d0; - if (this.bS.a().a()) { + if (this.bQ.a().a()) { d0 = -1.0D; } else { double[] adouble = this.a(5, 1.0F); @@ -328,7 +318,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo return (float) d0; } - private void dt() { + private void dW() { if (this.currentEnderCrystal != null) { if (this.currentEnderCrystal.dead) { this.currentEnderCrystal = null; @@ -366,8 +356,8 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } private void a(List list) { - double d0 = (this.bF.getBoundingBox().minX + this.bF.getBoundingBox().maxX) / 2.0D; - double d1 = (this.bF.getBoundingBox().minZ + this.bF.getBoundingBox().maxZ) / 2.0D; + double d0 = (this.bC.getBoundingBox().minX + this.bC.getBoundingBox().maxX) / 2.0D; + double d1 = (this.bC.getBoundingBox().minZ + this.bC.getBoundingBox().maxZ) / 2.0D; Iterator iterator = list.iterator(); while (iterator.hasNext()) { @@ -379,7 +369,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo double d4 = d2 * d2 + d3 * d3; entity.f(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D); - if (!this.bS.a().a() && ((EntityLiving) entity).cg() < entity.ticksLived - 2) { + if (!this.bQ.a().a() && ((EntityLiving) entity).ct() < entity.ticksLived - 2) { entity.damageEntity(DamageSource.mobAttack(this), 5.0F); this.a((EntityLiving) this, entity); } @@ -400,7 +390,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } - private float c(double d0) { + private float d(double d0) { return (float) MathHelper.g(d0); } @@ -415,7 +405,6 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo boolean flag1 = false; // CraftBukkit start - Create a list to hold all the destroyed blocks List destroyedBlocks = new java.util.ArrayList(); - org.bukkit.craftbukkit.CraftWorld craftWorld = this.world.getWorld(); // CraftBukkit end for (int k1 = i; k1 <= l; ++k1) { @@ -426,18 +415,12 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo Block block = iblockdata.getBlock(); if (!iblockdata.isAir() && iblockdata.getMaterial() != Material.FIRE) { - if (!this.world.getGameRules().getBoolean("mobGriefing")) { - flag = true; - } else if (block != Blocks.BARRIER && block != Blocks.OBSIDIAN && block != Blocks.END_STONE && block != Blocks.BEDROCK && block != Blocks.END_PORTAL && block != Blocks.END_PORTAL_FRAME) { - if (block != Blocks.COMMAND_BLOCK && block != Blocks.REPEATING_COMMAND_BLOCK && block != Blocks.CHAIN_COMMAND_BLOCK && block != Blocks.IRON_BARS && block != Blocks.END_GATEWAY) { - // CraftBukkit start - Add blocks to list rather than destroying them - // flag1 = this.world.setAir(blockposition) || flag1; - flag1 = true; - destroyedBlocks.add(craftWorld.getBlockAt(blockposition)); // Akarin - // CraftBukkit end - } else { - flag = true; - } + if (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) && !TagsBlock.DRAGON_IMMUNE.isTagged(block)) { + // CraftBukkit start - Add blocks to list rather than destroying them + // flag1 = this.world.a(blockposition, false) || flag1; + flag1 = true; + destroyedBlocks.add(CraftBlock.at(world, blockposition)); + // CraftBukkit end } else { flag = true; } @@ -447,6 +430,11 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } // CraftBukkit start - Set off an EntityExplodeEvent for the dragon exploding all these blocks + // SPIGOT-4882: don't fire event if nothing hit + if (!flag1) { + return flag; + } + org.bukkit.entity.Entity bukkitEntity = this.getBukkitEntity(); EntityExplodeEvent event = new EntityExplodeEvent(bukkitEntity, bukkitEntity.getLocation(), destroyedBlocks, 0F); bukkitEntity.getServer().getPluginManager().callEvent(event); @@ -457,7 +445,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } else if (event.getYield() == 0F) { // Yield zero ==> no drops for (org.bukkit.block.Block block : event.blockList()) { - this.world.setAir(new BlockPosition(block.getX(), block.getY(), block.getZ())); + this.world.a(new BlockPosition(block.getX(), block.getY(), block.getZ()), false); } } else { for (org.bukkit.block.Block block : event.blockList()) { @@ -466,45 +454,40 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo continue; } - int blockX = block.getX(); - int blockY = block.getY(); - int blockZ = block.getZ(); + CraftBlock craftBlock = ((CraftBlock) block); + BlockPosition blockposition = craftBlock.getPosition(); - Block nmsBlock = org.bukkit.craftbukkit.util.CraftMagicNumbers.getBlock(blockId); + Block nmsBlock = craftBlock.getNMS().getBlock(); if (nmsBlock.a(explosionSource)) { - BlockPosition pos = new BlockPosition(blockX, blockY, blockZ); - nmsBlock.dropNaturally(world.getType(pos), world, pos, event.getYield(), 0); + TileEntity tileentity = nmsBlock.isTileEntity() ? this.world.getTileEntity(blockposition) : null; + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).a(this.world.random).set(LootContextParameters.POSITION, blockposition).set(LootContextParameters.TOOL, ItemStack.a).set(LootContextParameters.EXPLOSION_RADIUS, 1.0F / event.getYield()).setOptional(LootContextParameters.BLOCK_ENTITY, tileentity); + + Block.b(craftBlock.getNMS(), loottableinfo_builder); } // Paper start - TNTPrimeEvent - org.bukkit.block.Block tntBlock = world.getWorld().getBlockAt(blockX, blockY, blockZ); - if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getSource().bukkitEntity).callEvent()) + org.bukkit.block.Block tntBlock = world.getWorld().getBlockAt(blockposition.x, blockposition.y, blockposition.z); + if(!new TNTPrimeEvent(tntBlock, TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getSource().getBukkitEntity()).callEvent()) continue; // Paper end - nmsBlock.wasExploded(world, new BlockPosition(blockX, blockY, blockZ), explosionSource); + nmsBlock.wasExploded(world, blockposition, explosionSource); - this.world.setAir(new BlockPosition(blockX, blockY, blockZ)); + this.world.a(blockposition, false); } } // CraftBukkit end - // Akarin start - this handle by client - /* if (flag1) { - double d0 = axisalignedbb.minX + (axisalignedbb.maxX - axisalignedbb.minX) * (double) this.random.nextFloat(); - double d1 = axisalignedbb.minY + (axisalignedbb.maxY - axisalignedbb.minY) * (double) this.random.nextFloat(); - double d2 = axisalignedbb.minZ + (axisalignedbb.maxZ - axisalignedbb.minZ) * (double) this.random.nextFloat(); + BlockPosition blockposition1 = new BlockPosition(i + this.random.nextInt(l - i + 1), j + this.random.nextInt(i1 - j + 1), k + this.random.nextInt(j1 - k + 1)); - this.world.addParticle(Particles.u, d0, d1, d2, 0.0D, 0.0D, 0.0D); + this.world.triggerEffect(2008, blockposition1, 0); } - */ - // Akarin end return flag; } public boolean a(EntityComplexPart entitycomplexpart, DamageSource damagesource, float f) { - f = this.bS.a().a(entitycomplexpart, damagesource, f); - if (entitycomplexpart != this.bD) { + f = this.bQ.a().a(damagesource, f); + if (entitycomplexpart != this.bA) { f = f / 4.0F + Math.min(f, 1.0F); } @@ -515,16 +498,16 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo float f1 = this.getHealth(); this.dealDamage(damagesource, f); - if (this.getHealth() <= 0.0F && !this.bS.a().a()) { + if (this.getHealth() <= 0.0F && !this.bQ.a().a()) { this.setHealth(1.0F); - this.bS.setControllerPhase(DragonControllerPhase.DYING); + this.bQ.setControllerPhase(DragonControllerPhase.DYING); } - if (this.bS.a().a()) { - this.bU = (int) ((float) this.bU + (f1 - this.getHealth())); - if ((float) this.bU > 0.25F * this.getMaxHealth()) { - this.bU = 0; - this.bS.setControllerPhase(DragonControllerPhase.TAKEOFF); + if (this.bQ.a().a()) { + this.bS = (int) ((float) this.bS + (f1 - this.getHealth())); + if ((float) this.bS > 0.25F * this.getMaxHealth()) { + this.bS = 0; + this.bQ.setControllerPhase(DragonControllerPhase.TAKEOFF); } } } @@ -533,9 +516,10 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (damagesource instanceof EntityDamageSource && ((EntityDamageSource) damagesource).y()) { - this.a(this.bF, damagesource, f); + this.a(this.bC, damagesource, f); } return false; @@ -545,53 +529,50 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo return super.damageEntity(damagesource, f); } + @Override public void killEntity() { this.die(); - if (this.bR != null) { - this.bR.b(this); - this.bR.a(this); + if (this.bP != null) { + this.bP.b(this); + this.bP.a(this); } } - protected void cb() { - if (this.bR != null) { - this.bR.b(this); + @Override + protected void co() { + if (this.bP != null) { + this.bP.b(this); } - ++this.bO; - // Akarin start - this handle by client - /* - if (this.bO >= 180 && this.bO <= 200) { + ++this.bL; + if (this.bL >= 180 && this.bL <= 200) { float f = (this.random.nextFloat() - 0.5F) * 8.0F; float f1 = (this.random.nextFloat() - 0.5F) * 4.0F; float f2 = (this.random.nextFloat() - 0.5F) * 8.0F; - this.world.addParticle(Particles.t, this.locX + (double) f, this.locY + 2.0D + (double) f1, this.locZ + (double) f2, 0.0D, 0.0D, 0.0D); + this.world.addParticle(Particles.EXPLOSION_EMITTER, this.locX + (double) f, this.locY + 2.0D + (double) f1, this.locZ + (double) f2, 0.0D, 0.0D, 0.0D); } - */ - // Akarin end - boolean flag = this.world.getGameRules().getBoolean("doMobLoot"); + boolean flag = this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT); short short0 = 500; - if (this.bR != null && !this.bR.d()) { + if (this.bP != null && !this.bP.d()) { short0 = 12000; } if (!this.world.isClientSide) { - if (this.bO > 150 && this.bO % 5 == 0 && flag) { + if (this.bL > 150 && this.bL % 5 == 0 && flag) { this.a(MathHelper.d((float) short0 * 0.08F)); } - if (this.bO == 1) { + if (this.bL == 1) { // CraftBukkit start - Use relative location for far away sounds - // this.world.a(1028, new BlockPosition(this), 0); + // this.world.b(1028, new BlockPosition(this), 0); // Paper start - //int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API - for (EntityHuman human : world.players) { - EntityPlayer player = (EntityPlayer) human; - int viewDistance = player.getViewDistance(); + int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API + for (EntityPlayer player : ((WorldServer)world).getPlayers()) { + //final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch // Paper end double deltaX = this.locX - player.locX; double deltaZ = this.locZ - player.locZ; @@ -610,16 +591,16 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } } - this.move(EnumMoveType.SELF, 0.0D, 0.10000000149011612D, 0.0D); + this.move(EnumMoveType.SELF, new Vec3D(0.0D, 0.10000000149011612D, 0.0D)); this.yaw += 20.0F; - this.aQ = this.yaw; - if (this.bO == 200 && !this.world.isClientSide) { + this.aK = this.yaw; + if (this.bL == 200 && !this.world.isClientSide) { if (flag) { this.a(MathHelper.d((float) short0 * 0.2F)); } - if (this.bR != null) { - this.bR.a(this); + if (this.bP != null) { + this.bP.a(this); } this.die(); @@ -638,77 +619,77 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } public int l() { - if (this.bV[0] == null) { + if (this.bT[0] == null) { for (int i = 0; i < 24; ++i) { int j = 5; int k; int l; if (i < 12) { - k = (int) (60.0F * MathHelper.cos(2.0F * (-3.1415927F + 0.2617994F * (float) i))); - l = (int) (60.0F * MathHelper.sin(2.0F * (-3.1415927F + 0.2617994F * (float) i))); + k = MathHelper.d(60.0F * MathHelper.cos(2.0F * (-3.1415927F + 0.2617994F * (float) i))); + l = MathHelper.d(60.0F * MathHelper.sin(2.0F * (-3.1415927F + 0.2617994F * (float) i))); } else { int i1; if (i < 20) { i1 = i - 12; - k = (int) (40.0F * MathHelper.cos(2.0F * (-3.1415927F + 0.3926991F * (float) i1))); - l = (int) (40.0F * MathHelper.sin(2.0F * (-3.1415927F + 0.3926991F * (float) i1))); + k = MathHelper.d(40.0F * MathHelper.cos(2.0F * (-3.1415927F + 0.3926991F * (float) i1))); + l = MathHelper.d(40.0F * MathHelper.sin(2.0F * (-3.1415927F + 0.3926991F * (float) i1))); j += 10; } else { i1 = i - 20; - k = (int) (20.0F * MathHelper.cos(2.0F * (-3.1415927F + 0.7853982F * (float) i1))); - l = (int) (20.0F * MathHelper.sin(2.0F * (-3.1415927F + 0.7853982F * (float) i1))); + k = MathHelper.d(20.0F * MathHelper.cos(2.0F * (-3.1415927F + 0.7853982F * (float) i1))); + l = MathHelper.d(20.0F * MathHelper.sin(2.0F * (-3.1415927F + 0.7853982F * (float) i1))); } } int j1 = Math.max(this.world.getSeaLevel() + 10, this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, new BlockPosition(k, 0, l)).getY() + j); - this.bV[i] = new PathPoint(k, j1, l); + this.bT[i] = new PathPoint(k, j1, l); } - this.bW[0] = 6146; - this.bW[1] = 8197; - this.bW[2] = 8202; - this.bW[3] = 16404; - this.bW[4] = 32808; - this.bW[5] = 32848; - this.bW[6] = 65696; - this.bW[7] = 131392; - this.bW[8] = 131712; - this.bW[9] = 263424; - this.bW[10] = 526848; - this.bW[11] = 525313; - this.bW[12] = 1581057; - this.bW[13] = 3166214; - this.bW[14] = 2138120; - this.bW[15] = 6373424; - this.bW[16] = 4358208; - this.bW[17] = 12910976; - this.bW[18] = 9044480; - this.bW[19] = 9706496; - this.bW[20] = 15216640; - this.bW[21] = 13688832; - this.bW[22] = 11763712; - this.bW[23] = 8257536; + this.bU[0] = 6146; + this.bU[1] = 8197; + this.bU[2] = 8202; + this.bU[3] = 16404; + this.bU[4] = 32808; + this.bU[5] = 32848; + this.bU[6] = 65696; + this.bU[7] = 131392; + this.bU[8] = 131712; + this.bU[9] = 263424; + this.bU[10] = 526848; + this.bU[11] = 525313; + this.bU[12] = 1581057; + this.bU[13] = 3166214; + this.bU[14] = 2138120; + this.bU[15] = 6373424; + this.bU[16] = 4358208; + this.bU[17] = 12910976; + this.bU[18] = 9044480; + this.bU[19] = 9706496; + this.bU[20] = 15216640; + this.bU[21] = 13688832; + this.bU[22] = 11763712; + this.bU[23] = 8257536; } - return this.k(this.locX, this.locY, this.locZ); + return this.l(this.locX, this.locY, this.locZ); } - public int k(double d0, double d1, double d2) { + public int l(double d0, double d1, double d2) { float f = 10000.0F; int i = 0; PathPoint pathpoint = new PathPoint(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); byte b0 = 0; - if (this.bR == null || this.bR.c() == 0) { + if (this.bP == null || this.bP.c() == 0) { b0 = 12; } for (int j = b0; j < 24; ++j) { - if (this.bV[j] != null) { - float f1 = this.bV[j].b(pathpoint); + if (this.bT[j] != null) { + float f1 = this.bT[j].b(pathpoint); if (f1 < f) { f = f1; @@ -725,7 +706,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo PathPoint pathpoint1; for (int k = 0; k < 24; ++k) { - pathpoint1 = this.bV[k]; + pathpoint1 = this.bT[k]; pathpoint1.i = false; pathpoint1.g = 0.0F; pathpoint1.e = 0.0F; @@ -734,24 +715,24 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo pathpoint1.d = -1; } - PathPoint pathpoint2 = this.bV[i]; + PathPoint pathpoint2 = this.bT[i]; - pathpoint1 = this.bV[j]; + pathpoint1 = this.bT[j]; pathpoint2.e = 0.0F; pathpoint2.f = pathpoint2.a(pathpoint1); pathpoint2.g = pathpoint2.f; - this.bX.a(); - this.bX.a(pathpoint2); + this.bV.a(); + this.bV.a(pathpoint2); PathPoint pathpoint3 = pathpoint2; byte b0 = 0; - if (this.bR == null || this.bR.c() == 0) { + if (this.bP == null || this.bP.c() == 0) { b0 = 12; } label70: - while (!this.bX.e()) { - PathPoint pathpoint4 = this.bX.c(); + while (!this.bV.e()) { + PathPoint pathpoint4 = this.bV.c(); if (pathpoint4.equals(pathpoint1)) { if (pathpoint != null) { @@ -772,7 +753,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo while (true) { if (i1 < 24) { - if (this.bV[i1] != pathpoint4) { + if (this.bT[i1] != pathpoint4) { ++i1; continue; } @@ -787,21 +768,21 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo continue label70; } - if ((this.bW[l] & 1 << i1) > 0) { - PathPoint pathpoint5 = this.bV[i1]; + if ((this.bU[l] & 1 << i1) > 0) { + PathPoint pathpoint5 = this.bT[i1]; if (!pathpoint5.i) { float f = pathpoint4.e + pathpoint4.a(pathpoint5); - if (!pathpoint5.a() || f < pathpoint5.e) { + if (!pathpoint5.c() || f < pathpoint5.e) { pathpoint5.h = pathpoint4; pathpoint5.e = f; pathpoint5.f = pathpoint5.a(pathpoint1); - if (pathpoint5.a()) { - this.bX.a(pathpoint5, pathpoint5.e + pathpoint5.f); + if (pathpoint5.c()) { + this.bV.a(pathpoint5, pathpoint5.e + pathpoint5.f); } else { pathpoint5.g = pathpoint5.e + pathpoint5.f; - this.bX.a(pathpoint5); + this.bV.a(pathpoint5); } } } @@ -815,7 +796,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo if (pathpoint3 == pathpoint2) { return null; } else { - EntityEnderDragon.bQ.debug("Failed to find path from {} to {}", i, j); + EntityEnderDragon.LOGGER.debug("Failed to find path from {} to {}", i, j); if (pathpoint != null) { pathpoint.h = pathpoint3; pathpoint3 = pathpoint; @@ -826,77 +807,68 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } private PathEntity a(PathPoint pathpoint, PathPoint pathpoint1) { - int i = 1; + List list = Lists.newArrayList(); + PathPoint pathpoint2 = pathpoint1; - PathPoint pathpoint2; + list.add(0, pathpoint1); - for (pathpoint2 = pathpoint1; pathpoint2.h != null; pathpoint2 = pathpoint2.h) { - ++i; - } - - PathPoint[] apathpoint = new PathPoint[i]; - - pathpoint2 = pathpoint1; - --i; - - for (apathpoint[i] = pathpoint1; pathpoint2.h != null; apathpoint[i] = pathpoint2) { + while (pathpoint2.h != null) { pathpoint2 = pathpoint2.h; - --i; + list.add(0, pathpoint2); } - return new PathEntity(apathpoint); + return new PathEntity(list, new BlockPosition(pathpoint1.a, pathpoint1.b, pathpoint1.c), true); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setInt("DragonPhase", this.bS.a().getControllerPhase().b()); + nbttagcompound.setInt("DragonPhase", this.bQ.a().getControllerPhase().b()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKey("DragonPhase")) { - this.bS.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase"))); + this.bQ.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase"))); } } - protected void I() {} + @Override + protected void checkDespawn() {} - public Entity[] bi() { + public EntityComplexPart[] dT() { return this.children; } + @Override public boolean isInteractable() { return false; } - public World J_() { - return this.world; - } - - public SoundCategory bV() { + @Override + public SoundCategory getSoundCategory() { return SoundCategory.HOSTILE; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_ENDER_DRAGON_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_ENDER_DRAGON_HURT; } - protected float cD() { + @Override + protected float getSoundVolume() { return 5.0F; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aH; - } - - public Vec3D a(float f) { - IDragonController idragoncontroller = this.bS.a(); + public Vec3D u(float f) { + IDragonController idragoncontroller = this.bQ.a(); DragonControllerPhase dragoncontrollerphase = idragoncontroller.getControllerPhase(); float f1; Vec3D vec3d; @@ -915,7 +887,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo } else { BlockPosition blockposition = this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, WorldGenEndTrophy.a); - f1 = Math.max(MathHelper.sqrt(this.d(blockposition)) / 4.0F, 1.0F); + f1 = Math.max(MathHelper.sqrt(blockposition.a(this.getPositionVector(), true)) / 4.0F, 1.0F); float f3 = 6.0F / f1; float f4 = this.pitch; float f5 = 1.5F; @@ -934,42 +906,46 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo if (damagesource.getEntity() instanceof EntityHuman) { entityhuman = (EntityHuman) damagesource.getEntity(); } else { - entityhuman = this.world.a(blockposition, 64.0D, 64.0D); + entityhuman = this.world.a(EntityEnderDragon.bO, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); } if (entityendercrystal == this.currentEnderCrystal) { - this.a(this.bD, DamageSource.b(entityhuman), 10.0F); + this.a(this.bA, DamageSource.b(entityhuman), 10.0F); } - this.bS.a().a(entityendercrystal, blockposition, damagesource, entityhuman); + this.bQ.a().a(entityendercrystal, blockposition, damagesource, entityhuman); } + @Override public void a(DataWatcherObject datawatcherobject) { if (EntityEnderDragon.PHASE.equals(datawatcherobject) && this.world.isClientSide) { - this.bS.setControllerPhase(DragonControllerPhase.getById((Integer) this.getDataWatcher().get(EntityEnderDragon.PHASE))); + this.bQ.setControllerPhase(DragonControllerPhase.getById((Integer) this.getDataWatcher().get(EntityEnderDragon.PHASE))); } super.a(datawatcherobject); } public DragonControllerManager getDragonControllerManager() { - return this.bS; + return this.bQ; } @Nullable public EnderDragonBattle getEnderDragonBattle() { - return this.bR; + return this.bP; } + @Override public boolean addEffect(MobEffect mobeffect) { return false; } + @Override protected boolean n(Entity entity) { return false; } - public boolean bm() { + @Override + public boolean canPortal() { return false; } } diff --git a/src/main/java/net/minecraft/server/EntityEnderPearl.java b/src/main/java/net/minecraft/server/EntityEnderPearl.java index 57030de4a..c553a92a0 100644 --- a/src/main/java/net/minecraft/server/EntityEnderPearl.java +++ b/src/main/java/net/minecraft/server/EntityEnderPearl.java @@ -8,12 +8,12 @@ import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.player.PlayerTeleportEvent; // CraftBukkit end -public class EntityEnderPearl extends EntityProjectile { +public class EntityEnderPearl extends EntityProjectileThrowable { private EntityLiving e; - public EntityEnderPearl(World world) { - super(EntityTypes.ENDER_PEARL, world); + public EntityEnderPearl(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntityEnderPearl(World world, EntityLiving entityliving) { @@ -21,19 +21,27 @@ public class EntityEnderPearl extends EntityProjectile { this.e = entityliving; } + @Override + protected Item i() { + return Items.ENDER_PEARL; + } + + @Override protected void a(MovingObjectPosition movingobjectposition) { EntityLiving entityliving = this.getShooter(); - if (movingobjectposition.entity != null) { - if (movingobjectposition.entity == this.e) { + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + Entity entity = ((MovingObjectPositionEntity) movingobjectposition).getEntity(); + + if (entity == this.e) { return; } - movingobjectposition.entity.damageEntity(DamageSource.projectile(this, entityliving), 0.0F); + entity.damageEntity(DamageSource.projectile(this, entityliving), 0.0F); } - if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { - BlockPosition blockposition = movingobjectposition.getBlockPosition(); + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + BlockPosition blockposition = ((MovingObjectPositionBlock) movingobjectposition).getBlockPosition(); TileEntity tileentity = this.world.getTileEntity(blockposition); if (tileentity instanceof TileEntityEndGateway) { @@ -54,13 +62,9 @@ public class EntityEnderPearl extends EntityProjectile { } } - // Akarin start - /* for (int i = 0; i < 32; ++i) { - this.world.addParticle(Particles.K, this.locX, this.locY + this.random.nextDouble() * 2.0D, this.locZ, this.random.nextGaussian(), 0.0D, this.random.nextGaussian()); + this.world.addParticle(Particles.PORTAL, this.locX, this.locY + this.random.nextDouble() * 2.0D, this.locZ, this.random.nextGaussian(), 0.0D, this.random.nextGaussian()); } - */ - // Akarin end if (!this.world.isClientSide) { if (entityliving instanceof EntityPlayer) { @@ -77,8 +81,8 @@ public class EntityEnderPearl extends EntityProjectile { Bukkit.getPluginManager().callEvent(teleEvent); if (!teleEvent.isCancelled() && !entityplayer.playerConnection.isDisconnected()) { - if (this.random.nextFloat() < 0.05F && this.world.getGameRules().getBoolean("doMobSpawning")) { - EntityEndermite entityendermite = EntityTypes.ENDERMITE.create(world); // Paper + if (this.random.nextFloat() < 0.05F && this.world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING)) { + EntityEndermite entityendermite = (EntityEndermite) EntityTypes.ENDERMITE.a(this.world); entityendermite.setPlayerSpawned(true); entityendermite.setPositionRotation(entityliving.locX, entityliving.locY, entityliving.locZ, entityliving.yaw, entityliving.pitch); @@ -107,6 +111,7 @@ public class EntityEnderPearl extends EntityProjectile { } + @Override public void tick() { EntityLiving entityliving = this.getShooter(); @@ -119,6 +124,7 @@ public class EntityEnderPearl extends EntityProjectile { } @Nullable + @Override public Entity a(DimensionManager dimensionmanager) { if (this.shooter.dimension != dimensionmanager) { this.shooter = null; diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java index 945040442..a94ed1ae0 100644 --- a/src/main/java/net/minecraft/server/EntityEnderman.java +++ b/src/main/java/net/minecraft/server/EntityEnderman.java @@ -1,30 +1,35 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.Optional; import com.destroystokyo.paper.event.entity.EndermanEscapeEvent; // Paper import java.util.Random; import java.util.UUID; -import java.util.function.Function; +import java.util.function.Predicate; import javax.annotation.Nullable; public class EntityEnderman extends EntityMonster { - private static final UUID a = UUID.fromString("020E0DFB-87AE-4653-9556-831010E291A0"); - private static final AttributeModifier b = (new AttributeModifier(EntityEnderman.a, "Attacking speed boost", 0.15000000596046448D, 0)).a(false); - private static final DataWatcherObject> c = DataWatcher.a(EntityEnderman.class, DataWatcherRegistry.h); - private static final DataWatcherObject bC = DataWatcher.a(EntityEnderman.class, DataWatcherRegistry.i); - private int bD; - private int bE; + private static final UUID b = UUID.fromString("020E0DFB-87AE-4653-9556-831010E291A0"); + private static final AttributeModifier c = (new AttributeModifier(EntityEnderman.b, "Attacking speed boost", 0.15000000596046448D, AttributeModifier.Operation.ADDITION)).a(false); + private static final DataWatcherObject> d = DataWatcher.a(EntityEnderman.class, DataWatcherRegistry.h); + private static final DataWatcherObject bz = DataWatcher.a(EntityEnderman.class, DataWatcherRegistry.i); + private static final Predicate bA = (entityliving) -> { + return entityliving instanceof EntityEndermite && ((EntityEndermite) entityliving).isPlayerSpawned(); + }; + private int bB; + private int bC; - public EntityEnderman(World world) { - super(EntityTypes.ENDERMAN, world); - this.setSize(0.6F, 2.9F); - this.Q = 1.0F; + public EntityEnderman(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.K = 1.0F; this.a(PathType.WATER, -1.0F); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new EntityEnderman.a(this)); this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D, 0.0F)); this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); @@ -32,18 +37,20 @@ public class EntityEnderman extends EntityMonster { this.goalSelector.a(10, new EntityEnderman.PathfinderGoalEndermanPlaceBlock(this)); this.goalSelector.a(11, new EntityEnderman.PathfinderGoalEndermanPickupBlock(this)); this.targetSelector.a(1, new EntityEnderman.PathfinderGoalPlayerWhoLookedAtTarget(this)); - this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, false, new Class[0])); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityEndermite.class, 10, true, false, EntityEndermite::isPlayerSpawned)); + this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0])); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityEndermite.class, 10, true, false, EntityEnderman.bA)); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(40.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(40.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(7.0D); this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(64.0D); } + @Override public void setGoalTarget(@Nullable EntityLiving entityliving) { // CraftBukkit start - fire event setGoalTarget(entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason.UNKNOWN, true); @@ -65,44 +72,47 @@ public class EntityEnderman extends EntityMonster { AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); if (entityliving == null) { - this.bE = 0; - this.datawatcher.set(EntityEnderman.bC, false); - attributeinstance.c(EntityEnderman.b); + this.bC = 0; + this.datawatcher.set(EntityEnderman.bz, false); + attributeinstance.removeModifier(EntityEnderman.c); } else { - this.bE = this.ticksLived; - this.datawatcher.set(EntityEnderman.bC, true); - if (!attributeinstance.a(EntityEnderman.b)) { - attributeinstance.b(EntityEnderman.b); + this.bC = this.ticksLived; + this.datawatcher.set(EntityEnderman.bz, true); + if (!attributeinstance.a(EntityEnderman.c)) { + attributeinstance.addModifier(EntityEnderman.c); } } return true; } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityEnderman.c, Optional.empty()); - this.datawatcher.register(EntityEnderman.bC, false); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityEnderman.d, Optional.empty()); + this.datawatcher.register(EntityEnderman.bz, false); } public void l() { - if (this.ticksLived >= this.bD + 400) { - this.bD = this.ticksLived; + if (this.ticksLived >= this.bB + 400) { + this.bB = this.ticksLived; if (!this.isSilent()) { - this.world.a(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, SoundEffects.ENTITY_ENDERMAN_STARE, this.bV(), 2.5F, 1.0F, false); + this.world.a(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, SoundEffects.ENTITY_ENDERMAN_STARE, this.getSoundCategory(), 2.5F, 1.0F, false); } } } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntityEnderman.bC.equals(datawatcherobject) && this.dB() && this.world.isClientSide) { + if (EntityEnderman.bz.equals(datawatcherobject) && this.dX() && this.world.isClientSide) { this.l(); } super.a(datawatcherobject); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); IBlockData iblockdata = this.getCarried(); @@ -113,6 +123,7 @@ public class EntityEnderman extends EntityMonster { } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); IBlockData iblockdata = null; @@ -141,95 +152,112 @@ public class EntityEnderman extends EntityMonster { if (itemstack.getItem() == Blocks.CARVED_PUMPKIN.getItem()) { return false; } else { - Vec3D vec3d = entityhuman.f(1.0F).a(); + Vec3D vec3d = entityhuman.f(1.0F).d(); Vec3D vec3d1 = new Vec3D(this.locX - entityhuman.locX, this.getBoundingBox().minY + (double) this.getHeadHeight() - (entityhuman.locY + (double) entityhuman.getHeadHeight()), this.locZ - entityhuman.locZ); - double d0 = vec3d1.b(); + double d0 = vec3d1.f(); - vec3d1 = vec3d1.a(); + vec3d1 = vec3d1.d(); double d1 = vec3d.b(vec3d1); return d1 > 1.0D - 0.025D / d0 ? entityhuman.hasLineOfSight(this) : false; } } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 2.55F; } + @Override public void movementTick() { if (this.world.isClientSide) { for (int i = 0; i < 2; ++i) { - this.world.addParticle(Particles.K, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length - 0.25D, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, (this.random.nextDouble() - 0.5D) * 2.0D, -this.random.nextDouble(), (this.random.nextDouble() - 0.5D) * 2.0D); + this.world.addParticle(Particles.PORTAL, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.getWidth(), this.locY + this.random.nextDouble() * (double) this.getHeight() - 0.25D, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.getWidth(), (this.random.nextDouble() - 0.5D) * 2.0D, -this.random.nextDouble(), (this.random.nextDouble() - 0.5D) * 2.0D); } } - this.bg = false; + this.jumping = false; super.movementTick(); } + @Override protected void mobTick() { - if (this.ap()) { + if (this.au()) { this.damageEntity(DamageSource.DROWN, 1.0F); } - if (this.world.L() && this.ticksLived >= this.bE + 600) { - float f = this.az(); + if (this.world.J() && this.ticksLived >= this.bC + 600) { + float f = this.aF(); - if (f > 0.5F && this.world.e(new BlockPosition(this)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper + if (f > 0.5F && this.world.f(new BlockPosition(this)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper this.setGoalTarget((EntityLiving) null); - this.dz(); + this.dV(); } } super.mobTick(); } - public boolean teleportRandomly() { return dz(); } // Paper - OBFHELPER - protected boolean dz() { + public final boolean teleportRandomly() { return this.dV(); } // Paper - OBFHELPER + protected boolean dV() { double d0 = this.locX + (this.random.nextDouble() - 0.5D) * 64.0D; double d1 = this.locY + (double) (this.random.nextInt(64) - 32); double d2 = this.locZ + (this.random.nextDouble() - 0.5D) * 64.0D; - return this.k(d0, d1, d2); + return this.l(d0, d1, d2); } - protected boolean a(Entity entity) { - Vec3D vec3d = new Vec3D(this.locX - entity.locX, this.getBoundingBox().minY + (double) (this.length / 2.0F) - entity.locY + (double) entity.getHeadHeight(), this.locZ - entity.locZ); + private boolean a(Entity entity) { + Vec3D vec3d = new Vec3D(this.locX - entity.locX, this.getBoundingBox().minY + (double) (this.getHeight() / 2.0F) - entity.locY + (double) entity.getHeadHeight(), this.locZ - entity.locZ); - vec3d = vec3d.a(); + vec3d = vec3d.d(); double d0 = 16.0D; double d1 = this.locX + (this.random.nextDouble() - 0.5D) * 8.0D - vec3d.x * 16.0D; double d2 = this.locY + (double) (this.random.nextInt(16) - 8) - vec3d.y * 16.0D; double d3 = this.locZ + (this.random.nextDouble() - 0.5D) * 8.0D - vec3d.z * 16.0D; - return this.k(d1, d2, d3); + return this.l(d1, d2, d3); } - private boolean k(double d0, double d1, double d2) { - boolean flag = this.j(d0, d1, d2); + private boolean l(double d0, double d1, double d2) { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(d0, d1, d2); - if (flag) { - this.world.a((EntityHuman) null, this.lastX, this.lastY, this.lastZ, SoundEffects.ENTITY_ENDERMAN_TELEPORT, this.bV(), 1.0F, 1.0F); - this.a(SoundEffects.ENTITY_ENDERMAN_TELEPORT, 1.0F, 1.0F); + while (blockposition_mutableblockposition.getY() > 0 && !this.world.getType(blockposition_mutableblockposition).getMaterial().isSolid()) { + blockposition_mutableblockposition.c(EnumDirection.DOWN); } - return flag; + if (!this.world.getType(blockposition_mutableblockposition).getMaterial().isSolid()) { + return false; + } else { + boolean flag = this.a(d0, d1, d2, true); + + if (flag) { + this.world.playSound((EntityHuman) null, this.lastX, this.lastY, this.lastZ, SoundEffects.ENTITY_ENDERMAN_TELEPORT, this.getSoundCategory(), 1.0F, 1.0F); + this.a(SoundEffects.ENTITY_ENDERMAN_TELEPORT, 1.0F, 1.0F); + } + + return flag; + } } - protected SoundEffect D() { - return this.dB() ? SoundEffects.ENTITY_ENDERMAN_SCREAM : SoundEffects.ENTITY_ENDERMAN_AMBIENT; + @Override + protected SoundEffect getSoundAmbient() { + return this.dX() ? SoundEffects.ENTITY_ENDERMAN_SCREAM : SoundEffects.ENTITY_ENDERMAN_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_ENDERMAN_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_ENDERMAN_DEATH; } - protected void dropEquipment(boolean flag, int i) { - super.dropEquipment(flag, i); + @Override + protected void dropDeathLoot(DamageSource damagesource, int i, boolean flag) { + super.dropDeathLoot(damagesource, i, flag); IBlockData iblockdata = this.getCarried(); if (iblockdata != null) { @@ -238,44 +266,42 @@ public class EntityEnderman extends EntityMonster { } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.C; - } - public void setCarried(@Nullable IBlockData iblockdata) { - this.datawatcher.set(EntityEnderman.c, Optional.ofNullable(iblockdata)); + this.datawatcher.set(EntityEnderman.d, Optional.ofNullable(iblockdata)); } @Nullable public IBlockData getCarried() { - return (IBlockData) ((Optional) this.datawatcher.get(EntityEnderman.c)).orElse((Object) null); + return (IBlockData) ((Optional) this.datawatcher.get(EntityEnderman.d)).orElse((Object) null); } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; - } else if (damagesource instanceof EntityDamageSourceIndirect && tryEscape(EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - for (int i = 0; i < 64; ++i) { - if (this.dz()) { - return true; - } - } - - return false; - } else { + } else if (!(damagesource instanceof EntityDamageSourceIndirect) && damagesource != DamageSource.FIREWORKS) { boolean flag = super.damageEntity(damagesource, f); - if (damagesource.ignoresArmor() && this.random.nextInt(10) != 0 && tryEscape(damagesource == DamageSource.DROWN ? EndermanEscapeEvent.Reason.DROWN : EndermanEscapeEvent.Reason.CRITICAL_HIT)) { // Paper - this.dz(); + if (damagesource.ignoresArmor() && this.random.nextInt(10) != 0 && this.tryEscape(damagesource == DamageSource.DROWN ? EndermanEscapeEvent.Reason.DROWN : EndermanEscapeEvent.Reason.CRITICAL_HIT)) { // Paper + this.dV(); } return flag; + } else { + if (this.tryEscape(EndermanEscapeEvent.Reason.INDIRECT)) { // Paper start + for (int i = 0; i < 64; ++i) { + if (this.dV()) { + return true; + } + } + } // Paper end + + return false; } } - public boolean dB() { - return (Boolean) this.datawatcher.get(EntityEnderman.bC); + public boolean dX() { + return (Boolean) this.datawatcher.get(EntityEnderman.bz); } static class PathfinderGoalEndermanPickupBlock extends PathfinderGoal { @@ -286,10 +312,12 @@ public class EntityEnderman extends EntityMonster { this.enderman = entityenderman; } + @Override public boolean a() { - return this.enderman.getCarried() != null ? false : (!this.enderman.world.getGameRules().getBoolean("mobGriefing") ? false : this.enderman.getRandom().nextInt(20) == 0); + return this.enderman.getCarried() != null ? false : (!this.enderman.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.enderman.getRandom().nextInt(20) == 0); } + @Override public void e() { Random random = this.enderman.getRandom(); World world = this.enderman.world; @@ -300,14 +328,16 @@ public class EntityEnderman extends EntityMonster { IBlockData iblockdata = world.getTypeIfLoaded(blockposition); // Paper if (iblockdata == null) return; // Paper Block block = iblockdata.getBlock(); - MovingObjectPosition movingobjectposition = world.rayTrace(new Vec3D((double) ((float) MathHelper.floor(this.enderman.locX) + 0.5F), (double) ((float) j + 0.5F), (double) ((float) MathHelper.floor(this.enderman.locZ) + 0.5F)), new Vec3D((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F)), FluidCollisionOption.NEVER, true, false); - boolean flag = movingobjectposition != null && movingobjectposition.getBlockPosition().equals(blockposition); + Vec3D vec3d = new Vec3D((double) MathHelper.floor(this.enderman.locX) + 0.5D, (double) j + 0.5D, (double) MathHelper.floor(this.enderman.locZ) + 0.5D); + Vec3D vec3d1 = new Vec3D((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D); + MovingObjectPositionBlock movingobjectpositionblock = world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this.enderman)); + boolean flag = movingobjectpositionblock.getType() != MovingObjectPosition.EnumMovingObjectType.MISS && movingobjectpositionblock.getBlockPosition().equals(blockposition); if (block.a(TagsBlock.ENDERMAN_HOLDABLE) && flag) { // CraftBukkit start - Pickup event if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.enderman, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { //this.enderman.setCarried(iblockdata); // Paper - moved down - world.setAir(blockposition); + world.a(blockposition, false); this.enderman.setCarried(Block.getValidBlockForPosition(iblockdata, this.enderman.world, blockposition)); // Paper - Fix MC-124320 } // CraftBukkit end @@ -325,10 +355,12 @@ public class EntityEnderman extends EntityMonster { this.a = entityenderman; } + @Override public boolean a() { - return this.a.getCarried() == null ? false : (!this.a.world.getGameRules().getBoolean("mobGriefing") ? false : this.a.getRandom().nextInt(2000) == 0); + return this.a.getCarried() == null ? false : (!this.a.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.a.getRandom().nextInt(2000) == 0); } + @Override public void e() { Random random = this.a.getRandom(); World world = this.a.world; @@ -338,10 +370,11 @@ public class EntityEnderman extends EntityMonster { BlockPosition blockposition = new BlockPosition(i, j, k); IBlockData iblockdata = world.getTypeIfLoaded(blockposition); // Paper if (iblockdata == null) return; // Paper - IBlockData iblockdata1 = world.getType(blockposition.down()); + BlockPosition blockposition1 = blockposition.down(); + IBlockData iblockdata1 = world.getType(blockposition1); IBlockData iblockdata2 = Block.getValidBlockForPosition(getEnderman().getCarried(), getEnderman().world, blockposition); // Paper - Fix MC-124320 - if (iblockdata2 != null && this.a(world, blockposition, iblockdata2, iblockdata, iblockdata1)) { + if (iblockdata2 != null && this.a(world, blockposition, iblockdata2, iblockdata, iblockdata1, blockposition1)) { // CraftBukkit start - Place event if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.a, blockposition, iblockdata2).isCancelled()) { world.setTypeAndData(blockposition, iblockdata2, 3); @@ -352,42 +385,75 @@ public class EntityEnderman extends EntityMonster { } - private boolean a(IWorldReader iworldreader, BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, IBlockData iblockdata2) { - return iblockdata1.isAir() && !iblockdata2.isAir() && iblockdata2.g() && iblockdata.canPlace(iworldreader, blockposition); + private boolean a(IWorldReader iworldreader, BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, IBlockData iblockdata2, BlockPosition blockposition1) { + return iblockdata1.isAir() && !iblockdata2.isAir() && iblockdata2.o(iworldreader, blockposition1) && iblockdata.canPlace(iworldreader, blockposition); + } + } + + static class a extends PathfinderGoal { + + private final EntityEnderman a; + + public a(EntityEnderman entityenderman) { + this.a = entityenderman; + this.a(EnumSet.of(PathfinderGoal.Type.JUMP, PathfinderGoal.Type.MOVE)); + } + + @Override + public boolean a() { + EntityLiving entityliving = this.a.getGoalTarget(); + + if (!(entityliving instanceof EntityHuman)) { + return false; + } else { + double d0 = entityliving.h((Entity) this.a); + + return d0 > 256.0D ? false : this.a.f((EntityHuman) entityliving); + } + } + + @Override + public void c() { + this.a.getNavigation().o(); } } static class PathfinderGoalPlayerWhoLookedAtTarget extends PathfinderGoalNearestAttackableTarget { - private final EntityEnderman i; public EntityEnderman getEnderman() { return i; } // Paper - OBFHELPER + private final EntityEnderman i; public final EntityEnderman getEnderman() { return this.i; } // Paper - OBFHELPER private EntityHuman j; private int k; private int l; + private final PathfinderTargetCondition m; + private final PathfinderTargetCondition n = (new PathfinderTargetCondition()).c(); public PathfinderGoalPlayerWhoLookedAtTarget(EntityEnderman entityenderman) { super(entityenderman, EntityHuman.class, false); this.i = entityenderman; + this.m = (new PathfinderTargetCondition()).a(this.k()).a((entityliving) -> { + return entityenderman.f((EntityHuman) entityliving); + }); } + @Override public boolean a() { - double d0 = this.i(); - - this.j = this.i.world.a(this.i.locX, this.i.locY, this.i.locZ, d0, d0, (Function) null, (entityhuman) -> { - return entityhuman != null && this.i.f(entityhuman); - }); + this.j = this.i.world.a(this.m, (EntityLiving) this.i); return this.j != null; } + @Override public void c() { this.k = 5; this.l = 0; } + @Override public void d() { this.j = null; super.d(); } + @Override public boolean b() { if (this.j != null) { if (!this.i.f(this.j)) { @@ -397,26 +463,27 @@ public class EntityEnderman extends EntityMonster { return true; } } else { - return this.d != null && ((EntityHuman) this.d).isAlive() ? true : super.b(); + return this.c != null && this.n.a(this.i, this.c) ? true : super.b(); } } + @Override public void e() { if (this.j != null) { if (--this.k <= 0) { - this.d = this.j; + this.c = this.j; this.j = null; super.c(); } } else { - if (this.d != null) { - if (this.i.f((EntityHuman) this.d)) { - if (((EntityHuman) this.d).h(this.i) < 16.0D && this.getEnderman().tryEscape(EndermanEscapeEvent.Reason.STARE)) { // Paper - this.i.dz(); + if (this.c != null && !this.i.isPassenger()) { + if (this.i.f((EntityHuman) this.c)) { + if (this.c.h((Entity) this.i) < 16.0D && this.getEnderman().tryEscape(EndermanEscapeEvent.Reason.STARE)) { + this.i.dV(); } this.l = 0; - } else if (((EntityHuman) this.d).h(this.i) > 256.0D && this.l++ >= 30 && this.i.a((Entity) this.d)) { + } else if (this.c.h((Entity) this.i) > 256.0D && this.l++ >= 30 && this.i.a((Entity) this.c)) { this.l = 0; } } diff --git a/src/main/java/net/minecraft/server/EntityEvoker.java b/src/main/java/net/minecraft/server/EntityEvoker.java deleted file mode 100644 index fc20bbe27..000000000 --- a/src/main/java/net/minecraft/server/EntityEvoker.java +++ /dev/null @@ -1,310 +0,0 @@ -package net.minecraft.server; - -import java.util.List; -import java.util.function.Predicate; -import javax.annotation.Nullable; - -public class EntityEvoker extends EntityIllagerWizard { - - private EntitySheep c; - - public EntityEvoker(World world) { - super(EntityTypes.EVOKER, world); - this.setSize(0.6F, 1.95F); - this.b_ = 10; - } - - protected void n() { - super.n(); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); - this.goalSelector.a(1, new EntityEvoker.b()); - this.goalSelector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 0.6D, 1.0D)); - this.goalSelector.a(4, new EntityEvoker.c()); - this.goalSelector.a(5, new EntityEvoker.a()); - this.goalSelector.a(6, new EntityEvoker.d()); - this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); - this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[] { EntityEvoker.class})); - this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).b(300)); - this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)).b(300)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)); - } - - protected void initAttributes() { - super.initAttributes(); - this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.5D); - this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(12.0D); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(24.0D); - } - - protected void x_() { - super.x_(); - } - - public void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - } - - public void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); - } - - protected MinecraftKey getDefaultLootTable() { - return LootTables.aB; - } - - protected void mobTick() { - super.mobTick(); - } - - public void tick() { - super.tick(); - } - - public boolean r(Entity entity) { - return entity == null ? false : (entity == this ? true : (super.r(entity) ? true : (entity instanceof EntityVex ? this.r(((EntityVex) entity).l()) : (entity instanceof EntityLiving && ((EntityLiving) entity).getMonsterType() == EnumMonsterType.ILLAGER ? this.getScoreboardTeam() == null && entity.getScoreboardTeam() == null : false)))); - } - - protected SoundEffect D() { - return SoundEffects.ENTITY_EVOKER_AMBIENT; - } - - protected SoundEffect cs() { - return SoundEffects.ENTITY_EVOKER_DEATH; - } - - protected SoundEffect d(DamageSource damagesource) { - return SoundEffects.ENTITY_EVOKER_HURT; - } - - private void a(@Nullable EntitySheep entitysheep) { - this.c = entitysheep; - } - - @Nullable - private EntitySheep dD() { - return this.c; - } - - protected SoundEffect dz() { - return SoundEffects.ENTITY_EVOKER_CAST_SPELL; - } - - public class d extends EntityIllagerWizard.c { - - private final Predicate e = (entitysheep) -> { - return entitysheep.getColor() == EnumColor.BLUE; - }; - - public d() { - super(); - } - - public boolean a() { - if (EntityEvoker.this.getGoalTarget() != null) { - return false; - } else if (EntityEvoker.this.dA()) { - return false; - } else if (EntityEvoker.this.ticksLived < this.c) { - return false; - } else if (!EntityEvoker.this.world.getGameRules().getBoolean("mobGriefing")) { - return false; - } else { - List list = EntityEvoker.this.world.a(EntitySheep.class, EntityEvoker.this.getBoundingBox().grow(16.0D, 4.0D, 16.0D), this.e); - - if (list.isEmpty()) { - return false; - } else { - EntityEvoker.this.a((EntitySheep) list.get(EntityEvoker.this.random.nextInt(list.size()))); - return true; - } - } - } - - public boolean b() { - return EntityEvoker.this.dD() != null && this.b > 0; - } - - public void d() { - super.d(); - EntityEvoker.this.a((EntitySheep) null); - } - - protected void j() { - EntitySheep entitysheep = EntityEvoker.this.dD(); - - if (entitysheep != null && entitysheep.isAlive()) { - entitysheep.setColor(EnumColor.RED); - } - - } - - protected int m() { - return 40; - } - - protected int g() { - return 60; - } - - protected int i() { - return 140; - } - - protected SoundEffect k() { - return SoundEffects.ENTITY_EVOKER_PREPARE_WOLOLO; - } - - protected EntityIllagerWizard.Spell l() { - return EntityIllagerWizard.Spell.WOLOLO; - } - } - - class c extends EntityIllagerWizard.c { - - private c() { - super(); - } - - public boolean a() { - if (!super.a()) { - return false; - } else { - int i = EntityEvoker.this.world.a(EntityVex.class, EntityEvoker.this.getBoundingBox().g(16.0D)).size(); - - return EntityEvoker.this.random.nextInt(8) + 1 > i; - } - } - - protected int g() { - return 100; - } - - protected int i() { - return 340; - } - - protected void j() { - for (int i = 0; i < 3; ++i) { - BlockPosition blockposition = (new BlockPosition(EntityEvoker.this)).a(-2 + EntityEvoker.this.random.nextInt(5), 1, -2 + EntityEvoker.this.random.nextInt(5)); - EntityVex entityvex = EntityTypes.VEX.create(EntityEvoker.this.world); // Paper - entityvex.setPositionRotation(blockposition, 0.0F, 0.0F); - entityvex.prepare(EntityEvoker.this.world.getDamageScaler(blockposition), (GroupDataEntity) null, (NBTTagCompound) null); - entityvex.a((EntityInsentient) EntityEvoker.this); - entityvex.g(blockposition); - entityvex.a(20 * (30 + EntityEvoker.this.random.nextInt(90))); - EntityEvoker.this.world.addEntity(entityvex); - } - - } - - protected SoundEffect k() { - return SoundEffects.ENTITY_EVOKER_PREPARE_SUMMON; - } - - protected EntityIllagerWizard.Spell l() { - return EntityIllagerWizard.Spell.SUMMON_VEX; - } - } - - class a extends EntityIllagerWizard.c { - - private a() { - super(); - } - - protected int g() { - return 40; - } - - protected int i() { - return 100; - } - - protected void j() { - EntityLiving entityliving = EntityEvoker.this.getGoalTarget(); - double d0 = Math.min(entityliving.locY, EntityEvoker.this.locY); - double d1 = Math.max(entityliving.locY, EntityEvoker.this.locY) + 1.0D; - float f = (float) MathHelper.c(entityliving.locZ - EntityEvoker.this.locZ, entityliving.locX - EntityEvoker.this.locX); - int i; - - if (EntityEvoker.this.h(entityliving) < 9.0D) { - float f1; - - for (i = 0; i < 5; ++i) { - f1 = f + (float) i * 3.1415927F * 0.4F; - this.a(EntityEvoker.this.locX + (double) MathHelper.cos(f1) * 1.5D, EntityEvoker.this.locZ + (double) MathHelper.sin(f1) * 1.5D, d0, d1, f1, 0); - } - - for (i = 0; i < 8; ++i) { - f1 = f + (float) i * 3.1415927F * 2.0F / 8.0F + 1.2566371F; - this.a(EntityEvoker.this.locX + (double) MathHelper.cos(f1) * 2.5D, EntityEvoker.this.locZ + (double) MathHelper.sin(f1) * 2.5D, d0, d1, f1, 3); - } - } else { - for (i = 0; i < 16; ++i) { - double d2 = 1.25D * (double) (i + 1); - int j = 1 * i; - - this.a(EntityEvoker.this.locX + (double) MathHelper.cos(f) * d2, EntityEvoker.this.locZ + (double) MathHelper.sin(f) * d2, d0, d1, f, j); - } - } - - } - - private void a(double d0, double d1, double d2, double d3, float f, int i) { - BlockPosition blockposition = new BlockPosition(d0, d3, d1); - boolean flag = false; - double d4 = 0.0D; - - do { - if (!EntityEvoker.this.world.q(blockposition) && EntityEvoker.this.world.q(blockposition.down())) { - if (!EntityEvoker.this.world.isEmpty(blockposition)) { - IBlockData iblockdata = EntityEvoker.this.world.getType(blockposition); - VoxelShape voxelshape = iblockdata.getCollisionShape(EntityEvoker.this.world, blockposition); - - if (!voxelshape.isEmpty()) { - d4 = voxelshape.c(EnumDirection.EnumAxis.Y); - } - } - - flag = true; - break; - } - - blockposition = blockposition.down(); - } while (blockposition.getY() >= MathHelper.floor(d2) - 1); - - if (flag) { - EntityEvokerFangs entityevokerfangs = new EntityEvokerFangs(EntityEvoker.this.world, d0, (double) blockposition.getY() + d4, d1, f, i, EntityEvoker.this); - - EntityEvoker.this.world.addEntity(entityevokerfangs); - } - - } - - protected SoundEffect k() { - return SoundEffects.ENTITY_EVOKER_PREPARE_ATTACK; - } - - protected EntityIllagerWizard.Spell l() { - return EntityIllagerWizard.Spell.FANGS; - } - } - - class b extends EntityIllagerWizard.b { - - private b() { - super(); - } - - public void e() { - if (EntityEvoker.this.getGoalTarget() != null) { - EntityEvoker.this.getControllerLook().a(EntityEvoker.this.getGoalTarget(), (float) EntityEvoker.this.L(), (float) EntityEvoker.this.K()); - } else if (EntityEvoker.this.dD() != null) { - EntityEvoker.this.getControllerLook().a(EntityEvoker.this.dD(), (float) EntityEvoker.this.L(), (float) EntityEvoker.this.K()); - } - - } - } -} diff --git a/src/main/java/net/minecraft/server/EntityEvokerFangs.java b/src/main/java/net/minecraft/server/EntityEvokerFangs.java index cbe9acba1..853002e6e 100644 --- a/src/main/java/net/minecraft/server/EntityEvokerFangs.java +++ b/src/main/java/net/minecraft/server/EntityEvokerFangs.java @@ -7,83 +7,86 @@ import javax.annotation.Nullable; public class EntityEvokerFangs extends Entity { - private int a; - private boolean b; - private int c; - private boolean d; - private EntityLiving e; - private UUID f; + private int b; + private boolean c; + private int d; + private boolean e; + private EntityLiving f; + private UUID g; - public EntityEvokerFangs(World world) { - super(EntityTypes.EVOKER_FANGS, world); - this.c = 22; - this.setSize(0.5F, 0.8F); + public EntityEvokerFangs(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.d = 22; } public EntityEvokerFangs(World world, double d0, double d1, double d2, float f, int i, EntityLiving entityliving) { - this(world); - this.a = i; + this(EntityTypes.EVOKER_FANGS, world); + this.b = i; this.a(entityliving); this.yaw = f * 57.295776F; this.setPosition(d0, d1, d2); } - protected void x_() {} + @Override + protected void initDatawatcher() {} public void a(@Nullable EntityLiving entityliving) { - this.e = entityliving; - this.f = entityliving == null ? null : entityliving.getUniqueID(); + this.f = entityliving; + this.g = entityliving == null ? null : entityliving.getUniqueID(); } @Nullable public EntityLiving getOwner() { - if (this.e == null && this.f != null && this.world instanceof WorldServer) { - Entity entity = ((WorldServer) this.world).getEntity(this.f); + if (this.f == null && this.g != null && this.world instanceof WorldServer) { + Entity entity = ((WorldServer) this.world).getEntity(this.g); if (entity instanceof EntityLiving) { - this.e = (EntityLiving) entity; + this.f = (EntityLiving) entity; } } - return this.e; + return this.f; } + @Override protected void a(NBTTagCompound nbttagcompound) { - this.a = nbttagcompound.getInt("Warmup"); + this.b = nbttagcompound.getInt("Warmup"); if (nbttagcompound.b("OwnerUUID")) { - this.f = nbttagcompound.a("OwnerUUID"); + this.g = nbttagcompound.a("OwnerUUID"); } } + @Override protected void b(NBTTagCompound nbttagcompound) { - nbttagcompound.setInt("Warmup", this.a); - if (this.f != null) { - nbttagcompound.a("OwnerUUID", this.f); + nbttagcompound.setInt("Warmup", this.b); + if (this.g != null) { + nbttagcompound.a("OwnerUUID", this.g); } } + @Override public void tick() { super.tick(); if (this.world.isClientSide) { - if (this.d) { - --this.c; - if (this.c == 14) { + if (this.e) { + --this.d; + if (this.d == 14) { for (int i = 0; i < 12; ++i) { - double d0 = this.locX + (this.random.nextDouble() * 2.0D - 1.0D) * (double) this.width * 0.5D; + double d0 = this.locX + (this.random.nextDouble() * 2.0D - 1.0D) * (double) this.getWidth() * 0.5D; double d1 = this.locY + 0.05D + this.random.nextDouble(); - double d2 = this.locZ + (this.random.nextDouble() * 2.0D - 1.0D) * (double) this.width * 0.5D; + double d2 = this.locZ + (this.random.nextDouble() * 2.0D - 1.0D) * (double) this.getWidth() * 0.5D; double d3 = (this.random.nextDouble() * 2.0D - 1.0D) * 0.3D; double d4 = 0.3D + this.random.nextDouble() * 0.3D; double d5 = (this.random.nextDouble() * 2.0D - 1.0D) * 0.3D; - this.world.addParticle(Particles.h, d0, d1 + 1.0D, d2, d3, d4, d5); + this.world.addParticle(Particles.CRIT, d0, d1 + 1.0D, d2, d3, d4, d5); } } } - } else if (--this.a < 0) { - if (this.a == -8) { + } else if (--this.b < 0) { + if (this.b == -8) { List list = this.world.a(EntityLiving.class, this.getBoundingBox().grow(0.2D, 0.0D, 0.2D)); Iterator iterator = list.iterator(); @@ -94,12 +97,12 @@ public class EntityEvokerFangs extends Entity { } } - if (!this.b) { + if (!this.c) { this.world.broadcastEntityEffect(this, (byte) 4); - this.b = true; + this.c = true; } - if (--this.c < 0) { + if (--this.d < 0) { this.die(); } } @@ -109,7 +112,7 @@ public class EntityEvokerFangs extends Entity { private void c(EntityLiving entityliving) { EntityLiving entityliving1 = this.getOwner(); - if (entityliving.isAlive() && !entityliving.bl() && entityliving != entityliving1) { + if (entityliving.isAlive() && !entityliving.isInvulnerable() && entityliving != entityliving1) { if (entityliving1 == null) { org.bukkit.craftbukkit.event.CraftEventFactory.entityDamage = this; // CraftBukkit entityliving.damageEntity(DamageSource.MAGIC, 6.0F); @@ -124,4 +127,9 @@ public class EntityEvokerFangs extends Entity { } } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); + } } diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java index 3606b1014..d8f23ff02 100644 --- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java +++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.Map.Entry; // CraftBukkit start import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.entity.EntityTargetLivingEntityEvent; @@ -8,10 +9,10 @@ import org.bukkit.event.entity.EntityTargetEvent; public class EntityExperienceOrb extends Entity { - public int a; public int b; public int c; - private int d = 5; + public int d; + private int e; public int value; private EntityHuman targetPlayer; private int targetTime; @@ -34,7 +35,7 @@ public class EntityExperienceOrb extends Entity { if (comp.hasKey("reason")) { String reason = comp.getString("reason"); try { - spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason); + this.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason); } catch (Exception e) { this.world.getServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason); } @@ -42,14 +43,14 @@ public class EntityExperienceOrb extends Entity { } private void savePaperNBT(NBTTagCompound nbttagcompound) { NBTTagCompound comp = new NBTTagCompound(); - if (sourceEntityId != null) { - comp.setUUID("source", sourceEntityId); + if (this.sourceEntityId != null) { + comp.setUUID("source", this.sourceEntityId); } - if (triggerEntityId != null) { + if (this.triggerEntityId != null) { comp.setUUID("trigger", triggerEntityId); } - if (spawnReason != null && spawnReason != org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN) { - comp.setString("reason", spawnReason.name()); + if (this.spawnReason != null && this.spawnReason != org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN) { + comp.setString("reason", this.spawnReason.name()); } nbttagcompound.set("Paper.ExpData", comp); } @@ -63,36 +64,36 @@ public class EntityExperienceOrb extends Entity { } public EntityExperienceOrb(World world, double d0, double d1, double d2, int i, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId, Entity sourceId) { - super(EntityTypes.EXPERIENCE_ORB, world); + this(EntityTypes.EXPERIENCE_ORB, world); this.sourceEntityId = sourceId != null ? sourceId.getUniqueID() : null; this.triggerEntityId = triggerId != null ? triggerId.getUniqueID() : null; this.spawnReason = reason != null ? reason : org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN; // Paper end - this.setSize(0.5F, 0.5F); this.setPosition(d0, d1, d2); - this.yaw = (float) (Math.random() * 360.0D); - this.motX = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F); - this.motY = (double) ((float) (Math.random() * 0.2D) * 2.0F); - this.motZ = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F); + this.yaw = (float) (this.random.nextDouble() * 360.0D); + this.setMot((this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D, this.random.nextDouble() * 0.2D * 2.0D, (this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D); this.value = i; } - public EntityExperienceOrb(World world) { - super(EntityTypes.EXPERIENCE_ORB, world); - this.setSize(0.25F, 0.25F); + public EntityExperienceOrb(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.e = 5; } + @Override protected boolean playStepSound() { return false; } - protected void x_() {} + @Override + protected void initDatawatcher() {} + @Override public void tick() { super.tick(); EntityHuman prevTarget = this.targetPlayer;// CraftBukkit - store old target - if (this.c > 0) { - --this.c; + if (this.d > 0) { + --this.d; } this.lastX = this.locX; @@ -101,100 +102,100 @@ public class EntityExperienceOrb extends Entity { if (this.a(TagsFluid.WATER)) { this.k(); } else if (!this.isNoGravity()) { - this.motY -= 0.029999999329447746D; + this.setMot(this.getMot().add(0.0D, -0.03D, 0.0D)); } if (this.world.getFluid(new BlockPosition(this)).a(TagsFluid.LAVA)) { - this.motY = 0.20000000298023224D; - this.motX = (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F); - this.motZ = (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F); + this.setMot((double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F), 0.20000000298023224D, (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F)); this.a(SoundEffects.ENTITY_GENERIC_BURN, 0.4F, 2.0F + this.random.nextFloat() * 0.4F); } - this.i(this.locX, (this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D, this.locZ); + if (!this.world.c(this.getBoundingBox())) { + this.i(this.locX, (this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D, this.locZ); + } + double d0 = 8.0D; - if (this.targetTime < this.a - 20 + this.getId() % 100) { - if (this.targetPlayer == null || this.targetPlayer.h(this) > 64.0D) { + if (this.targetTime < this.b - 20 + this.getId() % 100) { + if (this.targetPlayer == null || this.targetPlayer.h((Entity) this) > 64.0D) { this.targetPlayer = this.world.findNearbyPlayer(this, 8.0D); } - this.targetTime = this.a; + this.targetTime = this.b; } if (this.targetPlayer != null && this.targetPlayer.isSpectator()) { this.targetPlayer = null; } - if (this.targetPlayer != null) { - // CraftBukkit start - boolean cancelled = false; - if (this.targetPlayer != prevTarget) { - EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(this, targetPlayer, EntityTargetEvent.TargetReason.CLOSEST_PLAYER); - EntityLiving target = event.getTarget() == null ? null : ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle(); - targetPlayer = target instanceof EntityHuman ? (EntityHuman) target : null; - cancelled = event.isCancelled(); - } + // CraftBukkit start + boolean cancelled = false; + if (this.targetPlayer != prevTarget) { + EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(this, targetPlayer, (targetPlayer != null) ? EntityTargetEvent.TargetReason.CLOSEST_PLAYER : EntityTargetEvent.TargetReason.FORGOT_TARGET); + EntityLiving target = (event.getTarget() == null) ? null : ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle(); + cancelled = event.isCancelled(); - if (!cancelled && targetPlayer != null) { - double d1 = (this.targetPlayer.locX - this.locX) / 8.0D; - double d2 = (this.targetPlayer.locY + (double) this.targetPlayer.getHeadHeight() / 2.0D - this.locY) / 8.0D; - double d3 = (this.targetPlayer.locZ - this.locZ) / 8.0D; - double d4 = Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3); - double d5 = 1.0D - d4; - - if (d5 > 0.0D) { - d5 *= d5; - this.motX += d1 / d4 * d5 * 0.1D; - this.motY += d2 / d4 * d5 * 0.1D; - this.motZ += d3 / d4 * d5 * 0.1D; + if (cancelled) { + targetPlayer = prevTarget; + } else { + targetPlayer = (target instanceof EntityHuman) ? (EntityHuman) target : null; } - } - // CraftBukkit end } - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); + if (this.targetPlayer != null && !cancelled) { + // CraftBukkit end + Vec3D vec3d = new Vec3D(this.targetPlayer.locX - this.locX, this.targetPlayer.locY + (double) this.targetPlayer.getHeadHeight() / 2.0D - this.locY, this.targetPlayer.locZ - this.locZ); + double d1 = vec3d.g(); + + if (d1 < 64.0D) { + double d2 = 1.0D - Math.sqrt(d1) / 8.0D; + + this.setMot(this.getMot().e(vec3d.d().a(d2 * d2 * 0.1D))); + } + } + + this.move(EnumMoveType.SELF, this.getMot()); float f = 0.98F; if (this.onGround) { - f = this.world.getType(new BlockPosition(MathHelper.floor(this.locX), MathHelper.floor(this.getBoundingBox().minY) - 1, MathHelper.floor(this.locZ))).getBlock().n() * 0.98F; + f = this.world.getType(new BlockPosition(this.locX, this.getBoundingBox().minY - 1.0D, this.locZ)).getBlock().m() * 0.98F; } - this.motX *= (double) f; - this.motY *= 0.9800000190734863D; - this.motZ *= (double) f; + this.setMot(this.getMot().d((double) f, 0.98D, (double) f)); if (this.onGround) { - this.motY *= -0.8999999761581421D; + this.setMot(this.getMot().d(1.0D, -0.9D, 1.0D)); } - ++this.a; ++this.b; - if (this.b >= 6000) { + ++this.c; + if (this.c >= 6000) { this.die(); } } private void k() { - this.motY += 5.000000237487257E-4D; - this.motY = Math.min(this.motY, 0.05999999865889549D); - this.motX *= 0.9900000095367432D; - this.motZ *= 0.9900000095367432D; + Vec3D vec3d = this.getMot(); + + this.setMot(vec3d.x * 0.9900000095367432D, Math.min(vec3d.y + 5.000000237487257E-4D, 0.05999999865889549D), vec3d.z * 0.9900000095367432D); } - protected void au() {} + @Override + protected void az() {} - protected void burn(int i) { + @Override + protected void burn(float i) { // CraftBukkit - int -> float this.damageEntity(DamageSource.FIRE, (float) i); } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; } else { - this.aA(); - this.d = (int) ((float) this.d - f); - if (this.d <= 0) { + this.velocityChanged(); + this.e = (int) ((float) this.e - f); + if (this.e <= 0) { this.die(); } @@ -202,38 +203,45 @@ public class EntityExperienceOrb extends Entity { } } + @Override public void b(NBTTagCompound nbttagcompound) { - nbttagcompound.setShort("Health", (short) this.d); - nbttagcompound.setShort("Age", (short) this.b); + nbttagcompound.setShort("Health", (short) this.e); + nbttagcompound.setShort("Age", (short) this.c); nbttagcompound.setInt("Value", this.value); // Paper - save as Integer - savePaperNBT(nbttagcompound); // Paper + this.savePaperNBT(nbttagcompound); // Paper } + @Override public void a(NBTTagCompound nbttagcompound) { - this.d = nbttagcompound.getShort("Health"); - this.b = nbttagcompound.getShort("Age"); + this.e = nbttagcompound.getShort("Health"); + this.c = nbttagcompound.getShort("Age"); this.value = nbttagcompound.getInt("Value"); // Paper - load as Integer - loadPaperNBT(nbttagcompound); // Paper + this.loadPaperNBT(nbttagcompound); // Paper } - public void d(EntityHuman entityhuman) { + @Override + public void pickup(EntityHuman entityhuman) { if (!this.world.isClientSide) { - if (this.c == 0 && entityhuman.bJ == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((EntityPlayer) entityhuman).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - entityhuman.bJ = 2; + if (this.d == 0 && entityhuman.bF == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((EntityPlayer) entityhuman).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper + entityhuman.bF = 2; entityhuman.receive(this, 1); - ItemStack itemstack = EnchantmentManager.b(Enchantments.MENDING, (EntityLiving) entityhuman); + Entry entry = EnchantmentManager.b(Enchantments.MENDING, (EntityLiving) entityhuman); - if (!itemstack.isEmpty() && itemstack.f()) { - int i = Math.min(this.c(this.value), itemstack.getDamage()); + if (entry != null) { + ItemStack itemstack = (ItemStack) entry.getValue(); - // CraftBukkit start - org.bukkit.event.player.PlayerItemMendEvent event = CraftEventFactory.callPlayerItemMendEvent(entityhuman, this, itemstack, i); - i = event.getRepairAmount(); - if (!event.isCancelled()) { - this.value -= this.b(i); - itemstack.setDamage(itemstack.getDamage() - i); + if (!itemstack.isEmpty() && itemstack.f()) { + int i = Math.min(this.c(this.value), itemstack.getDamage()); + + // CraftBukkit start + org.bukkit.event.player.PlayerItemMendEvent event = CraftEventFactory.callPlayerItemMendEvent(entityhuman, this, itemstack, i); + i = event.getRepairAmount(); + if (!event.isCancelled()) { + this.value -= this.b(i); + itemstack.setDamage(itemstack.getDamage() - i); + } + // CraftBukkit end } - // CraftBukkit end } if (this.value > 0) { @@ -282,7 +290,13 @@ public class EntityExperienceOrb extends Entity { return i >= 2477 ? 2477 : (i >= 1237 ? 1237 : (i >= 617 ? 617 : (i >= 307 ? 307 : (i >= 149 ? 149 : (i >= 73 ? 73 : (i >= 37 ? 37 : (i >= 17 ? 17 : (i >= 7 ? 7 : (i >= 3 ? 3 : 1))))))))); } - public boolean bk() { + @Override + public boolean bs() { return false; } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntityExperienceOrb(this); + } } diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java index 3eaee8d89..0a6d2b9b3 100644 --- a/src/main/java/net/minecraft/server/EntityFallingBlock.java +++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java @@ -11,15 +11,15 @@ public class EntityFallingBlock extends Entity { private IBlockData block; public int ticksLived; public boolean dropItem; - private boolean f; + private boolean g; public boolean hurtEntities; private int fallHurtMax; private float fallHurtAmount; public NBTTagCompound tileEntityData; - protected static final DataWatcherObject d = DataWatcher.a(EntityFallingBlock.class, DataWatcherRegistry.l); + protected static final DataWatcherObject e = DataWatcher.a(EntityFallingBlock.class, DataWatcherRegistry.l); - public EntityFallingBlock(World world) { - super(EntityTypes.FALLING_BLOCK, world); + public EntityFallingBlock(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.block = Blocks.SAND.getBlockData(); this.dropItem = true; this.fallHurtMax = 40; @@ -27,40 +27,42 @@ public class EntityFallingBlock extends Entity { } public EntityFallingBlock(World world, double d0, double d1, double d2, IBlockData iblockdata) { - this(world); + this(EntityTypes.FALLING_BLOCK, world); this.block = iblockdata; - this.j = true; - this.setSize(0.98F, 0.98F); - this.setPosition(d0, d1 + (double) ((1.0F - this.length) / 2.0F), d2); - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; + this.i = true; + this.setPosition(d0, d1 + (double) ((1.0F - this.getHeight()) / 2.0F), d2); + this.setMot(Vec3D.a); this.lastX = d0; this.lastY = d1; this.lastZ = d2; this.a(new BlockPosition(this)); } - public boolean bk() { + @Override + public boolean bs() { return false; } public void a(BlockPosition blockposition) { - this.datawatcher.set(EntityFallingBlock.d, blockposition); + this.datawatcher.set(EntityFallingBlock.e, blockposition); } + @Override protected boolean playStepSound() { return false; } - protected void x_() { - this.datawatcher.register(EntityFallingBlock.d, BlockPosition.ZERO); + @Override + protected void initDatawatcher() { + this.datawatcher.register(EntityFallingBlock.e, BlockPosition.ZERO); } + @Override public boolean isInteractable() { return !this.dead; } + @Override public void tick() { if (this.block.isAir()) { this.die(); @@ -74,7 +76,7 @@ public class EntityFallingBlock extends Entity { if (this.ticksLived++ == 0) { blockposition = new BlockPosition(this); if (this.world.getType(blockposition).getBlock() == block && !CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { - this.world.setAir(blockposition); + this.world.a(blockposition, false); } else if (!this.world.isClientSide) { this.die(); return; @@ -82,39 +84,38 @@ public class EntityFallingBlock extends Entity { } if (!this.isNoGravity()) { - this.motY -= 0.03999999910593033D; + this.setMot(this.getMot().add(0.0D, -0.04D, 0.0D)); } - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); + this.move(EnumMoveType.SELF, this.getMot()); // Paper start - Configurable EntityFallingBlock height nerf if (this.world.paperConfig.fallingBlockHeightNerf != 0 && this.locY > this.world.paperConfig.fallingBlockHeightNerf) { - if (this.dropItem && this.world.getGameRules().getBoolean("doEntityDrops")) { - this.dropItem(new ItemStack(block), 0.0F); + if (this.dropItem && this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { + this.a(block); } this.die(); } // Paper end - if (!this.world.isClientSide) { blockposition = new BlockPosition(this); boolean flag = this.block.getBlock() instanceof BlockConcretePowder; boolean flag1 = flag && this.world.getFluid(blockposition).a(TagsFluid.WATER); - double d0 = this.motX * this.motX + this.motY * this.motY + this.motZ * this.motZ; + double d0 = this.getMot().g(); if (flag && d0 > 1.0D) { - MovingObjectPosition movingobjectposition = this.world.rayTrace(new Vec3D(this.lastX, this.lastY, this.lastZ), new Vec3D(this.locX, this.locY, this.locZ), FluidCollisionOption.SOURCE_ONLY); + MovingObjectPositionBlock movingobjectpositionblock = this.world.rayTrace(new RayTrace(new Vec3D(this.lastX, this.lastY, this.lastZ), new Vec3D(this.locX, this.locY, this.locZ), RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.SOURCE_ONLY, this)); - if (movingobjectposition != null && this.world.getFluid(movingobjectposition.getBlockPosition()).a(TagsFluid.WATER)) { - blockposition = movingobjectposition.getBlockPosition(); + if (movingobjectpositionblock.getType() != MovingObjectPosition.EnumMovingObjectType.MISS && this.world.getFluid(movingobjectpositionblock.getBlockPosition()).a(TagsFluid.WATER)) { + blockposition = movingobjectpositionblock.getBlockPosition(); flag1 = true; } } if (!this.onGround && !flag1) { - if (this.ticksLived > 100 && !this.world.isClientSide && (blockposition.getY() < 1 || blockposition.getY() > 256) || this.ticksLived > 600) { - if (this.dropItem && this.world.getGameRules().getBoolean("doEntityDrops")) { + if (!this.world.isClientSide && (this.ticksLived > 100 && (blockposition.getY() < 1 || blockposition.getY() > 256) || this.ticksLived > 600)) { + if (this.dropItem && this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { this.a((IMaterial) block); } @@ -123,49 +124,52 @@ public class EntityFallingBlock extends Entity { } else { IBlockData iblockdata = this.world.getType(blockposition); - if (!flag1 && BlockFalling.canFallThrough(this.world.getType(new BlockPosition(this.locX, this.locY - 0.009999999776482582D, this.locZ)))) { - this.onGround = false; - // return; // CraftBukkit - } - - this.motX *= 0.699999988079071D; - this.motZ *= 0.699999988079071D; - this.motY *= -0.5D; + this.setMot(this.getMot().d(0.7D, -0.5D, 0.7D)); if (iblockdata.getBlock() != Blocks.MOVING_PISTON) { this.die(); - if (!this.f) { - // CraftBukkit start - if (iblockdata.getMaterial().isReplaceable() && (flag1 || !BlockFalling.canFallThrough(this.world.getType(blockposition.down())))) { + if (!this.g) { + boolean flag2 = iblockdata.a((BlockActionContext) (new BlockActionContextDirectional(this.world, blockposition, EnumDirection.DOWN, ItemStack.a, EnumDirection.UP))); + boolean flag3 = this.block.canPlace(this.world, blockposition); + + if (flag2 && flag3) { + if (this.block.b((IBlockState) BlockProperties.C) && this.world.getFluid(blockposition).getType() == FluidTypes.WATER) { + this.block = (IBlockData) this.block.set(BlockProperties.C, true); + } + + // CraftBukkit start if (CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, this.block).isCancelled()) { return; } - this.world.setTypeAndData(blockposition, this.block, 3); // CraftBukkit end - if (block instanceof BlockFalling) { - ((BlockFalling) block).a(this.world, blockposition, this.block, iblockdata); - } - - if (this.tileEntityData != null && block instanceof ITileEntity) { - TileEntity tileentity = this.world.getTileEntity(blockposition); - - if (tileentity != null) { - NBTTagCompound nbttagcompound = tileentity.save(new NBTTagCompound()); - Iterator iterator = this.tileEntityData.getKeys().iterator(); - - while (iterator.hasNext()) { - String s = (String) iterator.next(); - NBTBase nbtbase = this.tileEntityData.get(s); - - if (!"x".equals(s) && !"y".equals(s) && !"z".equals(s)) { - nbttagcompound.set(s, nbtbase.clone()); - } - } - - tileentity.load(nbttagcompound); - tileentity.update(); + if (this.world.setTypeAndData(blockposition, this.block, 3)) { + if (block instanceof BlockFalling) { + ((BlockFalling) block).a(this.world, blockposition, this.block, iblockdata); } + + if (this.tileEntityData != null && block instanceof ITileEntity) { + TileEntity tileentity = this.world.getTileEntity(blockposition); + + if (tileentity != null) { + NBTTagCompound nbttagcompound = tileentity.save(new NBTTagCompound()); + Iterator iterator = this.tileEntityData.getKeys().iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + NBTBase nbtbase = this.tileEntityData.get(s); + + if (!"x".equals(s) && !"y".equals(s) && !"z".equals(s)) { + nbttagcompound.set(s, nbtbase.clone()); + } + } + + tileentity.load(nbttagcompound); + tileentity.update(); + } + } + } else if (this.dropItem && this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { + this.a((IMaterial) block); } - } else if (this.dropItem && this.world.getGameRules().getBoolean("doEntityDrops")) { + } else if (this.dropItem && this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { this.a((IMaterial) block); } } else if (block instanceof BlockFalling) { @@ -175,13 +179,12 @@ public class EntityFallingBlock extends Entity { } } - this.motX *= 0.9800000190734863D; - this.motY *= 0.9800000190734863D; - this.motZ *= 0.9800000190734863D; + this.setMot(this.getMot().a(0.98D)); } } - public void c(float f, float f1) { + @Override + public void b(float f, float f1) { if (this.hurtEntities) { int i = MathHelper.f(f - 1.0F); @@ -203,7 +206,7 @@ public class EntityFallingBlock extends Entity { IBlockData iblockdata = BlockAnvil.a_(this.block); if (iblockdata == null) { - this.f = true; + this.g = true; } else { this.block = iblockdata; } @@ -213,6 +216,7 @@ public class EntityFallingBlock extends Entity { } + @Override protected void b(NBTTagCompound nbttagcompound) { nbttagcompound.set("BlockState", GameProfileSerializer.a(this.block)); nbttagcompound.setInt("Time", this.ticksLived); @@ -226,6 +230,7 @@ public class EntityFallingBlock extends Entity { } + @Override protected void a(NBTTagCompound nbttagcompound) { this.block = GameProfileSerializer.d(nbttagcompound.getCompound("BlockState")); @@ -272,6 +277,7 @@ public class EntityFallingBlock extends Entity { this.hurtEntities = flag; } + @Override public void appendEntityCrashDetails(CrashReportSystemDetails crashreportsystemdetails) { super.appendEntityCrashDetails(crashreportsystemdetails); crashreportsystemdetails.a("Immitating BlockState", (Object) this.block.toString()); @@ -281,7 +287,13 @@ public class EntityFallingBlock extends Entity { return this.block; } - public boolean bM() { + @Override + public boolean bT() { return true; } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this, Block.getCombinedId(this.getBlock())); + } } diff --git a/src/main/java/net/minecraft/server/EntityFireball.java b/src/main/java/net/minecraft/server/EntityFireball.java index b6cdfef4a..14c439493 100644 --- a/src/main/java/net/minecraft/server/EntityFireball.java +++ b/src/main/java/net/minecraft/server/EntityFireball.java @@ -5,21 +5,20 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public abstract class EntityFireball extends Entity { public EntityLiving shooter; - private int e; private int f; + private int g; public double dirX; public double dirY; public double dirZ; public float bukkitYield = 1; // CraftBukkit public boolean isIncendiary = true; // CraftBukkit - protected EntityFireball(EntityTypes entitytypes, World world, float f, float f1) { + protected EntityFireball(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.setSize(f, f1); } - public EntityFireball(EntityTypes entitytypes, double d0, double d1, double d2, double d3, double d4, double d5, World world, float f, float f1) { - this(entitytypes, world, f, f1); + public EntityFireball(EntityTypes entitytypes, double d0, double d1, double d2, double d3, double d4, double d5, World world) { + this(entitytypes, world); this.setPositionRotation(d0, d1, d2, this.yaw, this.pitch); this.setPosition(d0, d1, d2); double d6 = (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); @@ -29,15 +28,13 @@ public abstract class EntityFireball extends Entity { this.dirZ = d5 / d6 * 0.1D; } - public EntityFireball(EntityTypes entitytypes, EntityLiving entityliving, double d0, double d1, double d2, World world, float f, float f1) { - this(entitytypes, world, f, f1); + public EntityFireball(EntityTypes entitytypes, EntityLiving entityliving, double d0, double d1, double d2, World world) { + this(entitytypes, world); this.shooter = entityliving; this.projectileSource = (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit this.setPositionRotation(entityliving.locX, entityliving.locY, entityliving.locZ, entityliving.yaw, entityliving.pitch); this.setPosition(this.locX, this.locY, this.locZ); - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; + this.setMot(Vec3D.a); // CraftBukkit start - Added setDirection method this.setDirection(d0, d1, d2); } @@ -54,30 +51,32 @@ public abstract class EntityFireball extends Entity { this.dirZ = d2 / d3 * 0.1D; } - protected void x_() {} + @Override + protected void initDatawatcher() {} + @Override public void tick() { if (!this.world.isClientSide && (this.shooter != null && this.shooter.dead || !this.world.isLoaded(new BlockPosition(this)))) { this.die(); } else { super.tick(); - if (this.f()) { + if (this.K_()) { this.setOnFire(1); } - ++this.f; - MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, true, this.f >= 25, this.shooter); + ++this.g; + MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, true, this.g >= 25, this.shooter, RayTrace.BlockCollisionOption.COLLIDER); // Paper start - Call ProjectileCollideEvent - if (movingobjectposition != null && movingobjectposition.entity != null) { - com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = CraftEventFactory.callProjectileCollideEvent(this, movingobjectposition); + if (movingobjectposition instanceof MovingObjectPositionEntity) { + com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = CraftEventFactory.callProjectileCollideEvent(this, (MovingObjectPositionEntity)movingobjectposition); if (event.isCancelled()) { movingobjectposition = null; } } // Paper end - if (movingobjectposition != null) { + if (movingobjectposition != null && movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { // Paper - add null check in case cancelled this.a(movingobjectposition); // CraftBukkit start - Fire ProjectileHitEvent @@ -87,43 +86,36 @@ public abstract class EntityFireball extends Entity { // CraftBukkit end } - this.locX += this.motX; - this.locY += this.motY; - this.locZ += this.motZ; + Vec3D vec3d = this.getMot(); + + this.locX += vec3d.x; + this.locY += vec3d.y; + this.locZ += vec3d.z; ProjectileHelper.a(this, 0.2F); float f = this.k(); if (this.isInWater()) { - // Akarin start - this handle by client - /* for (int i = 0; i < 4; ++i) { float f1 = 0.25F; - this.world.addParticle(Particles.e, this.locX - this.motX * 0.25D, this.locY - this.motY * 0.25D, this.locZ - this.motZ * 0.25D, this.motX, this.motY, this.motZ); + this.world.addParticle(Particles.BUBBLE, this.locX - vec3d.x * 0.25D, this.locY - vec3d.y * 0.25D, this.locZ - vec3d.z * 0.25D, vec3d.x, vec3d.y, vec3d.z); } - */ - // Akarin end f = 0.8F; } - this.motX += this.dirX; - this.motY += this.dirY; - this.motZ += this.dirZ; - this.motX *= (double) f; - this.motY *= (double) f; - this.motZ *= (double) f; - //this.world.addParticle(this.i(), this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D); // Akarin - this handle by client + this.setMot(vec3d.add(this.dirX, this.dirY, this.dirZ).a((double) f)); + this.world.addParticle(this.i(), this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D); this.setPosition(this.locX, this.locY, this.locZ); } } - protected boolean f() { + protected boolean K_() { return true; } protected ParticleParam i() { - return Particles.M; + return Particles.SMOKE; } protected float k() { @@ -132,66 +124,66 @@ public abstract class EntityFireball extends Entity { protected abstract void a(MovingObjectPosition movingobjectposition); + @Override public void b(NBTTagCompound nbttagcompound) { - nbttagcompound.set("direction", this.a(new double[] { this.motX, this.motY, this.motZ})); - nbttagcompound.set("power", this.a(new double[] { this.dirX, this.dirY, this.dirZ})); - nbttagcompound.setInt("life", this.e); + Vec3D vec3d = this.getMot(); + + nbttagcompound.set("direction", this.a(new double[]{vec3d.x, vec3d.y, vec3d.z})); + nbttagcompound.set("power", this.a(new double[]{this.dirX, this.dirY, this.dirZ})); + nbttagcompound.setInt("life", this.f); } + @Override public void a(NBTTagCompound nbttagcompound) { NBTTagList nbttaglist; if (nbttagcompound.hasKeyOfType("power", 9)) { nbttaglist = nbttagcompound.getList("power", 6); if (nbttaglist.size() == 3) { - this.dirX = nbttaglist.k(0); - this.dirY = nbttaglist.k(1); - this.dirZ = nbttaglist.k(2); + this.dirX = nbttaglist.h(0); + this.dirY = nbttaglist.h(1); + this.dirZ = nbttaglist.h(2); } } - this.e = nbttagcompound.getInt("life"); + this.f = nbttagcompound.getInt("life"); if (nbttagcompound.hasKeyOfType("direction", 9) && nbttagcompound.getList("direction", 6).size() == 3) { nbttaglist = nbttagcompound.getList("direction", 6); - this.motX = nbttaglist.k(0); - this.motY = nbttaglist.k(1); - this.motZ = nbttaglist.k(2); + this.setMot(nbttaglist.h(0), nbttaglist.h(1), nbttaglist.h(2)); } else { this.die(); } } + @Override public boolean isInteractable() { return true; } - public float aM() { + @Override + public float aS() { return 1.0F; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; } else { - this.aA(); + this.velocityChanged(); if (damagesource.getEntity() != null) { // CraftBukkit start if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { return false; } // CraftBukkit end - Vec3D vec3d = damagesource.getEntity().aN(); - - if (vec3d != null) { - this.motX = vec3d.x; - this.motY = vec3d.y; - this.motZ = vec3d.z; - this.dirX = this.motX * 0.1D; - this.dirY = this.motY * 0.1D; - this.dirZ = this.motZ * 0.1D; - } + Vec3D vec3d = damagesource.getEntity().getLookDirection(); + this.setMot(vec3d); + this.dirX = vec3d.x * 0.1D; + this.dirY = vec3d.y * 0.1D; + this.dirZ = vec3d.z * 0.1D; if (damagesource.getEntity() instanceof EntityLiving) { this.shooter = (EntityLiving) damagesource.getEntity(); this.projectileSource = (org.bukkit.projectiles.ProjectileSource) this.shooter.getBukkitEntity(); @@ -204,7 +196,15 @@ public abstract class EntityFireball extends Entity { } } - public float az() { + @Override + public float aF() { return 1.0F; } + + @Override + public Packet N() { + int i = this.shooter == null ? 0 : this.shooter.getId(); + + return new PacketPlayOutSpawnEntity(this.getId(), this.getUniqueID(), this.locX, this.locY, this.locZ, this.pitch, this.yaw, this.getEntityType(), i, new Vec3D(this.dirX, this.dirY, this.dirZ)); + } } diff --git a/src/main/java/net/minecraft/server/EntityFireworks.java b/src/main/java/net/minecraft/server/EntityFireworks.java index 9764c76fb..dbbb96ac5 100644 --- a/src/main/java/net/minecraft/server/EntityFireworks.java +++ b/src/main/java/net/minecraft/server/EntityFireworks.java @@ -2,41 +2,51 @@ package net.minecraft.server; import java.util.Iterator; import java.util.List; +import java.util.OptionalInt; import java.util.UUID; import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit -public class EntityFireworks extends Entity { +public class EntityFireworks extends Entity implements IProjectile { public static final DataWatcherObject FIREWORK_ITEM = DataWatcher.a(EntityFireworks.class, DataWatcherRegistry.g); - private static final DataWatcherObject b = DataWatcher.a(EntityFireworks.class, DataWatcherRegistry.b); + private static final DataWatcherObject c = DataWatcher.a(EntityFireworks.class, DataWatcherRegistry.r); + public static final DataWatcherObject d = DataWatcher.a(EntityFireworks.class, DataWatcherRegistry.i); // PAIL private int ticksFlown; public int expectedLifespan; + private EntityLiving ridingEntity; public final EntityLiving getBoostedEntity() { return this.ridingEntity; } // Paper - OBFHELPER public UUID spawningEntity; // Paper - private EntityLiving e;public EntityLiving getBoostedEntity() { return e; } // Paper - OBFHELPER - public EntityFireworks(World world) { - super(EntityTypes.FIREWORK_ROCKET, world); - this.setSize(0.25F, 0.25F); + public EntityFireworks(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - // Spigot Start + // Spigot Start - copied from tick @Override public void inactiveTick() { this.ticksFlown += 1; + + if (!this.world.isClientSide && this.ticksFlown > this.expectedLifespan) { + // CraftBukkit start + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) { + this.explode(); + } + // CraftBukkit end + } super.inactiveTick(); } // Spigot End - protected void x_() { + @Override + protected void initDatawatcher() { this.datawatcher.register(EntityFireworks.FIREWORK_ITEM, ItemStack.a); - this.datawatcher.register(EntityFireworks.b, 0); + this.datawatcher.register(EntityFireworks.c, OptionalInt.empty()); + this.datawatcher.register(EntityFireworks.d, false); } public EntityFireworks(World world, double d0, double d1, double d2, ItemStack itemstack) { super(EntityTypes.FIREWORK_ROCKET, world); this.ticksFlown = 0; - this.setSize(0.25F, 0.25F); this.setPosition(d0, d1, d2); int i = 1; @@ -45,60 +55,77 @@ public class EntityFireworks extends Entity { i += itemstack.a("Fireworks").getByte("Flight"); } - this.motX = this.random.nextGaussian() * 0.001D; - this.motZ = this.random.nextGaussian() * 0.001D; - this.motY = 0.05D; + this.setMot(this.random.nextGaussian() * 0.001D, 0.05D, this.random.nextGaussian() * 0.001D); this.expectedLifespan = 10 * i + this.random.nextInt(6) + this.random.nextInt(7); } public EntityFireworks(World world, ItemStack itemstack, EntityLiving entityliving) { this(world, entityliving.locX, entityliving.locY, entityliving.locZ, itemstack); - this.datawatcher.set(EntityFireworks.b, entityliving.getId()); - this.e = entityliving; + this.datawatcher.set(EntityFireworks.c, OptionalInt.of(entityliving.getId())); + this.ridingEntity = entityliving; } - public void tick() { - this.N = this.locX; - this.O = this.locY; - this.P = this.locZ; - super.tick(); - if (this.f()) { - if (this.e == null) { - Entity entity = this.world.getEntity((Integer) this.datawatcher.get(EntityFireworks.b)); + public EntityFireworks(World world, ItemStack itemstack, double d0, double d1, double d2, boolean flag) { + this(world, d0, d1, d2, itemstack); + this.datawatcher.set(EntityFireworks.d, flag); + } - if (entity instanceof EntityLiving) { - this.e = (EntityLiving) entity; - } + @Override + public void tick() { + this.H = this.locX; + this.I = this.locY; + this.J = this.locZ; + super.tick(); + Vec3D vec3d; + + if (this.n()) { + if (this.ridingEntity == null) { + ((OptionalInt) this.datawatcher.get(EntityFireworks.c)).ifPresent((i) -> { + Entity entity = this.world.getEntity(i); + + if (entity instanceof EntityLiving) { + this.ridingEntity = (EntityLiving) entity; + } + + }); } - if (this.e != null) { - if (this.e.dc()) { - Vec3D vec3d = this.e.aN(); + if (this.ridingEntity != null) { + if (this.ridingEntity.isGliding()) { + vec3d = this.ridingEntity.getLookDirection(); double d0 = 1.5D; double d1 = 0.1D; + Vec3D vec3d1 = this.ridingEntity.getMot(); - this.e.motX += vec3d.x * 0.1D + (vec3d.x * 1.5D - this.e.motX) * 0.5D; - this.e.motY += vec3d.y * 0.1D + (vec3d.y * 1.5D - this.e.motY) * 0.5D; - this.e.motZ += vec3d.z * 0.1D + (vec3d.z * 1.5D - this.e.motZ) * 0.5D; + this.ridingEntity.setMot(vec3d1.add(vec3d.x * 0.1D + (vec3d.x * 1.5D - vec3d1.x) * 0.5D, vec3d.y * 0.1D + (vec3d.y * 1.5D - vec3d1.y) * 0.5D, vec3d.z * 0.1D + (vec3d.z * 1.5D - vec3d1.z) * 0.5D)); } - this.setPosition(this.e.locX, this.e.locY, this.e.locZ); - this.motX = this.e.motX; - this.motY = this.e.motY; - this.motZ = this.e.motZ; + this.setPosition(this.ridingEntity.locX, this.ridingEntity.locY, this.ridingEntity.locZ); + this.setMot(this.ridingEntity.getMot()); } } else { - this.motX *= 1.15D; - this.motZ *= 1.15D; - this.motY += 0.04D; - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); + if (!this.i()) { + this.setMot(this.getMot().d(1.15D, 1.0D, 1.15D).add(0.0D, 0.04D, 0.0D)); + } + + this.move(EnumMoveType.SELF, this.getMot()); } - float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + vec3d = this.getMot(); + MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, this.getBoundingBox().a(vec3d).g(1.0D), (entity) -> { + return !entity.isSpectator() && entity.isAlive() && entity.isInteractable(); + }, RayTrace.BlockCollisionOption.COLLIDER, true); - this.yaw = (float) (MathHelper.c(this.motX, this.motZ) * 57.2957763671875D); + if (!this.noclip) { + this.a(movingobjectposition); + this.impulse = true; + } - for (this.pitch = (float) (MathHelper.c(this.motY, (double) f) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + float f = MathHelper.sqrt(b(vec3d)); + + this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); + + for (this.pitch = (float) (MathHelper.d(vec3d.y, (double) f) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { ; } @@ -114,43 +141,83 @@ public class EntityFireworks extends Entity { this.lastYaw += 360.0F; } - this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; - this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; + this.pitch = MathHelper.g(0.2F, this.lastPitch, this.pitch); + this.yaw = MathHelper.g(0.2F, this.lastYaw, this.yaw); if (this.ticksFlown == 0 && !this.isSilent()) { - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_FIREWORK_ROCKET_LAUNCH, SoundCategory.AMBIENT, 3.0F, 1.0F); + this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_FIREWORK_ROCKET_LAUNCH, SoundCategory.AMBIENT, 3.0F, 1.0F); } ++this.ticksFlown; if (this.world.isClientSide && this.ticksFlown % 2 < 2) { - this.world.addParticle(Particles.w, this.locX, this.locY - 0.3D, this.locZ, this.random.nextGaussian() * 0.05D, -this.motY * 0.5D, this.random.nextGaussian() * 0.05D); + this.world.addParticle(Particles.FIREWORK, this.locX, this.locY - 0.3D, this.locZ, this.random.nextGaussian() * 0.05D, -this.getMot().y * 0.5D, this.random.nextGaussian() * 0.05D); } if (!this.world.isClientSide && this.ticksFlown > this.expectedLifespan) { // CraftBukkit start if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) { - this.world.broadcastEntityEffect(this, (byte) 17); - this.i(); + this.explode(); } // CraftBukkit end - this.die(); } } - private void i() { + private void explode() { + this.world.broadcastEntityEffect(this, (byte) 17); + this.m(); + this.die(); + } + + protected void a(MovingObjectPosition movingobjectposition) { + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY && !this.world.isClientSide) { + // CraftBukkit start + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) { + this.explode(); + } + // CraftBukkit end + } else if (this.z) { + BlockPosition blockposition; + + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + blockposition = new BlockPosition(((MovingObjectPositionBlock) movingobjectposition).getBlockPosition()); + } else { + blockposition = new BlockPosition(this); + } + + this.world.getType(blockposition).a(this.world, blockposition, (Entity) this); + if (this.l()) { + // CraftBukkit start + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) { + this.explode(); + } + // CraftBukkit end + } + } + + } + + private boolean l() { + ItemStack itemstack = (ItemStack) this.datawatcher.get(EntityFireworks.FIREWORK_ITEM); + NBTTagCompound nbttagcompound = itemstack.isEmpty() ? null : itemstack.b("Fireworks"); + NBTTagList nbttaglist = nbttagcompound != null ? nbttagcompound.getList("Explosions", 10) : null; + + return nbttaglist != null && !nbttaglist.isEmpty(); + } + + private void m() { float f = 0.0F; ItemStack itemstack = (ItemStack) this.datawatcher.get(EntityFireworks.FIREWORK_ITEM); NBTTagCompound nbttagcompound = itemstack.isEmpty() ? null : itemstack.b("Fireworks"); NBTTagList nbttaglist = nbttagcompound != null ? nbttagcompound.getList("Explosions", 10) : null; if (nbttaglist != null && !nbttaglist.isEmpty()) { - f = (float) (5 + nbttaglist.size() * 2); + f = 5.0F + (float) (nbttaglist.size() * 2); } if (f > 0.0F) { - if (this.e != null) { + if (this.ridingEntity != null) { CraftEventFactory.entityDamage = this; // CraftBukkit - this.e.damageEntity(DamageSource.FIREWORKS, (float) (5 + nbttaglist.size() * 2)); + this.ridingEntity.damageEntity(DamageSource.FIREWORKS, 5.0F + (float) (nbttaglist.size() * 2)); CraftEventFactory.entityDamage = null; // CraftBukkit } @@ -162,13 +229,14 @@ public class EntityFireworks extends Entity { while (iterator.hasNext()) { EntityLiving entityliving = (EntityLiving) iterator.next(); - if (entityliving != this.e && this.h(entityliving) <= 25.0D) { + if (entityliving != this.ridingEntity && this.h(entityliving) <= 25.0D) { boolean flag = false; for (int i = 0; i < 2; ++i) { - MovingObjectPosition movingobjectposition = this.world.rayTrace(vec3d, new Vec3D(entityliving.locX, entityliving.locY + (double) entityliving.length * 0.5D * (double) i, entityliving.locZ), FluidCollisionOption.NEVER, true, false); + Vec3D vec3d1 = new Vec3D(entityliving.locX, entityliving.locY + (double) entityliving.getHeight() * 0.5D * (double) i, entityliving.locZ); + MovingObjectPositionBlock movingobjectpositionblock = this.world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this)); - if (movingobjectposition == null || movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.MISS) { + if (movingobjectpositionblock.getType() == MovingObjectPosition.EnumMovingObjectType.MISS) { flag = true; break; } @@ -187,10 +255,15 @@ public class EntityFireworks extends Entity { } - public boolean f() { - return (Integer) this.datawatcher.get(EntityFireworks.b) > 0; + private boolean n() { + return ((OptionalInt) this.datawatcher.get(EntityFireworks.c)).isPresent(); } + public boolean i() { + return (Boolean) this.datawatcher.get(EntityFireworks.d); + } + + @Override public void b(NBTTagCompound nbttagcompound) { nbttagcompound.setInt("Life", this.ticksFlown); nbttagcompound.setInt("LifeTime", this.expectedLifespan); @@ -200,14 +273,15 @@ public class EntityFireworks extends Entity { nbttagcompound.set("FireworksItem", itemstack.save(new NBTTagCompound())); } + nbttagcompound.setBoolean("ShotAtAngle", (Boolean) this.datawatcher.get(EntityFireworks.d)); // Paper start - if (spawningEntity != null) { - nbttagcompound.setUUID("SpawningEntity", spawningEntity); + if (this.spawningEntity != null) { + nbttagcompound.setUUID("SpawningEntity", this.spawningEntity); } // Paper end - } + @Override public void a(NBTTagCompound nbttagcompound) { this.ticksFlown = nbttagcompound.getInt("Life"); this.expectedLifespan = nbttagcompound.getInt("LifeTime"); @@ -216,14 +290,40 @@ public class EntityFireworks extends Entity { if (!itemstack.isEmpty()) { this.datawatcher.set(EntityFireworks.FIREWORK_ITEM, itemstack); } + + if (nbttagcompound.hasKey("ShotAtAngle")) { + this.datawatcher.set(EntityFireworks.d, nbttagcompound.getBoolean("ShotAtAngle")); + } // Paper start if (nbttagcompound.hasUUID("SpawningEntity")) { - spawningEntity = nbttagcompound.getUUID("SpawningEntity"); + this.spawningEntity = nbttagcompound.getUUID("SpawningEntity"); } // Paper end } - public boolean bk() { + @Override + public boolean bs() { return false; } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); + } + + @Override + public void shoot(double d0, double d1, double d2, float f, float f1) { + float f2 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + + d0 /= (double) f2; + d1 /= (double) f2; + d2 /= (double) f2; + d0 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; + d1 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; + d2 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; + d0 *= (double) f; + d1 *= (double) f; + d2 *= (double) f; + this.setMot(d0, d1, d2); + } } diff --git a/src/main/java/net/minecraft/server/EntityFish.java b/src/main/java/net/minecraft/server/EntityFish.java index 5da2d72af..90479feb4 100644 --- a/src/main/java/net/minecraft/server/EntityFish.java +++ b/src/main/java/net/minecraft/server/EntityFish.java @@ -1,105 +1,119 @@ package net.minecraft.server; -public abstract class EntityFish extends EntityWaterAnimal implements IAnimal { +import java.util.Random; +import java.util.function.Predicate; - private static final DataWatcherObject a = DataWatcher.a(EntityFish.class, DataWatcherRegistry.i); +public abstract class EntityFish extends EntityWaterAnimal { - public EntityFish(EntityTypes entitytypes, World world) { + private static final DataWatcherObject FROM_BUCKET = DataWatcher.a(EntityFish.class, DataWatcherRegistry.i); + + public EntityFish(EntityTypes entitytypes, World world) { super(entitytypes, world); this.moveController = new EntityFish.a(this); } - public float getHeadHeight() { - return this.length * 0.65F; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height * 0.65F; } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(3.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(3.0D); } - public boolean isPersistent() { - return this.isFromBucket() || super.isPersistent(); + @Override + public boolean I() { + return this.isFromBucket(); } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - BlockPosition blockposition = new BlockPosition(this); - - return generatoraccess.getType(blockposition).getBlock() == Blocks.WATER && generatoraccess.getType(blockposition.up()).getBlock() == Blocks.WATER ? super.a(generatoraccess, flag) : false; + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return generatoraccess.getType(blockposition).getBlock() == Blocks.WATER && generatoraccess.getType(blockposition.up()).getBlock() == Blocks.WATER; } - public boolean isTypeNotPersistent() { + @Override + public boolean isTypeNotPersistent(double d0) { return true; // CraftBukkit } - public int dg() { + @Override + public int dC() { return 8; } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityFish.a, false); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityFish.FROM_BUCKET, false); } public boolean isFromBucket() { - return (Boolean) this.datawatcher.get(EntityFish.a); + return (Boolean) this.datawatcher.get(EntityFish.FROM_BUCKET); } public void setFromBucket(boolean flag) { - this.datawatcher.set(EntityFish.a, flag); + this.datawatcher.set(EntityFish.FROM_BUCKET, flag); this.persistent = this.isPersistent(); // CraftBukkit - SPIGOT-4106 update persistence } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setBoolean("FromBucket", this.isFromBucket()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setFromBucket(nbttagcompound.getBoolean("FromBucket")); } - protected void n() { - super.n(); + @Override + protected void initPathfinder() { + super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); - this.goalSelector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, IEntitySelector.f)); + PathfinderGoalSelector pathfindergoalselector = this.goalSelector; + Predicate predicate = IEntitySelector.f; + + predicate.getClass(); + pathfindergoalselector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, predicate::test)); this.goalSelector.a(4, new EntityFish.b(this)); } + @Override protected NavigationAbstract b(World world) { return new NavigationGuardian(this, world); } - public void a(float f, float f1, float f2) { - if (this.cP() && this.isInWater()) { - this.a(f, f1, f2, 0.01F); - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - this.motX *= 0.8999999761581421D; - this.motY *= 0.8999999761581421D; - this.motZ *= 0.8999999761581421D; + @Override + public void e(Vec3D vec3d) { + if (this.df() && this.isInWater()) { + this.a(0.01F, vec3d); + this.move(EnumMoveType.SELF, this.getMot()); + this.setMot(this.getMot().a(0.9D)); if (this.getGoalTarget() == null) { - this.motY -= 0.005D; + this.setMot(this.getMot().add(0.0D, -0.005D, 0.0D)); } } else { - super.a(f, f1, f2); + super.e(vec3d); } } + @Override public void movementTick() { - if (!this.isInWater() && this.onGround && this.C) { - this.motY += 0.4000000059604645D; - this.motX += (double) ((this.random.nextFloat() * 2.0F - 1.0F) * 0.05F); - this.motZ += (double) ((this.random.nextFloat() * 2.0F - 1.0F) * 0.05F); + if (!this.isInWater() && this.onGround && this.y) { + this.setMot(this.getMot().add((double) ((this.random.nextFloat() * 2.0F - 1.0F) * 0.05F), 0.4000000059604645D, (double) ((this.random.nextFloat() * 2.0F - 1.0F) * 0.05F))); this.onGround = false; this.impulse = true; - this.a(this.dz(), this.cD(), this.cE()); + this.a(this.getSoundFlop(), this.getSoundVolume(), this.cV()); } super.movementTick(); } + @Override protected boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -108,7 +122,7 @@ public abstract class EntityFish extends EntityWaterAnimal implements IAnimal { itemstack.subtract(1); ItemStack itemstack1 = this.l(); - this.f(itemstack1); + this.i(itemstack1); if (!this.world.isClientSide) { CriterionTriggers.j.a((EntityPlayer) entityhuman, itemstack1); } @@ -126,7 +140,7 @@ public abstract class EntityFish extends EntityWaterAnimal implements IAnimal { } } - protected void f(ItemStack itemstack) { + protected void i(ItemStack itemstack) { if (this.hasCustomName()) { itemstack.a(this.getCustomName()); } @@ -135,13 +149,14 @@ public abstract class EntityFish extends EntityWaterAnimal implements IAnimal { protected abstract ItemStack l(); - protected boolean dy() { + protected boolean dV() { return true; } - protected abstract SoundEffect dz(); + protected abstract SoundEffect getSoundFlop(); - protected SoundEffect ad() { + @Override + protected SoundEffect getSoundSwim() { return SoundEffects.ENTITY_FISH_SWIM; } @@ -154,26 +169,27 @@ public abstract class EntityFish extends EntityWaterAnimal implements IAnimal { this.i = entityfish; } + @Override public void a() { if (this.i.a(TagsFluid.WATER)) { - this.i.motY += 0.005D; + this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); } - if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().p()) { + if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().n()) { double d0 = this.b - this.i.locX; double d1 = this.c - this.i.locY; double d2 = this.d - this.i.locZ; double d3 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); d1 /= d3; - float f = (float) (MathHelper.c(d2, d0) * 57.2957763671875D) - 90.0F; + float f = (float) (MathHelper.d(d2, d0) * 57.2957763671875D) - 90.0F; this.i.yaw = this.a(this.i.yaw, f, 90.0F); - this.i.aQ = this.i.yaw; + this.i.aK = this.i.yaw; float f1 = (float) (this.e * this.i.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); - this.i.o(this.i.cK() + (f1 - this.i.cK()) * 0.125F); - this.i.motY += (double) this.i.cK() * d1 * 0.1D; + this.i.o(MathHelper.g(0.125F, this.i.db(), f1)); + this.i.setMot(this.i.getMot().add(0.0D, (double) this.i.db() * d1 * 0.1D, 0.0D)); } else { this.i.o(0.0F); } @@ -189,8 +205,9 @@ public abstract class EntityFish extends EntityWaterAnimal implements IAnimal { this.h = entityfish; } + @Override public boolean a() { - return this.h.dy() && super.a(); + return this.h.dV() && super.a(); } } } diff --git a/src/main/java/net/minecraft/server/EntityFishingHook.java b/src/main/java/net/minecraft/server/EntityFishingHook.java index afbf46842..2a351701b 100644 --- a/src/main/java/net/minecraft/server/EntityFishingHook.java +++ b/src/main/java/net/minecraft/server/EntityFishingHook.java @@ -3,6 +3,7 @@ package net.minecraft.server; import java.util.Collections; import java.util.Iterator; import java.util.List; +import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.entity.Player; import org.bukkit.entity.FishHook; @@ -11,47 +12,32 @@ import org.bukkit.event.player.PlayerFishEvent; public class EntityFishingHook extends Entity { - private static final DataWatcherObject b = DataWatcher.a(EntityFishingHook.class, DataWatcherRegistry.b); + private static final DataWatcherObject c = DataWatcher.a(EntityFishingHook.class, DataWatcherRegistry.b); private boolean isInGround; - private int d; + private int e; public EntityHuman owner; - private int f; private int g; - private int h; - private int aw; - private float ax; + private int ar; + private int as; + private int at; + private float au; public Entity hooked; - private EntityFishingHook.HookState ay; - private int az; - private int aA; + private EntityFishingHook.HookState av; + private final int aw; + private final int ax; - private EntityFishingHook(World world) { + private EntityFishingHook(World world, EntityHuman entityhuman, int i, int j) { super(EntityTypes.FISHING_BOBBER, world); - this.ay = EntityFishingHook.HookState.FLYING; - } - - public EntityFishingHook(World world, EntityHuman entityhuman) { - this(world); - this.a(entityhuman); - this.k(); - } - - private void a(EntityHuman entityhuman) { - this.setSize(0.25F, 0.25F); - this.ak = true; + this.av = EntityFishingHook.HookState.FLYING; + this.af = true; this.owner = entityhuman; this.owner.hookedFish = this; + this.aw = Math.max(0, i); + this.ax = Math.max(0, j); } - public void a(int i) { - this.aA = i; - } - - public void b(int i) { - this.az = i; - } - - private void k() { + public EntityFishingHook(EntityHuman entityhuman, World world, int i, int j) { + this(world, entityhuman, i, j); float f = this.owner.pitch; float f1 = this.owner.yaw; float f2 = MathHelper.cos(-f1 * 0.017453292F - 3.1415927F); @@ -63,29 +49,26 @@ public class EntityFishingHook extends Entity { double d2 = this.owner.locZ - (double) f2 * 0.3D; this.setPositionRotation(d0, d1, d2, f1, f); - this.motX = (double) (-f3); - this.motY = (double) MathHelper.a(-(f5 / f4), -5.0F, 5.0F); - this.motZ = (double) (-f2); - float f6 = MathHelper.sqrt(this.motX * this.motX + this.motY * this.motY + this.motZ * this.motZ); + Vec3D vec3d = new Vec3D((double) (-f3), (double) MathHelper.a(-(f5 / f4), -5.0F, 5.0F), (double) (-f2)); + double d3 = vec3d.f(); - this.motX *= 0.6D / (double) f6 + 0.5D + this.random.nextGaussian() * 0.0045D; - this.motY *= 0.6D / (double) f6 + 0.5D + this.random.nextGaussian() * 0.0045D; - this.motZ *= 0.6D / (double) f6 + 0.5D + this.random.nextGaussian() * 0.0045D; - float f7 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); - - this.yaw = (float) (MathHelper.c(this.motX, this.motZ) * 57.2957763671875D); - this.pitch = (float) (MathHelper.c(this.motY, (double) f7) * 57.2957763671875D); + vec3d = vec3d.d(0.6D / d3 + 0.5D + this.random.nextGaussian() * 0.0045D, 0.6D / d3 + 0.5D + this.random.nextGaussian() * 0.0045D, 0.6D / d3 + 0.5D + this.random.nextGaussian() * 0.0045D); + this.setMot(vec3d); + this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); + this.pitch = (float) (MathHelper.d(vec3d.y, (double) MathHelper.sqrt(b(vec3d))) * 57.2957763671875D); this.lastYaw = this.yaw; this.lastPitch = this.pitch; } - protected void x_() { - this.getDataWatcher().register(EntityFishingHook.b, 0); + @Override + protected void initDatawatcher() { + this.getDataWatcher().register(EntityFishingHook.c, 0); } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntityFishingHook.b.equals(datawatcherobject)) { - int i = (Integer) this.getDataWatcher().get(EntityFishingHook.b); + if (EntityFishingHook.c.equals(datawatcherobject)) { + int i = (Integer) this.getDataWatcher().get(EntityFishingHook.c); this.hooked = i > 0 ? this.world.getEntity(i - 1) : null; } @@ -93,14 +76,15 @@ public class EntityFishingHook extends Entity { super.a(datawatcherobject); } + @Override public void tick() { super.tick(); if (this.owner == null) { this.die(); - } else if (this.world.isClientSide || !this.l()) { + } else if (this.world.isClientSide || !this.k()) { if (this.isInGround) { - ++this.d; - if (this.d >= 1200) { + ++this.e; + if (this.e >= 1200) { this.die(); return; } @@ -111,51 +95,41 @@ public class EntityFishingHook extends Entity { Fluid fluid = this.world.getFluid(blockposition); if (fluid.a(TagsFluid.WATER)) { - f = fluid.getHeight(); + f = fluid.getHeight(this.world, blockposition); } - double d0; - - if (this.ay == EntityFishingHook.HookState.FLYING) { + if (this.av == EntityFishingHook.HookState.FLYING) { if (this.hooked != null) { - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; - this.ay = EntityFishingHook.HookState.HOOKED_IN_ENTITY; + this.setMot(Vec3D.a); + this.av = EntityFishingHook.HookState.HOOKED_IN_ENTITY; return; } if (f > 0.0F) { - this.motX *= 0.3D; - this.motY *= 0.2D; - this.motZ *= 0.3D; - this.ay = EntityFishingHook.HookState.BOBBING; + this.setMot(this.getMot().d(0.3D, 0.2D, 0.3D)); + this.av = EntityFishingHook.HookState.BOBBING; return; } if (!this.world.isClientSide) { - this.n(); + this.m(); } if (!this.isInGround && !this.onGround && !this.positionChanged) { - ++this.f; + ++this.g; } else { - this.f = 0; - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; + this.g = 0; + this.setMot(Vec3D.a); } } else { - if (this.ay == EntityFishingHook.HookState.HOOKED_IN_ENTITY) { + if (this.av == EntityFishingHook.HookState.HOOKED_IN_ENTITY) { if (this.hooked != null) { if (this.hooked.dead) { this.hooked = null; - this.ay = EntityFishingHook.HookState.FLYING; + this.av = EntityFishingHook.HookState.FLYING; } else { this.locX = this.hooked.locX; - double d1 = (double) this.hooked.length; - - this.locY = this.hooked.getBoundingBox().minY + d1 * 0.8D; + this.locY = this.hooked.getBoundingBox().minY + (double) this.hooked.getHeight() * 0.8D; this.locZ = this.hooked.locZ; this.setPosition(this.locX, this.locY, this.locZ); } @@ -164,15 +138,15 @@ public class EntityFishingHook extends Entity { return; } - if (this.ay == EntityFishingHook.HookState.BOBBING) { - this.motX *= 0.9D; - this.motZ *= 0.9D; - d0 = this.locY + this.motY - (double) blockposition.getY() - (double) f; + if (this.av == EntityFishingHook.HookState.BOBBING) { + Vec3D vec3d = this.getMot(); + double d0 = this.locY + vec3d.y - (double) blockposition.getY() - (double) f; + if (Math.abs(d0) < 0.01D) { d0 += Math.signum(d0) * 0.1D; } - this.motY -= d0 * (double) this.random.nextFloat() * 0.2D; + this.setMot(vec3d.x * 0.9D, vec3d.y - d0 * (double) this.random.nextFloat() * 0.2D, vec3d.z * 0.9D); if (!this.world.isClientSide && f > 0.0F) { this.a(blockposition); } @@ -180,15 +154,14 @@ public class EntityFishingHook extends Entity { } if (!fluid.a(TagsFluid.WATER)) { - this.motY -= 0.03D; + this.setMot(this.getMot().add(0.0D, -0.03D, 0.0D)); } - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - this.m(); - d0 = 0.92D; - this.motX *= 0.92D; - this.motY *= 0.92D; - this.motZ *= 0.92D; + this.move(EnumMoveType.SELF, this.getMot()); + this.l(); + double d1 = 0.92D; + + this.setMot(this.getMot().a(0.92D)); this.setPosition(this.locX, this.locY, this.locZ); // Paper start - These shouldn't be going through portals @@ -199,7 +172,7 @@ public class EntityFishingHook extends Entity { } } - private boolean l() { + private boolean k() { ItemStack itemstack = this.owner.getItemInMainHand(); ItemStack itemstack1 = this.owner.getItemInOffHand(); boolean flag = itemstack.getItem() == Items.FISHING_ROD; @@ -213,12 +186,13 @@ public class EntityFishingHook extends Entity { } } - private void m() { - float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + private void l() { + Vec3D vec3d = this.getMot(); + float f = MathHelper.sqrt(b(vec3d)); - this.yaw = (float) (MathHelper.c(this.motX, this.motZ) * 57.2957763671875D); + this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); - for (this.pitch = (float) (MathHelper.c(this.motY, (double) f) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + for (this.pitch = (float) (MathHelper.d(vec3d.y, (double) f) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { ; } @@ -234,63 +208,29 @@ public class EntityFishingHook extends Entity { this.lastYaw += 360.0F; } - this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; - this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; + this.pitch = MathHelper.g(0.2F, this.lastPitch, this.pitch); + this.yaw = MathHelper.g(0.2F, this.lastYaw, this.yaw); } - private void n() { - Vec3D vec3d = new Vec3D(this.locX, this.locY, this.locZ); - Vec3D vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); - MovingObjectPosition movingobjectposition = this.world.rayTrace(vec3d, vec3d1, FluidCollisionOption.NEVER, true, false); - - vec3d = new Vec3D(this.locX, this.locY, this.locZ); - vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + private void m() { + MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, this.getBoundingBox().a(this.getMot()).g(1.0D), (entity) -> { + return !entity.isSpectator() && (entity.isInteractable() || entity instanceof EntityItem) && (entity != this.owner || this.g >= 5); + }, RayTrace.BlockCollisionOption.COLLIDER, true); // Paper start - Call ProjectileCollideEvent - if (movingobjectposition != null && movingobjectposition.entity != null) { - com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, movingobjectposition); + if (movingobjectposition instanceof MovingObjectPositionEntity) { + com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, (MovingObjectPositionEntity)movingobjectposition); if (event.isCancelled()) { movingobjectposition = null; } } // Paper end - if (movingobjectposition != null) { - vec3d1 = new Vec3D(movingobjectposition.pos.x, movingobjectposition.pos.y, movingobjectposition.pos.z); - } - - Entity entity = null; - List list = this.world.getEntities(this, this.getBoundingBox().b(this.motX, this.motY, this.motZ).g(1.0D)); - double d0 = 0.0D; - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - Entity entity1 = (Entity) iterator.next(); - - if (this.a(entity1) && (entity1 != this.owner || this.f >= 5)) { - AxisAlignedBB axisalignedbb = entity1.getBoundingBox().g(0.30000001192092896D); - MovingObjectPosition movingobjectposition1 = axisalignedbb.b(vec3d, vec3d1); - - if (movingobjectposition1 != null) { - double d1 = vec3d.distanceSquared(movingobjectposition1.pos); - - if (d1 < d0 || d0 == 0.0D) { - entity = entity1; - d0 = d1; - } - } - } - } - - if (entity != null) { - movingobjectposition = new MovingObjectPosition(entity); - } - - if (movingobjectposition != null && movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.MISS) { + if (movingobjectposition != null && movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { // Paper - add null check in case cancelled org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition); // Craftbukkit - Call event - if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.ENTITY) { - this.hooked = movingobjectposition.entity; - this.o(); + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + this.hooked = ((MovingObjectPositionEntity) movingobjectposition).getEntity(); + this.n(); } else { this.isInGround = true; } @@ -298,8 +238,8 @@ public class EntityFishingHook extends Entity { } - private void o() { - this.getDataWatcher().set(EntityFishingHook.b, this.hooked.getId() + 1); + private void n() { + this.getDataWatcher().set(EntityFishingHook.c, this.hooked.getId() + 1); } private void a(BlockPosition blockposition) { @@ -311,21 +251,21 @@ public class EntityFishingHook extends Entity { ++i; } - if (this.random.nextFloat() < 0.5F && !this.world.e(blockposition1)) { + if (this.random.nextFloat() < 0.5F && !this.world.f(blockposition1)) { --i; } - if (this.g > 0) { - --this.g; - if (this.g <= 0) { - this.h = 0; - this.aw = 0; + if (this.ar > 0) { + --this.ar; + if (this.ar <= 0) { + this.as = 0; + this.at = 0; // CraftBukkit start PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.FAILED_ATTEMPT); this.world.getServer().getPluginManager().callEvent(playerFishEvent); // CraftBukkit end } else { - this.motY -= 0.2D * (double) this.random.nextFloat() * (double) this.random.nextFloat(); + this.setMot(this.getMot().add(0.0D, -0.2D * (double) this.random.nextFloat() * (double) this.random.nextFloat(), 0.0D)); } } else { float f; @@ -336,27 +276,27 @@ public class EntityFishingHook extends Entity { double d2; Block block; - if (this.aw > 0) { - this.aw -= i; - if (this.aw > 0) { - this.ax = (float) ((double) this.ax + this.random.nextGaussian() * 4.0D); - f = this.ax * 0.017453292F; + if (this.at > 0) { + this.at -= i; + if (this.at > 0) { + this.au = (float) ((double) this.au + this.random.nextGaussian() * 4.0D); + f = this.au * 0.017453292F; f1 = MathHelper.sin(f); f2 = MathHelper.cos(f); - d0 = this.locX + (double) (f1 * (float) this.aw * 0.1F); + d0 = this.locX + (double) (f1 * (float) this.at * 0.1F); d1 = (double) ((float) MathHelper.floor(this.getBoundingBox().minY) + 1.0F); - d2 = this.locZ + (double) (f2 * (float) this.aw * 0.1F); + d2 = this.locZ + (double) (f2 * (float) this.at * 0.1F); block = worldserver.getType(new BlockPosition(d0, d1 - 1.0D, d2)).getBlock(); if (block == Blocks.WATER) { if (this.random.nextFloat() < 0.15F) { - worldserver.a(Particles.e, d0, d1 - 0.10000000149011612D, d2, 1, (double) f1, 0.1D, (double) f2, 0.0D); + worldserver.a(Particles.BUBBLE, d0, d1 - 0.10000000149011612D, d2, 1, (double) f1, 0.1D, (double) f2, 0.0D); } float f3 = f1 * 0.04F; float f4 = f2 * 0.04F; - worldserver.a(Particles.x, d0, d1, d2, 0, (double) f4, 0.01D, (double) (-f3), 1.0D); - worldserver.a(Particles.x, d0, d1, d2, 0, (double) (-f4), 0.01D, (double) f3, 1.0D); + worldserver.a(Particles.FISHING, d0, d1, d2, 0, (double) f4, 0.01D, (double) (-f3), 1.0D); + worldserver.a(Particles.FISHING, d0, d1, d2, 0, (double) (-f4), 0.01D, (double) f3, 1.0D); } } else { // CraftBukkit start @@ -366,23 +306,25 @@ public class EntityFishingHook extends Entity { return; } // CraftBukkit end - this.motY = (double) (-0.4F * MathHelper.a(this.random, 0.6F, 1.0F)); + Vec3D vec3d = this.getMot(); + + this.setMot(vec3d.x, (double) (-0.4F * MathHelper.a(this.random, 0.6F, 1.0F)), vec3d.z); this.a(SoundEffects.ENTITY_FISHING_BOBBER_SPLASH, 0.25F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); double d3 = this.getBoundingBox().minY + 0.5D; - worldserver.a(Particles.e, this.locX, d3, this.locZ, (int) (1.0F + this.width * 20.0F), (double) this.width, 0.0D, (double) this.width, 0.20000000298023224D); - worldserver.a(Particles.x, this.locX, d3, this.locZ, (int) (1.0F + this.width * 20.0F), (double) this.width, 0.0D, (double) this.width, 0.20000000298023224D); - this.g = MathHelper.nextInt(this.random, 20, 40); + worldserver.a(Particles.BUBBLE, this.locX, d3, this.locZ, (int) (1.0F + this.getWidth() * 20.0F), (double) this.getWidth(), 0.0D, (double) this.getWidth(), 0.20000000298023224D); + worldserver.a(Particles.FISHING, this.locX, d3, this.locZ, (int) (1.0F + this.getWidth() * 20.0F), (double) this.getWidth(), 0.0D, (double) this.getWidth(), 0.20000000298023224D); + this.ar = MathHelper.nextInt(this.random, 20, 40); } - } else if (this.h > 0) { - this.h -= i; + } else if (this.as > 0) { + this.as -= i; f = 0.15F; - if (this.h < 20) { - f = (float) ((double) f + (double) (20 - this.h) * 0.05D); - } else if (this.h < 40) { - f = (float) ((double) f + (double) (40 - this.h) * 0.02D); - } else if (this.h < 60) { - f = (float) ((double) f + (double) (60 - this.h) * 0.01D); + if (this.as < 20) { + f = (float) ((double) f + (double) (20 - this.as) * 0.05D); + } else if (this.as < 40) { + f = (float) ((double) f + (double) (40 - this.as) * 0.02D); + } else if (this.as < 60) { + f = (float) ((double) f + (double) (60 - this.as) * 0.01D); } if (this.random.nextFloat() < f) { @@ -391,31 +333,29 @@ public class EntityFishingHook extends Entity { d0 = this.locX + (double) (MathHelper.sin(f1) * f2 * 0.1F); d1 = (double) ((float) MathHelper.floor(this.getBoundingBox().minY) + 1.0F); d2 = this.locZ + (double) (MathHelper.cos(f1) * f2 * 0.1F); - block = worldserver.getType(new BlockPosition((int) d0, (int) d1 - 1, (int) d2)).getBlock(); + block = worldserver.getType(new BlockPosition(d0, d1 - 1.0D, d2)).getBlock(); if (block == Blocks.WATER) { - worldserver.a(Particles.R, d0, d1, d2, 2 + this.random.nextInt(2), 0.10000000149011612D, 0.0D, 0.10000000149011612D, 0.0D); + worldserver.a(Particles.SPLASH, d0, d1, d2, 2 + this.random.nextInt(2), 0.10000000149011612D, 0.0D, 0.10000000149011612D, 0.0D); } } - if (this.h <= 0) { - this.ax = MathHelper.a(this.random, 0.0F, 360.0F); - this.aw = MathHelper.nextInt(this.random, 20, 80); + if (this.as <= 0) { + this.au = MathHelper.a(this.random, 0.0F, 360.0F); + this.at = MathHelper.nextInt(this.random, 20, 80); } } else { - this.h = MathHelper.nextInt(this.random, world.paperConfig.fishingMinTicks, world.paperConfig.fishingMaxTicks); // Paper - this.h -= this.aA * 20 * 5; - this.h = Math.max(0, this.h); // Paper - Don't allow negative values + this.as = MathHelper.nextInt(this.random, world.paperConfig.fishingMinTicks, world.paperConfig.fishingMaxTicks); // Paper + this.as -= this.ax * 20 * 5; + this.as = Math.max(0, this.as); // Paper - Don't allow negative values } } } - protected boolean a(Entity entity) { - return entity.isInteractable() || entity instanceof EntityItem; - } - + @Override public void b(NBTTagCompound nbttagcompound) {} + @Override public void a(NBTTagCompound nbttagcompound) {} public int b(ItemStack itemstack) { @@ -431,15 +371,14 @@ public class EntityFishingHook extends Entity { return 0; } // CraftBukkit end - this.f(); + this.reel(); CriterionTriggers.D.a((EntityPlayer) this.owner, itemstack, this, Collections.emptyList()); this.world.broadcastEntityEffect(this, (byte) 31); i = this.hooked instanceof EntityItem ? 3 : 5; - } else if (this.g > 0) { - LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).position(new BlockPosition(this)); - - loottableinfo_builder.luck((float) this.az + this.owner.dJ()); - List list = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.aO).populateLoot(this.random, loottableinfo_builder.build()); + } else if (this.ar > 0) { + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).set(LootContextParameters.POSITION, new BlockPosition(this)).set(LootContextParameters.TOOL, itemstack).a(this.random).a((float) this.aw + this.owner.eb()); + LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(LootTables.ab); + List list = loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.FISHING)); CriterionTriggers.D.a((EntityPlayer) this.owner, itemstack, this, list); Iterator iterator = list.iterator(); @@ -459,12 +398,9 @@ public class EntityFishingHook extends Entity { double d0 = this.owner.locX - this.locX; double d1 = this.owner.locY - this.locY; double d2 = this.owner.locZ - this.locZ; - double d3 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); - double d4 = 0.1D; + double d3 = 0.1D; - entityitem.motX = d0 * 0.1D; - entityitem.motY = d1 * 0.1D + (double) MathHelper.sqrt(d3) * 0.08D; - entityitem.motZ = d2 * 0.1D; + entityitem.setMot(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D); this.world.addEntity(entityitem); // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop() if (playerFishEvent.getExpToDrop() > 0) { @@ -492,7 +428,7 @@ public class EntityFishingHook extends Entity { } // CraftBukkit start if (i == 0) { - PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.FAILED_ATTEMPT); + PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.REEL_IN); this.world.getServer().getPluginManager().callEvent(playerFishEvent); if (playerFishEvent.isCancelled()) { return 0; @@ -507,23 +443,20 @@ public class EntityFishingHook extends Entity { } } - protected void f() { + protected void reel() { if (this.owner != null) { - double d0 = this.owner.locX - this.locX; - double d1 = this.owner.locY - this.locY; - double d2 = this.owner.locZ - this.locZ; - double d3 = 0.1D; + Vec3D vec3d = (new Vec3D(this.owner.locX - this.locX, this.owner.locY - this.locY, this.owner.locZ - this.locZ)).a(0.1D); - this.hooked.motX += d0 * 0.1D; - this.hooked.motY += d1 * 0.1D; - this.hooked.motZ += d2 * 0.1D; + this.hooked.setMot(this.hooked.getMot().e(vec3d)); } } + @Override protected boolean playStepSound() { return false; } + @Override public void die() { super.die(); if (this.owner != null) { @@ -532,14 +465,23 @@ public class EntityFishingHook extends Entity { } + @Nullable public EntityHuman i() { return this.owner; } - public boolean bm() { + @Override + public boolean canPortal() { return false; } + @Override + public Packet N() { + EntityHuman entityhuman = this.i(); + + return new PacketPlayOutSpawnEntity(this, entityhuman == null ? this.getId() : entityhuman.getId()); + } + static enum HookState { FLYING, HOOKED_IN_ENTITY, BOBBING; diff --git a/src/main/java/net/minecraft/server/EntityFox.java b/src/main/java/net/minecraft/server/EntityFox.java new file mode 100644 index 000000000..ca38ccf76 --- /dev/null +++ b/src/main/java/net/minecraft/server/EntityFox.java @@ -0,0 +1,1474 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Arrays; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import javax.annotation.Nullable; + +public class EntityFox extends EntityAnimal { + + private static final DataWatcherObject bz = DataWatcher.a(EntityFox.class, DataWatcherRegistry.b); + private static final DataWatcherObject bA = DataWatcher.a(EntityFox.class, DataWatcherRegistry.a); + private static final DataWatcherObject> bB = DataWatcher.a(EntityFox.class, DataWatcherRegistry.o); + private static final DataWatcherObject> bC = DataWatcher.a(EntityFox.class, DataWatcherRegistry.o); + private static final Predicate bD = (entityitem) -> { + return !entityitem.q() && entityitem.isAlive(); + }; + private static final Predicate bE = (entity) -> { + if (!(entity instanceof EntityLiving)) { + return false; + } else { + EntityLiving entityliving = (EntityLiving) entity; + + return entityliving.cu() != null && entityliving.cv() < entityliving.ticksLived + 600; + } + }; + private static final Predicate bF = (entity) -> { + return entity instanceof EntityChicken || entity instanceof EntityRabbit; + }; + private static final Predicate bG = (entity) -> { + return !entity.isSneaking() && IEntitySelector.e.test(entity); + }; + private PathfinderGoal bH; + private PathfinderGoal bI; + private PathfinderGoal bJ; + private float bK; + private float bL; + private float bM; + private float bN; + private int bO; + + public EntityFox(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.lookController = new EntityFox.k(); + this.moveController = new EntityFox.m(); + this.a(PathType.DANGER_OTHER, 0.0F); + this.a(PathType.DAMAGE_OTHER, 0.0F); + this.setCanPickupLoot(true); + } + + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityFox.bB, Optional.empty()); + this.datawatcher.register(EntityFox.bC, Optional.empty()); + this.datawatcher.register(EntityFox.bz, 0); + this.datawatcher.register(EntityFox.bA, (byte) 0); + } + + @Override + protected void initPathfinder() { + this.bH = new PathfinderGoalNearestAttackableTarget<>(this, EntityAnimal.class, 10, false, false, (entityliving) -> { + return entityliving instanceof EntityChicken || entityliving instanceof EntityRabbit; + }); + this.bI = new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, false, false, EntityTurtle.bz); + this.bJ = new PathfinderGoalNearestAttackableTarget<>(this, EntityFish.class, 20, false, false, (entityliving) -> { + return entityliving instanceof EntityFishSchool; + }); + this.goalSelector.a(0, new EntityFox.g()); + this.goalSelector.a(1, new EntityFox.b()); + this.goalSelector.a(2, new EntityFox.n(2.2D)); + this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 16.0F, 1.6D, 1.4D, (entityliving) -> { + return EntityFox.bG.test(entityliving) && !this.c(entityliving.getUniqueID()) && !this.el(); + })); + this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityWolf.class, 8.0F, 1.6D, 1.4D, (entityliving) -> { + return !((EntityWolf) entityliving).isTamed() && !this.el(); + })); + this.goalSelector.a(4, new EntityFox.u()); + this.goalSelector.a(5, new EntityFox.o()); + this.goalSelector.a(5, new EntityFox.e(1.0D)); + this.goalSelector.a(5, new EntityFox.s(1.25D)); + this.goalSelector.a(6, new EntityFox.l(1.2000000476837158D, true)); + this.goalSelector.a(6, new EntityFox.t()); + this.goalSelector.a(7, new EntityFox.h(this, 1.25D)); + this.goalSelector.a(8, new EntityFox.q(32, 200)); + this.goalSelector.a(9, new EntityFox.f(1.2000000476837158D, 12, 2)); + this.goalSelector.a(9, new PathfinderGoalLeapAtTarget(this, 0.4F)); + this.goalSelector.a(10, new PathfinderGoalRandomStrollLand(this, 1.0D)); + this.goalSelector.a(10, new EntityFox.p()); + this.goalSelector.a(11, new EntityFox.j(this, EntityHuman.class, 24.0F)); + this.goalSelector.a(12, new EntityFox.r()); + this.targetSelector.a(3, new EntityFox.a(EntityLiving.class, false, false, (entityliving) -> { + return EntityFox.bE.test(entityliving) && !this.c(entityliving.getUniqueID()); + })); + } + + @Override + public SoundEffect d(ItemStack itemstack) { + return SoundEffects.ENTITY_FOX_EAT; + } + + @Override + public void movementTick() { + if (!this.world.isClientSide && this.isAlive() && this.df()) { + ++this.bO; + ItemStack itemstack = this.getEquipment(EnumItemSlot.MAINHAND); + + if (this.j(itemstack)) { + if (this.bO > 600) { + ItemStack itemstack1 = itemstack.a(this.world, (EntityLiving) this); + + if (!itemstack1.isEmpty()) { + this.setSlot(EnumItemSlot.MAINHAND, itemstack1); + } + + this.bO = 0; + } else if (this.bO > 560 && this.random.nextFloat() < 0.1F) { + this.a(this.d(itemstack), 1.0F, 1.0F); + this.world.broadcastEntityEffect(this, (byte) 45); + } + } + + EntityLiving entityliving = this.getGoalTarget(); + + if (entityliving == null || !entityliving.isAlive()) { + this.setCrouching(false); + this.u(false); + } + } + + if (this.isSleeping() || this.isFrozen()) { + this.jumping = false; + this.bb = 0.0F; + this.bd = 0.0F; + this.be = 0.0F; + } + + super.movementTick(); + if (this.el() && this.random.nextFloat() < 0.05F) { + this.a(SoundEffects.ENTITY_FOX_AGGRO, 1.0F, 1.0F); + } + + } + + @Override + protected boolean isFrozen() { + return this.getHealth() <= 0.0F; + } + + private boolean j(ItemStack itemstack) { + return itemstack.getItem().isFood() && this.getGoalTarget() == null && this.onGround && !this.isSleeping(); + } + + @Override + protected void a(DifficultyDamageScaler difficultydamagescaler) { + if (this.random.nextFloat() < 0.2F) { + float f = this.random.nextFloat(); + ItemStack itemstack; + + if (f < 0.05F) { + itemstack = new ItemStack(Items.EMERALD); + } else if (f < 0.2F) { + itemstack = new ItemStack(Items.EGG); + } else if (f < 0.4F) { + itemstack = this.random.nextBoolean() ? new ItemStack(Items.RABBIT_FOOT) : new ItemStack(Items.RABBIT_HIDE); + } else if (f < 0.6F) { + itemstack = new ItemStack(Items.WHEAT); + } else if (f < 0.8F) { + itemstack = new ItemStack(Items.LEATHER); + } else { + itemstack = new ItemStack(Items.FEATHER); + } + + this.setSlot(EnumItemSlot.MAINHAND, itemstack); + } + + } + + @Override + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D); + this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(2.0D); + } + + @Override + public EntityFox createChild(EntityAgeable entityageable) { + EntityFox entityfox = (EntityFox) EntityTypes.FOX.a(this.world); + + entityfox.setFoxType(this.random.nextBoolean() ? this.getFoxType() : ((EntityFox) entityageable).getFoxType()); + return entityfox; + } + + @Nullable + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this)); + EntityFox.Type entityfox_type = EntityFox.Type.a(biomebase); + boolean flag = false; + + if (groupdataentity instanceof EntityFox.i) { + entityfox_type = ((EntityFox.i) groupdataentity).a; + if (((EntityFox.i) groupdataentity).b >= 2) { + flag = true; + } else { + ++((EntityFox.i) groupdataentity).b; + } + } else { + groupdataentity = new EntityFox.i(entityfox_type); + ++((EntityFox.i) groupdataentity).b; + } + + this.setFoxType(entityfox_type); + if (flag) { + this.setAgeRaw(-24000); + } + + this.initializePathFinderGoals(); + this.a(difficultydamagescaler); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, (GroupDataEntity) groupdataentity, nbttagcompound); + } + + private void initializePathFinderGoals() { + if (this.getFoxType() == EntityFox.Type.RED) { + this.targetSelector.a(4, this.bH); + this.targetSelector.a(4, this.bI); + this.targetSelector.a(6, this.bJ); + } else { + this.targetSelector.a(4, this.bJ); + this.targetSelector.a(6, this.bH); + this.targetSelector.a(6, this.bI); + } + + } + + @Override + protected void a(EntityHuman entityhuman, ItemStack itemstack) { + if (this.i(itemstack)) { + this.a(this.d(itemstack), 1.0F, 1.0F); + } + + super.a(entityhuman, itemstack); + } + + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return this.isBaby() ? entitysize.height * 0.85F : 0.4F; + } + + public EntityFox.Type getFoxType() { + return EntityFox.Type.a((Integer) this.datawatcher.get(EntityFox.bz)); + } + + public void setFoxType(EntityFox.Type entityfox_type) { + this.datawatcher.set(EntityFox.bz, entityfox_type.c()); + } + + private List ek() { + List list = Lists.newArrayList(); + + list.add(((Optional) this.datawatcher.get(EntityFox.bB)).orElse(null)); // CraftBukkit - decompile error + list.add(((Optional) this.datawatcher.get(EntityFox.bC)).orElse(null)); // CraftBukkit - decompile error + return list; + } + + private void b(@Nullable UUID uuid) { + if (((Optional) this.datawatcher.get(EntityFox.bB)).isPresent()) { + this.datawatcher.set(EntityFox.bC, Optional.ofNullable(uuid)); + } else { + this.datawatcher.set(EntityFox.bB, Optional.ofNullable(uuid)); + } + + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + List list = this.ek(); + NBTTagList nbttaglist = new NBTTagList(); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + UUID uuid = (UUID) iterator.next(); + + if (uuid != null) { + nbttaglist.add(GameProfileSerializer.a(uuid)); + } + } + + nbttagcompound.set("TrustedUUIDs", nbttaglist); + nbttagcompound.setBoolean("Sleeping", this.isSleeping()); + nbttagcompound.setString("Type", this.getFoxType().a()); + nbttagcompound.setBoolean("Sitting", this.isSitting()); + nbttagcompound.setBoolean("Crouching", this.isCrouching()); + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getList("TrustedUUIDs", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + this.b(GameProfileSerializer.b(nbttaglist.getCompound(i))); + } + + this.setSleeping(nbttagcompound.getBoolean("Sleeping")); + this.setFoxType(EntityFox.Type.a(nbttagcompound.getString("Type"))); + this.setSitting(nbttagcompound.getBoolean("Sitting")); + this.setCrouching(nbttagcompound.getBoolean("Crouching")); + this.initializePathFinderGoals(); + } + + public boolean isSitting() { + return this.s(1); + } + + public void setSitting(boolean flag) { + this.d(1, flag); + } + + public boolean dX() { + return this.s(64); + } + + private void v(boolean flag) { + this.d(64, flag); + } + + private boolean el() { + return this.s(128); + } + + private void w(boolean flag) { + this.d(128, flag); + } + + @Override + public boolean isSleeping() { + return this.s(32); + } + + public void setSleeping(boolean flag) { + this.d(32, flag); + } + + private void d(int i, boolean flag) { + if (flag) { + this.datawatcher.set(EntityFox.bA, (byte) ((Byte) this.datawatcher.get(EntityFox.bA) | i)); + } else { + this.datawatcher.set(EntityFox.bA, (byte) ((Byte) this.datawatcher.get(EntityFox.bA) & ~i)); + } + + } + + private boolean s(int i) { + return ((Byte) this.datawatcher.get(EntityFox.bA) & i) != 0; + } + + @Override + public boolean e(ItemStack itemstack) { + EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); + + return !this.getEquipment(enumitemslot).isEmpty() ? false : enumitemslot == EnumItemSlot.MAINHAND && super.e(itemstack); + } + + @Override + protected boolean g(ItemStack itemstack) { + Item item = itemstack.getItem(); + ItemStack itemstack1 = this.getEquipment(EnumItemSlot.MAINHAND); + + return itemstack1.isEmpty() || this.bO > 0 && item.isFood() && !itemstack1.getItem().isFood(); + } + + private void k(ItemStack itemstack) { + if (!itemstack.isEmpty() && !this.world.isClientSide) { + EntityItem entityitem = new EntityItem(this.world, this.locX + this.getLookDirection().x, this.locY + 1.0D, this.locZ + this.getLookDirection().z, itemstack); + + entityitem.setPickupDelay(40); + entityitem.setThrower(this.getUniqueID()); + this.a(SoundEffects.ENTITY_FOX_SPIT, 1.0F, 1.0F); + this.world.addEntity(entityitem); + } + } + + private void l(ItemStack itemstack) { + EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY, this.locZ, itemstack); + + this.world.addEntity(entityitem); + } + + @Override + protected void a(EntityItem entityitem) { + ItemStack itemstack = entityitem.getItemStack(); + + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entityitem, itemstack.getCount() - 1, !this.g(itemstack)).isCancelled()) { // CraftBukkit - call EntityPickupItemEvent + int i = itemstack.getCount(); + + if (i > 1) { + this.l(itemstack.cloneAndSubtract(i - 1)); + } + + this.k(this.getEquipment(EnumItemSlot.MAINHAND)); + this.setSlot(EnumItemSlot.MAINHAND, itemstack.cloneAndSubtract(1)); + this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F; + this.receive(entityitem, itemstack.getCount()); + entityitem.die(); + this.bO = 0; + } + + } + + @Override + public void tick() { + super.tick(); + if (this.df()) { + boolean flag = this.isInWater(); + + if (flag || this.getGoalTarget() != null || this.world.U()) { + this.em(); + } + + if (flag || this.isSleeping()) { + this.setSitting(false); + } + + if (this.dX() && this.world.random.nextFloat() < 0.2F) { + BlockPosition blockposition = new BlockPosition(this.locX, this.locY, this.locZ); + IBlockData iblockdata = this.world.getType(blockposition); + + this.world.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); + } + } + + this.bL = this.bK; + if (this.eg()) { + this.bK += (1.0F - this.bK) * 0.4F; + } else { + this.bK += (0.0F - this.bK) * 0.4F; + } + + this.bN = this.bM; + if (this.isCrouching()) { + this.bM += 0.2F; + if (this.bM > 3.0F) { + this.bM = 3.0F; + } + } else { + this.bM = 0.0F; + } + + } + + @Override + public boolean i(ItemStack itemstack) { + return itemstack.getItem() == Items.SWEET_BERRIES; + } + + @Override + protected void a(EntityHuman entityhuman, EntityAgeable entityageable) { + ((EntityFox) entityageable).b(entityhuman.getUniqueID()); + } + + public boolean dY() { + return this.s(16); + } + + public void s(boolean flag) { + this.d(16, flag); + } + + public boolean ee() { + return this.bM == 3.0F; + } + + public void setCrouching(boolean flag) { + this.d(4, flag); + } + + public boolean isCrouching() { + return this.s(4); + } + + public void u(boolean flag) { + this.d(8, flag); + } + + public boolean eg() { + return this.s(8); + } + + @Override + public void setGoalTarget(@Nullable EntityLiving entityliving) { + if (this.el() && entityliving == null) { + this.w(false); + } + + super.setGoalTarget(entityliving); + } + + @Override + public void b(float f, float f1) { + int i = MathHelper.f((f - 5.0F) * f1); + + if (i > 0) { + this.damageEntity(DamageSource.FALL, (float) i); + if (this.isVehicle()) { + Iterator iterator = this.getAllPassengers().iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + entity.damageEntity(DamageSource.FALL, (float) i); + } + } + + IBlockData iblockdata = this.world.getType(new BlockPosition(this.locX, this.locY - 0.2D - (double) this.lastYaw, this.locZ)); + + if (!iblockdata.isAir() && !this.isSilent()) { + SoundEffectType soundeffecttype = iblockdata.r(); + + this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, soundeffecttype.d(), this.getSoundCategory(), soundeffecttype.a() * 0.5F, soundeffecttype.b() * 0.75F); + } + + } + } + + private void em() { + this.setSleeping(false); + } + + private void en() { + this.u(false); + this.setCrouching(false); + this.setSitting(false); + this.setSleeping(false); + this.w(false); + this.v(false); + } + + private boolean eo() { + return !this.isSleeping() && !this.isSitting() && !this.dX(); + } + + @Override + public void B() { + SoundEffect soundeffect = this.getSoundAmbient(); + + if (soundeffect == SoundEffects.ENTITY_FOX_SCREECH) { + this.a(soundeffect, 2.0F, this.cV()); + } else { + super.B(); + } + + } + + @Nullable + @Override + protected SoundEffect getSoundAmbient() { + if (this.isSleeping()) { + return SoundEffects.ENTITY_FOX_SLEEP; + } else { + if (!this.world.J() && this.random.nextFloat() < 0.1F) { + List list = this.world.a(EntityHuman.class, this.getBoundingBox().grow(16.0D, 16.0D, 16.0D), IEntitySelector.f); + + if (list.isEmpty()) { + return SoundEffects.ENTITY_FOX_SCREECH; + } + } + + return SoundEffects.ENTITY_FOX_AMBIENT; + } + } + + @Nullable + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return SoundEffects.ENTITY_FOX_HURT; + } + + @Nullable + @Override + protected SoundEffect getSoundDeath() { + return SoundEffects.ENTITY_FOX_DEATH; + } + + private boolean c(UUID uuid) { + return this.ek().contains(uuid); + } + + @Override + protected org.bukkit.event.entity.EntityDeathEvent d(DamageSource damagesource) { // Paper + ItemStack itemstack = this.getEquipment(EnumItemSlot.MAINHAND).cloneItemStack(); // Paper + + // Paper start - Cancellable death event + org.bukkit.event.entity.EntityDeathEvent deathEvent = super.d(damagesource); + + // Below is code to drop + + if (deathEvent == null || deathEvent.isCancelled()) { + return deathEvent; + } + // Paper end + + if (!itemstack.isEmpty()) { + this.a(itemstack); + this.setSlot(EnumItemSlot.MAINHAND, ItemStack.a); + } + + return deathEvent; // Paper + } + + public static boolean a(EntityFox entityfox, EntityLiving entityliving) { + double d0 = entityliving.locZ - entityfox.locZ; + double d1 = entityliving.locX - entityfox.locX; + double d2 = d0 / d1; + boolean flag = true; + + for (int i = 0; i < 6; ++i) { + double d3 = d2 == 0.0D ? 0.0D : d0 * (double) ((float) i / 6.0F); + double d4 = d2 == 0.0D ? d1 * (double) ((float) i / 6.0F) : d3 / d2; + + for (int j = 1; j < 4; ++j) { + if (!entityfox.world.getType(new BlockPosition(entityfox.locX + d4, entityfox.locY + (double) j, entityfox.locZ + d3)).getMaterial().isReplaceable()) { + return false; + } + } + } + + return true; + } + + class j extends PathfinderGoalLookAtPlayer { + + public j(EntityInsentient entityinsentient, Class oclass, float f) { + super(entityinsentient, oclass, f); + } + + @Override + public boolean a() { + return super.a() && !EntityFox.this.dX() && !EntityFox.this.eg(); + } + + @Override + public boolean b() { + return super.b() && !EntityFox.this.dX() && !EntityFox.this.eg(); + } + } + + class h extends PathfinderGoalFollowParent { + + private final EntityFox b; + + public h(EntityFox entityfox, double d0) { + super(entityfox, d0); + this.b = entityfox; + } + + @Override + public boolean a() { + return !this.b.el() && super.a(); + } + + @Override + public boolean b() { + return !this.b.el() && super.b(); + } + + @Override + public void c() { + this.b.en(); + super.c(); + } + } + + public class k extends ControllerLook { + + public k() { + super(EntityFox.this); + } + + @Override + public void a() { + if (!EntityFox.this.isSleeping()) { + super.a(); + } + + } + + @Override + protected boolean b() { + return !EntityFox.this.dY() && !EntityFox.this.isCrouching() && !EntityFox.this.eg() & !EntityFox.this.dX(); + } + } + + public class o extends PathfinderGoalWaterJumpAbstract { + + public o() {} + + @Override + public boolean a() { + if (!EntityFox.this.ee()) { + return false; + } else { + EntityLiving entityliving = EntityFox.this.getGoalTarget(); + + if (entityliving != null && entityliving.isAlive()) { + if (entityliving.getAdjustedDirection() != entityliving.getDirection()) { + return false; + } else { + boolean flag = EntityFox.a((EntityFox) EntityFox.this, entityliving); + + if (!flag) { + EntityFox.this.getNavigation().a((Entity) entityliving, 0); + EntityFox.this.setCrouching(false); + EntityFox.this.u(false); + } + + return flag; + } + } else { + return false; + } + } + } + + @Override + public boolean b() { + EntityLiving entityliving = EntityFox.this.getGoalTarget(); + + if (entityliving != null && entityliving.isAlive()) { + double d0 = EntityFox.this.getMot().y; + + return (d0 * d0 >= 0.05000000074505806D || Math.abs(EntityFox.this.pitch) >= 15.0F || !EntityFox.this.onGround) && !EntityFox.this.dX(); + } else { + return false; + } + } + + @Override + public boolean C_() { + return false; + } + + @Override + public void c() { + EntityFox.this.setJumping(true); + EntityFox.this.s(true); + EntityFox.this.u(false); + EntityLiving entityliving = EntityFox.this.getGoalTarget(); + + EntityFox.this.getControllerLook().a(entityliving, 60.0F, 30.0F); + Vec3D vec3d = (new Vec3D(entityliving.locX - EntityFox.this.locX, entityliving.locY - EntityFox.this.locY, entityliving.locZ - EntityFox.this.locZ)).d(); + + EntityFox.this.setMot(EntityFox.this.getMot().add(vec3d.x * 0.8D, 0.9D, vec3d.z * 0.8D)); + EntityFox.this.getNavigation().o(); + } + + @Override + public void d() { + EntityFox.this.setCrouching(false); + EntityFox.this.bM = 0.0F; + EntityFox.this.bN = 0.0F; + EntityFox.this.u(false); + EntityFox.this.s(false); + } + + @Override + public void e() { + EntityLiving entityliving = EntityFox.this.getGoalTarget(); + + if (entityliving != null) { + EntityFox.this.getControllerLook().a(entityliving, 60.0F, 30.0F); + } + + if (!EntityFox.this.dX()) { + Vec3D vec3d = EntityFox.this.getMot(); + + if (vec3d.y * vec3d.y < 0.029999999329447746D && EntityFox.this.pitch != 0.0F) { + EntityFox.this.pitch = this.a(EntityFox.this.pitch, 0.0F, 0.2F); + } else { + double d0 = Math.sqrt(Entity.b(vec3d)); + double d1 = Math.signum(-vec3d.y) * Math.acos(d0 / vec3d.f()) * 57.2957763671875D; + + EntityFox.this.pitch = (float) d1; + } + } + + if (entityliving != null && EntityFox.this.g((Entity) entityliving) <= 2.0F) { + EntityFox.this.C(entityliving); + } else if (EntityFox.this.pitch > 0.0F && EntityFox.this.onGround && (float) EntityFox.this.getMot().y != 0.0F && EntityFox.this.world.getType(new BlockPosition(EntityFox.this)).getBlock() == Blocks.SNOW) { + EntityFox.this.pitch = 60.0F; + EntityFox.this.setGoalTarget((EntityLiving) null); + EntityFox.this.v(true); + } + + } + } + + class g extends PathfinderGoalFloat { + + public g() { + super(EntityFox.this); + } + + @Override + public void c() { + super.c(); + EntityFox.this.en(); + } + + @Override + public boolean a() { + return EntityFox.this.isInWater() && EntityFox.this.cf() > 0.25D || EntityFox.this.aD(); + } + } + + class q extends PathfinderGoalNearestVillage { + + public q(int i, int j) { + super(EntityFox.this, j); + } + + @Override + public void c() { + EntityFox.this.en(); + super.c(); + } + + @Override + public boolean a() { + return super.a() && this.g(); + } + + @Override + public boolean b() { + return super.b() && this.g(); + } + + private boolean g() { + return !EntityFox.this.isSleeping() && !EntityFox.this.isSitting() && !EntityFox.this.el() && EntityFox.this.getGoalTarget() == null; + } + } + + class n extends PathfinderGoalPanic { + + public n(double d0) { + super(EntityFox.this, d0); + } + + @Override + public boolean a() { + return !EntityFox.this.el() && super.a(); + } + } + + class b extends PathfinderGoal { + + int a; + + public b() { + this.a(EnumSet.of(PathfinderGoal.Type.LOOK, PathfinderGoal.Type.JUMP, PathfinderGoal.Type.MOVE)); + } + + @Override + public boolean a() { + return EntityFox.this.dX(); + } + + @Override + public boolean b() { + return this.a() && this.a > 0; + } + + @Override + public void c() { + this.a = 40; + } + + @Override + public void d() { + EntityFox.this.v(false); + } + + @Override + public void e() { + --this.a; + } + } + + public static class i implements GroupDataEntity { + + public final EntityFox.Type a; + public int b; + + public i(EntityFox.Type entityfox_type) { + this.a = entityfox_type; + } + } + + public class f extends PathfinderGoalGotoTarget { + + protected int g; + + public f(double d0, int i, int j) { + super(EntityFox.this, d0, i, j); + } + + @Override + public double h() { + return 2.0D; + } + + @Override + public boolean j() { + return this.d % 100 == 0; + } + + @Override + protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) { + IBlockData iblockdata = iworldreader.getType(blockposition); + + return iblockdata.getBlock() == Blocks.SWEET_BERRY_BUSH && (Integer) iblockdata.get(BlockSweetBerryBush.a) >= 2; + } + + @Override + public void e() { + if (this.k()) { + if (this.g >= 40) { + this.m(); + } else { + ++this.g; + } + } else if (!this.k() && EntityFox.this.random.nextFloat() < 0.05F) { + EntityFox.this.a(SoundEffects.ENTITY_FOX_SNIFF, 1.0F, 1.0F); + } + + super.e(); + } + + protected void m() { + if (EntityFox.this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { + IBlockData iblockdata = EntityFox.this.world.getType(this.e); + + if (iblockdata.getBlock() == Blocks.SWEET_BERRY_BUSH) { + int i = (Integer) iblockdata.get(BlockSweetBerryBush.a); + + iblockdata.set(BlockSweetBerryBush.a, 1); + // CraftBukkit start - call EntityChangeBlockEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(EntityFox.this, this.e, iblockdata.set(BlockSweetBerryBush.a, 1)).isCancelled()) { + return; + } + // CraftBukkit end + int j = 1 + EntityFox.this.world.random.nextInt(2) + (i == 3 ? 1 : 0); + ItemStack itemstack = EntityFox.this.getEquipment(EnumItemSlot.MAINHAND); + + if (itemstack.isEmpty()) { + EntityFox.this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.SWEET_BERRIES)); + --j; + } + + if (j > 0) { + Block.a(EntityFox.this.world, this.e, new ItemStack(Items.SWEET_BERRIES, j)); + } + + EntityFox.this.a(SoundEffects.ITEM_SWEET_BERRIES_PICK_FROM_BUSH, 1.0F, 1.0F); + EntityFox.this.world.setTypeAndData(this.e, (IBlockData) iblockdata.set(BlockSweetBerryBush.a, 1), 2); + } + } + } + + @Override + public boolean a() { + return !EntityFox.this.isSleeping() && super.a(); + } + + @Override + public void c() { + this.g = 0; + EntityFox.this.setSitting(false); + super.c(); + } + } + + class r extends EntityFox.d { + + private double c; + private double d; + private int e; + private int f; + + public r() { + super(); // CraftBukkit - decompile error + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); + } + + @Override + public boolean a() { + return EntityFox.this.getLastDamager() == null && EntityFox.this.getRandom().nextFloat() < 0.02F && !EntityFox.this.isSleeping() && EntityFox.this.getGoalTarget() == null && EntityFox.this.getNavigation().n() && !this.h() && !EntityFox.this.dY() && !EntityFox.this.isCrouching(); + } + + @Override + public boolean b() { + return this.f > 0; + } + + @Override + public void c() { + this.j(); + this.f = 2 + EntityFox.this.getRandom().nextInt(3); + EntityFox.this.setSitting(true); + EntityFox.this.getNavigation().o(); + } + + @Override + public void d() { + EntityFox.this.setSitting(false); + } + + @Override + public void e() { + --this.e; + if (this.e <= 0) { + --this.f; + this.j(); + } + + EntityFox.this.getControllerLook().a(EntityFox.this.locX + this.c, EntityFox.this.locY + (double) EntityFox.this.getHeadHeight(), EntityFox.this.locZ + this.d, (float) EntityFox.this.dA(), (float) EntityFox.this.M()); + } + + private void j() { + double d0 = 6.283185307179586D * EntityFox.this.getRandom().nextDouble(); + + this.c = Math.cos(d0); + this.d = Math.sin(d0); + this.e = 80 + EntityFox.this.getRandom().nextInt(20); + } + } + + class t extends EntityFox.d { + + private int c; + + public t() { + super(); // CraftBukkit - decompile error + this.c = EntityFox.this.random.nextInt(140); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK, PathfinderGoal.Type.JUMP)); + } + + @Override + public boolean a() { + return EntityFox.this.bb == 0.0F && EntityFox.this.bc == 0.0F && EntityFox.this.bd == 0.0F ? this.j() || EntityFox.this.isSleeping() : false; + } + + @Override + public boolean b() { + return this.j(); + } + + private boolean j() { + if (this.c > 0) { + --this.c; + return false; + } else { + return EntityFox.this.world.J() && this.g() && !this.h(); + } + } + + @Override + public void d() { + this.c = EntityFox.this.random.nextInt(140); + EntityFox.this.en(); + } + + @Override + public void c() { + EntityFox.this.setSitting(false); + EntityFox.this.setCrouching(false); + EntityFox.this.u(false); + EntityFox.this.setJumping(false); + EntityFox.this.setSleeping(true); + EntityFox.this.getNavigation().o(); + EntityFox.this.getControllerMove().a(EntityFox.this.locX, EntityFox.this.locY, EntityFox.this.locZ, 0.0D); + } + } + + abstract class d extends PathfinderGoal { + + private final PathfinderTargetCondition b; + + private d() { + this.b = (new PathfinderTargetCondition()).a(12.0D).c().a(EntityFox.this.new c()); + } + + protected boolean g() { + BlockPosition blockposition = new BlockPosition(EntityFox.this); + + return !EntityFox.this.world.f(blockposition) && EntityFox.this.f(blockposition) >= 0.0F; + } + + protected boolean h() { + return !EntityFox.this.world.a(EntityLiving.class, this.b, EntityFox.this, EntityFox.this.getBoundingBox().grow(12.0D, 6.0D, 12.0D)).isEmpty(); + } + } + + public class c implements Predicate { + + public c() {} + + public boolean test(EntityLiving entityliving) { + return entityliving instanceof EntityFox ? false : (!(entityliving instanceof EntityChicken) && !(entityliving instanceof EntityRabbit) && !(entityliving instanceof EntityMonster) ? (entityliving instanceof EntityTameableAnimal ? !((EntityTameableAnimal) entityliving).isTamed() : (entityliving instanceof EntityHuman && (entityliving.isSpectator() || ((EntityHuman) entityliving).isCreative()) ? false : (EntityFox.this.c(entityliving.getUniqueID()) ? false : !entityliving.isSleeping() && !entityliving.isSneaking()))) : true); + } + } + + class s extends PathfinderGoalFleeSun { + + private int c = 100; + + public s(double d0) { + super(EntityFox.this, d0); + } + + @Override + public boolean a() { + if (!EntityFox.this.isSleeping() && this.a.getGoalTarget() == null) { + if (EntityFox.this.world.U()) { + return true; + } else if (this.c > 0) { + --this.c; + return false; + } else { + this.c = 100; + BlockPosition blockposition = new BlockPosition(this.a); + + return EntityFox.this.world.J() && EntityFox.this.world.f(blockposition) && !((WorldServer) EntityFox.this.world).b_(blockposition) && this.g(); + } + } else { + return false; + } + } + + @Override + public void c() { + EntityFox.this.en(); + super.c(); + } + } + + class a extends PathfinderGoalNearestAttackableTarget { + + @Nullable + private EntityLiving j; + private EntityLiving k; + private int l; + + public a(Class oclass, boolean flag, boolean flag1, Predicate predicate) { // CraftBukkit - decompile error + super(EntityFox.this, oclass, 10, flag, flag1, predicate); + } + + @Override + public boolean a() { + if (this.b > 0 && this.e.getRandom().nextInt(this.b) != 0) { + return false; + } else { + Iterator iterator = EntityFox.this.ek().iterator(); + + while (iterator.hasNext()) { + UUID uuid = (UUID) iterator.next(); + + if (uuid != null && EntityFox.this.world instanceof WorldServer) { + Entity entity = ((WorldServer) EntityFox.this.world).getEntity(uuid); + + if (entity instanceof EntityLiving) { + EntityLiving entityliving = (EntityLiving) entity; + + this.k = entityliving; + this.j = entityliving.getLastDamager(); + int i = entityliving.ct(); + + return i != this.l && this.a(this.j, this.d); + } + } + } + + return false; + } + } + + @Override + public void c() { + EntityFox.this.setGoalTarget(this.j, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_OWNER, true); // CraftBukkit + this.c = this.j; + if (this.k != null) { + this.l = this.k.ct(); + } + + EntityFox.this.a(SoundEffects.ENTITY_FOX_AGGRO, 1.0F, 1.0F); + EntityFox.this.w(true); + EntityFox.this.em(); + super.c(); + } + } + + class e extends PathfinderGoalBreed { + + public e(double d0) { + super(EntityFox.this, d0); + } + + @Override + public void c() { + ((EntityFox) this.animal).en(); + ((EntityFox) this.partner).en(); + super.c(); + } + + @Override + protected void g() { + EntityFox entityfox = (EntityFox) this.animal.createChild(this.partner); + + if (entityfox != null) { + EntityPlayer entityplayer = this.animal.getBreedCause(); + EntityPlayer entityplayer1 = this.partner.getBreedCause(); + EntityPlayer entityplayer2 = entityplayer; + + if (entityplayer != null) { + entityfox.b(entityplayer.getUniqueID()); + } else { + entityplayer2 = entityplayer1; + } + + if (entityplayer1 != null && entityplayer != entityplayer1) { + entityfox.b(entityplayer1.getUniqueID()); + } + // CraftBukkit start - call EntityBreedEvent + int experience = this.animal.getRandom().nextInt(7) + 1; + org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityfox, animal, partner, entityplayer, this.animal.breedItem, experience); + if (entityBreedEvent.isCancelled()) { + return; + } + experience = entityBreedEvent.getExperience(); + // CraftBukkit end + + if (entityplayer2 != null) { + entityplayer2.a(StatisticList.ANIMALS_BRED); + CriterionTriggers.o.a(entityplayer2, this.animal, this.partner, entityfox); + } + + boolean flag = true; + + this.animal.setAgeRaw(6000); + this.partner.setAgeRaw(6000); + this.animal.resetLove(); + this.partner.resetLove(); + entityfox.setAgeRaw(-24000); + entityfox.setPositionRotation(this.animal.locX, this.animal.locY, this.animal.locZ, 0.0F, 0.0F); + this.b.addEntity(entityfox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + this.b.broadcastEntityEffect(this.animal, (byte) 18); + if (this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { + // CraftBukkit start - use event experience + if (experience > 0) { + this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX, this.animal.locY, this.animal.locZ, experience)); + } + // CraftBukkit end + } + + } + } + } + + class l extends PathfinderGoalMeleeAttack { + + public l(double d0, boolean flag) { + super(EntityFox.this, d0, flag); + } + + @Override + protected void a(EntityLiving entityliving, double d0) { + double d1 = this.a(entityliving); + + if (d0 <= d1 && this.b <= 0) { + this.b = 20; + this.a.C(entityliving); + EntityFox.this.a(SoundEffects.ENTITY_FOX_BITE, 1.0F, 1.0F); + } + + } + + @Override + public void c() { + EntityFox.this.u(false); + super.c(); + } + + @Override + public boolean a() { + return !EntityFox.this.isSitting() && !EntityFox.this.isSleeping() && !EntityFox.this.isCrouching() && !EntityFox.this.dX() && super.a(); + } + } + + class u extends PathfinderGoal { + + public u() { + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); + } + + @Override + public boolean a() { + if (EntityFox.this.isSleeping()) { + return false; + } else { + EntityLiving entityliving = EntityFox.this.getGoalTarget(); + + return entityliving != null && entityliving.isAlive() && EntityFox.bF.test(entityliving) && EntityFox.this.h((Entity) entityliving) > 36.0D && !EntityFox.this.isCrouching() && !EntityFox.this.eg() && !EntityFox.this.jumping; + } + } + + @Override + public void c() { + EntityFox.this.setSitting(false); + EntityFox.this.v(false); + } + + @Override + public void d() { + EntityLiving entityliving = EntityFox.this.getGoalTarget(); + + if (entityliving != null && EntityFox.a((EntityFox) EntityFox.this, entityliving)) { + EntityFox.this.u(true); + EntityFox.this.setCrouching(true); + EntityFox.this.getNavigation().o(); + EntityFox.this.getControllerLook().a(entityliving, (float) EntityFox.this.dA(), (float) EntityFox.this.M()); + } else { + EntityFox.this.u(false); + EntityFox.this.setCrouching(false); + } + + } + + @Override + public void e() { + EntityLiving entityliving = EntityFox.this.getGoalTarget(); + + EntityFox.this.getControllerLook().a(entityliving, (float) EntityFox.this.dA(), (float) EntityFox.this.M()); + if (EntityFox.this.h((Entity) entityliving) <= 36.0D) { + EntityFox.this.u(true); + EntityFox.this.setCrouching(true); + EntityFox.this.getNavigation().o(); + } else { + EntityFox.this.getNavigation().a((Entity) entityliving, 1.5D); + } + + } + } + + class m extends ControllerMove { + + public m() { + super(EntityFox.this); + } + + @Override + public void a() { + if (EntityFox.this.eo()) { + super.a(); + } + + } + } + + class p extends PathfinderGoal { + + public p() { + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); + } + + @Override + public boolean a() { + if (!EntityFox.this.getEquipment(EnumItemSlot.MAINHAND).isEmpty()) { + return false; + } else if (EntityFox.this.getGoalTarget() == null && EntityFox.this.getLastDamager() == null) { + if (!EntityFox.this.eo()) { + return false; + } else if (EntityFox.this.getRandom().nextInt(10) != 0) { + return false; + } else { + List list = EntityFox.this.world.a(EntityItem.class, EntityFox.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityFox.bD); + + return !list.isEmpty() && EntityFox.this.getEquipment(EnumItemSlot.MAINHAND).isEmpty(); + } + } else { + return false; + } + } + + @Override + public void e() { + List list = EntityFox.this.world.a(EntityItem.class, EntityFox.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityFox.bD); + ItemStack itemstack = EntityFox.this.getEquipment(EnumItemSlot.MAINHAND); + + if (itemstack.isEmpty() && !list.isEmpty()) { + EntityFox.this.getNavigation().a((Entity) list.get(0), 1.2000000476837158D); + } + + } + + @Override + public void c() { + List list = EntityFox.this.world.a(EntityItem.class, EntityFox.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityFox.bD); + + if (!list.isEmpty()) { + EntityFox.this.getNavigation().a((Entity) list.get(0), 1.2000000476837158D); + } + + } + } + + public static enum Type { + + RED(0, "red", new BiomeBase[]{Biomes.TAIGA, Biomes.TAIGA_HILLS, Biomes.TAIGA_MOUNTAINS, Biomes.GIANT_TREE_TAIGA, Biomes.GIANT_SPRUCE_TAIGA, Biomes.GIANT_TREE_TAIGA_HILLS, Biomes.GIANT_SPRUCE_TAIGA_HILLS}), SNOW(1, "snow", new BiomeBase[]{Biomes.SNOWY_TAIGA, Biomes.SNOWY_TAIGA_HILLS, Biomes.SNOWY_TAIGA_MOUNTAINS}); + + private static final EntityFox.Type[] c = (EntityFox.Type[]) Arrays.stream(values()).sorted(Comparator.comparingInt(EntityFox.Type::c)).toArray((i) -> { + return new EntityFox.Type[i]; + }); + private static final Map d = (Map) Arrays.stream(values()).collect(Collectors.toMap(EntityFox.Type::a, (entityfox_type) -> { + return entityfox_type; + })); + private final int e; + private final String f; + private final List g; + + private Type(int i, String s, BiomeBase... abiomebase) { + this.e = i; + this.f = s; + this.g = Arrays.asList(abiomebase); + } + + public String a() { + return this.f; + } + + public List b() { + return this.g; + } + + public int c() { + return this.e; + } + + public static EntityFox.Type a(String s) { + return (EntityFox.Type) EntityFox.Type.d.getOrDefault(s, EntityFox.Type.RED); + } + + public static EntityFox.Type a(int i) { + if (i < 0 || i > EntityFox.Type.c.length) { + i = 0; + } + + return EntityFox.Type.c[i]; + } + + public static EntityFox.Type a(BiomeBase biomebase) { + return EntityFox.Type.SNOW.b().contains(biomebase) ? EntityFox.Type.SNOW : EntityFox.Type.RED; + } + } +} diff --git a/src/main/java/net/minecraft/server/EntityGhast.java b/src/main/java/net/minecraft/server/EntityGhast.java index 5fac201b9..f25c828df 100644 --- a/src/main/java/net/minecraft/server/EntityGhast.java +++ b/src/main/java/net/minecraft/server/EntityGhast.java @@ -1,36 +1,38 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.Random; -import javax.annotation.Nullable; public class EntityGhast extends EntityFlying implements IMonster { - private static final DataWatcherObject a = DataWatcher.a(EntityGhast.class, DataWatcherRegistry.i); - private int b = 1; + private static final DataWatcherObject b = DataWatcher.a(EntityGhast.class, DataWatcherRegistry.i); + private int c = 1; - public EntityGhast(World world) { - super(EntityTypes.GHAST, world); - this.setSize(4.0F, 4.0F); - this.fireProof = true; - this.b_ = 5; + public EntityGhast(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.f = 5; this.moveController = new EntityGhast.ControllerGhast(this); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(5, new EntityGhast.PathfinderGoalGhastIdleMove(this)); this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastMoveTowardsTarget(this)); this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastAttackTarget(this)); - this.targetSelector.a(1, new PathfinderGoalTargetNearestPlayer(this)); + this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, (entityliving) -> { + return Math.abs(entityliving.locY - this.locY) <= 4.0D; + })); } - public void a(boolean flag) { - this.datawatcher.set(EntityGhast.a, flag); + public void r(boolean flag) { + this.datawatcher.set(EntityGhast.b, flag); } public int getPower() { - return this.b; + return this.c; } + @Override public void tick() { super.tick(); if (!this.world.isClientSide && this.world.getDifficulty() == EnumDifficulty.PEACEFUL) { @@ -39,6 +41,7 @@ public class EntityGhast extends EntityFlying implements IMonster { } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -50,64 +53,70 @@ public class EntityGhast extends EntityFlying implements IMonster { } } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityGhast.a, false); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityGhast.b, false); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(100.0D); } - public SoundCategory bV() { + @Override + public SoundCategory getSoundCategory() { return SoundCategory.HOSTILE; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_GHAST_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_GHAST_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_GHAST_DEATH; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aq; - } - - protected float cD() { + @Override + protected float getSoundVolume() { return 10.0F; } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - return this.random.nextInt(20) == 0 && super.a(generatoraccess, flag) && generatoraccess.getDifficulty() != EnumDifficulty.PEACEFUL; + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return generatoraccess.getDifficulty() != EnumDifficulty.PEACEFUL && random.nextInt(20) == 0 && a(entitytypes, generatoraccess, enummobspawn, blockposition, random); } - public int dg() { + @Override + public int dC() { return 1; } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setInt("ExplosionPower", this.b); + nbttagcompound.setInt("ExplosionPower", this.c); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKeyOfType("ExplosionPower", 99)) { - this.b = nbttagcompound.getInt("ExplosionPower"); + this.c = nbttagcompound.getInt("ExplosionPower"); } } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 2.6F; } @@ -120,23 +129,27 @@ public class EntityGhast extends EntityFlying implements IMonster { this.ghast = entityghast; } + @Override public boolean a() { return this.ghast.getGoalTarget() != null; } + @Override public void c() { this.a = 0; } + @Override public void d() { - this.ghast.a(false); + this.ghast.r(false); } + @Override public void e() { EntityLiving entityliving = this.ghast.getGoalTarget(); double d0 = 64.0D; - if (entityliving.h(this.ghast) < 4096.0D && this.ghast.hasLineOfSight(entityliving)) { + if (entityliving.h((Entity) this.ghast) < 4096.0D && this.ghast.hasLineOfSight(entityliving)) { World world = this.ghast.world; ++this.a; @@ -148,7 +161,7 @@ public class EntityGhast extends EntityFlying implements IMonster { double d1 = 4.0D; Vec3D vec3d = this.ghast.f(1.0F); double d2 = entityliving.locX - (this.ghast.locX + vec3d.x * 4.0D); - double d3 = entityliving.getBoundingBox().minY + (double) (entityliving.length / 2.0F) - (0.5D + this.ghast.locY + (double) (this.ghast.length / 2.0F)); + double d3 = entityliving.getBoundingBox().minY + (double) (entityliving.getHeight() / 2.0F) - (0.5D + this.ghast.locY + (double) (this.ghast.getHeight() / 2.0F)); double d4 = entityliving.locZ - (this.ghast.locZ + vec3d.z * 4.0D); world.a((EntityHuman) null, 1016, new BlockPosition(this.ghast), 0); @@ -157,7 +170,7 @@ public class EntityGhast extends EntityFlying implements IMonster { // CraftBukkit - set bukkitYield when setting explosionpower entitylargefireball.bukkitYield = entitylargefireball.yield = this.ghast.getPower(); entitylargefireball.locX = this.ghast.locX + vec3d.x * 4.0D; - entitylargefireball.locY = this.ghast.locY + (double) (this.ghast.length / 2.0F) + 0.5D; + entitylargefireball.locY = this.ghast.locY + (double) (this.ghast.getHeight() / 2.0F) + 0.5D; entitylargefireball.locZ = this.ghast.locZ + vec3d.z * 4.0D; world.addEntity(entitylargefireball); this.a = -40; @@ -166,7 +179,7 @@ public class EntityGhast extends EntityFlying implements IMonster { --this.a; } - this.ghast.a(this.a > 10); + this.ghast.r(this.a > 10); } } @@ -176,27 +189,31 @@ public class EntityGhast extends EntityFlying implements IMonster { public PathfinderGoalGhastMoveTowardsTarget(EntityGhast entityghast) { this.a = entityghast; - this.a(2); + this.a(EnumSet.of(PathfinderGoal.Type.LOOK)); } + @Override public boolean a() { return true; } + @Override public void e() { if (this.a.getGoalTarget() == null) { - this.a.yaw = -((float) MathHelper.c(this.a.motX, this.a.motZ)) * 57.295776F; - this.a.aQ = this.a.yaw; + Vec3D vec3d = this.a.getMot(); + + this.a.yaw = -((float) MathHelper.d(vec3d.x, vec3d.z)) * 57.295776F; + this.a.aK = this.a.yaw; } else { EntityLiving entityliving = this.a.getGoalTarget(); double d0 = 64.0D; - if (entityliving.h(this.a) < 4096.0D) { + if (entityliving.h((Entity) this.a) < 4096.0D) { double d1 = entityliving.locX - this.a.locX; double d2 = entityliving.locZ - this.a.locZ; - this.a.yaw = -((float) MathHelper.c(d1, d2)) * 57.295776F; - this.a.aQ = this.a.yaw; + this.a.yaw = -((float) MathHelper.d(d1, d2)) * 57.295776F; + this.a.aK = this.a.yaw; } } @@ -209,9 +226,10 @@ public class EntityGhast extends EntityFlying implements IMonster { public PathfinderGoalGhastIdleMove(EntityGhast entityghast) { this.a = entityghast; - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); } + @Override public boolean a() { ControllerMove controllermove = this.a.getControllerMove(); @@ -227,10 +245,12 @@ public class EntityGhast extends EntityFlying implements IMonster { } } + @Override public boolean b() { return false; } + @Override public void c() { Random random = this.a.getRandom(); double d0 = this.a.locX + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); @@ -251,20 +271,17 @@ public class EntityGhast extends EntityFlying implements IMonster { this.i = entityghast; } + @Override public void a() { if (this.h == ControllerMove.Operation.MOVE_TO) { - double d0 = this.b - this.i.locX; - double d1 = this.c - this.i.locY; - double d2 = this.d - this.i.locZ; - double d3 = d0 * d0 + d1 * d1 + d2 * d2; - if (this.j-- <= 0) { this.j += this.i.getRandom().nextInt(5) + 2; - d3 = (double) MathHelper.sqrt(d3); - if (this.b(this.b, this.c, this.d, d3)) { - this.i.motX += d0 / d3 * 0.1D; - this.i.motY += d1 / d3 * 0.1D; - this.i.motZ += d2 / d3 * 0.1D; + Vec3D vec3d = new Vec3D(this.b - this.i.locX, this.c - this.i.locY, this.d - this.i.locZ); + double d0 = vec3d.f(); + + vec3d = vec3d.d(); + if (this.a(vec3d, MathHelper.f(d0))) { + this.i.setMot(this.i.getMot().e(vec3d.a(0.1D))); } else { this.h = ControllerMove.Operation.WAIT; } @@ -273,14 +290,11 @@ public class EntityGhast extends EntityFlying implements IMonster { } } - private boolean b(double d0, double d1, double d2, double d3) { - double d4 = (d0 - this.i.locX) / d3; - double d5 = (d1 - this.i.locY) / d3; - double d6 = (d2 - this.i.locZ) / d3; + private boolean a(Vec3D vec3d, int i) { AxisAlignedBB axisalignedbb = this.i.getBoundingBox(); - for (int i = 1; (double) i < d3; ++i) { - axisalignedbb = axisalignedbb.d(d4, d5, d6); + for (int j = 1; j < i; ++j) { + axisalignedbb = axisalignedbb.b(vec3d); if (!this.i.world.getCubes(this.i, axisalignedbb)) { return false; } diff --git a/src/main/java/net/minecraft/server/EntityGuardianElder.java b/src/main/java/net/minecraft/server/EntityGuardianElder.java index 6ccc15e9d..7248d46cf 100644 --- a/src/main/java/net/minecraft/server/EntityGuardianElder.java +++ b/src/main/java/net/minecraft/server/EntityGuardianElder.java @@ -2,60 +2,62 @@ package net.minecraft.server; import java.util.Iterator; import java.util.List; -import javax.annotation.Nullable; public class EntityGuardianElder extends EntityGuardian { - public EntityGuardianElder(World world) { - super(EntityTypes.ELDER_GUARDIAN, world); - this.setSize(this.width * 2.35F, this.length * 2.35F); - this.di(); + public static final float b = EntityTypes.ELDER_GUARDIAN.i() / EntityTypes.GUARDIAN.i(); + + public EntityGuardianElder(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.setPersistent(); if (this.goalRandomStroll != null) { this.goalRandomStroll.setTimeBetweenMovement(400); } } + @Override public void initAttributes() { super.initAttributes(); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(8.0D); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(80.0D); - } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.E; + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(80.0D); } + @Override public int l() { return 60; } - protected SoundEffect D() { - return this.aq() ? SoundEffects.ENTITY_ELDER_GUARDIAN_AMBIENT : SoundEffects.ENTITY_ELDER_GUARDIAN_AMBIENT_LAND; + @Override + protected SoundEffect getSoundAmbient() { + return this.av() ? SoundEffects.ENTITY_ELDER_GUARDIAN_AMBIENT : SoundEffects.ENTITY_ELDER_GUARDIAN_AMBIENT_LAND; } - protected SoundEffect d(DamageSource damagesource) { - return this.aq() ? SoundEffects.ENTITY_ELDER_GUARDIAN_HURT : SoundEffects.ENTITY_ELDER_GUARDIAN_HURT_LAND; + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return this.av() ? SoundEffects.ENTITY_ELDER_GUARDIAN_HURT : SoundEffects.ENTITY_ELDER_GUARDIAN_HURT_LAND; } - protected SoundEffect cs() { - return this.aq() ? SoundEffects.ENTITY_ELDER_GUARDIAN_DEATH : SoundEffects.ENTITY_ELDER_GUARDIAN_DEATH_LAND; + @Override + protected SoundEffect getSoundDeath() { + return this.av() ? SoundEffects.ENTITY_ELDER_GUARDIAN_DEATH : SoundEffects.ENTITY_ELDER_GUARDIAN_DEATH_LAND; } - protected SoundEffect dA() { + @Override + protected SoundEffect getSoundFlop() { return SoundEffects.ENTITY_ELDER_GUARDIAN_FLOP; } + @Override protected void mobTick() { super.mobTick(); boolean flag = true; if ((this.ticksLived + this.getId()) % 1200 == 0) { MobEffectList mobeffectlist = MobEffects.SLOWER_DIG; - List list = this.world.b(EntityPlayer.class, (entityplayer) -> { - return this.h(entityplayer) < 2500.0D && entityplayer.playerInteractManager.c(); + List list = ((WorldServer) this.world).a((entityplayer) -> { + return this.h((Entity) entityplayer) < 2500.0D && entityplayer.playerInteractManager.c(); }); boolean flag1 = true; boolean flag2 = true; @@ -72,7 +74,7 @@ public class EntityGuardianElder extends EntityGuardian { } } - if (!this.dw()) { + if (!this.dL()) { this.a(new BlockPosition(this), 16); } diff --git a/src/main/java/net/minecraft/server/EntityHanging.java b/src/main/java/net/minecraft/server/EntityHanging.java index 381140eee..2b4a849f4 100644 --- a/src/main/java/net/minecraft/server/EntityHanging.java +++ b/src/main/java/net/minecraft/server/EntityHanging.java @@ -12,25 +12,25 @@ import org.bukkit.event.hanging.HangingBreakEvent; public abstract class EntityHanging extends Entity { - protected static final Predicate a = (entity) -> { + protected static final Predicate b = (entity) -> { return entity instanceof EntityHanging; }; - private int d; + private int e; { this.e = this.getId() % this.world.spigotConfig.hangingTickFrequency; } // Paper public BlockPosition blockPosition; - @Nullable - public EnumDirection direction; + protected EnumDirection direction; - protected EntityHanging(EntityTypes entitytypes, World world) { + protected EntityHanging(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.setSize(0.5F, 0.5F); + this.direction = EnumDirection.SOUTH; } - protected EntityHanging(EntityTypes entitytypes, World world, BlockPosition blockposition) { + protected EntityHanging(EntityTypes entitytypes, World world, BlockPosition blockposition) { this(entitytypes, world); this.blockPosition = blockposition; } - protected void x_() {} + @Override + protected void initDatawatcher() {} public void setDirection(EnumDirection enumdirection) { Validate.notNull(enumdirection); @@ -41,61 +41,65 @@ public abstract class EntityHanging extends Entity { this.updateBoundingBox(); } - // CraftBukkit start - break out BB calc into own method - public static AxisAlignedBB calculateBoundingBox(Entity entity, BlockPosition blockPosition, EnumDirection direction, int width, int height) { - double d0 = (double) blockPosition.getX() + 0.5D; - double d1 = (double) blockPosition.getY() + 0.5D; - double d2 = (double) blockPosition.getZ() + 0.5D; - double d3 = 0.46875D; - double d4 = a(width); - double d5 = a(height); - - d0 -= (double) direction.getAdjacentX() * 0.46875D; - d2 -= (double) direction.getAdjacentZ() * 0.46875D; - d1 += d5; - EnumDirection enumdirection = direction.f(); - - d0 += d4 * (double) enumdirection.getAdjacentX(); - d2 += d4 * (double) enumdirection.getAdjacentZ(); - if (entity != null) { - entity.locX = d0; - entity.locY = d1; - entity.locZ = d2; - } - double d6 = (double) width; - double d7 = (double) height; - double d8 = (double) width; - - if (direction.k() == EnumDirection.EnumAxis.Z) { - d8 = 1.0D; - } else { - d6 = 1.0D; - } - - d6 /= 32.0D; - d7 /= 32.0D; - d8 /= 32.0D; - return new AxisAlignedBB(d0 - d6, d1 - d7, d2 - d8, d0 + d6, d1 + d7, d2 + d8); - } - protected void updateBoundingBox() { if (this.direction != null) { // CraftBukkit start code moved in to calculateBoundingBox - this.a(calculateBoundingBox(this, this.blockPosition, this.direction, this.getWidth(), this.getHeight())); + this.a(calculateBoundingBox(this, this.blockPosition, this.direction, this.getHangingWidth(), this.getHangingHeight())); // CraftBukkit end } } + // CraftBukkit start - break out BB calc into own method + public static AxisAlignedBB calculateBoundingBox(@Nullable Entity entity, BlockPosition blockPosition, EnumDirection direction, int width, int height) { + { + double d0 = (double) blockPosition.getX() + 0.5D; + double d1 = (double) blockPosition.getY() + 0.5D; + double d2 = (double) blockPosition.getZ() + 0.5D; + double d3 = 0.46875D; + double d4 = a(width); + double d5 = a(height); + + d0 -= (double) direction.getAdjacentX() * 0.46875D; + d2 -= (double) direction.getAdjacentZ() * 0.46875D; + d1 += d5; + EnumDirection enumdirection = direction.f(); + + d0 += d4 * (double) enumdirection.getAdjacentX(); + d2 += d4 * (double) enumdirection.getAdjacentZ(); + if (entity != null) { + entity.locX = d0; + entity.locY = d1; + entity.locZ = d2; + } + double d6 = (double) width; + double d7 = (double) height; + double d8 = (double) width; + + if (direction.k() == EnumDirection.EnumAxis.Z) { + d8 = 1.0D; + } else { + d6 = 1.0D; + } + + d6 /= 32.0D; + d7 /= 32.0D; + d8 /= 32.0D; + return new AxisAlignedBB(d0 - d6, d1 - d7, d2 - d8, d0 + d6, d1 + d7, d2 + d8); + } + } + // CraftBukkit end + private static double a(int i) { // CraftBukkit - static return i % 32 == 0 ? 0.5D : 0.0D; } + @Override public void tick() { this.lastX = this.locX; this.lastY = this.locY; this.lastZ = this.locZ; - if (this.d++ == this.world.spigotConfig.hangingTickFrequency && !this.world.isClientSide) { // Spigot - this.d = 0; + if (this.e++ == this.world.spigotConfig.hangingTickFrequency && !this.world.isClientSide) { // Spigot + this.e = 0; if (!this.dead && !this.survives()) { // CraftBukkit start - fire break events Material material = this.world.getType(new BlockPosition(this)).getMaterial(); @@ -123,11 +127,11 @@ public abstract class EntityHanging extends Entity { } public boolean survives() { - if (!this.world.getCubes(this, this.getBoundingBox())) { + if (!this.world.getCubes(this)) { return false; } else { - int i = Math.max(1, this.getWidth() / 16); - int j = Math.max(1, this.getHeight() / 16); + int i = Math.max(1, this.getHangingWidth() / 16); + int j = Math.max(1, this.getHangingHeight() / 16); BlockPosition blockposition = this.blockPosition.shift(this.direction.opposite()); EnumDirection enumdirection = this.direction.f(); BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); @@ -146,22 +150,26 @@ public abstract class EntityHanging extends Entity { } } - return this.world.getEntities(this, this.getBoundingBox(), EntityHanging.a).isEmpty(); + return this.world.getEntities(this, this.getBoundingBox(), EntityHanging.b).isEmpty(); } } + @Override public boolean isInteractable() { return true; } + @Override public boolean t(Entity entity) { return entity instanceof EntityHuman ? this.damageEntity(DamageSource.playerAttack((EntityHuman) entity), 0.0F) : false; } + @Override public EnumDirection getDirection() { return this.direction; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -183,7 +191,7 @@ public abstract class EntityHanging extends Entity { // CraftBukkit end this.die(); - this.aA(); + this.velocityChanged(); this.a(damagesource.getEntity()); } @@ -191,8 +199,9 @@ public abstract class EntityHanging extends Entity { } } - public void move(EnumMoveType enummovetype, double d0, double d1, double d2) { - if (!this.world.isClientSide && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { + @Override + public void move(EnumMoveType enummovetype, Vec3D vec3d) { + if (!this.world.isClientSide && !this.dead && vec3d.g() > 0.0D) { if (this.dead) return; // CraftBukkit // CraftBukkit start - fire break events @@ -211,6 +220,7 @@ public abstract class EntityHanging extends Entity { } + @Override public void f(double d0, double d1, double d2) { if (false && !this.world.isClientSide && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { // CraftBukkit - not needed this.die(); @@ -219,6 +229,7 @@ public abstract class EntityHanging extends Entity { } + @Override public void b(NBTTagCompound nbttagcompound) { nbttagcompound.setByte("Facing", (byte) this.direction.get2DRotationValue()); BlockPosition blockposition = this.getBlockPosition(); @@ -228,31 +239,35 @@ public abstract class EntityHanging extends Entity { nbttagcompound.setInt("TileZ", blockposition.getZ()); } + @Override public void a(NBTTagCompound nbttagcompound) { this.blockPosition = new BlockPosition(nbttagcompound.getInt("TileX"), nbttagcompound.getInt("TileY"), nbttagcompound.getInt("TileZ")); - this.setDirection(EnumDirection.fromType2(nbttagcompound.getByte("Facing"))); + this.direction = EnumDirection.fromType2(nbttagcompound.getByte("Facing")); } - public abstract int getWidth(); + public abstract int getHangingWidth(); - public abstract int getHeight(); + public abstract int getHangingHeight(); public abstract void a(@Nullable Entity entity); - public abstract void m(); + public abstract void playPlaceSound(); + @Override public EntityItem a(ItemStack itemstack, float f) { EntityItem entityitem = new EntityItem(this.world, this.locX + (double) ((float) this.direction.getAdjacentX() * 0.15F), this.locY + (double) f, this.locZ + (double) ((float) this.direction.getAdjacentZ() * 0.15F), itemstack); - entityitem.n(); + entityitem.defaultPickupDelay(); this.world.addEntity(entityitem); return entityitem; } - protected boolean aD() { + @Override + protected boolean aJ() { return false; } + @Override public void setPosition(double d0, double d1, double d2) { this.blockPosition = new BlockPosition(d0, d1, d2); this.updateBoundingBox(); @@ -263,37 +278,43 @@ public abstract class EntityHanging extends Entity { return this.blockPosition; } + @Override public float a(EnumBlockRotation enumblockrotation) { - if (this.direction != null && this.direction.k() != EnumDirection.EnumAxis.Y) { + if (this.direction.k() != EnumDirection.EnumAxis.Y) { switch (enumblockrotation) { - case CLOCKWISE_180: - this.direction = this.direction.opposite(); - break; - case COUNTERCLOCKWISE_90: - this.direction = this.direction.f(); - break; - case CLOCKWISE_90: - this.direction = this.direction.e(); + case CLOCKWISE_180: + this.direction = this.direction.opposite(); + break; + case COUNTERCLOCKWISE_90: + this.direction = this.direction.f(); + break; + case CLOCKWISE_90: + this.direction = this.direction.e(); } } float f = MathHelper.g(this.yaw); switch (enumblockrotation) { - case CLOCKWISE_180: - return f + 180.0F; - case COUNTERCLOCKWISE_90: - return f + 90.0F; - case CLOCKWISE_90: - return f + 270.0F; - default: - return f; + case CLOCKWISE_180: + return f + 180.0F; + case COUNTERCLOCKWISE_90: + return f + 90.0F; + case CLOCKWISE_90: + return f + 270.0F; + default: + return f; } } + @Override public float a(EnumBlockMirror enumblockmirror) { return this.a(enumblockmirror.a(this.direction)); } + @Override public void onLightningStrike(EntityLightning entitylightning) {} + + @Override + public void updateSize() {} } diff --git a/src/main/java/net/minecraft/server/EntityHorse.java b/src/main/java/net/minecraft/server/EntityHorse.java deleted file mode 100644 index 1b9425f3e..000000000 --- a/src/main/java/net/minecraft/server/EntityHorse.java +++ /dev/null @@ -1,276 +0,0 @@ -package net.minecraft.server; - -import java.util.UUID; -import javax.annotation.Nullable; - -public class EntityHorse extends EntityHorseAbstract { - - private static final UUID bM = UUID.fromString("556E1665-8B10-40C8-8F9D-CF9B1667F295"); - private static final DataWatcherObject bN = DataWatcher.a(EntityHorse.class, DataWatcherRegistry.b); - private static final DataWatcherObject bO = DataWatcher.a(EntityHorse.class, DataWatcherRegistry.b); - private static final String[] bP = new String[] { "textures/entity/horse/horse_white.png", "textures/entity/horse/horse_creamy.png", "textures/entity/horse/horse_chestnut.png", "textures/entity/horse/horse_brown.png", "textures/entity/horse/horse_black.png", "textures/entity/horse/horse_gray.png", "textures/entity/horse/horse_darkbrown.png"}; - private static final String[] bQ = new String[] { "hwh", "hcr", "hch", "hbr", "hbl", "hgr", "hdb"}; - private static final String[] bR = new String[] { null, "textures/entity/horse/horse_markings_white.png", "textures/entity/horse/horse_markings_whitefield.png", "textures/entity/horse/horse_markings_whitedots.png", "textures/entity/horse/horse_markings_blackdots.png"}; - private static final String[] bS = new String[] { "", "wo_", "wmo", "wdo", "bdo"}; - private String bT; - private final String[] bU = new String[3]; - - public EntityHorse(World world) { - super(EntityTypes.HORSE, world); - } - - protected void x_() { - super.x_(); - this.datawatcher.register(EntityHorse.bN, 0); - this.datawatcher.register(EntityHorse.bO, EnumHorseArmor.NONE.a()); - } - - public void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); - nbttagcompound.setInt("Variant", this.getVariant()); - if (!this.inventoryChest.getItem(1).isEmpty()) { - nbttagcompound.set("ArmorItem", this.inventoryChest.getItem(1).save(new NBTTagCompound())); - } - - } - - public void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - this.setVariant(nbttagcompound.getInt("Variant")); - if (nbttagcompound.hasKeyOfType("ArmorItem", 10)) { - ItemStack itemstack = ItemStack.a(nbttagcompound.getCompound("ArmorItem")); - - if (!itemstack.isEmpty() && EnumHorseArmor.b(itemstack.getItem())) { - this.inventoryChest.setItem(1, itemstack); - } - } - - this.dS(); - } - - public void setVariant(int i) { - this.datawatcher.set(EntityHorse.bN, i); - this.eg(); - } - - public int getVariant() { - return (Integer) this.datawatcher.get(EntityHorse.bN); - } - - private void eg() { - this.bT = null; - } - - protected void dS() { - super.dS(); - this.h(this.inventoryChest.getItem(1)); - } - - public void h(ItemStack itemstack) { - EnumHorseArmor enumhorsearmor = EnumHorseArmor.a(itemstack); - - this.datawatcher.set(EntityHorse.bO, enumhorsearmor.a()); - this.eg(); - if (!this.world.isClientSide) { - this.getAttributeInstance(GenericAttributes.h).b(EntityHorse.bM); - int i = enumhorsearmor.c(); - - if (i != 0) { - this.getAttributeInstance(GenericAttributes.h).b((new AttributeModifier(EntityHorse.bM, "Horse armor bonus", (double) i, 0)).a(false)); - } - } - - } - - public EnumHorseArmor dH() { - return EnumHorseArmor.a((Integer) this.datawatcher.get(EntityHorse.bO)); - } - - public void a(IInventory iinventory) { - EnumHorseArmor enumhorsearmor = this.dH(); - - super.a(iinventory); - EnumHorseArmor enumhorsearmor1 = this.dH(); - - if (this.ticksLived > 20 && enumhorsearmor != enumhorsearmor1 && enumhorsearmor1 != EnumHorseArmor.NONE) { - this.a(SoundEffects.ENTITY_HORSE_ARMOR, 0.5F, 1.0F); - } - - } - - protected void a(SoundEffectType soundeffecttype) { - super.a(soundeffecttype); - if (this.random.nextInt(10) == 0) { - this.a(SoundEffects.ENTITY_HORSE_BREATHE, soundeffecttype.a() * 0.6F, soundeffecttype.b()); - } - - } - - protected void initAttributes() { - super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue((double) this.ec()); - this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(this.ee()); - this.getAttributeInstance(EntityHorse.attributeJumpStrength).setValue(this.ed()); - } - - public void tick() { - super.tick(); - if (this.world.isClientSide && this.datawatcher.a()) { - this.datawatcher.e(); - this.eg(); - } - - } - - protected SoundEffect D() { - super.D(); - return SoundEffects.ENTITY_HORSE_AMBIENT; - } - - protected SoundEffect cs() { - super.cs(); - return SoundEffects.ENTITY_HORSE_DEATH; - } - - protected SoundEffect d(DamageSource damagesource) { - super.d(damagesource); - return SoundEffects.ENTITY_HORSE_HURT; - } - - protected SoundEffect dB() { - super.dB(); - return SoundEffects.ENTITY_HORSE_ANGRY; - } - - protected MinecraftKey getDefaultLootTable() { - return LootTables.N; - } - - public boolean a(EntityHuman entityhuman, EnumHand enumhand) { - ItemStack itemstack = entityhuman.b(enumhand); - boolean flag = !itemstack.isEmpty(); - - if (flag && itemstack.getItem() instanceof ItemMonsterEgg) { - return super.a(entityhuman, enumhand); - } else { - if (!this.isBaby()) { - if (this.isTamed() && entityhuman.isSneaking()) { - this.c(entityhuman); - return true; - } - - if (this.isVehicle()) { - return super.a(entityhuman, enumhand); - } - } - - if (flag) { - if (this.b(entityhuman, itemstack)) { - if (!entityhuman.abilities.canInstantlyBuild) { - itemstack.subtract(1); - } - - return true; - } - - if (itemstack.a(entityhuman, (EntityLiving) this, enumhand)) { - return true; - } - - if (!this.isTamed()) { - this.dZ(); - return true; - } - - boolean flag1 = EnumHorseArmor.a(itemstack) != EnumHorseArmor.NONE; - boolean flag2 = !this.isBaby() && !this.dV() && itemstack.getItem() == Items.SADDLE; - - if (flag1 || flag2) { - this.c(entityhuman); - return true; - } - } - - if (this.isBaby()) { - return super.a(entityhuman, enumhand); - } else { - this.g(entityhuman); - return true; - } - } - } - - public boolean mate(EntityAnimal entityanimal) { - return entityanimal == this ? false : (!(entityanimal instanceof EntityHorseDonkey) && !(entityanimal instanceof EntityHorse) ? false : this.eb() && ((EntityHorseAbstract) entityanimal).eb()); - } - - public EntityAgeable createChild(EntityAgeable entityageable) { - Object object; - - if (entityageable instanceof EntityHorseDonkey) { - object = EntityTypes.MULE.create(world); // Paper - } else { - EntityHorse entityhorse = (EntityHorse) entityageable; - - object = EntityTypes.HORSE.create(world); // Paper - int i = this.random.nextInt(9); - int j; - - if (i < 4) { - j = this.getVariant() & 255; - } else if (i < 8) { - j = entityhorse.getVariant() & 255; - } else { - j = this.random.nextInt(7); - } - - int k = this.random.nextInt(5); - - if (k < 2) { - j |= this.getVariant() & '\uff00'; - } else if (k < 4) { - j |= entityhorse.getVariant() & '\uff00'; - } else { - j |= this.random.nextInt(5) << 8 & '\uff00'; - } - - ((EntityHorse) object).setVariant(j); - } - - this.a(entityageable, (EntityHorseAbstract) object); - return (EntityAgeable) object; - } - - public boolean ef() { - return true; - } - - public boolean g(ItemStack itemstack) { - return EnumHorseArmor.b(itemstack.getItem()); - } - - @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - Object object = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); - int i; - - if (object instanceof EntityHorse.a) { - i = ((EntityHorse.a) object).a; - } else { - i = this.random.nextInt(7); - object = new EntityHorse.a(i); - } - - this.setVariant(i | this.random.nextInt(5) << 8); - return (GroupDataEntity) object; - } - - public static class a implements GroupDataEntity { - - public int a; - - public a(int i) { - this.a = i; - } - } -} diff --git a/src/main/java/net/minecraft/server/EntityHorseAbstract.java b/src/main/java/net/minecraft/server/EntityHorseAbstract.java index 36d36b5ee..8aa60e95f 100644 --- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java +++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java @@ -1,7 +1,6 @@ package net.minecraft.server; import java.util.Iterator; -import java.util.List; import java.util.Optional; import java.util.UUID; import java.util.function.Predicate; @@ -10,40 +9,41 @@ import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; // CraftBuk public abstract class EntityHorseAbstract extends EntityAnimal implements IInventoryListener, IJumpable { - private static final Predicate bM = (entity) -> { - return entity instanceof EntityHorseAbstract && ((EntityHorseAbstract) entity).hasReproduced(); + private static final Predicate bI = (entityliving) -> { + return entityliving instanceof EntityHorseAbstract && ((EntityHorseAbstract) entityliving).hasReproduced(); }; + private static final PathfinderTargetCondition bJ = (new PathfinderTargetCondition()).a(16.0D).a().b().c().a(EntityHorseAbstract.bI); public static final IAttribute attributeJumpStrength = (new AttributeRanged((IAttribute) null, "horse.jumpStrength", 0.7D, 0.0D, 2.0D)).a("Jump Strength").a(true); - private static final DataWatcherObject bN = DataWatcher.a(EntityHorseAbstract.class, DataWatcherRegistry.a); - private static final DataWatcherObject> bO = DataWatcher.a(EntityHorseAbstract.class, DataWatcherRegistry.o); - private int bP; - private int bQ; - private int bR; - public int bD; - public int bE; - protected boolean bG; - public InventoryHorseChest inventoryChest; - protected int bI; + private static final DataWatcherObject bK = DataWatcher.a(EntityHorseAbstract.class, DataWatcherRegistry.a); + private static final DataWatcherObject> bL = DataWatcher.a(EntityHorseAbstract.class, DataWatcherRegistry.o); + private int bM; + private int bN; + private int bO; + public int bA; + public int bB; + protected boolean bC; + public InventorySubcontainer inventoryChest; + protected int bE; protected float jumpPower; private boolean canSlide; + private float bQ; + private float bR; + private float bS; private float bT; private float bU; private float bV; - private float bW; - private float bX; - private float bY; - protected boolean bK = true; - protected int bL; + protected boolean bG = true; + protected int bH; public int maxDomestication = 100; // CraftBukkit - store max domestication value - protected EntityHorseAbstract(EntityTypes entitytypes, World world) { + protected EntityHorseAbstract(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.setSize(1.3964844F, 1.6F); - this.Q = 1.0F; + this.K = 1.0F; this.loadChest(); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.2D)); this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D, EntityHorseAbstract.class)); @@ -51,132 +51,130 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.7D)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); - this.dI(); + this.ee(); } - protected void dI() { + protected void ee() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityHorseAbstract.bN, (byte) 0); - this.datawatcher.register(EntityHorseAbstract.bO, Optional.empty()); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityHorseAbstract.bK, (byte) 0); + this.datawatcher.register(EntityHorseAbstract.bL, Optional.empty()); } - protected boolean p(int i) { - return ((Byte) this.datawatcher.get(EntityHorseAbstract.bN) & i) != 0; + protected boolean s(int i) { + return ((Byte) this.datawatcher.get(EntityHorseAbstract.bK) & i) != 0; } protected void d(int i, boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntityHorseAbstract.bN); + byte b0 = (Byte) this.datawatcher.get(EntityHorseAbstract.bK); if (flag) { - this.datawatcher.set(EntityHorseAbstract.bN, (byte) (b0 | i)); + this.datawatcher.set(EntityHorseAbstract.bK, (byte) (b0 | i)); } else { - this.datawatcher.set(EntityHorseAbstract.bN, (byte) (b0 & ~i)); + this.datawatcher.set(EntityHorseAbstract.bK, (byte) (b0 & ~i)); } } public boolean isTamed() { - return this.p(2); + return this.s(2); } @Nullable public UUID getOwnerUUID() { - return (UUID) ((Optional) this.datawatcher.get(EntityHorseAbstract.bO)).orElse((Object) null); + return (UUID) ((Optional) this.datawatcher.get(EntityHorseAbstract.bL)).orElse((Object) null); } public void setOwnerUUID(@Nullable UUID uuid) { - this.datawatcher.set(EntityHorseAbstract.bO, Optional.ofNullable(uuid)); + this.datawatcher.set(EntityHorseAbstract.bL, Optional.ofNullable(uuid)); } - public float dL() { - return 0.5F; - } - - public void a(boolean flag) { - this.a(flag ? this.dL() : 1.0F); - } - - public boolean dM() { - return this.bG; + public boolean eh() { + return this.bC; } public void setTamed(boolean flag) { this.d(2, flag); } - public void v(boolean flag) { - this.bG = flag; + public void t(boolean flag) { + this.bC = flag; } + @Override public boolean a(EntityHuman entityhuman) { return world.paperConfig.allowLeashingUndeadHorse ? super.a(entityhuman) : super.a(entityhuman) && this.getMonsterType() != EnumMonsterType.UNDEAD; // Paper } + @Override protected void u(float f) { - if (f > 6.0F && this.dN()) { - this.y(false); + if (f > 6.0F && this.ei()) { + this.w(false); } } - public boolean dN() { - return this.p(16); + public boolean ei() { + return this.s(16); } - public boolean dO() { - return this.p(32); + public boolean ej() { + return this.s(32); } public boolean hasReproduced() { - return this.p(8); + return this.s(8); } - public void w(boolean flag) { + public void u(boolean flag) { this.d(8, flag); } - public void x(boolean flag) { + public void v(boolean flag) { this.d(4, flag); } public int getTemper() { - return this.bI; + return this.bE; } public void setTemper(int i) { - this.bI = i; + this.bE = i; } - public int r(int i) { + public int u(int i) { int j = MathHelper.clamp(this.getTemper() + i, 0, this.getMaxDomestication()); this.setTemper(j); return j; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { Entity entity = damagesource.getEntity(); return this.isVehicle() && entity != null && this.y(entity) ? false : super.damageEntity(damagesource, f); } + @Override public boolean isCollidable() { return !this.isVehicle(); } - private void dy() { - this.dC(); + private void dV() { + this.dZ(); if (!this.isSilent()) { - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_HORSE_EAT, this.bV(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); + this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_HORSE_EAT, this.getSoundCategory(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); } } - public void c(float f, float f1) { + @Override + public void b(float f, float f1) { if (f > 1.0F) { this.a(SoundEffects.ENTITY_HORSE_LAND, 0.4F, 1.0F); } @@ -196,32 +194,30 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } IBlockData iblockdata = this.world.getType(new BlockPosition(this.locX, this.locY - 0.2D - (double) this.lastYaw, this.locZ)); - Block block = iblockdata.getBlock(); if (!iblockdata.isAir() && !this.isSilent()) { - SoundEffectType soundeffecttype = block.getStepSound(); + SoundEffectType soundeffecttype = iblockdata.r(); - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, soundeffecttype.d(), this.bV(), soundeffecttype.a() * 0.5F, soundeffecttype.b() * 0.75F); + this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, soundeffecttype.d(), this.getSoundCategory(), soundeffecttype.a() * 0.5F, soundeffecttype.b() * 0.75F); } } } - protected int dA() { + protected int getChestSlots() { return 2; } public void loadChest() { - InventoryHorseChest inventoryhorsechest = this.inventoryChest; + InventorySubcontainer inventorysubcontainer = this.inventoryChest; - this.inventoryChest = new InventoryHorseChest(this.getDisplayName(), this.dA(), this); // CraftBukkit - this.inventoryChest.a(this.getCustomName()); - if (inventoryhorsechest != null) { - inventoryhorsechest.b(this); - int i = Math.min(inventoryhorsechest.getSize(), this.inventoryChest.getSize()); + this.inventoryChest = new InventorySubcontainer(this.getChestSlots(), (org.bukkit.entity.AbstractHorse) this.getBukkitEntity()); // CraftBukkit + if (inventorysubcontainer != null) { + inventorysubcontainer.b((IInventoryListener) this); + int i = Math.min(inventorysubcontainer.getSize(), this.inventoryChest.getSize()); for (int j = 0; j < i; ++j) { - ItemStack itemstack = inventoryhorsechest.getItem(j); + ItemStack itemstack = inventorysubcontainer.getItem(j); if (!itemstack.isEmpty()) { this.inventoryChest.setItem(j, itemstack.cloneItemStack()); @@ -230,99 +226,85 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } this.inventoryChest.a((IInventoryListener) this); - this.dS(); + this.en(); } - protected void dS() { + protected void en() { if (!this.world.isClientSide) { - this.x(!this.inventoryChest.getItem(0).isEmpty() && this.dU()); + this.v(!this.inventoryChest.getItem(0).isEmpty() && this.ep()); } } + @Override public void a(IInventory iinventory) { - boolean flag = this.dV(); + boolean flag = this.eq(); - this.dS(); - if (this.ticksLived > 20 && !flag && this.dV()) { + this.en(); + if (this.ticksLived > 20 && !flag && this.eq()) { this.a(SoundEffects.ENTITY_HORSE_SADDLE, 0.5F, 1.0F); } } - @Nullable - protected EntityHorseAbstract a(Entity entity, double d0) { - double d1 = Double.MAX_VALUE; - Entity entity1 = null; - List list = this.world.getEntities(entity, entity.getBoundingBox().b(d0, d0, d0), EntityHorseAbstract.bM); - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - Entity entity2 = (Entity) iterator.next(); - double d2 = entity2.d(entity.locX, entity.locY, entity.locZ); - - if (d2 < d1) { - entity1 = entity2; - d1 = d2; - } - } - - return (EntityHorseAbstract) entity1; - } - public double getJumpStrength() { return this.getAttributeInstance(EntityHorseAbstract.attributeJumpStrength).getValue(); } @Nullable - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return null; } @Nullable - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { if (this.random.nextInt(3) == 0) { - this.dH(); + this.eB(); } return null; } @Nullable - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { if (this.random.nextInt(10) == 0 && !this.isFrozen()) { - this.dH(); + this.eB(); } return null; } - public boolean dU() { + public boolean ep() { return true; } - public boolean dV() { - return this.p(4); + public boolean eq() { + return this.s(4); } @Nullable - protected SoundEffect dB() { - this.dH(); + protected SoundEffect getSoundAngry() { + this.eB(); return null; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { if (!iblockdata.getMaterial().isLiquid()) { - SoundEffectType soundeffecttype = iblockdata.getBlock().getStepSound(); + IBlockData iblockdata1 = this.world.getType(blockposition.up()); + SoundEffectType soundeffecttype = iblockdata.r(); - if (this.world.getType(blockposition.up()).getBlock() == Blocks.SNOW) { - soundeffecttype = Blocks.SNOW.getStepSound(); + if (iblockdata1.getBlock() == Blocks.SNOW) { + soundeffecttype = iblockdata1.r(); } - if (this.isVehicle() && this.bK) { - ++this.bL; - if (this.bL > 5 && this.bL % 3 == 0) { + if (this.isVehicle() && this.bG) { + ++this.bH; + if (this.bH > 5 && this.bH % 3 == 0) { this.a(soundeffecttype); - } else if (this.bL <= 5) { + } else if (this.bH <= 5) { this.a(SoundEffects.ENTITY_HORSE_STEP_WOOD, soundeffecttype.a() * 0.15F, soundeffecttype.b()); } } else if (soundeffecttype == SoundEffectType.a) { @@ -338,14 +320,16 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven this.a(SoundEffects.ENTITY_HORSE_GALLOP, soundeffecttype.a() * 0.15F, soundeffecttype.b()); } + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeMap().b(EntityHorseAbstract.attributeJumpStrength); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(53.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(53.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.22499999403953552D); } - public int dg() { + @Override + public int dC() { return 6; } @@ -353,17 +337,18 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven return this.maxDomestication; // CraftBukkit - return stored max domestication instead of 100 } - protected float cD() { + @Override + protected float getSoundVolume() { return 0.8F; } - public int z() { + @Override + public int A() { return 400; } - public void c(EntityHuman entityhuman) { + public void e(EntityHuman entityhuman) { if (!this.world.isClientSide && (!this.isVehicle() || this.w(entityhuman)) && this.isTamed()) { - this.inventoryChest.a(this.getCustomName()); entityhuman.openHorseInventory(this, this.inventoryChest); } @@ -415,7 +400,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } if (this.isBaby() && short0 > 0) { - //this.world.addParticle(Particles.z, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, 0.0D, 0.0D, 0.0D); // Akarin - this handle by client + this.world.addParticle(Particles.HAPPY_VILLAGER, this.locX + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), this.locY + 0.5D + (double) (this.random.nextFloat() * this.getHeight()), this.locZ + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), 0.0D, 0.0D, 0.0D); if (!this.world.isClientSide) { this.setAge(short0); } @@ -426,19 +411,19 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven if (b0 > 0 && (flag || !this.isTamed()) && this.getTemper() < this.getMaxDomestication()) { flag = true; if (!this.world.isClientSide) { - this.r(b0); + this.u(b0); } } if (flag) { - this.dy(); + this.dV(); } return flag; } protected void g(EntityHuman entityhuman) { - this.y(false); + this.w(false); this.setStanding(false); if (!this.world.isClientSide) { entityhuman.yaw = this.yaw; @@ -448,175 +433,179 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } + @Override protected boolean isFrozen() { - return super.isFrozen() && this.isVehicle() && this.dV() || this.dN() || this.dO(); + return super.isFrozen() && this.isVehicle() && this.eq() || this.ei() || this.ej(); } - public boolean f(ItemStack itemstack) { + @Override + public boolean i(ItemStack itemstack) { return false; } - private void dz() { - this.bD = 1; + private void dY() { + this.bA = 1; } - public void die(DamageSource damagesource) { - // super.die(damagesource); // Moved down - if (!this.world.isClientSide && this.inventoryChest != null) { + @Override + protected void cF() { + super.cF(); + if (this.inventoryChest != null) { for (int i = 0; i < this.inventoryChest.getSize(); ++i) { ItemStack itemstack = this.inventoryChest.getItem(i); if (!itemstack.isEmpty()) { - this.a_(itemstack); + this.a(itemstack); } } } - super.die(damagesource); // CraftBukkit } + @Override public void movementTick() { if (this.random.nextInt(200) == 0) { - this.dz(); + this.dY(); } super.movementTick(); - if (!this.world.isClientSide) { + if (!this.world.isClientSide && this.isAlive()) { if (this.random.nextInt(900) == 0 && this.deathTicks == 0) { this.heal(1.0F, RegainReason.REGEN); // CraftBukkit } - if (this.dY()) { - if (!this.dN() && !this.isVehicle() && this.random.nextInt(300) == 0 && this.world.getType(new BlockPosition(MathHelper.floor(this.locX), MathHelper.floor(this.locY) - 1, MathHelper.floor(this.locZ))).getBlock() == Blocks.GRASS_BLOCK) { - this.y(true); + if (this.et()) { + if (!this.ei() && !this.isVehicle() && this.random.nextInt(300) == 0 && this.world.getType((new BlockPosition(this)).down()).getBlock() == Blocks.GRASS_BLOCK) { + this.w(true); } - if (this.dN() && ++this.bP > 50) { - this.bP = 0; - this.y(false); + if (this.ei() && ++this.bM > 50) { + this.bM = 0; + this.w(false); } } - this.dX(); + this.es(); } } - protected void dX() { - if (this.hasReproduced() && this.isBaby() && !this.dN()) { - EntityHorseAbstract entityhorseabstract = this.a(this, 16.0D); + protected void es() { + if (this.hasReproduced() && this.isBaby() && !this.ei()) { + EntityLiving entityliving = this.world.a(EntityHorseAbstract.class, EntityHorseAbstract.bJ, this, this.locX, this.locY, this.locZ, this.getBoundingBox().g(16.0D)); - if (entityhorseabstract != null && this.h((Entity) entityhorseabstract) > 4.0D) { - this.navigation.a((Entity) entityhorseabstract); + if (entityliving != null && this.h((Entity) entityliving) > 4.0D) { + this.navigation.a((Entity) entityliving, 0); } } } - public boolean dY() { + public boolean et() { return true; } + @Override public void tick() { super.tick(); - if (this.bQ > 0 && ++this.bQ > 30) { - this.bQ = 0; + if (this.bN > 0 && ++this.bN > 30) { + this.bN = 0; this.d(64, false); } - if ((this.bT() || this.cP()) && this.bR > 0 && ++this.bR > 20) { - this.bR = 0; + if ((this.ca() || this.df()) && this.bO > 0 && ++this.bO > 20) { + this.bO = 0; this.setStanding(false); } - if (this.bD > 0 && ++this.bD > 8) { - this.bD = 0; + if (this.bA > 0 && ++this.bA > 8) { + this.bA = 0; } - if (this.bE > 0) { - ++this.bE; - if (this.bE > 300) { - this.bE = 0; + if (this.bB > 0) { + ++this.bB; + if (this.bB > 300) { + this.bB = 0; } } - this.bU = this.bT; - if (this.dN()) { - this.bT += (1.0F - this.bT) * 0.4F + 0.05F; - if (this.bT > 1.0F) { - this.bT = 1.0F; + this.bR = this.bQ; + if (this.ei()) { + this.bQ += (1.0F - this.bQ) * 0.4F + 0.05F; + if (this.bQ > 1.0F) { + this.bQ = 1.0F; } } else { - this.bT += (0.0F - this.bT) * 0.4F - 0.05F; - if (this.bT < 0.0F) { - this.bT = 0.0F; + this.bQ += (0.0F - this.bQ) * 0.4F - 0.05F; + if (this.bQ < 0.0F) { + this.bQ = 0.0F; } } - this.bW = this.bV; - if (this.dO()) { - this.bT = 0.0F; - this.bU = this.bT; - this.bV += (1.0F - this.bV) * 0.4F + 0.05F; - if (this.bV > 1.0F) { - this.bV = 1.0F; + this.bT = this.bS; + if (this.ej()) { + this.bQ = 0.0F; + this.bR = this.bQ; + this.bS += (1.0F - this.bS) * 0.4F + 0.05F; + if (this.bS > 1.0F) { + this.bS = 1.0F; } } else { this.canSlide = false; - this.bV += (0.8F * this.bV * this.bV * this.bV - this.bV) * 0.6F - 0.05F; - if (this.bV < 0.0F) { - this.bV = 0.0F; + this.bS += (0.8F * this.bS * this.bS * this.bS - this.bS) * 0.6F - 0.05F; + if (this.bS < 0.0F) { + this.bS = 0.0F; } } - this.bY = this.bX; - if (this.p(64)) { - this.bX += (1.0F - this.bX) * 0.7F + 0.05F; - if (this.bX > 1.0F) { - this.bX = 1.0F; + this.bV = this.bU; + if (this.s(64)) { + this.bU += (1.0F - this.bU) * 0.7F + 0.05F; + if (this.bU > 1.0F) { + this.bU = 1.0F; } } else { - this.bX += (0.0F - this.bX) * 0.7F - 0.05F; - if (this.bX < 0.0F) { - this.bX = 0.0F; + this.bU += (0.0F - this.bU) * 0.7F - 0.05F; + if (this.bU < 0.0F) { + this.bU = 0.0F; } } } - private void dC() { + private void dZ() { if (!this.world.isClientSide) { - this.bQ = 1; + this.bN = 1; this.d(64, true); } } - public void y(boolean flag) { + public void w(boolean flag) { this.d(16, flag); } public void setStanding(boolean flag) { if (flag) { - this.y(false); + this.w(false); } this.d(32, flag); } - private void dH() { - if (this.bT() || this.cP()) { - this.bR = 1; + private void eB() { + if (this.ca() || this.df()) { + this.bO = 1; this.setStanding(true); } } - public void dZ() { - this.dH(); - SoundEffect soundeffect = this.dB(); + public void eu() { + this.eB(); + SoundEffect soundeffect = this.getSoundAngry(); if (soundeffect != null) { - this.a(soundeffect, this.cD(), this.cE()); + this.a(soundeffect, this.getSoundVolume(), this.cV()); } } @@ -632,87 +621,97 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven return true; } - public void a(float f, float f1, float f2) { - if (this.isVehicle() && this.dh() && this.dV()) { - EntityLiving entityliving = (EntityLiving) this.bO(); + @Override + public void e(Vec3D vec3d) { + if (this.isAlive()) { + if (this.isVehicle() && this.dD() && this.eq()) { + EntityLiving entityliving = (EntityLiving) this.getRidingPassenger(); - this.yaw = entityliving.yaw; - this.lastYaw = this.yaw; - this.pitch = entityliving.pitch * 0.5F; - this.setYawPitch(this.yaw, this.pitch); - this.aQ = this.yaw; - this.aS = this.aQ; - f = entityliving.bh * 0.5F; - f2 = entityliving.bj; - if (f2 <= 0.0F) { - f2 *= 0.25F; - this.bL = 0; - } + this.yaw = entityliving.yaw; + this.lastYaw = this.yaw; + this.pitch = entityliving.pitch * 0.5F; + this.setYawPitch(this.yaw, this.pitch); + this.aK = this.yaw; + this.aM = this.aK; + float f = entityliving.bb * 0.5F; + float f1 = entityliving.bd; - if (this.onGround && this.jumpPower == 0.0F && this.dO() && !this.canSlide) { - f = 0.0F; - f2 = 0.0F; - } - - if (this.jumpPower > 0.0F && !this.dM() && this.onGround) { - this.motY = this.getJumpStrength() * (double) this.jumpPower; - if (this.hasEffect(MobEffects.JUMP)) { - this.motY += (double) ((float) (this.getEffect(MobEffects.JUMP).getAmplifier() + 1) * 0.1F); + if (f1 <= 0.0F) { + f1 *= 0.25F; + this.bH = 0; } - this.v(true); - this.impulse = true; - if (f2 > 0.0F) { - float f3 = MathHelper.sin(this.yaw * 0.017453292F); - float f4 = MathHelper.cos(this.yaw * 0.017453292F); - - this.motX += (double) (-0.4F * f3 * this.jumpPower); - this.motZ += (double) (0.4F * f4 * this.jumpPower); - this.ea(); + if (this.onGround && this.jumpPower == 0.0F && this.ej() && !this.canSlide) { + f = 0.0F; + f1 = 0.0F; } - this.jumpPower = 0.0F; + double d0; + double d1; + + if (this.jumpPower > 0.0F && !this.eh() && this.onGround) { + d0 = this.getJumpStrength() * (double) this.jumpPower; + if (this.hasEffect(MobEffects.JUMP)) { + d1 = d0 + (double) ((float) (this.getEffect(MobEffects.JUMP).getAmplifier() + 1) * 0.1F); + } else { + d1 = d0; + } + + Vec3D vec3d1 = this.getMot(); + + this.setMot(vec3d1.x, d1, vec3d1.z); + this.t(true); + this.impulse = true; + if (f1 > 0.0F) { + float f2 = MathHelper.sin(this.yaw * 0.017453292F); + float f3 = MathHelper.cos(this.yaw * 0.017453292F); + + this.setMot(this.getMot().add((double) (-0.4F * f2 * this.jumpPower), 0.0D, (double) (0.4F * f3 * this.jumpPower))); + this.ev(); + } + + this.jumpPower = 0.0F; + } + + this.aO = this.db() * 0.1F; + if (this.ca()) { + this.o((float) this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); + super.e(new Vec3D((double) f, vec3d.y, (double) f1)); + } else if (entityliving instanceof EntityHuman) { + this.setMot(Vec3D.a); + } + + if (this.onGround) { + this.jumpPower = 0.0F; + this.t(false); + } + + this.aE = this.aF; + d0 = this.locX - this.lastX; + d1 = this.locZ - this.lastZ; + float f4 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F; + + if (f4 > 1.0F) { + f4 = 1.0F; + } + + this.aF += (f4 - this.aF) * 0.4F; + this.aG += this.aF; + } else { + this.aO = 0.02F; + super.e(vec3d); } - - this.aU = this.cK() * 0.1F; - if (this.bT()) { - this.o((float) this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); - super.a(f, f1, f2); - } else if (entityliving instanceof EntityHuman) { - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; - } - - if (this.onGround) { - this.jumpPower = 0.0F; - this.v(false); - } - - this.aI = this.aJ; - double d0 = this.locX - this.lastX; - double d1 = this.locZ - this.lastZ; - float f5 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F; - - if (f5 > 1.0F) { - f5 = 1.0F; - } - - this.aJ += (f5 - this.aJ) * 0.4F; - this.aK += this.aJ; - } else { - this.aU = 0.02F; - super.a(f, f1, f2); } } - protected void ea() { + protected void ev() { this.a(SoundEffects.ENTITY_HORSE_JUMP, 0.4F, 1.0F); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setBoolean("EatingHaystack", this.dN()); + nbttagcompound.setBoolean("EatingHaystack", this.ei()); nbttagcompound.setBoolean("Bred", this.hasReproduced()); nbttagcompound.setInt("Temper", this.getTemper()); nbttagcompound.setBoolean("Tame", this.isTamed()); @@ -727,10 +726,11 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.y(nbttagcompound.getBoolean("EatingHaystack")); - this.w(nbttagcompound.getBoolean("Bred")); + this.w(nbttagcompound.getBoolean("EatingHaystack")); + this.u(nbttagcompound.getBoolean("Bred")); this.setTemper(nbttagcompound.getInt("Temper")); this.setTamed(nbttagcompound.getBoolean("Tame")); String s; @@ -740,7 +740,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } else { String s1 = nbttagcompound.getString("Owner"); - s = NameReferencingFileConverter.a(this.bK(), s1); + s = NameReferencingFileConverter.a(this.getMinecraftServer(), s1); } if (!s.isEmpty()) { @@ -755,7 +755,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven AttributeInstance attributeinstance = this.getAttributeMap().a("Speed"); if (attributeinstance != null) { - this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(attributeinstance.b() * 0.25D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(attributeinstance.getBaseValue() * 0.25D); } if (nbttagcompound.hasKeyOfType("SaddleItem", 10)) { @@ -766,42 +766,47 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } } - this.dS(); + this.en(); } + @Override public boolean mate(EntityAnimal entityanimal) { return false; } - protected boolean eb() { + protected boolean ew() { return !this.isVehicle() && !this.isPassenger() && this.isTamed() && !this.isBaby() && this.getHealth() >= this.getMaxHealth() && this.isInLove(); } @Nullable + @Override public EntityAgeable createChild(EntityAgeable entityageable) { return null; } protected void a(EntityAgeable entityageable, EntityHorseAbstract entityhorseabstract) { - double d0 = this.getAttributeInstance(GenericAttributes.maxHealth).b() + entityageable.getAttributeInstance(GenericAttributes.maxHealth).b() + (double) this.ec(); + double d0 = this.getAttributeInstance(GenericAttributes.MAX_HEALTH).getBaseValue() + entityageable.getAttributeInstance(GenericAttributes.MAX_HEALTH).getBaseValue() + (double) this.ex(); - entityhorseabstract.getAttributeInstance(GenericAttributes.maxHealth).setValue(d0 / 3.0D); - double d1 = this.getAttributeInstance(EntityHorseAbstract.attributeJumpStrength).b() + entityageable.getAttributeInstance(EntityHorseAbstract.attributeJumpStrength).b() + this.ed(); + entityhorseabstract.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(d0 / 3.0D); + double d1 = this.getAttributeInstance(EntityHorseAbstract.attributeJumpStrength).getBaseValue() + entityageable.getAttributeInstance(EntityHorseAbstract.attributeJumpStrength).getBaseValue() + this.ey(); entityhorseabstract.getAttributeInstance(EntityHorseAbstract.attributeJumpStrength).setValue(d1 / 3.0D); - double d2 = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).b() + entityageable.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).b() + this.ee(); + double d2 = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getBaseValue() + entityageable.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getBaseValue() + this.ez(); entityhorseabstract.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(d2 / 3.0D); } - public boolean dh() { - return this.bO() instanceof EntityLiving; + @Override + public boolean dD() { + return this.getRidingPassenger() instanceof EntityLiving; } - public boolean G_() { - return this.dV(); + @Override + public boolean F_() { + return this.eq(); } + @Override public void b(int i) { // CraftBukkit start float power; @@ -816,72 +821,77 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } // CraftBukkit end this.canSlide = true; - this.dH(); + this.eB(); } - public void I_() {} + @Override + public void c() {} + @Override public void k(Entity entity) { super.k(entity); if (entity instanceof EntityInsentient) { EntityInsentient entityinsentient = (EntityInsentient) entity; - this.aQ = entityinsentient.aQ; + this.aK = entityinsentient.aK; } - if (this.bW > 0.0F) { - float f = MathHelper.sin(this.aQ * 0.017453292F); - float f1 = MathHelper.cos(this.aQ * 0.017453292F); - float f2 = 0.7F * this.bW; - float f3 = 0.15F * this.bW; + if (this.bT > 0.0F) { + float f = MathHelper.sin(this.aK * 0.017453292F); + float f1 = MathHelper.cos(this.aK * 0.017453292F); + float f2 = 0.7F * this.bT; + float f3 = 0.15F * this.bT; - entity.setPosition(this.locX + (double) (f2 * f), this.locY + this.aJ() + entity.aI() + (double) f3, this.locZ - (double) (f2 * f1)); + entity.setPosition(this.locX + (double) (f2 * f), this.locY + this.aP() + entity.aO() + (double) f3, this.locZ - (double) (f2 * f1)); if (entity instanceof EntityLiving) { - ((EntityLiving) entity).aQ = this.aQ; + ((EntityLiving) entity).aK = this.aK; } } } - protected float ec() { + protected float ex() { return 15.0F + (float) this.random.nextInt(8) + (float) this.random.nextInt(9); } - protected double ed() { + protected double ey() { return 0.4000000059604645D + this.random.nextDouble() * 0.2D + this.random.nextDouble() * 0.2D + this.random.nextDouble() * 0.2D; } - protected double ee() { + protected double ez() { return (0.44999998807907104D + this.random.nextDouble() * 0.3D + this.random.nextDouble() * 0.3D + this.random.nextDouble() * 0.3D) * 0.25D; } - public boolean z_() { + @Override + public boolean isClimbing() { return false; } - public float getHeadHeight() { - return this.length; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height * 0.95F; } - public boolean ef() { + public boolean eA() { return false; } - public boolean g(ItemStack itemstack) { + public boolean j(ItemStack itemstack) { return false; } - public boolean c(int i, ItemStack itemstack) { + @Override + public boolean a_(int i, ItemStack itemstack) { int j = i - 400; if (j >= 0 && j < 2 && j < this.inventoryChest.getSize()) { if (j == 0 && itemstack.getItem() != Items.SADDLE) { return false; - } else if (j == 1 && (!this.ef() || !this.g(itemstack))) { + } else if (j == 1 && (!this.eA() || !this.j(itemstack))) { return false; } else { this.inventoryChest.setItem(j, itemstack); - this.dS(); + this.en(); return true; } } else { @@ -897,13 +907,15 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven } @Nullable - public Entity bO() { - return this.bP().isEmpty() ? null : (Entity) this.bP().get(0); + @Override + public Entity getRidingPassenger() { + return this.getPassengers().isEmpty() ? null : (Entity) this.getPassengers().get(0); } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - groupdataentity = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + groupdataentity = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); if (this.random.nextInt(5) == 0) { this.setAgeRaw(-24000); } diff --git a/src/main/java/net/minecraft/server/EntityHorseChestedAbstract.java b/src/main/java/net/minecraft/server/EntityHorseChestedAbstract.java index 6eddc2a84..2a988366c 100644 --- a/src/main/java/net/minecraft/server/EntityHorseChestedAbstract.java +++ b/src/main/java/net/minecraft/server/EntityHorseChestedAbstract.java @@ -2,62 +2,73 @@ package net.minecraft.server; public abstract class EntityHorseChestedAbstract extends EntityHorseAbstract { - private static final DataWatcherObject bM = DataWatcher.a(EntityHorseChestedAbstract.class, DataWatcherRegistry.i); + private static final DataWatcherObject bI = DataWatcher.a(EntityHorseChestedAbstract.class, DataWatcherRegistry.i); - protected EntityHorseChestedAbstract(EntityTypes entitytypes, World world) { + protected EntityHorseChestedAbstract(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.bK = false; + this.bG = false; } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityHorseChestedAbstract.bM, false); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityHorseChestedAbstract.bI, false); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue((double) this.ec()); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue((double) this.ex()); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.17499999701976776D); this.getAttributeInstance(EntityHorseChestedAbstract.attributeJumpStrength).setValue(0.5D); } public boolean isCarryingChest() { - return (Boolean) this.datawatcher.get(EntityHorseChestedAbstract.bM); + return (Boolean) this.datawatcher.get(EntityHorseChestedAbstract.bI); } public void setCarryingChest(boolean flag) { - this.datawatcher.set(EntityHorseChestedAbstract.bM, flag); + this.datawatcher.set(EntityHorseChestedAbstract.bI, flag); } - protected int dA() { - return this.isCarryingChest() ? 17 : super.dA(); + @Override + protected int getChestSlots() { + return this.isCarryingChest() ? 17 : super.getChestSlots(); } - public double aJ() { - return super.aJ() - 0.25D; + @Override + public double aP() { + return super.aP() - 0.25D; } - protected SoundEffect dB() { - super.dB(); + @Override + protected SoundEffect getSoundAngry() { + super.getSoundAngry(); return SoundEffects.ENTITY_DONKEY_ANGRY; } - public void die(DamageSource damagesource) { - // super.die(damagesource); // CraftBukkit - moved down + @Override + protected void cF() { + super.cF(); if (this.isCarryingChest()) { if (!this.world.isClientSide) { this.a((IMaterial) Blocks.CHEST); } - // this.setCarryingChest(false); // CraftBukkit - moved down + //this.setCarryingChest(false); // Paper - moved to post death logic } - // CraftBukkit start - super.die(damagesource); - this.setCarryingChest(false); - // CraftBukkit end } + // Paper start + protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) { + if (this.isCarryingChest() && (event == null || !event.isCancelled())) { + this.setCarryingChest(false); + } + } + // Paper end + + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setBoolean("ChestedHorse", this.isCarryingChest()); @@ -72,7 +83,7 @@ public abstract class EntityHorseChestedAbstract extends EntityHorseAbstract { nbttagcompound1.setByte("Slot", (byte) i); itemstack.save(nbttagcompound1); - nbttaglist.add((NBTBase) nbttagcompound1); + nbttaglist.add(nbttagcompound1); } } @@ -81,6 +92,7 @@ public abstract class EntityHorseChestedAbstract extends EntityHorseAbstract { } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setCarryingChest(nbttagcompound.getBoolean("ChestedHorse")); @@ -99,10 +111,11 @@ public abstract class EntityHorseChestedAbstract extends EntityHorseAbstract { } } - this.dS(); + this.en(); } - public boolean c(int i, ItemStack itemstack) { + @Override + public boolean a_(int i, ItemStack itemstack) { if (i == 499) { if (this.isCarryingChest() && itemstack.isEmpty()) { this.setCarryingChest(false); @@ -117,9 +130,10 @@ public abstract class EntityHorseChestedAbstract extends EntityHorseAbstract { } } - return super.c(i, itemstack); + return super.a_(i, itemstack); } + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -128,7 +142,7 @@ public abstract class EntityHorseChestedAbstract extends EntityHorseAbstract { } else { if (!this.isBaby()) { if (this.isTamed() && entityhuman.isSneaking()) { - this.c(entityhuman); + this.e(entityhuman); return true; } @@ -146,19 +160,19 @@ public abstract class EntityHorseChestedAbstract extends EntityHorseAbstract { return true; } - this.dZ(); + this.eu(); return true; } if (!this.isCarryingChest() && itemstack.getItem() == Blocks.CHEST.getItem()) { this.setCarryingChest(true); - this.dC(); + this.dY(); flag = true; this.loadChest(); } - if (!this.isBaby() && !this.dV() && itemstack.getItem() == Items.SADDLE) { - this.c(entityhuman); + if (!this.isBaby() && !this.eq() && itemstack.getItem() == Items.SADDLE) { + this.e(entityhuman); return true; } } @@ -181,11 +195,11 @@ public abstract class EntityHorseChestedAbstract extends EntityHorseAbstract { } } - protected void dC() { + protected void dY() { this.a(SoundEffects.ENTITY_DONKEY_CHEST, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); } - public int dH() { + public int dZ() { return 5; } } diff --git a/src/main/java/net/minecraft/server/EntityHorseDonkey.java b/src/main/java/net/minecraft/server/EntityHorseDonkey.java deleted file mode 100644 index 65c40e72b..000000000 --- a/src/main/java/net/minecraft/server/EntityHorseDonkey.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.minecraft.server; - -import javax.annotation.Nullable; - -public class EntityHorseDonkey extends EntityHorseChestedAbstract { - - public EntityHorseDonkey(World world) { - super(EntityTypes.DONKEY, world); - } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.O; - } - - protected SoundEffect D() { - super.D(); - return SoundEffects.ENTITY_DONKEY_AMBIENT; - } - - protected SoundEffect cs() { - super.cs(); - return SoundEffects.ENTITY_DONKEY_DEATH; - } - - protected SoundEffect d(DamageSource damagesource) { - super.d(damagesource); - return SoundEffects.ENTITY_DONKEY_HURT; - } - - public boolean mate(EntityAnimal entityanimal) { - return entityanimal == this ? false : (!(entityanimal instanceof EntityHorseDonkey) && !(entityanimal instanceof EntityHorse) ? false : this.eb() && ((EntityHorseAbstract) entityanimal).eb()); - } - - public EntityAgeable createChild(EntityAgeable entityageable) { - Object object = entityageable instanceof EntityHorse ? EntityTypes.MULE.create(world) : EntityTypes.DONKEY.create(world); // Paper - - this.a(entityageable, (EntityHorseAbstract) object); - return (EntityAgeable) object; - } -} diff --git a/src/main/java/net/minecraft/server/EntityHorseSkeleton.java b/src/main/java/net/minecraft/server/EntityHorseSkeleton.java index 0a092acdf..0aa77914c 100644 --- a/src/main/java/net/minecraft/server/EntityHorseSkeleton.java +++ b/src/main/java/net/minecraft/server/EntityHorseSkeleton.java @@ -4,50 +4,56 @@ import javax.annotation.Nullable; public class EntityHorseSkeleton extends EntityHorseAbstract { - private final PathfinderGoalHorseTrap bM = new PathfinderGoalHorseTrap(this); - private boolean bN; - private int bO; public int getTrapTime() { return this.bO; } // Paper - OBFHELPER + private final PathfinderGoalHorseTrap bI = new PathfinderGoalHorseTrap(this); + private boolean bJ; + private int bK;public int getTrapTime() { return this.bK; } // Paper - OBFHELPER - public EntityHorseSkeleton(World world) { - super(EntityTypes.SKELETON_HORSE, world); + public EntityHorseSkeleton(EntityTypes entitytypes, World world) { + super(entitytypes, world); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(15.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(15.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.20000000298023224D); - this.getAttributeInstance(EntityHorseSkeleton.attributeJumpStrength).setValue(this.ed()); + this.getAttributeInstance(EntityHorseSkeleton.attributeJumpStrength).setValue(this.ey()); } - protected void dI() {} + @Override + protected void ee() {} - protected SoundEffect D() { - super.D(); + @Override + protected SoundEffect getSoundAmbient() { + super.getSoundAmbient(); return this.a(TagsFluid.WATER) ? SoundEffects.ENTITY_SKELETON_HORSE_AMBIENT_WATER : SoundEffects.ENTITY_SKELETON_HORSE_AMBIENT; } - protected SoundEffect cs() { - super.cs(); + @Override + protected SoundEffect getSoundDeath() { + super.getSoundDeath(); return SoundEffects.ENTITY_SKELETON_HORSE_DEATH; } - protected SoundEffect d(DamageSource damagesource) { - super.d(damagesource); + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + super.getSoundHurt(damagesource); return SoundEffects.ENTITY_SKELETON_HORSE_HURT; } - protected SoundEffect ad() { + @Override + protected SoundEffect getSoundSwim() { if (this.onGround) { if (!this.isVehicle()) { return SoundEffects.ENTITY_SKELETON_HORSE_STEP_WATER; } - ++this.bL; - if (this.bL > 5 && this.bL % 3 == 0) { + ++this.bH; + if (this.bH > 5 && this.bH % 3 == 0) { return SoundEffects.ENTITY_SKELETON_HORSE_GALLOP_WATER; } - if (this.bL <= 5) { + if (this.bH <= 5) { return SoundEffects.ENTITY_SKELETON_HORSE_STEP_WATER; } } @@ -55,6 +61,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { return SoundEffects.ENTITY_SKELETON_HORSE_SWIM; } + @Override protected void d(float f) { if (this.onGround) { super.d(0.3F); @@ -64,79 +71,84 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { } - protected void ea() { + @Override + protected void ev() { if (this.isInWater()) { this.a(SoundEffects.ENTITY_SKELETON_HORSE_JUMP_WATER, 0.4F, 1.0F); } else { - super.ea(); + super.ev(); } } + @Override public EnumMonsterType getMonsterType() { return EnumMonsterType.UNDEAD; } - public double aJ() { - return super.aJ() - 0.1875D; - } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.R; + @Override + public double aP() { + return super.aP() - 0.1875D; } + @Override public void movementTick() { super.movementTick(); - if (this.dy() && this.bO++ >= 18000) { + if (this.dV() && this.bK++ >= 18000) { this.die(); } } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setBoolean("SkeletonTrap", this.dy()); - nbttagcompound.setInt("SkeletonTrapTime", this.bO); + nbttagcompound.setBoolean("SkeletonTrap", this.dV()); + nbttagcompound.setInt("SkeletonTrapTime", this.bK); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.s(nbttagcompound.getBoolean("SkeletonTrap")); - this.bO = nbttagcompound.getInt("SkeletonTrapTime"); + this.r(nbttagcompound.getBoolean("SkeletonTrap")); + this.bK = nbttagcompound.getInt("SkeletonTrapTime"); } - public boolean aY() { + @Override + public boolean bf() { return true; } - protected float cJ() { + @Override + protected float da() { return 0.96F; } - public boolean isTrap() { return this.dy(); } // Paper - OBFHELPER - public boolean dy() { - return this.bN; + public boolean isTrap() { return this.dV(); } // Paper - OBFHELPER + public boolean dV() { + return this.bJ; } - public void setTrap(boolean trap) { this.s(trap); } // Paper - OBFHELPER - public void s(boolean flag) { - if (flag != this.bN) { - this.bN = flag; + public void setTrap(boolean trap) { this.r(trap); } // Paper - OBFHELPER + public void r(boolean flag) { + if (flag != this.bJ) { + this.bJ = flag; if (flag) { - this.goalSelector.a(1, this.bM); + this.goalSelector.a(1, this.bI); } else { - this.goalSelector.a((PathfinderGoal) this.bM); + this.goalSelector.a((PathfinderGoal) this.bI); } } } @Nullable + @Override public EntityAgeable createChild(EntityAgeable entityageable) { - return EntityTypes.SKELETON_HORSE.create(world); // Paper + return (EntityAgeable) EntityTypes.SKELETON_HORSE.a(this.world); } + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -147,14 +159,14 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { } else if (this.isBaby()) { return super.a(entityhuman, enumhand); } else if (entityhuman.isSneaking()) { - this.c(entityhuman); + this.e(entityhuman); return true; } else if (this.isVehicle()) { return super.a(entityhuman, enumhand); } else { if (!itemstack.isEmpty()) { - if (itemstack.getItem() == Items.SADDLE && !this.dV()) { - this.c(entityhuman); + if (itemstack.getItem() == Items.SADDLE && !this.eq()) { + this.e(entityhuman); return true; } diff --git a/src/main/java/net/minecraft/server/EntityHorseZombie.java b/src/main/java/net/minecraft/server/EntityHorseZombie.java deleted file mode 100644 index a1873f557..000000000 --- a/src/main/java/net/minecraft/server/EntityHorseZombie.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.minecraft.server; - -import javax.annotation.Nullable; - -public class EntityHorseZombie extends EntityHorseAbstract { - - public EntityHorseZombie(World world) { - super(EntityTypes.ZOMBIE_HORSE, world); - } - - protected void initAttributes() { - super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(15.0D); - this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.20000000298023224D); - this.getAttributeInstance(EntityHorseZombie.attributeJumpStrength).setValue(this.ed()); - } - - public EnumMonsterType getMonsterType() { - return EnumMonsterType.UNDEAD; - } - - protected SoundEffect D() { - super.D(); - return SoundEffects.ENTITY_ZOMBIE_HORSE_AMBIENT; - } - - protected SoundEffect cs() { - super.cs(); - return SoundEffects.ENTITY_ZOMBIE_HORSE_DEATH; - } - - protected SoundEffect d(DamageSource damagesource) { - super.d(damagesource); - return SoundEffects.ENTITY_ZOMBIE_HORSE_HURT; - } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.Q; - } - - @Nullable - public EntityAgeable createChild(EntityAgeable entityageable) { - return EntityTypes.ZOMBIE_HORSE.create(world); // Paper - } - - public boolean a(EntityHuman entityhuman, EnumHand enumhand) { - ItemStack itemstack = entityhuman.b(enumhand); - - if (itemstack.getItem() instanceof ItemMonsterEgg) { - return super.a(entityhuman, enumhand); - } else if (!this.isTamed()) { - return false; - } else if (this.isBaby()) { - return super.a(entityhuman, enumhand); - } else if (entityhuman.isSneaking()) { - this.c(entityhuman); - return true; - } else if (this.isVehicle()) { - return super.a(entityhuman, enumhand); - } else { - if (!itemstack.isEmpty()) { - if (!this.dV() && itemstack.getItem() == Items.SADDLE) { - this.c(entityhuman); - return true; - } - - if (itemstack.a(entityhuman, (EntityLiving) this, enumhand)) { - return true; - } - } - - this.g(entityhuman); - return true; - } - } - - protected void dI() {} -} diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java index fc450ff54..cd73cde8d 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -1,19 +1,23 @@ package net.minecraft.server; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.mojang.authlib.GameProfile; +import com.mojang.datafixers.util.Either; import java.nio.charset.StandardCharsets; -import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalInt; import java.util.UUID; import java.util.function.Predicate; import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.util.CraftVector; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent; @@ -26,60 +30,50 @@ import org.bukkit.util.Vector; public abstract class EntityHuman extends EntityLiving { - private static final DataWatcherObject a = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.c); - private static final DataWatcherObject b = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.b); - protected static final DataWatcherObject bx = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); - protected static final DataWatcherObject by = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); - protected static final DataWatcherObject bz = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); - protected static final DataWatcherObject bA = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); - public PlayerInventory inventory = new PlayerInventory(this); + public static final EntitySize bs = EntitySize.b(0.6F, 1.8F); + // CraftBukkit - decompile error + private static final Map b = ImmutableMap.builder().put(EntityPose.STANDING, EntityHuman.bs).put(EntityPose.SLEEPING, EntityHuman.as).put(EntityPose.FALL_FLYING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SWIMMING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SPIN_ATTACK, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SNEAKING, EntitySize.b(0.6F, 1.5F)).put(EntityPose.DYING, EntitySize.c(0.2F, 0.2F)).build(); + private static final DataWatcherObject c = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.c); + private static final DataWatcherObject d = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.b); + protected static final DataWatcherObject bt = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); + protected static final DataWatcherObject bu = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); + protected static final DataWatcherObject bv = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); + protected static final DataWatcherObject bw = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p); + private long e; + public final PlayerInventory inventory = new PlayerInventory(this); protected InventoryEnderChest enderChest = new InventoryEnderChest(this); // CraftBukkit - add "this" to constructor - public Container defaultContainer; + public final ContainerPlayer defaultContainer; public Container activeContainer; protected FoodMetaData foodData = new FoodMetaData(this); // CraftBukkit - add "this" to constructor - protected int bG; - public float bH; - public float bI; - public int bJ; + protected int bC; + public float bD; + public float bE; + public int bF; + public double bG; + public double bH; + public double bI; + public double bJ; public double bK; public double bL; - public double bM; - public double bN; - public double bO; - public double bP; - public boolean sleeping; - public BlockPosition bedPosition; public int sleepTicks; - public float bS; - public float bT; - private boolean d; - protected boolean bU; - private BlockPosition e; - private boolean f; - public PlayerAbilities abilities = new PlayerAbilities(); + protected boolean bM; + private BlockPosition g; + private boolean bU; + public final PlayerAbilities abilities = new PlayerAbilities(); public int expLevel; public int expTotal; public float exp; - protected int bZ; - protected float ca = 0.02F; - private int g; - private GameProfile h; public void setProfile(GameProfile profile) { this.h = profile; } // Paper - OBFHELPER - private ItemStack cd; - private final ItemCooldown ce; + protected int bR; + protected final float bS = 0.02F; + private int bV; + private GameProfile bW; public final void setProfile(final GameProfile profile) { this.bW = profile; } // Paper - OBFHELPER + private ItemStack bY; + private final ItemCooldown bZ; @Nullable public EntityFishingHook hookedFish; // Paper start public boolean affectsSpawning = true; // Paper end - // Paper start - Player view distance API - private int viewDistance = -1; - public int getViewDistance() { - return viewDistance == -1 ? ((WorldServer) world).getPlayerChunkMap().getViewDistance() : viewDistance; - } - public void setViewDistance(int viewDistance) { - this.viewDistance = viewDistance; - } - // Paper end // CraftBukkit start public boolean fauxSleeping; @@ -94,44 +88,61 @@ public abstract class EntityHuman extends EntityLiving { public EntityHuman(World world, GameProfile gameprofile) { super(EntityTypes.PLAYER, world); - this.cd = ItemStack.a; - this.ce = this.g(); + this.bY = ItemStack.a; + this.bZ = this.g(); this.a(a(gameprofile)); - this.h = gameprofile; + this.bW = gameprofile; this.defaultContainer = new ContainerPlayer(this.inventory, !world.isClientSide, this); this.activeContainer = this.defaultContainer; BlockPosition blockposition = world.getSpawn(); this.setPositionRotation((double) blockposition.getX() + 0.5D, (double) (blockposition.getY() + 1), (double) blockposition.getZ() + 0.5D, 0.0F, 0.0F); - this.bd = 180.0F; + this.aX = 180.0F; } + public boolean a(World world, BlockPosition blockposition, EnumGamemode enumgamemode) { + if (!enumgamemode.d()) { + return false; + } else if (enumgamemode == EnumGamemode.SPECTATOR) { + return true; + } else if (this.dQ()) { + return false; + } else { + ItemStack itemstack = this.getItemInMainHand(); + + return itemstack.isEmpty() || !itemstack.a(world.t(), new ShapeDetectorBlock(world, blockposition, false)); + } + } + + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(1.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.10000000149011612D); - this.getAttributeMap().b(GenericAttributes.g); - this.getAttributeMap().b(GenericAttributes.j); + this.getAttributeMap().b(GenericAttributes.ATTACK_SPEED); + this.getAttributeMap().b(GenericAttributes.LUCK); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityHuman.a, 0.0F); - this.datawatcher.register(EntityHuman.b, 0); - this.datawatcher.register(EntityHuman.bx, (byte) 0); - this.datawatcher.register(EntityHuman.by, (byte) 1); - this.datawatcher.register(EntityHuman.bz, new NBTTagCompound()); - this.datawatcher.register(EntityHuman.bA, new NBTTagCompound()); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityHuman.c, 0.0F); + this.datawatcher.register(EntityHuman.d, 0); + this.datawatcher.register(EntityHuman.bt, (byte) 0); + this.datawatcher.register(EntityHuman.bu, (byte) 1); + this.datawatcher.register(EntityHuman.bv, new NBTTagCompound()); + this.datawatcher.register(EntityHuman.bw, new NBTTagCompound()); } + @Override public void tick() { this.noclip = this.isSpectator(); if (this.isSpectator()) { this.onGround = false; } - if (this.bJ > 0) { - --this.bJ; + if (this.bF > 0) { + --this.bF; } if (this.isSleeping()) { @@ -140,12 +151,8 @@ public abstract class EntityHuman extends EntityLiving { this.sleepTicks = 100; } - if (!this.world.isClientSide) { - if (!this.p()) { - this.a(true, true, false); - } else if (this.world.L()) { - this.a(false, true, true); - } + if (!this.world.isClientSide && this.world.J()) { + this.wakeup(false, true, true); } } else if (this.sleepTicks > 0) { ++this.sleepTicks; @@ -154,8 +161,7 @@ public abstract class EntityHuman extends EntityLiving { } } - this.n(); - this.dg(); + this.dA(); super.tick(); if (!this.world.isClientSide && this.activeContainer != null && !this.activeContainer.canUse(this)) { this.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper @@ -166,7 +172,7 @@ public abstract class EntityHuman extends EntityLiving { this.extinguish(); } - this.o(); + this.n(); if (!this.world.isClientSide) { this.foodData.a(this); this.a(StatisticList.PLAY_ONE_MINUTE); @@ -191,25 +197,25 @@ public abstract class EntityHuman extends EntityLiving { this.setPosition(d0, this.locY, d1); } - ++this.aH; + ++this.aD; ItemStack itemstack = this.getItemInMainHand(); - if (!ItemStack.matches(this.cd, itemstack)) { - if (!ItemStack.d(this.cd, itemstack)) { - this.dH(); + if (!ItemStack.matches(this.bY, itemstack)) { + if (!ItemStack.d(this.bY, itemstack)) { + this.dZ(); } - this.cd = itemstack.isEmpty() ? ItemStack.a : itemstack.cloneItemStack(); + this.bY = itemstack.isEmpty() ? ItemStack.a : itemstack.cloneItemStack(); } this.l(); - this.ce.a(); - this.dh(); + this.bZ.a(); + this.dB(); } - protected boolean dg() { - this.bU = this.a(TagsFluid.WATER); - return this.bU; + protected boolean dA() { + this.bM = this.a(TagsFluid.WATER, true); + return this.bM; } private void l() { @@ -226,140 +232,125 @@ public abstract class EntityHuman extends EntityLiving { } private void n() { - IBlockData iblockdata = this.world.a(this.getBoundingBox().grow(0.0D, -0.4000000059604645D, 0.0D).shrink(0.001D), Blocks.BUBBLE_COLUMN); - - if (iblockdata != null) { - if (!this.d && !this.justCreated && iblockdata.getBlock() == Blocks.BUBBLE_COLUMN && !this.isSpectator()) { - boolean flag = (Boolean) iblockdata.get(BlockBubbleColumn.a); - - if (flag) { - this.world.a(this.locX, this.locY, this.locZ, SoundEffects.BLOCK_BUBBLE_COLUMN_WHIRLPOOL_INSIDE, this.bV(), 1.0F, 1.0F, false); - } else { - this.world.a(this.locX, this.locY, this.locZ, SoundEffects.BLOCK_BUBBLE_COLUMN_UPWARDS_INSIDE, this.bV(), 1.0F, 1.0F, false); - } - } - - this.d = true; - } else { - this.d = false; - } - - } - - private void o() { - this.bK = this.bN; - this.bL = this.bO; - this.bM = this.bP; - double d0 = this.locX - this.bN; - double d1 = this.locY - this.bO; - double d2 = this.locZ - this.bP; + this.bG = this.bJ; + this.bH = this.bK; + this.bI = this.bL; + double d0 = this.locX - this.bJ; + double d1 = this.locY - this.bK; + double d2 = this.locZ - this.bL; double d3 = 10.0D; if (d0 > 10.0D) { - this.bN = this.locX; - this.bK = this.bN; + this.bJ = this.locX; + this.bG = this.bJ; } if (d2 > 10.0D) { - this.bP = this.locZ; - this.bM = this.bP; + this.bL = this.locZ; + this.bI = this.bL; } if (d1 > 10.0D) { - this.bO = this.locY; - this.bL = this.bO; + this.bK = this.locY; + this.bH = this.bK; } if (d0 < -10.0D) { - this.bN = this.locX; - this.bK = this.bN; + this.bJ = this.locX; + this.bG = this.bJ; } if (d2 < -10.0D) { - this.bP = this.locZ; - this.bM = this.bP; + this.bL = this.locZ; + this.bI = this.bL; } if (d1 < -10.0D) { - this.bO = this.locY; - this.bL = this.bO; + this.bK = this.locY; + this.bH = this.bK; } - this.bN += d0 * 0.25D; - this.bP += d2 * 0.25D; - this.bO += d1 * 0.25D; + this.bJ += d0 * 0.25D; + this.bL += d2 * 0.25D; + this.bK += d1 * 0.25D; } - protected void dh() { - float f; - float f1; + protected void dB() { + if (this.c(EntityPose.SWIMMING)) { + EntityPose entitypose; - if (this.dc()) { - f = 0.6F; - f1 = 0.6F; - } else if (this.isSleeping()) { - f = 0.2F; - f1 = 0.2F; - } else if (!this.isSwimming() && !this.isRiptiding()) { - if (this.isSneaking()) { - f = 0.6F; - f1 = 1.65F; + if (this.isGliding()) { + entitypose = EntityPose.FALL_FLYING; + } else if (this.isSleeping()) { + entitypose = EntityPose.SLEEPING; + } else if (this.isSwimming()) { + entitypose = EntityPose.SWIMMING; + } else if (this.isRiptiding()) { + entitypose = EntityPose.SPIN_ATTACK; + } else if (this.isSneaking() && !this.abilities.isFlying) { + entitypose = EntityPose.SNEAKING; } else { - f = 0.6F; - f1 = 1.8F; + entitypose = EntityPose.STANDING; } - } else { - f = 0.6F; - f1 = 0.6F; - } - if (f != this.width || f1 != this.length) { - AxisAlignedBB axisalignedbb = this.getBoundingBox(); + EntityPose entitypose1; - axisalignedbb = new AxisAlignedBB(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ, axisalignedbb.minX + (double) f, axisalignedbb.minY + (double) f1, axisalignedbb.minZ + (double) f); - if (this.world.getCubes((Entity) null, axisalignedbb)) { - this.setSize(f, f1); + if (!this.isSpectator() && !this.isPassenger() && !this.c(entitypose)) { + if (this.c(EntityPose.SNEAKING)) { + entitypose1 = EntityPose.SNEAKING; + } else { + entitypose1 = EntityPose.SWIMMING; + } + } else { + entitypose1 = entitypose; } - } + this.setPose(entitypose1); + } } - public int X() { + @Override + public int ab() { return this.abilities.isInvulnerable ? 1 : 80; } - protected SoundEffect ad() { + @Override + protected SoundEffect getSoundSwim() { return SoundEffects.ENTITY_PLAYER_SWIM; } - protected SoundEffect ae() { + @Override + protected SoundEffect getSoundSplash() { return SoundEffects.ENTITY_PLAYER_SPLASH; } - protected SoundEffect af() { + @Override + protected SoundEffect getSoundSplashHighSpeed() { return SoundEffects.ENTITY_PLAYER_SPLASH_HIGH_SPEED; } - public int aQ() { + @Override + public int aX() { return 10; } + @Override public void a(SoundEffect soundeffect, float f, float f1) { - this.world.a(this, this.locX, this.locY, this.locZ, soundeffect, this.bV(), f, f1); + this.world.playSound(this, this.locX, this.locY, this.locZ, soundeffect, this.getSoundCategory(), f, f1); } - public SoundCategory bV() { + public void a(SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) {} + + @Override + public SoundCategory getSoundCategory() { return SoundCategory.PLAYERS; } + @Override public int getMaxFireTicks() { return 20; } - protected boolean isFrozen() { - return this.getHealth() <= 0.0F || this.isSleeping(); - } - // Paper start - unused code, but to keep signatures aligned public void closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { closeInventory(); @@ -371,7 +362,8 @@ public abstract class EntityHuman extends EntityLiving { this.activeContainer = this.defaultContainer; } - public void aH() { + @Override + public void passengerTick() { if (!this.world.isClientSide && this.isSneaking() && this.isPassenger()) { this.stopRiding(); this.setSneaking(false); @@ -382,31 +374,33 @@ public abstract class EntityHuman extends EntityLiving { float f = this.yaw; float f1 = this.pitch; - super.aH(); - this.bH = this.bI; - this.bI = 0.0F; - this.l(this.locX - d0, this.locY - d1, this.locZ - d2); + super.passengerTick(); + this.bD = this.bE; + this.bE = 0.0F; + this.m(this.locX - d0, this.locY - d1, this.locZ - d2); if (this.getVehicle() instanceof EntityPig) { this.pitch = f1; this.yaw = f; - this.aQ = ((EntityPig) this.getVehicle()).aQ; + this.aK = ((EntityPig) this.getVehicle()).aK; } } } + @Override protected void doTick() { super.doTick(); - this.cy(); - this.aS = this.yaw; + this.cO(); + this.aM = this.yaw; } + @Override public void movementTick() { - if (this.bG > 0) { - --this.bG; + if (this.bC > 0) { + --this.bC; } - if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL && this.world.getGameRules().getBoolean("naturalRegeneration")) { + if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL && this.world.getGameRules().getBoolean(GameRules.NATURAL_REGENERATION)) { if (this.getHealth() < this.getMaxHealth() && this.ticksLived % 20 == 0) { // CraftBukkit - added regain reason of "REGEN" for filtering purposes. this.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN); @@ -417,8 +411,8 @@ public abstract class EntityHuman extends EntityLiving { } } - this.inventory.p(); - this.bH = this.bI; + this.inventory.j(); + this.bD = this.bE; super.movementTick(); AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); @@ -426,29 +420,21 @@ public abstract class EntityHuman extends EntityLiving { attributeinstance.setValue((double) this.abilities.b()); } - this.aU = this.ca; + this.aO = 0.02F; if (this.isSprinting()) { - this.aU = (float) ((double) this.aU + (double) this.ca * 0.3D); + this.aO = (float) ((double) this.aO + 0.005999999865889549D); } this.o((float) attributeinstance.getValue()); - float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); - float f1 = (float) ( org.bukkit.craftbukkit.TrigMath.atan(-this.motY * 0.20000000298023224D) * 15.0D); // CraftBukkit + float f; - if (f > 0.1F) { - f = 0.1F; - } - - if (!this.onGround || this.getHealth() <= 0.0F || this.isSwimming()) { + if (this.onGround && this.getHealth() > 0.0F && !this.isSwimming()) { + f = Math.min(0.1F, MathHelper.sqrt(b(this.getMot()))); + } else { f = 0.0F; } - if (this.onGround || this.getHealth() <= 0.0F) { - f1 = 0.0F; - } - - this.bI += (f - this.bI) * 0.4F; - this.aN += (f1 - this.aN) * 0.8F; + this.bE += (f - this.bE) * 0.4F; if (this.getHealth() > 0.0F && !this.isSpectator()) { AxisAlignedBB axisalignedbb; @@ -471,7 +457,7 @@ public abstract class EntityHuman extends EntityLiving { this.j(this.getShoulderEntityLeft()); this.j(this.getShoulderEntityRight()); - if (!this.world.isClientSide && (this.fallDistance > 0.5F || this.isInWater() || this.isPassenger()) || this.abilities.isFlying) { + if (!this.world.isClientSide && (this.fallDistance > 0.5F || this.isInWater() || this.isPassenger()) || this.abilities.isFlying || this.isSleeping()) { if (!this.world.paperConfig.parrotsHangOnBetter) this.releaseShoulderEntities(); // Paper - Hang on! } @@ -481,51 +467,45 @@ public abstract class EntityHuman extends EntityLiving { if (nbttagcompound != null && !nbttagcompound.hasKey("Silent") || !nbttagcompound.getBoolean("Silent")) { String s = nbttagcompound.getString("id"); - if (EntityTypes.a(s) == EntityTypes.PARROT) { + EntityTypes.a(s).filter((entitytypes) -> { + return entitytypes == EntityTypes.PARROT; + }).ifPresent((entitytypes) -> { EntityParrot.a(this.world, (Entity) this); - } + }); } } private void c(Entity entity) { - entity.d(this); + entity.pickup(this); } public int getScore() { - return (Integer) this.datawatcher.get(EntityHuman.b); + return (Integer) this.datawatcher.get(EntityHuman.d); } public void setScore(int i) { - this.datawatcher.set(EntityHuman.b, i); + this.datawatcher.set(EntityHuman.d, i); } public void addScore(int i) { int j = this.getScore(); - this.datawatcher.set(EntityHuman.b, j + i); + this.datawatcher.set(EntityHuman.d, j + i); } + @Override public void die(DamageSource damagesource) { super.die(damagesource); - this.setSize(0.2F, 0.2F); this.setPosition(this.locX, this.locY, this.locZ); - this.motY = 0.10000000149011612D; - if ("Notch".equals(this.getDisplayName().getString())) { - this.a(new ItemStack(Items.APPLE), true, false); - } - - if (!this.world.getGameRules().getBoolean("keepInventory") && !this.isSpectator()) { - this.removeCursedItems(); - this.inventory.dropContents(); + if (!this.isSpectator()) { + this.d(damagesource); } if (damagesource != null) { - this.motX = (double) (-MathHelper.cos((this.aD + this.yaw) * 0.017453292F) * 0.1F); - this.motZ = (double) (-MathHelper.sin((this.aD + this.yaw) * 0.017453292F) * 0.1F); + this.setMot((double) (-MathHelper.cos((this.az + this.yaw) * 0.017453292F) * 0.1F), 0.10000000149011612D, (double) (-MathHelper.sin((this.az + this.yaw) * 0.017453292F) * 0.1F)); } else { - this.motX = 0.0D; - this.motZ = 0.0D; + this.setMot(0.0D, 0.1D, 0.0D); } this.a(StatisticList.DEATHS); @@ -535,6 +515,16 @@ public abstract class EntityHuman extends EntityLiving { this.setFlag(0, false); } + @Override + protected void cF() { + super.cF(); + if (!this.world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY)) { + this.removeCursedItems(); + this.inventory.dropContents(); + } + + } + protected void removeCursedItems() { for (int i = 0; i < this.inventory.getSize(); ++i) { ItemStack itemstack = this.inventory.getItem(i); @@ -546,16 +536,18 @@ public abstract class EntityHuman extends EntityLiving { } - protected SoundEffect d(DamageSource damagesource) { - return damagesource == DamageSource.BURN ? SoundEffects.ENTITY_PLAYER_HURT_ON_FIRE : (damagesource == DamageSource.DROWN ? SoundEffects.ENTITY_PLAYER_HURT_DROWN : SoundEffects.ENTITY_PLAYER_HURT); + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return damagesource == DamageSource.BURN ? SoundEffects.ENTITY_PLAYER_HURT_ON_FIRE : (damagesource == DamageSource.DROWN ? SoundEffects.ENTITY_PLAYER_HURT_DROWN : (damagesource == DamageSource.SWEET_BERRY_BUSH ? SoundEffects.ENTITY_PLAYER_HURT_SWEET_BERRY_BUSH : SoundEffects.ENTITY_PLAYER_HURT)); } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_PLAYER_DEATH; } @Nullable - public EntityItem a(boolean flag) { + public EntityItem n(boolean flag) { // Called only when dropped by Q or CTRL-Q return this.a(this.inventory.splitStack(this.inventory.itemInHandIndex, flag && !this.inventory.getItemInHand().isEmpty() ? this.inventory.getItemInHand().getCount() : 1), false, true); } @@ -573,9 +565,9 @@ public abstract class EntityHuman extends EntityLiving { double d0 = this.locY - 0.30000001192092896D + (double) this.getHeadHeight(); EntityItem entityitem = new EntityItem(this.world, this.locX, d0, this.locZ, itemstack); - entityitem.a(40); + entityitem.setPickupDelay(40); if (flag1) { - entityitem.c(this.getUniqueID()); + entityitem.setThrower(this.getUniqueID()); } float f; @@ -584,19 +576,17 @@ public abstract class EntityHuman extends EntityLiving { if (flag) { f = this.random.nextFloat() * 0.5F; f1 = this.random.nextFloat() * 6.2831855F; - entityitem.motX = (double) (-MathHelper.sin(f1) * f); - entityitem.motZ = (double) (MathHelper.cos(f1) * f); - entityitem.motY = 0.20000000298023224D; + this.setMot((double) (-MathHelper.sin(f1) * f), 0.20000000298023224D, (double) (MathHelper.cos(f1) * f)); } else { f = 0.3F; - entityitem.motX = (double) (-MathHelper.sin(this.yaw * 0.017453292F) * MathHelper.cos(this.pitch * 0.017453292F) * f); - entityitem.motZ = (double) (MathHelper.cos(this.yaw * 0.017453292F) * MathHelper.cos(this.pitch * 0.017453292F) * f); - entityitem.motY = (double) (-MathHelper.sin(this.pitch * 0.017453292F) * f + 0.1F); - f1 = this.random.nextFloat() * 6.2831855F; - f = 0.02F * this.random.nextFloat(); - entityitem.motX += Math.cos((double) f1) * (double) f; - entityitem.motY += (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F); - entityitem.motZ += Math.sin((double) f1) * (double) f; + f1 = MathHelper.sin(this.pitch * 0.017453292F); + float f2 = MathHelper.cos(this.pitch * 0.017453292F); + float f3 = MathHelper.sin(this.yaw * 0.017453292F); + float f4 = MathHelper.cos(this.yaw * 0.017453292F); + float f5 = this.random.nextFloat() * 6.2831855F; + float f6 = 0.02F * this.random.nextFloat(); + + entityitem.setMot((double) (-f3 * f2 * 0.3F) + Math.cos((double) f5) * (double) f6, (double) (-f1 * 0.3F + 0.1F + (this.random.nextFloat() - this.random.nextFloat()) * 0.1F), (double) (f4 * f2 * 0.3F) + Math.sin((double) f5) * (double) f6); } // CraftBukkit start - fire PlayerDropItemEvent @@ -627,27 +617,12 @@ public abstract class EntityHuman extends EntityLiving { WorldMap worldmap = ItemWorldMap.getSavedMap(itemstack, this.world); worldmap.updateSeenPlayers(this, itemstack); } - // Paper stop - - ItemStack itemstack1 = this.a(entityitem); - - if (flag1) { - if (!itemstack1.isEmpty()) { - this.a(StatisticList.ITEM_DROPPED.b(itemstack1.getItem()), itemstack.getCount()); - } - - this.a(StatisticList.DROP); - } + // Paper end return entityitem; } } - protected ItemStack a(EntityItem entityitem) { - this.world.addEntity(entityitem); - return entityitem.getItemStack(); - } - public float b(IBlockData iblockdata) { float f = this.inventory.a(iblockdata); @@ -668,18 +643,18 @@ public abstract class EntityHuman extends EntityLiving { float f1; switch (this.getEffect(MobEffects.SLOWER_DIG).getAmplifier()) { - case 0: - f1 = 0.3F; - break; - case 1: - f1 = 0.09F; - break; - case 2: - f1 = 0.0027F; - break; - case 3: - default: - f1 = 8.1E-4F; + case 0: + f1 = 0.3F; + break; + case 1: + f1 = 0.09F; + break; + case 2: + f1 = 0.0027F; + break; + case 3: + default: + f1 = 8.1E-4F; } f *= f1; @@ -700,28 +675,24 @@ public abstract class EntityHuman extends EntityLiving { return iblockdata.getMaterial().isAlwaysDestroyable() || this.inventory.b(iblockdata); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.a(a(this.h)); + this.a(a(this.bW)); NBTTagList nbttaglist = nbttagcompound.getList("Inventory", 10); this.inventory.b(nbttaglist); this.inventory.itemInHandIndex = nbttagcompound.getInt("SelectedItemSlot"); - this.sleeping = nbttagcompound.getBoolean("Sleeping"); this.sleepTicks = nbttagcompound.getShort("SleepTimer"); this.exp = nbttagcompound.getFloat("XpP"); this.expLevel = nbttagcompound.getInt("XpLevel"); this.expTotal = nbttagcompound.getInt("XpTotal"); - this.bZ = nbttagcompound.getInt("XpSeed"); - if (this.bZ == 0) { - this.bZ = this.random.nextInt(); + this.bR = nbttagcompound.getInt("XpSeed"); + if (this.bR == 0) { + this.bR = this.random.nextInt(); } this.setScore(nbttagcompound.getInt("Score")); - if (this.sleeping) { - this.bedPosition = new BlockPosition(this); - this.a(true, true, false); - } // CraftBukkit start this.spawnWorld = nbttagcompound.getString("SpawnWorld"); @@ -731,8 +702,8 @@ public abstract class EntityHuman extends EntityLiving { // CraftBukkit end if (nbttagcompound.hasKeyOfType("SpawnX", 99) && nbttagcompound.hasKeyOfType("SpawnY", 99) && nbttagcompound.hasKeyOfType("SpawnZ", 99)) { - this.e = new BlockPosition(nbttagcompound.getInt("SpawnX"), nbttagcompound.getInt("SpawnY"), nbttagcompound.getInt("SpawnZ")); - this.f = nbttagcompound.getBoolean("SpawnForced"); + this.g = new BlockPosition(nbttagcompound.getInt("SpawnX"), nbttagcompound.getInt("SpawnY"), nbttagcompound.getInt("SpawnZ")); + this.bU = nbttagcompound.getBoolean("SpawnForced"); } this.foodData.a(nbttagcompound); @@ -751,28 +722,28 @@ public abstract class EntityHuman extends EntityLiving { } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setInt("DataVersion", 1631); + nbttagcompound.setInt("DataVersion", SharedConstants.a().getWorldVersion()); nbttagcompound.set("Inventory", this.inventory.a(new NBTTagList())); nbttagcompound.setInt("SelectedItemSlot", this.inventory.itemInHandIndex); - nbttagcompound.setBoolean("Sleeping", this.sleeping); nbttagcompound.setShort("SleepTimer", (short) this.sleepTicks); nbttagcompound.setFloat("XpP", this.exp); nbttagcompound.setInt("XpLevel", this.expLevel); nbttagcompound.setInt("XpTotal", this.expTotal); - nbttagcompound.setInt("XpSeed", this.bZ); + nbttagcompound.setInt("XpSeed", this.bR); nbttagcompound.setInt("Score", this.getScore()); - if (this.e != null) { - nbttagcompound.setInt("SpawnX", this.e.getX()); - nbttagcompound.setInt("SpawnY", this.e.getY()); - nbttagcompound.setInt("SpawnZ", this.e.getZ()); - nbttagcompound.setBoolean("SpawnForced", this.f); + if (this.g != null) { + nbttagcompound.setInt("SpawnX", this.g.getX()); + nbttagcompound.setInt("SpawnY", this.g.getY()); + nbttagcompound.setInt("SpawnZ", this.g.getZ()); + nbttagcompound.setBoolean("SpawnForced", this.bU); } this.foodData.b(nbttagcompound); this.abilities.a(nbttagcompound); - nbttagcompound.set("EnderItems", this.enderChest.i()); + nbttagcompound.set("EnderItems", this.enderChest.f()); if (!this.getShoulderEntityLeft().isEmpty()) { nbttagcompound.set("ShoulderEntityLeft", this.getShoulderEntityLeft()); } @@ -784,20 +755,18 @@ public abstract class EntityHuman extends EntityLiving { } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; } else if (this.abilities.isInvulnerable && !damagesource.ignoresInvulnerability()) { + this.forceExplosionKnockback = true; // SPIGOT-5258 - Make invulnerable players get knockback from explosions return false; } else { this.ticksFarFromPlayer = 0; if (this.getHealth() <= 0.0F) { return false; } else { - if (this.isSleeping() && !this.world.isClientSide) { - this.a(true, true, false); - } - // this.releaseShoulderEntities(); // CraftBukkit - moved down if (damagesource.s()) { if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL) { @@ -824,10 +793,11 @@ public abstract class EntityHuman extends EntityLiving { } } - protected void c(EntityLiving entityliving) { - super.c(entityliving); + @Override + protected void shieldBlock(EntityLiving entityliving) { + super.shieldBlock(entityliving); if (entityliving.getItemInMainHand().getItem() instanceof ItemAxe) { - this.p(true); + this.o(true); } } @@ -858,18 +828,21 @@ public abstract class EntityHuman extends EntityLiving { // CraftBukkit end } + @Override protected void damageArmor(float f) { this.inventory.a(f); } + @Override protected void damageShield(float f) { if (f >= 3.0F && this.activeItem.getItem() == Items.SHIELD) { int i = 1 + MathHelper.d(f); + EnumHand enumhand = this.getRaisedHand(); - this.activeItem.damage(i, this); + this.activeItem.damage(i, this, (entityhuman) -> { + entityhuman.d(enumhand); + }); if (this.activeItem.isEmpty()) { - EnumHand enumhand = this.cU(); - if (enumhand == EnumHand.MAIN_HAND) { this.setSlot(EnumItemSlot.MAINHAND, ItemStack.a); } else { @@ -883,22 +856,8 @@ public abstract class EntityHuman extends EntityLiving { } - public float dk() { - int i = 0; - Iterator iterator = this.inventory.armor.iterator(); - - while (iterator.hasNext()) { - ItemStack itemstack = (ItemStack) iterator.next(); - - if (!itemstack.isEmpty()) { - ++i; - } - } - - return (float) i / (float) this.inventory.armor.size(); - } - // CraftBukkit start + @Override protected boolean damageEntity0(DamageSource damagesource, float f) { // void -> boolean if (true) { return super.damageEntity0(damagesource, f); @@ -940,20 +899,22 @@ public abstract class EntityHuman extends EntityLiving { public void a(TileEntityStructure tileentitystructure) {} - public void openTrade(IMerchant imerchant) {} - - public void openContainer(IInventory iinventory) {} + public void a(TileEntityJigsaw tileentityjigsaw) {} public void openHorseInventory(EntityHorseAbstract entityhorseabstract, IInventory iinventory) {} - public void openTileEntity(ITileEntityContainer itileentitycontainer) {} + public OptionalInt openContainer(@Nullable ITileInventory itileinventory) { + return OptionalInt.empty(); + } - public void a(ItemStack itemstack, EnumHand enumhand) {} + public void openTrade(int i, MerchantRecipeList merchantrecipelist, int j, int k, boolean flag, boolean flag1) {} + + public void openBook(ItemStack itemstack, EnumHand enumhand) {} public EnumInteractionResult a(Entity entity, EnumHand enumhand) { if (this.isSpectator()) { - if (entity instanceof IInventory) { - this.openContainer((IInventory) entity); + if (entity instanceof ITileInventory) { + this.openContainer((ITileInventory) entity); } return EnumInteractionResult.PASS; @@ -987,16 +948,22 @@ public abstract class EntityHuman extends EntityLiving { } } - public double aI() { + @Override + public double aO() { return -0.35D; } // Paper start - public void stopRiding() { stopRiding(false); } - public void stopRiding(boolean suppressCancellation) { - // Paper end + @Override public void stopRiding() { stopRiding(false); } + @Override public void stopRiding(boolean suppressCancellation) { + // Paper end super.stopRiding(suppressCancellation); // Paper - suppress - this.k = 0; + this.j = 0; + } + + @Override + protected boolean isFrozen() { + return super.isFrozen() || this.isSleeping(); } // Paper start - send SoundEffect to everyone who can see fromEntity @@ -1009,7 +976,7 @@ public abstract class EntityHuman extends EntityLiving { // Paper end public void attack(Entity entity) { - if (entity.bk()) { + if (entity.bs()) { if (!entity.t(this)) { float f = (float) this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).getValue(); float f1; @@ -1020,11 +987,11 @@ public abstract class EntityHuman extends EntityLiving { f1 = EnchantmentManager.a(this.getItemInMainHand(), EnumMonsterType.UNDEFINED); } - float f2 = this.r(0.5F); + float f2 = this.s(0.5F); f *= 0.2F + f2 * f2 * 0.8F; f1 *= f2; - this.dH(); + this.dZ(); if (f > 0.0F || f1 > 0.0F) { boolean flag = f2 > 0.9F; boolean flag1 = false; @@ -1032,12 +999,12 @@ public abstract class EntityHuman extends EntityLiving { int i = b0 + EnchantmentManager.b((EntityLiving) this); if (this.isSprinting() && flag) { - sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_KNOCKBACK, this.bV(), 1.0F, 1.0F); // Paper - send while respecting visibility + sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_KNOCKBACK, this.getSoundCategory(), 1.0F, 1.0F); // Paper - send while respecting visibility ++i; flag1 = true; } - boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround && !this.z_() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && entity instanceof EntityLiving; + boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround && !this.isClimbing() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && entity instanceof EntityLiving; flag2 = flag2 && !world.paperConfig.disablePlayerCrits; // Paper flag2 = flag2 && !this.isSprinting(); @@ -1047,9 +1014,9 @@ public abstract class EntityHuman extends EntityLiving { f += f1; boolean flag3 = false; - double d0 = (double) (this.K - this.J); + double d0 = (double) (this.E - this.D); - if (flag && !flag2 && !flag1 && this.onGround && d0 < (double) this.cK()) { + if (flag && !flag2 && !flag1 && this.onGround && d0 < (double) this.db()) { ItemStack itemstack = this.b(EnumHand.MAIN_HAND); if (itemstack.getItem() instanceof ItemSword) { @@ -1076,9 +1043,7 @@ public abstract class EntityHuman extends EntityLiving { } } - double d1 = entity.motX; - double d2 = entity.motY; - double d3 = entity.motZ; + Vec3D vec3d = entity.getMot(); boolean flag5 = entity.damageEntity(DamageSource.playerAttack(this), f); if (flag5) { @@ -1089,8 +1054,7 @@ public abstract class EntityHuman extends EntityLiving { entity.f((double) (-MathHelper.sin(this.yaw * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (MathHelper.cos(this.yaw * 0.017453292F) * (float) i * 0.5F)); } - this.motX *= 0.6D; - this.motZ *= 0.6D; + this.setMot(this.getMot().d(0.6D, 1.0D, 0.6D)); // Paper start - Configuration option to disable automatic sprint interruption if (!world.paperConfig.disableSprintInterruptionOnAttack) { this.setSprinting(false); @@ -1106,7 +1070,7 @@ public abstract class EntityHuman extends EntityLiving { while (iterator.hasNext()) { EntityLiving entityliving = (EntityLiving) iterator.next(); - if (entityliving != this && entityliving != entity && !this.r(entityliving) && (!(entityliving instanceof EntityArmorStand) || !((EntityArmorStand) entityliving).isMarker()) && this.h(entityliving) < 9.0D) { + if (entityliving != this && entityliving != entity && !this.r(entityliving) && (!(entityliving instanceof EntityArmorStand) || !((EntityArmorStand) entityliving).isMarker()) && this.h((Entity) entityliving) < 9.0D) { // CraftBukkit start - Only apply knockback if the damage hits if (entityliving.damageEntity(DamageSource.playerAttack(this).sweep(), f4)) { entityliving.a(this, 0.4F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F))); @@ -1115,15 +1079,15 @@ public abstract class EntityHuman extends EntityLiving { } } - sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_SWEEP, this.bV(), 1.0F, 1.0F); // Paper - send while respecting visibility - this.dl(); + sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_SWEEP, this.getSoundCategory(), 1.0F, 1.0F); // Paper - send while respecting visibility + this.dE(); } if (entity instanceof EntityPlayer && entity.velocityChanged) { // CraftBukkit start - Add Velocity Event boolean cancelled = false; Player player = (Player) entity.getBukkitEntity(); - org.bukkit.util.Vector velocity = new Vector( d1, d2, d3 ); + org.bukkit.util.Vector velocity = CraftVector.toBukkit(vec3d); PlayerVelocityEvent event = new PlayerVelocityEvent(player, velocity.clone()); world.getServer().getPluginManager().callEvent(event); @@ -1137,23 +1101,21 @@ public abstract class EntityHuman extends EntityLiving { if (!cancelled) { ((EntityPlayer) entity).playerConnection.sendPacket(new PacketPlayOutEntityVelocity(entity)); entity.velocityChanged = false; - entity.motX = d1; - entity.motY = d2; - entity.motZ = d3; + entity.setMot(vec3d); } // CraftBukkit end } if (flag2) { - sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_CRIT, this.bV(), 1.0F, 1.0F); // Paper - send while respecting visibility + sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_CRIT, this.getSoundCategory(), 1.0F, 1.0F); // Paper - send while respecting visibility this.a(entity); } if (!flag2 && !flag3) { if (flag) { - sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_STRONG, this.bV(), 1.0F, 1.0F); // Paper - send while respecting visibility + sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_STRONG, this.getSoundCategory(), 1.0F, 1.0F); // Paper - send while respecting visibility } else { - sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_WEAK, this.bV(), 1.0F, 1.0F); // Paper - send while respecting visibility + sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_WEAK, this.getSoundCategory(), 1.0F, 1.0F); // Paper - send while respecting visibility } } @@ -1171,14 +1133,10 @@ public abstract class EntityHuman extends EntityLiving { Object object = entity; if (entity instanceof EntityComplexPart) { - IComplex icomplex = ((EntityComplexPart) entity).owner; - - if (icomplex instanceof EntityLiving) { - object = (EntityLiving) icomplex; - } + object = ((EntityComplexPart) entity).owner; } - if (!itemstack1.isEmpty() && object instanceof EntityLiving) { + if (!this.world.isClientSide && !itemstack1.isEmpty() && object instanceof EntityLiving) { itemstack1.a((EntityLiving) object, this); if (itemstack1.isEmpty()) { this.a(EnumHand.MAIN_HAND, ItemStack.a); @@ -1195,7 +1153,7 @@ public abstract class EntityHuman extends EntityLiving { org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); if (!combustEvent.isCancelled()) { - entity.setOnFire(combustEvent.getDuration()); + entity.setOnFire(combustEvent.getDuration(), false); } // CraftBukkit end } @@ -1203,13 +1161,13 @@ public abstract class EntityHuman extends EntityLiving { if (this.world instanceof WorldServer && f5 > 2.0F) { int k = (int) ((double) f5 * 0.5D); - ((WorldServer) this.world).a(Particles.i, entity.locX, entity.locY + (double) (entity.length * 0.5F), entity.locZ, k, 0.1D, 0.0D, 0.1D, 0.2D); + ((WorldServer) this.world).a(Particles.DAMAGE_INDICATOR, entity.locX, entity.locY + (double) (entity.getHeight() * 0.5F), entity.locZ, k, 0.1D, 0.0D, 0.1D, 0.2D); } } this.applyExhaustion(world.spigotConfig.combatExhaustion); // Spigot - Change to use configurable value } else { - sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_NODAMAGE, this.bV(), 1.0F, 1.0F); // Paper - send while respecting visibility + sendSoundEffect(this, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_ATTACK_NODAMAGE, this.getSoundCategory(), 1.0F, 1.0F); // Paper - send while respecting visibility if (flag4) { entity.extinguish(); } @@ -1225,11 +1183,12 @@ public abstract class EntityHuman extends EntityLiving { } } - protected void d(EntityLiving entityliving) { + @Override + protected void f(EntityLiving entityliving) { this.attack(entityliving); } - public void p(boolean flag) { + public void o(boolean flag) { float f = 0.25F + (float) EnchantmentManager.getDigSpeedEnchantmentLevel(this) * 0.05F; if (flag) { @@ -1237,8 +1196,8 @@ public abstract class EntityHuman extends EntityLiving { } if (this.random.nextFloat() < f) { - this.getCooldownTracker().a(Items.SHIELD, 100); - this.da(); + this.getCooldownTracker().setCooldown(Items.SHIELD, 100); + this.dp(); this.world.broadcastEntityEffect(this, (byte) 30); } @@ -1248,16 +1207,17 @@ public abstract class EntityHuman extends EntityLiving { public void b(Entity entity) {} - public void dl() { + public void dE() { double d0 = (double) (-MathHelper.sin(this.yaw * 0.017453292F)); double d1 = (double) MathHelper.cos(this.yaw * 0.017453292F); if (this.world instanceof WorldServer) { - ((WorldServer) this.world).a(Particles.O, this.locX + d0, this.locY + (double) this.length * 0.5D, this.locZ + d1, 0, d0, 0.0D, d1, 0.0D); + ((WorldServer) this.world).a(Particles.SWEEP_ATTACK, this.locX + d0, this.locY + (double) this.getHeight() * 0.5D, this.locZ + d1, 0, d0, 0.0D, d1, 0.0D); } } + @Override public void die() { super.die(); this.defaultContainer.b(this); @@ -1267,105 +1227,92 @@ public abstract class EntityHuman extends EntityLiving { } - public boolean inBlock() { - return !this.sleeping && super.inBlock(); - } - - public boolean dn() { + public boolean dG() { return false; } public GameProfile getProfile() { - return this.h; + return this.bW; } // CraftBukkit start - moved bed result checks from below into separate method - private EntityHuman.EnumBedResult getBedResult(BlockPosition blockposition, EnumDirection enumdirection) { + private Either getBedResult(BlockPosition blockposition, EnumDirection enumdirection) { if (!this.world.isClientSide) { if (this.isSleeping() || !this.isAlive()) { - return EntityHuman.EnumBedResult.OTHER_PROBLEM; + return Either.left(EntityHuman.EnumBedResult.OTHER_PROBLEM); } // CraftBukkit - moved world and biome check from BlockBed interact handling here if (!world.worldProvider.canRespawn() || world.getBiome(blockposition) == Biomes.NETHER || !this.world.worldProvider.isOverworld()) { - return EntityHuman.EnumBedResult.NOT_POSSIBLE_HERE; + return Either.left(EntityHuman.EnumBedResult.NOT_POSSIBLE_HERE); } - if (this.world.L()) { - return EntityHuman.EnumBedResult.NOT_POSSIBLE_NOW; + if (this.world.J()) { + return Either.left(EntityHuman.EnumBedResult.NOT_POSSIBLE_NOW); } if (!this.a(blockposition, enumdirection)) { - return EntityHuman.EnumBedResult.TOO_FAR_AWAY; + return Either.left(EntityHuman.EnumBedResult.TOO_FAR_AWAY); } - if (!this.u()) { + if (this.b(blockposition, enumdirection)) { + return Either.left(EntityHuman.EnumBedResult.OBSTRUCTED); + } + + if (!this.isCreative()) { double d0 = 8.0D; double d1 = 5.0D; - List list = this.world.a(EntityMonster.class, new AxisAlignedBB((double) blockposition.getX() - 8.0D, (double) blockposition.getY() - 5.0D, (double) blockposition.getZ() - 8.0D, (double) blockposition.getX() + 8.0D, (double) blockposition.getY() + 5.0D, (double) blockposition.getZ() + 8.0D), (Predicate) (new EntityHuman.c(this))); + List list = this.world.a(EntityMonster.class, new AxisAlignedBB((double) blockposition.getX() - 8.0D, (double) blockposition.getY() - 5.0D, (double) blockposition.getZ() - 8.0D, (double) blockposition.getX() + 8.0D, (double) blockposition.getY() + 5.0D, (double) blockposition.getZ() + 8.0D), (entitymonster) -> { + return entitymonster.e(this); + }); if (!list.isEmpty()) { - return EntityHuman.EnumBedResult.NOT_SAFE; + return Either.left(EntityHuman.EnumBedResult.NOT_SAFE); } } } - return EntityHuman.EnumBedResult.OK; + return Either.right(Unit.INSTANCE); } - public EntityHuman.EnumBedResult a(BlockPosition blockposition) { + public Either sleep(BlockPosition blockposition) { // CraftBukkit start - moved checks into separate method above, add force - return this.a(blockposition, false); + return this.sleep(blockposition, false); } - public EntityHuman.EnumBedResult a(BlockPosition blockposition, boolean force) { + public Either sleep(BlockPosition blockposition, boolean force) { EnumDirection enumdirection = (EnumDirection) this.world.getType(blockposition).get(BlockFacingHorizontal.FACING); - EntityHuman.EnumBedResult bedResult = this.getBedResult(blockposition, enumdirection); + Either bedResult = this.getBedResult(blockposition, enumdirection); - if (bedResult == EntityHuman.EnumBedResult.OTHER_PROBLEM) { + if (bedResult.left().orElse(null) == EntityHuman.EnumBedResult.OTHER_PROBLEM) { return bedResult; // return immediately if the result is not bypassable by plugins } if (force) { - bedResult = EnumBedResult.OK; + bedResult = Either.right(Unit.INSTANCE); } if (this.getBukkitEntity() instanceof Player) { bedResult = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBedEnterEvent(this, blockposition, bedResult); - if (bedResult != EntityHuman.EnumBedResult.OK) { + if (bedResult.left().isPresent()) { return bedResult; } } // CraftBukkit end - if (this.isPassenger()) { - this.stopRiding(); - } - - this.releaseShoulderEntities(); - this.a(StatisticList.CUSTOM.b(StatisticList.TIME_SINCE_REST)); - this.setSize(0.2F, 0.2F); - if (this.world.isLoaded(blockposition)) { - float f = 0.5F + (float) enumdirection.getAdjacentX() * 0.4F; - float f1 = 0.5F + (float) enumdirection.getAdjacentZ() * 0.4F; - - this.a(enumdirection); - this.setPosition((double) ((float) blockposition.getX() + f), (double) ((float) blockposition.getY() + 0.6875F), (double) ((float) blockposition.getZ() + f1)); - } else { - this.setPosition((double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.6875F), (double) ((float) blockposition.getZ() + 0.5F)); - } - - this.sleeping = true; + this.e(blockposition); this.sleepTicks = 0; - this.bedPosition = blockposition; - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; - if (!this.world.isClientSide) { - this.world.everyoneSleeping(); + if (this.world instanceof WorldServer) { + ((WorldServer) this.world).everyoneSleeping(); } - return EntityHuman.EnumBedResult.OK; + return Either.right(Unit.INSTANCE); + } + + @Override + public void e(BlockPosition blockposition) { + this.a(StatisticList.CUSTOM.b(StatisticList.TIME_SINCE_REST)); + super.e(blockposition); } private boolean a(BlockPosition blockposition, EnumDirection enumdirection) { @@ -1378,29 +1325,18 @@ public abstract class EntityHuman extends EntityLiving { } } - private void a(EnumDirection enumdirection) { - this.bS = -1.8F * (float) enumdirection.getAdjacentX(); - this.bT = -1.8F * (float) enumdirection.getAdjacentZ(); + private boolean b(BlockPosition blockposition, EnumDirection enumdirection) { + BlockPosition blockposition1 = blockposition.up(); + + return !this.f(blockposition1) || !this.f(blockposition1.shift(enumdirection.opposite())); } - public void a(boolean flag, boolean flag1, boolean flag2) { - this.setSize(0.6F, 1.8F); - IBlockData iblockdata = this.world.getType(this.bedPosition); + public void wakeup(boolean flag, boolean flag1, boolean flag2) { + Optional optional = this.getBedPosition(); - if (this.bedPosition != null && iblockdata.getBlock() instanceof BlockBed) { - this.world.setTypeAndData(this.bedPosition, (IBlockData) iblockdata.set(BlockBed.OCCUPIED, false), 4); - BlockPosition blockposition = BlockBed.a(this.world, this.bedPosition, 0); - - if (blockposition == null) { - blockposition = this.bedPosition.up(); - } - - this.setPosition((double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.1F), (double) ((float) blockposition.getZ() + 0.5F)); - } - - this.sleeping = false; - if (!this.world.isClientSide && flag1) { - this.world.everyoneSleeping(); + super.dy(); + if (this.world instanceof WorldServer && flag1) { + ((WorldServer) this.world).everyoneSleeping(); } // CraftBukkit start - fire PlayerBedLeaveEvent @@ -1408,9 +1344,9 @@ public abstract class EntityHuman extends EntityLiving { Player player = (Player) this.getBukkitEntity(); org.bukkit.block.Block bed; - BlockPosition blockposition = this.bedPosition; + BlockPosition blockposition = optional.orElse(null); if (blockposition != null) { - bed = this.world.getWorld().getBlockAt(blockposition); // Akarin + bed = this.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); } else { bed = this.world.getWorld().getBlockAt(player.getLocation()); } @@ -1423,59 +1359,61 @@ public abstract class EntityHuman extends EntityLiving { this.sleepTicks = flag ? 0 : 100; if (flag2) { - this.setRespawnPosition(this.bedPosition, false); + optional.ifPresent((blockposition) -> { + this.setRespawnPosition(blockposition, false); + }); } } - private boolean p() { - return this.world.getType(this.bedPosition).getBlock() instanceof BlockBed; + @Override + public void dy() { + this.wakeup(true, true, false); } - @Nullable - public static BlockPosition getBed(IBlockAccess iblockaccess, BlockPosition blockposition, boolean flag) { - Block block = iblockaccess.getType(blockposition).getBlock(); + public static Optional getBed(IWorldReader iworldreader, BlockPosition blockposition, boolean flag) { + Block block = iworldreader.getType(blockposition).getBlock(); if (!(block instanceof BlockBed)) { if (!flag) { - return null; + return Optional.empty(); } else { - boolean flag1 = block.a(); - boolean flag2 = iblockaccess.getType(blockposition.up()).getBlock().a(); + boolean flag1 = block.S_(); + boolean flag2 = iworldreader.getType(blockposition.up()).getBlock().S_(); - return flag1 && flag2 ? blockposition : null; + return flag1 && flag2 ? Optional.of(new Vec3D((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.1D, (double) blockposition.getZ() + 0.5D)) : Optional.empty(); } } else { - return BlockBed.a(iblockaccess, blockposition, 0); + return BlockBed.a(EntityTypes.PLAYER, iworldreader, blockposition, 0); } } - public boolean isSleeping() { - return this.sleeping; + public boolean isDeeplySleeping() { + return this.isSleeping() && this.sleepTicks >= 100; } - public boolean isDeeplySleeping() { - return this.sleeping && this.sleepTicks >= 100; + public int dJ() { + return this.sleepTicks; } public void a(IChatBaseComponent ichatbasecomponent, boolean flag) {} public BlockPosition getBed() { - return this.e; + return this.g; } public boolean isRespawnForced() { - return this.f; + return this.bU; } public void setRespawnPosition(BlockPosition blockposition, boolean flag) { if (blockposition != null) { - this.e = blockposition; - this.f = flag; + this.g = blockposition; + this.bU = flag; this.spawnWorld = this.world.worldData.getName(); // CraftBukkit } else { - this.e = null; - this.f = false; + this.g = null; + this.bU = false; this.spawnWorld = ""; // CraftBukkit } @@ -1497,19 +1435,19 @@ public abstract class EntityHuman extends EntityLiving { public void a(Statistic statistic) {} - public int discoverRecipes(Collection collection) { + public int discoverRecipes(Collection> collection) { return 0; } public void a(MinecraftKey[] aminecraftkey) {} - public int undiscoverRecipes(Collection collection) { + public int undiscoverRecipes(Collection> collection) { return 0; } - public void jump() { this.cH(); } // Paper - OBFHELPER - public void cH() { - super.cH(); + @Override + public void jump() { + super.jump(); this.a(StatisticList.JUMP); if (this.isSprinting()) { this.applyExhaustion(world.spigotConfig.jumpSprintExhaustion); // Spigot - Change to use configurable value @@ -1519,29 +1457,34 @@ public abstract class EntityHuman extends EntityLiving { } - public void a(float f, float f1, float f2) { + @Override + public void e(Vec3D vec3d) { double d0 = this.locX; double d1 = this.locY; double d2 = this.locZ; double d3; if (this.isSwimming() && !this.isPassenger()) { - d3 = this.aN().y; + d3 = this.getLookDirection().y; double d4 = d3 < -0.2D ? 0.085D : 0.06D; - if (d3 <= 0.0D || this.bg || !this.world.getType(new BlockPosition(this.locX, this.locY + 1.0D - 0.1D, this.locZ)).s().e()) { - this.motY += (d3 - this.motY) * d4; + if (d3 <= 0.0D || this.jumping || !this.world.getType(new BlockPosition(this.locX, this.locY + 1.0D - 0.1D, this.locZ)).p().isEmpty()) { + Vec3D vec3d1 = this.getMot(); + + this.setMot(vec3d1.add(0.0D, (d3 - vec3d1.y) * d4, 0.0D)); } } if (this.abilities.isFlying && !this.isPassenger()) { - d3 = this.motY; - float f3 = this.aU; + d3 = this.getMot().y; + float f = this.aO; - this.aU = this.abilities.a() * (float) (this.isSprinting() ? 2 : 1); - super.a(f, f1, f2); - this.motY = d3 * 0.6D; - this.aU = f3; + this.aO = this.abilities.a() * (float) (this.isSprinting() ? 2 : 1); + super.e(vec3d); + Vec3D vec3d2 = this.getMot(); + + this.setMot(vec3d2.x, d3 * 0.6D, vec3d2.z); + this.aO = f; this.fallDistance = 0.0F; // CraftBukkit start if (getFlag(7) && !org.bukkit.craftbukkit.event.CraftEventFactory.callToggleGlideEvent(this, false).isCancelled()) { @@ -1549,22 +1492,28 @@ public abstract class EntityHuman extends EntityLiving { } // CraftBukkit end } else { - super.a(f, f1, f2); + super.e(vec3d); } this.checkMovement(this.locX - d0, this.locY - d1, this.locZ - d2); } - public void as() { + @Override + public void ax() { if (this.abilities.isFlying) { this.setSwimming(false); } else { - super.as(); + super.ax(); } } - public float cK() { + protected boolean f(BlockPosition blockposition) { + return !this.world.getType(blockposition).m(this.world, blockposition); + } + + @Override + public float db() { return (float) this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue(); } @@ -1578,7 +1527,7 @@ public abstract class EntityHuman extends EntityLiving { this.a(StatisticList.SWIM_ONE_CM, i); this.applyExhaustion(0.01F * (float) i * 0.01F); } - } else if (this.a(TagsFluid.WATER)) { + } else if (this.a(TagsFluid.WATER, true)) { i = Math.round(MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2) * 100.0F); if (i > 0) { this.a(StatisticList.WALK_UNDER_WATER_ONE_CM, i); @@ -1590,7 +1539,7 @@ public abstract class EntityHuman extends EntityLiving { this.a(StatisticList.WALK_ON_WATER_ONE_CM, i); this.applyExhaustion(world.spigotConfig.swimMultiplier * (float) i * 0.01F); // Spigot } - } else if (this.z_()) { + } else if (this.isClimbing()) { if (d1 > 0.0D) { this.a(StatisticList.CLIMB_ONE_CM, (int) Math.round(d1 * 100.0D)); } @@ -1608,7 +1557,7 @@ public abstract class EntityHuman extends EntityLiving { this.applyExhaustion(world.spigotConfig.otherMultiplier * (float) i * 0.01F); // Spigot } } - } else if (this.dc()) { + } else if (this.isGliding()) { i = Math.round(MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2) * 100.0F); this.a(StatisticList.AVIATE_ONE_CM, i); } else { @@ -1621,7 +1570,7 @@ public abstract class EntityHuman extends EntityLiving { } } - private void l(double d0, double d1, double d2) { + private void m(double d0, double d1, double d2) { if (this.isPassenger()) { int i = Math.round(MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2) * 100.0F); @@ -1640,34 +1589,39 @@ public abstract class EntityHuman extends EntityLiving { } - public void c(float f, float f1) { + @Override + public void b(float f, float f1) { if (!this.abilities.canFly) { if (f >= 2.0F) { this.a(StatisticList.FALL_ONE_CM, (int) Math.round((double) f * 100.0D)); } - super.c(f, f1); + super.b(f, f1); } } - protected void au() { + @Override + protected void az() { if (!this.isSpectator()) { - super.au(); + super.az(); } } - protected SoundEffect m(int i) { + @Override + protected SoundEffect getSoundFall(int i) { return i > 4 ? SoundEffects.ENTITY_PLAYER_BIG_FALL : SoundEffects.ENTITY_PLAYER_SMALL_FALL; } + @Override public void b(EntityLiving entityliving) { - this.b(StatisticList.ENTITY_KILLED.b(entityliving.P())); + this.b(StatisticList.ENTITY_KILLED.b(entityliving.getEntityType())); } - public void bh() { + @Override + public void a(IBlockData iblockdata, Vec3D vec3d) { if (!this.abilities.isFlying) { - super.bh(); + super.a(iblockdata, vec3d); } } @@ -1697,8 +1651,8 @@ public abstract class EntityHuman extends EntityLiving { } - public int du() { - return this.bZ; + public int dM() { + return this.bR; } public void enchantDone(ItemStack itemstack, int i) { @@ -1709,7 +1663,7 @@ public abstract class EntityHuman extends EntityLiving { this.expTotal = 0; } - this.bZ = this.random.nextInt(); + this.bR = this.random.nextInt(); } public void levelDown(int i) { @@ -1720,11 +1674,11 @@ public abstract class EntityHuman extends EntityLiving { this.expTotal = 0; } - if (i > 0 && this.expLevel % 5 == 0 && (float) this.g < (float) this.ticksLived - 100.0F) { + if (i > 0 && this.expLevel % 5 == 0 && (float) this.bV < (float) this.ticksLived - 100.0F) { float f = this.expLevel > 30 ? 1.0F : (float) this.expLevel / 30.0F; - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_LEVELUP, this.bV(), f * 0.75F, 1.0F); - this.g = this.ticksLived; + this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_LEVELUP, this.getSoundCategory(), f * 0.75F, 1.0F); + this.bV = this.ticksLived; } } @@ -1746,15 +1700,15 @@ public abstract class EntityHuman extends EntityLiving { return this.foodData; } - public boolean q(boolean flag) { + public boolean p(boolean flag) { return !this.abilities.isInvulnerable && (flag || this.foodData.c()); } - public boolean dx() { + public boolean dP() { return this.getHealth() > 0.0F && this.getHealth() < this.getMaxHealth(); } - public boolean dy() { + public boolean dQ() { return this.abilities.mayBuild; } @@ -1765,12 +1719,13 @@ public abstract class EntityHuman extends EntityLiving { BlockPosition blockposition1 = blockposition.shift(enumdirection.opposite()); ShapeDetectorBlock shapedetectorblock = new ShapeDetectorBlock(this.world, blockposition1, false); - return itemstack.b(this.world.F(), shapedetectorblock); + return itemstack.b(this.world.t(), shapedetectorblock); } } + @Override protected int getExpValue(EntityHuman entityhuman) { - if (!this.world.getGameRules().getBoolean("keepInventory") && !this.isSpectator()) { + if (!this.world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY) && !this.isSpectator()) { int i = this.expLevel * 7; return i > 100 ? 100 : i; @@ -1779,10 +1734,12 @@ public abstract class EntityHuman extends EntityLiving { } } + @Override protected boolean alwaysGivesExp() { return true; } + @Override protected boolean playStepSound() { return !this.abilities.isFlying; } @@ -1791,18 +1748,21 @@ public abstract class EntityHuman extends EntityLiving { public void a(EnumGamemode enumgamemode) {} + @Override public IChatBaseComponent getDisplayName() { - return new ChatComponentText(this.h.getName()); + return new ChatComponentText(this.bW.getName()); } public InventoryEnderChest getEnderChest() { return this.enderChest; } + @Override public ItemStack getEquipment(EnumItemSlot enumitemslot) { return enumitemslot == EnumItemSlot.MAINHAND ? this.inventory.getItemInHand() : (enumitemslot == EnumItemSlot.OFFHAND ? (ItemStack) this.inventory.extraSlots.get(0) : (enumitemslot.a() == EnumItemSlot.Function.ARMOR ? (ItemStack) this.inventory.armor.get(enumitemslot.b()) : ItemStack.a)); } + @Override public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) { if (enumitemslot == EnumItemSlot.MAINHAND) { this.b(itemstack); @@ -1817,15 +1777,17 @@ public abstract class EntityHuman extends EntityLiving { } - public boolean d(ItemStack itemstack) { + public boolean g(ItemStack itemstack) { this.b(itemstack); return this.inventory.pickup(itemstack); } - public Iterable aS() { - return Lists.newArrayList(new ItemStack[] { this.getItemInMainHand(), this.getItemInOffHand()}); + @Override + public Iterable aZ() { + return Lists.newArrayList(new ItemStack[]{this.getItemInMainHand(), this.getItemInOffHand()}); } + @Override public Iterable getArmorItems() { return this.inventory.armor; } @@ -1834,9 +1796,11 @@ public abstract class EntityHuman extends EntityLiving { if (!this.isPassenger() && this.onGround && !this.isInWater()) { if (this.getShoulderEntityLeft().isEmpty()) { this.setShoulderEntityLeft(nbttagcompound); + this.e = this.world.getTime(); return true; } else if (this.getShoulderEntityRight().isEmpty()) { this.setShoulderEntityRight(nbttagcompound); + this.e = this.world.getTime(); return true; } else { return false; @@ -1847,15 +1811,19 @@ public abstract class EntityHuman extends EntityLiving { } protected void releaseShoulderEntities() { - // CraftBukkit start - if (this.spawnEntityFromShoulder(this.getShoulderEntityLeft())) { - this.setShoulderEntityLeft(new NBTTagCompound()); + if (this.e + 20L < this.world.getTime()) { + // CraftBukkit start + if (this.spawnEntityFromShoulder(this.getShoulderEntityLeft())) { + this.setShoulderEntityLeft(new NBTTagCompound()); + } + if (this.spawnEntityFromShoulder(this.getShoulderEntityRight())) { + this.setShoulderEntityRight(new NBTTagCompound()); + } + // CraftBukkit end } - if (this.spawnEntityFromShoulder(this.getShoulderEntityRight())) { - this.setShoulderEntityRight(new NBTTagCompound()); - } - // CraftBukkit end + } + // Paper start public Entity releaseLeftShoulderEntity() { Entity entity = this.spawnEntityFromShoulder0(this.getShoulderEntityLeft()); @@ -1872,42 +1840,41 @@ public abstract class EntityHuman extends EntityLiving { } return entity; } - - // Paper - incase any plugins used NMS to call this... old method signature to avoid other diff - private boolean spawnEntityFromShoulder(@Nullable NBTTagCompound nbttagcompound) { + // Paper - maintain old signature + private boolean spawnEntityFromShoulder(NBTTagCompound nbttagcompound) { // CraftBukkit void->boolean return spawnEntityFromShoulder0(nbttagcompound) != null; } - // Paper - Moved to new method that now returns entity, and properly null checks - private Entity spawnEntityFromShoulder0(@Nullable NBTTagCompound nbttagcompound) { // CraftBukkit void->boolean - Paper - return Entity - if (!this.world.isClientSide && nbttagcompound != null && !nbttagcompound.isEmpty()) { // Paper - null check - Entity entity = EntityTypes.a(nbttagcompound, this.world); - if (entity == null) { // Paper - null check - return null; - } - if (entity instanceof EntityTameableAnimal) { - ((EntityTameableAnimal) entity).setOwnerUUID(this.uniqueID); - } + // Paper - return entity + private Entity spawnEntityFromShoulder0(@Nullable NBTTagCompound nbttagcompound) { + if (!this.world.isClientSide && nbttagcompound != null && !nbttagcompound.isEmpty()) { + return EntityTypes.a(nbttagcompound, this.world).map((entity) -> { // CraftBukkit + if (entity instanceof EntityTameableAnimal) { + ((EntityTameableAnimal) entity).setOwnerUUID(this.uniqueID); + } - entity.setPosition(this.locX, this.locY + 0.699999988079071D, this.locZ); - if (this.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY)) { // CraftBukkit - return entity; - } + entity.setPosition(this.locX, this.locY + 0.699999988079071D, this.locZ); + boolean addedToWorld = ((WorldServer) this.world).addEntitySerialized(entity, CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY); // CraftBukkit + return addedToWorld ? entity : null; + }).orElse(null); // CraftBukkit // Paper - false -> null } - return null; + return null; // Paper - return null } // Paper end + @Override public abstract boolean isSpectator(); + @Override public boolean isSwimming() { return !this.abilities.isFlying && !this.isSpectator() && super.isSwimming(); } - public abstract boolean u(); + public abstract boolean isCreative(); - public boolean bw() { + @Override + public boolean bE() { return !this.abilities.isFlying; } @@ -1915,54 +1882,56 @@ public abstract class EntityHuman extends EntityLiving { return this.world.getScoreboard(); } + @Override public IChatBaseComponent getScoreboardDisplayName() { IChatBaseComponent ichatbasecomponent = ScoreboardTeam.a(this.getScoreboardTeam(), this.getDisplayName()); return this.c(ichatbasecomponent); } - public IChatBaseComponent dC() { - return (new ChatComponentText("")).addSibling(this.getDisplayName()).a(" (").a(this.h.getId().toString()).a(")"); + public IChatBaseComponent dU() { + return (new ChatComponentText("")).addSibling(this.getDisplayName()).a(" (").a(this.bW.getId().toString()).a(")"); } private IChatBaseComponent c(IChatBaseComponent ichatbasecomponent) { String s = this.getProfile().getName(); return ichatbasecomponent.a((chatmodifier) -> { - chatmodifier.setChatClickable(new ChatClickable(ChatClickable.EnumClickAction.SUGGEST_COMMAND, "/tell " + s + " ")).setChatHoverable(this.bC()).setInsertion(s); + chatmodifier.setChatClickable(new ChatClickable(ChatClickable.EnumClickAction.SUGGEST_COMMAND, "/tell " + s + " ")).setChatHoverable(this.bK()).setInsertion(s); }); } + @Override public String getName() { return this.getProfile().getName(); } - public float getHeadHeight() { - float f = 1.62F; - - if (this.isSleeping()) { - f = 0.2F; - } else if (!this.isSwimming() && !this.dc() && this.length != 0.6F) { - if (this.isSneaking() || this.length == 1.65F) { - f -= 0.08F; - } - } else { - f = 0.4F; + @Override + public float b(EntityPose entitypose, EntitySize entitysize) { + switch (entitypose) { + case SWIMMING: + case FALL_FLYING: + case SPIN_ATTACK: + return 0.4F; + case SNEAKING: + return 1.27F; + default: + return 1.62F; } - - return f; } + @Override public void setAbsorptionHearts(float f) { if (f < 0.0F) { f = 0.0F; } - this.getDataWatcher().set(EntityHuman.a, f); + this.getDataWatcher().set(EntityHuman.c, f); } + @Override public float getAbsorptionHearts() { - return (Float) this.getDataWatcher().get(EntityHuman.a); + return (Float) this.getDataWatcher().get(EntityHuman.c); } public static UUID a(GameProfile gameprofile) { @@ -1979,17 +1948,8 @@ public abstract class EntityHuman extends EntityLiving { return UUID.nameUUIDFromBytes(("OfflinePlayer:" + s).getBytes(StandardCharsets.UTF_8)); } - public boolean a(ChestLock chestlock) { - if (chestlock.a()) { - return true; - } else { - ItemStack itemstack = this.getItemInMainHand(); - - return !itemstack.isEmpty() && itemstack.hasName() ? itemstack.getName().getString().equals(chestlock.getKey()) : false; - } - } - - public boolean c(int i, ItemStack itemstack) { + @Override + public boolean a_(int i, ItemStack itemstack) { if (i >= 0 && i < this.inventory.items.size()) { this.inventory.setItem(i, itemstack); return true; @@ -2029,7 +1989,7 @@ public abstract class EntityHuman extends EntityLiving { if (enumitemslot != EnumItemSlot.HEAD) { return false; } - } else if (EntityInsentient.e(itemstack) != enumitemslot) { + } else if (EntityInsentient.h(itemstack) != enumitemslot) { return false; } } @@ -2040,101 +2000,137 @@ public abstract class EntityHuman extends EntityLiving { } } + @Override public EnumMainHand getMainHand() { - return (Byte) this.datawatcher.get(EntityHuman.by) == 0 ? EnumMainHand.LEFT : EnumMainHand.RIGHT; + return (Byte) this.datawatcher.get(EntityHuman.bu) == 0 ? EnumMainHand.LEFT : EnumMainHand.RIGHT; } public void a(EnumMainHand enummainhand) { - this.datawatcher.set(EntityHuman.by, (byte) (enummainhand == EnumMainHand.LEFT ? 0 : 1)); + this.datawatcher.set(EntityHuman.bu, (byte) (enummainhand == EnumMainHand.LEFT ? 0 : 1)); } public NBTTagCompound getShoulderEntityLeft() { - return (NBTTagCompound) this.datawatcher.get(EntityHuman.bz); + return (NBTTagCompound) this.datawatcher.get(EntityHuman.bv); } public void setShoulderEntityLeft(NBTTagCompound nbttagcompound) { - this.datawatcher.set(EntityHuman.bz, nbttagcompound); + this.datawatcher.set(EntityHuman.bv, nbttagcompound); } public NBTTagCompound getShoulderEntityRight() { - return (NBTTagCompound) this.datawatcher.get(EntityHuman.bA); + return (NBTTagCompound) this.datawatcher.get(EntityHuman.bw); } public void setShoulderEntityRight(NBTTagCompound nbttagcompound) { - this.datawatcher.set(EntityHuman.bA, nbttagcompound); + this.datawatcher.set(EntityHuman.bw, nbttagcompound); } - public float getCooldownPeriod() { return dG(); } // Paper - OBFHELPER - public float dG() { - return (float) (1.0D / this.getAttributeInstance(GenericAttributes.g).getValue() * 20.0D); + public float getCooldownPeriod() { return this.dY(); } // Paper - OBFHELPER + public float dY() { + return (float) (1.0D / this.getAttributeInstance(GenericAttributes.ATTACK_SPEED).getValue() * 20.0D); } - public float getCooledAttackStrength(float adjustTicks) { return r(adjustTicks); } // Paper - OBFHELPER - public float r(float f) { - return MathHelper.a(((float) this.aH + f) / this.dG(), 0.0F, 1.0F); + public float getCooledAttackStrength(float adjustTicks) { return s(adjustTicks); } // Paper - OBFHELPER + public float s(float f) { + return MathHelper.a(((float) this.aD + f) / this.dY(), 0.0F, 1.0F); } - public void resetCooldown() { dH(); } // Paper - OBFHELPER - public void dH() { - this.aH = 0; + public void resetCooldown() { this.dZ(); } // Paper - OBFHELPER + public void dZ() { + this.aD = 0; } public ItemCooldown getCooldownTracker() { - return this.ce; + return this.bZ; } - public void collide(Entity entity) { - if (!this.isSleeping()) { - super.collide(entity); - } - - } - - public float dJ() { - return (float) this.getAttributeInstance(GenericAttributes.j).getValue(); + public float eb() { + return (float) this.getAttributeInstance(GenericAttributes.LUCK).getValue(); } public boolean isCreativeAndOp() { return this.abilities.canInstantlyBuild && this.y() >= 2; } - static class c implements Predicate { + @Override + public boolean e(ItemStack itemstack) { + EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); - private final EntityHuman a; + return this.getEquipment(enumitemslot).isEmpty(); + } - private c(EntityHuman entityhuman) { - this.a = entityhuman; + @Override + public EntitySize a(EntityPose entitypose) { + return (EntitySize) EntityHuman.b.getOrDefault(entitypose, EntityHuman.bs); + } + + // Paper start + protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack) { + return !(this instanceof EntityPlayer) || + new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent( + ((EntityPlayer) this).getBukkitEntity(), + org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow), + org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack) + ).callEvent(); + // Paper end + } + + @Override + public ItemStack f(ItemStack itemstack) { + if (!(itemstack.getItem() instanceof ItemProjectileWeapon)) { + return ItemStack.a; + } else { + Predicate predicate = ((ItemProjectileWeapon) itemstack.getItem()).d(); + ItemStack itemstack1 = ItemProjectileWeapon.a((EntityLiving) this, predicate); + + if (!itemstack1.isEmpty()) { + return itemstack1; + } else { + predicate = ((ItemProjectileWeapon) itemstack.getItem()).b(); + + for (int i = 0; i < this.inventory.getSize(); ++i) { + ItemStack itemstack2 = this.inventory.getItem(i); + + if (predicate.test(itemstack2) && tryReadyArrow(itemstack, itemstack2)) { // Paper + return itemstack2; + } + } + + return this.abilities.canInstantlyBuild ? new ItemStack(Items.ARROW) : ItemStack.a; + } + } + } + + @Override + public ItemStack a(World world, ItemStack itemstack) { + this.getFoodData().a(itemstack.getItem(), itemstack); + this.b(StatisticList.ITEM_USED.b(itemstack.getItem())); + world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PLAYER_BURP, SoundCategory.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); + if (this instanceof EntityPlayer) { + CriterionTriggers.z.a((EntityPlayer) this, itemstack); } - public boolean test(@Nullable EntityMonster entitymonster) { - return entitymonster.c(this.a); - } + return super.a(world, itemstack); } public static enum EnumBedResult { - OK, NOT_POSSIBLE_HERE, NOT_POSSIBLE_NOW, TOO_FAR_AWAY, OTHER_PROBLEM, NOT_SAFE; + NOT_POSSIBLE_HERE, NOT_POSSIBLE_NOW(new ChatMessage("block.minecraft.bed.no_sleep", new Object[0])), TOO_FAR_AWAY(new ChatMessage("block.minecraft.bed.too_far_away", new Object[0])), OBSTRUCTED(new ChatMessage("block.minecraft.bed.obstructed", new Object[0])), OTHER_PROBLEM, NOT_SAFE(new ChatMessage("block.minecraft.bed.not_safe", new Object[0])); - private EnumBedResult() {} - } + @Nullable + private final IChatBaseComponent g; - public static enum EnumChatVisibility { - - FULL(0, "options.chat.visibility.full"), SYSTEM(1, "options.chat.visibility.system"), HIDDEN(2, "options.chat.visibility.hidden"); - - private static final EntityHuman.EnumChatVisibility[] d = (EntityHuman.EnumChatVisibility[]) Arrays.stream(values()).sorted(Comparator.comparingInt(EntityHuman.EnumChatVisibility::a)).toArray((i) -> { - return new EntityHuman.EnumChatVisibility[i]; - }); - private final int e; - private final String f; - - private EnumChatVisibility(int i, String s) { - this.e = i; - this.f = s; + private EnumBedResult() { + this.g = null; } - public int a() { - return this.e; + private EnumBedResult(IChatBaseComponent ichatbasecomponent) { + this.g = ichatbasecomponent; + } + + @Nullable + public IChatBaseComponent a() { + return this.g; } } } diff --git a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java index e1cf43f24..cc37b5ff1 100644 --- a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java +++ b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java @@ -4,24 +4,24 @@ import javax.annotation.Nullable; public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRangedEntity { - private int c; - private final Vec3D[][] bC; + private int bz; + private final Vec3D[][] bA; - public EntityIllagerIllusioner(World world) { - super(EntityTypes.ILLUSIONER, world); - this.setSize(0.6F, 1.95F); - this.b_ = 5; - this.bC = new Vec3D[2][4]; + public EntityIllagerIllusioner(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.f = 5; + this.bA = new Vec3D[2][4]; for (int i = 0; i < 4; ++i) { - this.bC[0][i] = new Vec3D(0.0D, 0.0D, 0.0D); - this.bC[1][i] = new Vec3D(0.0D, 0.0D, 0.0D); + this.bA[0][i] = new Vec3D(0.0D, 0.0D, 0.0D); + this.bA[1][i] = new Vec3D(0.0D, 0.0D, 0.0D); } } - protected void n() { - super.n(); + @Override + protected void initPathfinder() { + super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); this.goalSelector.a(1, new EntityIllagerWizard.b()); this.goalSelector.a(4, new EntityIllagerIllusioner.b()); @@ -30,99 +30,110 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[] { EntityIllagerIllusioner.class})); - this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).b(300)); - this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)).b(300)); - this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)).b(300)); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error + this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300)); + this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300)); + this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, false)).a(300)); } + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.5D); this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(18.0D); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(32.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(32.0D); } - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.BOW)); - return super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } - protected void x_() { - super.x_(); - } - - protected MinecraftKey getDefaultLootTable() { - return LootTables.a; + @Override + protected void initDatawatcher() { + super.initDatawatcher(); } + @Override public void movementTick() { super.movementTick(); if (this.world.isClientSide && this.isInvisible()) { - --this.c; - if (this.c < 0) { - this.c = 0; + --this.bz; + if (this.bz < 0) { + this.bz = 0; } if (this.hurtTicks != 1 && this.ticksLived % 1200 != 0) { - if (this.hurtTicks == this.aC - 1) { - this.c = 3; + if (this.hurtTicks == this.hurtDuration - 1) { + this.bz = 3; for (int i = 0; i < 4; ++i) { - this.bC[0][i] = this.bC[1][i]; - this.bC[1][i] = new Vec3D(0.0D, 0.0D, 0.0D); + this.bA[0][i] = this.bA[1][i]; + this.bA[1][i] = new Vec3D(0.0D, 0.0D, 0.0D); } } } else { - this.c = 3; + this.bz = 3; float f = -6.0F; boolean flag = true; int j; for (j = 0; j < 4; ++j) { - this.bC[0][j] = this.bC[1][j]; - this.bC[1][j] = new Vec3D((double) (-6.0F + (float) this.random.nextInt(13)) * 0.5D, (double) Math.max(0, this.random.nextInt(6) - 4), (double) (-6.0F + (float) this.random.nextInt(13)) * 0.5D); + this.bA[0][j] = this.bA[1][j]; + this.bA[1][j] = new Vec3D((double) (-6.0F + (float) this.random.nextInt(13)) * 0.5D, (double) Math.max(0, this.random.nextInt(6) - 4), (double) (-6.0F + (float) this.random.nextInt(13)) * 0.5D); } - // Akarin start - this handle by client - /* for (j = 0; j < 16; ++j) { - this.world.addParticle(Particles.g, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D); + this.world.addParticle(Particles.CLOUD, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.getWidth(), this.locY + this.random.nextDouble() * (double) this.getHeight(), this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.getWidth(), 0.0D, 0.0D, 0.0D); } - */ - // Akarin end - this.world.a(this.locX, this.locY, this.locZ, SoundEffects.ENTITY_ILLUSIONER_MIRROR_MOVE, this.bV(), 1.0F, 1.0F, false); + this.world.a(this.locX, this.locY, this.locZ, SoundEffects.ENTITY_ILLUSIONER_MIRROR_MOVE, this.getSoundCategory(), 1.0F, 1.0F, false); } } } + @Override + public SoundEffect dV() { + return SoundEffects.ENTITY_ILLUSIONER_AMBIENT; + } + + @Override public boolean r(Entity entity) { return super.r(entity) ? true : (entity instanceof EntityLiving && ((EntityLiving) entity).getMonsterType() == EnumMonsterType.ILLAGER ? this.getScoreboardTeam() == null && entity.getScoreboardTeam() == null : false); } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_ILLUSIONER_AMBIENT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_ILLUSIONER_DEATH; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_ILLUSIONER_HURT; } - protected SoundEffect dz() { + @Override + protected SoundEffect getSoundCastSpell() { return SoundEffects.ENTITY_ILLUSIONER_CAST_SPELL; } + @Override + public void a(int i, boolean flag) {} + + @Override public void a(EntityLiving entityliving, float f) { - EntityArrow entityarrow = this.v(f); + ItemStack itemstack = this.f(this.b(ProjectileHelper.a(this, Items.BOW))); + EntityArrow entityarrow = ProjectileHelper.a(this, itemstack, f); double d0 = entityliving.locX - this.locX; - double d1 = entityliving.getBoundingBox().minY + (double) (entityliving.length / 3.0F) - entityarrow.locY; + double d1 = entityliving.getBoundingBox().minY + (double) (entityliving.getHeight() / 3.0F) - entityarrow.locY; double d2 = entityliving.locZ - this.locZ; double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2); @@ -141,17 +152,6 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan // Paper end } - protected EntityArrow v(float f) { - EntityTippedArrow entitytippedarrow = new EntityTippedArrow(this.world, this); - - entitytippedarrow.a((EntityLiving) this, f); - return entitytippedarrow; - } - - public void s(boolean flag) { - this.a(1, flag); - } - class a extends EntityIllagerWizard.c { private int e; @@ -160,31 +160,38 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan super(); } + @Override public boolean a() { return !super.a() ? false : (EntityIllagerIllusioner.this.getGoalTarget() == null ? false : (EntityIllagerIllusioner.this.getGoalTarget().getId() == this.e ? false : EntityIllagerIllusioner.this.world.getDamageScaler(new BlockPosition(EntityIllagerIllusioner.this)).a((float) EnumDifficulty.NORMAL.ordinal()))); } + @Override public void c() { super.c(); this.e = EntityIllagerIllusioner.this.getGoalTarget().getId(); } + @Override protected int g() { return 20; } - protected int i() { + @Override + protected int h() { return 180; } + @Override protected void j() { EntityIllagerIllusioner.this.getGoalTarget().addEffect(new MobEffect(MobEffects.BLINDNESS, 400), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit } + @Override protected SoundEffect k() { return SoundEffects.ENTITY_ILLUSIONER_PREPARE_BLINDNESS; } + @Override protected EntityIllagerWizard.Spell l() { return EntityIllagerWizard.Spell.BLINDNESS; } @@ -196,27 +203,33 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan super(); } + @Override public boolean a() { return !super.a() ? false : !EntityIllagerIllusioner.this.hasEffect(MobEffects.INVISIBILITY); } + @Override protected int g() { return 20; } - protected int i() { + @Override + protected int h() { return 340; } + @Override protected void j() { EntityIllagerIllusioner.this.addEffect(new MobEffect(MobEffects.INVISIBILITY, 1200), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ILLUSION); // CraftBukkit } @Nullable + @Override protected SoundEffect k() { return SoundEffects.ENTITY_ILLUSIONER_PREPARE_MIRROR; } + @Override protected EntityIllagerWizard.Spell l() { return EntityIllagerWizard.Spell.DISAPPEAR; } diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java index 9b6e96464..d00e99cdb 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -2,7 +2,6 @@ package net.minecraft.server; import com.google.common.collect.Maps; import java.util.Arrays; -import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -24,63 +23,71 @@ import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason; public abstract class EntityInsentient extends EntityLiving { - private static final DataWatcherObject a = DataWatcher.a(EntityInsentient.class, DataWatcherRegistry.a); - public int a_; - protected int b_; + private static final DataWatcherObject b = DataWatcher.a(EntityInsentient.class, DataWatcherRegistry.a); + public int e; + protected int f; protected ControllerLook lookController; protected ControllerMove moveController; - protected ControllerJump h; - private final EntityAIBodyControl b; + protected ControllerJump bt; + private final EntityAIBodyControl c; protected NavigationAbstract navigation; public PathfinderGoalSelector goalSelector; @Nullable public PathfinderGoalFloat goalFloat; // Paper public PathfinderGoalSelector targetSelector; private EntityLiving goalTarget; - private final EntitySenses bC; - private final NonNullList bD; - public float[] dropChanceHand; - private final NonNullList bE; - public float[] dropChanceArmor; - // public boolean canPickUpLoot; // CraftBukkit - moved up to EntityLiving + private final EntitySenses bz; + private final NonNullList bA; + public final float[] dropChanceHand; + private final NonNullList bB; + public final float[] dropChanceArmor; + // private boolean canPickUpLoot; // CraftBukkit - moved up to EntityLiving public boolean persistent; - private final Map bH; + private final Map bE; public MinecraftKey lootTableKey; public long lootTableSeed; - private boolean bK; + @Nullable private Entity leashHolder; - private NBTTagCompound bM; + private int bI; + @Nullable + private NBTTagCompound bJ; + private BlockPosition bK; + private float bL; - protected EntityInsentient(EntityTypes entitytypes, World world) { + protected EntityInsentient(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.bD = NonNullList.a(2, ItemStack.a); + this.bA = NonNullList.a(2, ItemStack.a); this.dropChanceHand = new float[2]; - this.bE = NonNullList.a(4, ItemStack.a); + this.bB = NonNullList.a(4, ItemStack.a); this.dropChanceArmor = new float[4]; - this.bH = Maps.newEnumMap(PathType.class); - this.goalSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null); - this.targetSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null); + this.bE = Maps.newEnumMap(PathType.class); + this.bK = BlockPosition.ZERO; + this.bL = -1.0F; + this.goalSelector = new PathfinderGoalSelector(world != null && world.getMethodProfiler() != null ? world.getMethodProfiler() : null); + this.targetSelector = new PathfinderGoalSelector(world != null && world.getMethodProfiler() != null ? world.getMethodProfiler() : null); this.lookController = new ControllerLook(this); this.moveController = new ControllerMove(this); - this.h = new ControllerJump(this); - this.b = this.o(); + this.bt = new ControllerJump(this); + this.c = this.o(); this.navigation = this.b(world); - this.bC = new EntitySenses(this); + this.bz = new EntitySenses(this); Arrays.fill(this.dropChanceArmor, 0.085F); Arrays.fill(this.dropChanceHand, 0.085F); if (world != null && !world.isClientSide) { - this.n(); + this.initPathfinder(); } // CraftBukkit start - default persistance to type's persistance value - this.persistent = !isTypeNotPersistent(); + this.persistent = !isTypeNotPersistent(0); // CraftBukkit end } - protected void n() {} + protected void initPathfinder() {} + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(16.0D); + this.getAttributeMap().b(GenericAttributes.ATTACK_KNOCKBACK); } protected NavigationAbstract b(World world) { @@ -88,13 +95,13 @@ public abstract class EntityInsentient extends EntityLiving { } public float a(PathType pathtype) { - Float ofloat = (Float) this.bH.get(pathtype); + Float ofloat = (Float) this.bE.get(pathtype); return ofloat == null ? pathtype.a() : ofloat; } public void a(PathType pathtype, float f) { - this.bH.put(pathtype, f); + this.bE.put(pathtype, f); } protected EntityAIBodyControl o() { @@ -105,31 +112,32 @@ public abstract class EntityInsentient extends EntityLiving { return this.lookController; } - // Paper start - @Override - public void inactiveTick() { - super.inactiveTick(); - this.goalSelector.inactiveTick(); - if (this.targetSelector.inactiveTick()) { - this.targetSelector.doTick(); - } - } - // Paper end - public ControllerMove getControllerMove() { - return this.moveController; + if (this.isPassenger() && this.getVehicle() instanceof EntityInsentient) { + EntityInsentient entityinsentient = (EntityInsentient) this.getVehicle(); + + return entityinsentient.getControllerMove(); + } else { + return this.moveController; + } } public ControllerJump getControllerJump() { - return this.h; + return this.bt; } public NavigationAbstract getNavigation() { - return this.navigation; + if (this.isPassenger() && this.getVehicle() instanceof EntityInsentient) { + EntityInsentient entityinsentient = (EntityInsentient) this.getVehicle(); + + return entityinsentient.getNavigation(); + } else { + return this.navigation; + } } public EntitySenses getEntitySenses() { - return this.bC; + return this.bz; } @Nullable @@ -173,71 +181,76 @@ public abstract class EntityInsentient extends EntityLiving { // CraftBukkit end } - public boolean b(Class oclass) { - return oclass != EntityGhast.class; + @Override + public boolean a(EntityTypes entitytypes) { + return entitytypes != EntityTypes.GHAST; } - public void x() {} + public void blockEaten() {} - protected void x_() { - super.x_(); - this.datawatcher.register(EntityInsentient.a, (byte) 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityInsentient.b, (byte) 0); } - public int z() { + public int A() { return 80; } - public void A() { - SoundEffect soundeffect = this.D(); + public void B() { + SoundEffect soundeffect = this.getSoundAmbient(); if (soundeffect != null) { - this.a(soundeffect, this.cD(), this.cE()); + this.a(soundeffect, this.getSoundVolume(), this.cV()); } } - public void W() { - super.W(); - //this.world.methodProfiler.enter("mobBaseTick"); // Akarin - remove caller - if (this.isAlive() && this.random.nextInt(1000) < this.a_++) { + @Override + public void entityBaseTick() { + super.entityBaseTick(); + this.world.getMethodProfiler().enter("mobBaseTick"); + if (this.isAlive() && this.random.nextInt(1000) < this.e++) { this.l(); - this.A(); + this.B(); } - //this.world.methodProfiler.exit(); // Akarin - remove caller + this.world.getMethodProfiler().exit(); } + @Override protected void c(DamageSource damagesource) { this.l(); super.c(damagesource); } private void l() { - this.a_ = -this.z(); + this.e = -this.A(); } + @Override protected int getExpValue(EntityHuman entityhuman) { - if (this.b_ > 0) { - int i = this.b_; + if (this.f > 0) { + int i = this.f; int j; - for (j = 0; j < this.bE.size(); ++j) { - if (!((ItemStack) this.bE.get(j)).isEmpty() && this.dropChanceArmor[j] <= 1.0F) { + for (j = 0; j < this.bB.size(); ++j) { + if (!((ItemStack) this.bB.get(j)).isEmpty() && this.dropChanceArmor[j] <= 1.0F) { i += 1 + this.random.nextInt(3); } } - for (j = 0; j < this.bD.size(); ++j) { - if (!((ItemStack) this.bD.get(j)).isEmpty() && this.dropChanceHand[j] <= 1.0F) { + for (j = 0; j < this.bA.size(); ++j) { + if (!((ItemStack) this.bA.get(j)).isEmpty() && this.dropChanceHand[j] <= 1.0F) { i += 1 + this.random.nextInt(3); } } return i; } else { - return this.b_; + return this.f; } } @@ -249,7 +262,7 @@ public abstract class EntityInsentient extends EntityLiving { double d2 = this.random.nextGaussian() * 0.02D; double d3 = 10.0D; - this.world.addParticle(Particles.J, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d0 * 10.0D, this.locY + (double) (this.random.nextFloat() * this.length) - d1 * 10.0D, this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width - d2 * 10.0D, d0, d1, d2); + this.world.addParticle(Particles.POOF, this.locX + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth() - d0 * 10.0D, this.locY + (double) (this.random.nextFloat() * this.getHeight()) - d1 * 10.0D, this.locZ + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth() - d2 * 10.0D, d0, d1, d2); } } else { this.world.broadcastEntityEffect(this, (byte) 20); @@ -257,64 +270,48 @@ public abstract class EntityInsentient extends EntityLiving { } + @Override public void tick() { super.tick(); - if (isTypeNotPersistent() && hasBeenCounted == this.isPersistent()) ((com.destroystokyo.paper.PaperWorldEntityList) this.world.entityList).updateEntityCount(this, hasBeenCounted ? -1 : 1); // Paper - adjust count if persistence state changes if (!this.world.isClientSide) { - this.dl(); + this.dM(); if (this.ticksLived % 5 == 0) { - boolean flag = !(this.bO() instanceof EntityInsentient); - boolean flag1 = !(this.getVehicle() instanceof EntityBoat); - - this.goalSelector.a(1, flag); - this.goalSelector.a(4, flag && flag1); - this.goalSelector.a(2, flag); + this.F(); } } } + protected void F() { + boolean flag = !(this.getRidingPassenger() instanceof EntityInsentient); + boolean flag1 = !(this.getVehicle() instanceof EntityBoat); + + this.goalSelector.a(PathfinderGoal.Type.MOVE, flag); + this.goalSelector.a(PathfinderGoal.Type.JUMP, flag && flag1); + this.goalSelector.a(PathfinderGoal.Type.LOOK, flag); + } + + @Override protected float e(float f, float f1) { - this.b.a(); + this.c.a(); return f1; } @Nullable - protected SoundEffect D() { + protected SoundEffect getSoundAmbient() { return null; } - @Nullable - protected Item getLoot() { - return null; - } - - protected void dropDeathLoot(boolean flag, int i) { - Item item = this.getLoot(); - - if (item != null) { - int j = this.random.nextInt(3); - - if (i > 0) { - j += this.random.nextInt(i + 1); - } - - for (int k = 0; k < j; ++k) { - this.a((IMaterial) item); - } - } - - } - + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setBoolean("CanPickUpLoot", this.dj()); + nbttagcompound.setBoolean("CanPickUpLoot", this.canPickupLoot()); nbttagcompound.setBoolean("PersistenceRequired", this.persistent); NBTTagList nbttaglist = new NBTTagList(); NBTTagCompound nbttagcompound1; - for (Iterator iterator = this.bE.iterator(); iterator.hasNext(); nbttaglist.add((NBTBase) nbttagcompound1)) { + for (Iterator iterator = this.bB.iterator(); iterator.hasNext(); nbttaglist.add(nbttagcompound1)) { ItemStack itemstack = (ItemStack) iterator.next(); nbttagcompound1 = new NBTTagCompound(); @@ -328,7 +325,7 @@ public abstract class EntityInsentient extends EntityLiving { NBTTagCompound nbttagcompound2; - for (Iterator iterator1 = this.bD.iterator(); iterator1.hasNext(); nbttaglist1.add((NBTBase) nbttagcompound2)) { + for (Iterator iterator1 = this.bA.iterator(); iterator1.hasNext(); nbttaglist1.add(nbttagcompound2)) { ItemStack itemstack1 = (ItemStack) iterator1.next(); nbttagcompound2 = new NBTTagCompound(); @@ -347,7 +344,7 @@ public abstract class EntityInsentient extends EntityLiving { for (j = 0; j < i; ++j) { float f = afloat[j]; - nbttaglist2.add((NBTBase) (new NBTTagFloat(f))); + nbttaglist2.add(new NBTTagFloat(f)); } nbttagcompound.set("ArmorDropChances", nbttaglist2); @@ -359,11 +356,10 @@ public abstract class EntityInsentient extends EntityLiving { for (int k = 0; k < j; ++k) { float f1 = afloat1[k]; - nbttaglist3.add((NBTBase) (new NBTTagFloat(f1))); + nbttaglist3.add(new NBTTagFloat(f1)); } nbttagcompound.set("HandDropChances", nbttaglist3); - nbttagcompound.setBoolean("Leashed", this.bK); if (this.leashHolder != null) { nbttagcompound2 = new NBTTagCompound(); if (this.leashHolder instanceof EntityLiving) { @@ -395,6 +391,7 @@ public abstract class EntityInsentient extends EntityLiving { } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); @@ -402,7 +399,7 @@ public abstract class EntityInsentient extends EntityLiving { if (nbttagcompound.hasKeyOfType("CanPickUpLoot", 1)) { boolean data = nbttagcompound.getBoolean("CanPickUpLoot"); if (isLevelAtLeast(nbttagcompound, 1) || data) { - this.p(data); + this.setCanPickupLoot(data); } } @@ -417,16 +414,16 @@ public abstract class EntityInsentient extends EntityLiving { if (nbttagcompound.hasKeyOfType("ArmorItems", 9)) { nbttaglist = nbttagcompound.getList("ArmorItems", 10); - for (i = 0; i < this.bE.size(); ++i) { - this.bE.set(i, ItemStack.a(nbttaglist.getCompound(i))); + for (i = 0; i < this.bB.size(); ++i) { + this.bB.set(i, ItemStack.a(nbttaglist.getCompound(i))); } } if (nbttagcompound.hasKeyOfType("HandItems", 9)) { nbttaglist = nbttagcompound.getList("HandItems", 10); - for (i = 0; i < this.bD.size(); ++i) { - this.bD.set(i, ItemStack.a(nbttaglist.getCompound(i))); + for (i = 0; i < this.bA.size(); ++i) { + this.bA.set(i, ItemStack.a(nbttaglist.getCompound(i))); } } @@ -434,7 +431,7 @@ public abstract class EntityInsentient extends EntityLiving { nbttaglist = nbttagcompound.getList("ArmorDropChances", 5); for (i = 0; i < nbttaglist.size(); ++i) { - this.dropChanceArmor[i] = nbttaglist.l(i); + this.dropChanceArmor[i] = nbttaglist.i(i); } } @@ -442,16 +439,15 @@ public abstract class EntityInsentient extends EntityLiving { nbttaglist = nbttagcompound.getList("HandDropChances", 5); for (i = 0; i < nbttaglist.size(); ++i) { - this.dropChanceHand[i] = nbttaglist.l(i); + this.dropChanceHand[i] = nbttaglist.i(i); } } - this.bK = nbttagcompound.getBoolean("Leashed"); - if (this.bK && nbttagcompound.hasKeyOfType("Leash", 10)) { - this.bM = nbttagcompound.getCompound("Leash"); + if (nbttagcompound.hasKeyOfType("Leash", 10)) { + this.bJ = nbttagcompound.getCompound("Leash"); } - this.r(nbttagcompound.getBoolean("LeftHanded")); + this.p(nbttagcompound.getBoolean("LeftHanded")); if (nbttagcompound.hasKeyOfType("DeathLootTable", 8)) { this.lootTableKey = new MinecraftKey(nbttagcompound.getString("DeathLootTable")); this.lootTableSeed = nbttagcompound.getLong("DeathLootTableSeed"); @@ -460,9 +456,10 @@ public abstract class EntityInsentient extends EntityLiving { this.setNoAI(nbttagcompound.getBoolean("NoAI")); } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return null; + @Override + protected void a(DamageSource damagesource, boolean flag) { + super.a(damagesource, flag); + this.lootTableKey = null; } // CraftBukkit - start public MinecraftKey getLootTable() { @@ -470,60 +467,43 @@ public abstract class EntityInsentient extends EntityLiving { } // CraftBukkit - end - protected void a(boolean flag, int i, DamageSource damagesource) { - MinecraftKey minecraftkey = this.lootTableKey; + @Override + protected LootTableInfo.Builder a(boolean flag, DamageSource damagesource) { + return super.a(flag, damagesource).a(this.lootTableSeed, this.random); + } - if (minecraftkey == null) { - minecraftkey = this.getDefaultLootTable(); - } - - if (minecraftkey != null) { - LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(minecraftkey); - - this.lootTableKey = null; - LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).entity(this).damageSource(damagesource).position(new BlockPosition(this)); - - if (flag && this.killer != null) { - loottableinfo_builder = loottableinfo_builder.killer(this.killer).luck(this.killer.dJ()); - } - - Collection collection = loottable.populateLoot(this.lootTableSeed == 0L ? this.random : new Random(this.lootTableSeed), loottableinfo_builder.build()); - Iterator iterator = collection.iterator(); - - while (iterator.hasNext()) { - ItemStack itemstack = (ItemStack) iterator.next(); - - this.a_(itemstack); - } - - this.dropEquipment(flag, i); - } else { - super.a(flag, i, damagesource); - } + @Override + public final MinecraftKey cG() { + return this.lootTableKey == null ? this.getDefaultLootTable() : this.lootTableKey; + } + protected MinecraftKey getDefaultLootTable() { + return super.cG(); } public void r(float f) { - this.bj = f; + this.bd = f; } public void s(float f) { - this.bi = f; + this.bc = f; } public void t(float f) { - this.bh = f; + this.bb = f; } + @Override public void o(float f) { super.o(f); this.r(f); } + @Override public void movementTick() { super.movementTick(); - //this.world.methodProfiler.enter("looting"); // Akarin - remove caller - if (!this.world.isClientSide && this.dj() && !this.killed && this.world.getGameRules().getBoolean("mobGriefing")) { + this.world.getMethodProfiler().enter("looting"); + if (!this.world.isClientSide && this.canPickupLoot() && this.isAlive() && !this.killed && this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { List list = this.world.a(EntityItem.class, this.getBoundingBox().grow(1.0D, 0.0D, 1.0D)); Iterator iterator = list.iterator(); @@ -541,39 +521,35 @@ public abstract class EntityInsentient extends EntityLiving { } } - //this.world.methodProfiler.exit(); // Akarin - remove caller + this.world.getMethodProfiler().exit(); } protected void a(EntityItem entityitem) { ItemStack itemstack = entityitem.getItemStack(); - EnumItemSlot enumitemslot = e(itemstack); + EnumItemSlot enumitemslot = h(itemstack); ItemStack itemstack1 = this.getEquipment(enumitemslot); boolean flag = this.a(itemstack, itemstack1, enumitemslot); // CraftBukkit start - boolean canPickup = flag && this.d(itemstack); - - EntityPickupItemEvent entityEvent = new EntityPickupItemEvent((LivingEntity) getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity(), 0); - entityEvent.setCancelled(!canPickup); - this.world.getServer().getPluginManager().callEvent(entityEvent); - canPickup = !entityEvent.isCancelled(); + boolean canPickup = flag && this.g(itemstack); + canPickup = !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entityitem, 0, !canPickup).isCancelled(); if (canPickup) { // CraftBukkit end - double d0 = (double) this.c(enumitemslot); + double d0 = (double) this.d(enumitemslot); if (!itemstack1.isEmpty() && (double) (this.random.nextFloat() - 0.1F) < d0) { this.forceDrops = true; // CraftBukkit - this.a_(itemstack1); + this.a(itemstack1); this.forceDrops = false; // CraftBukkit } this.setSlot(enumitemslot, itemstack); switch (enumitemslot.a()) { - case HAND: - this.dropChanceHand[enumitemslot.b()] = 2.0F; - break; - case ARMOR: - this.dropChanceArmor[enumitemslot.b()] = 2.0F; + case HAND: + this.dropChanceHand[enumitemslot.b()] = 2.0F; + break; + case ARMOR: + this.dropChanceArmor[enumitemslot.b()] = 2.0F; } this.persistent = true; @@ -623,47 +599,47 @@ public abstract class EntityInsentient extends EntityLiving { return flag; } - protected boolean d(ItemStack itemstack) { + protected boolean g(ItemStack itemstack) { return true; } - public boolean isTypeNotPersistent() { + public boolean isTypeNotPersistent(double d0) { return true; } - protected void I() { - if (this.persistent) { - this.ticksFarFromPlayer = 0; - } else { - Chunk currentChunk = getChunkAtLocation(); // Paper - if (currentChunk != null && currentChunk.scheduledForUnload != null) return; // Paper + public boolean I() { + return false; + } + + protected void checkDespawn() { + if (!this.isPersistent() && !this.I()) { EntityHuman entityhuman = this.world.findNearbyPlayer(this, -1.0D); if (entityhuman != null && entityhuman.affectsSpawning) { // Paper - Affects Spawning API - double d0 = entityhuman.locX - this.locX; - double d1 = entityhuman.locY - this.locY; - double d2 = entityhuman.locZ - this.locZ; - double d3 = d0 * d0 + d1 * d1 + d2 * d2; + double d0 = entityhuman.h(this); - if (d3 > world.paperConfig.hardDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances + if (d0 > world.paperConfig.hardDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances this.die(); } - if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d3 > world.paperConfig.softDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances + if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d0 > world.paperConfig.softDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // Paper - custom despawn distances this.die(); - } else if (d3 < world.paperConfig.softDespawnDistance) { // Paper - custom despawn distances + } else if (d0 < 1024.0D) { this.ticksFarFromPlayer = 0; } } + } else { + this.ticksFarFromPlayer = 0; } } + @Override protected final void doTick() { ++this.ticksFarFromPlayer; - //this.world.methodProfiler.enter("checkDespawn"); // Akarin - remove caller - this.I(); - //this.world.methodProfiler.exit(); // Akarin - remove caller + this.world.getMethodProfiler().enter("checkDespawn"); + this.checkDespawn(); + this.world.getMethodProfiler().exit(); // Spigot Start if ( this.fromMobSpawner ) { @@ -676,46 +652,48 @@ public abstract class EntityInsentient extends EntityLiving { return; } // Spigot End - //this.world.methodProfiler.enter("sensing"); // Akarin - remove caller - this.bC.a(); - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.enter("targetSelector"); // Akarin - remove caller + this.world.getMethodProfiler().enter("sensing"); + this.bz.a(); + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("targetSelector"); this.targetSelector.doTick(); - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.enter("goalSelector"); // Akarin - remove caller + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("goalSelector"); this.goalSelector.doTick(); - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.enter("navigation"); // Akarin - remove caller - this.navigation.d(); - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.enter("mob tick"); // Akarin - remove caller + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("navigation"); + this.navigation.c(); + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("mob tick"); this.mobTick(); - //this.world.methodProfiler.exit(); // Akarin - remove caller - if (this.isPassenger() && this.getVehicle() instanceof EntityInsentient) { - EntityInsentient entityinsentient = (EntityInsentient) this.getVehicle(); - - entityinsentient.getNavigation().a(this.getNavigation().m(), 1.5D); - entityinsentient.getControllerMove().a(this.getControllerMove()); - } - - //this.world.methodProfiler.enter("controls"); // Akarin - remove caller - //this.world.methodProfiler.enter("move"); // Akarin - remove caller + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("controls"); + this.world.getMethodProfiler().enter("move"); this.moveController.a(); - //this.world.methodProfiler.exitEnter("look"); // Akarin - remove caller + this.world.getMethodProfiler().exitEnter("look"); this.lookController.a(); - //this.world.methodProfiler.exitEnter("jump"); // Akarin - remove caller - this.h.b(); - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.exit(); // Akarin - remove caller + this.world.getMethodProfiler().exitEnter("jump"); + this.bt.b(); + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().exit(); + this.K(); + } + + protected void K() { + PacketDebug.a(this.world, this, this.goalSelector); } protected void mobTick() {} - public int K() { + public int M() { return 40; } - public int L() { + public int dA() { + return 75; + } + + public int dB() { return 10; } @@ -733,14 +711,14 @@ public abstract class EntityInsentient extends EntityLiving { } double d3 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1); - float f2 = (float) (MathHelper.c(d1, d0) * 57.2957763671875D) - 90.0F; - float f3 = (float) (-(MathHelper.c(d2, d3) * 57.2957763671875D)); + float f2 = (float) (MathHelper.d(d1, d0) * 57.2957763671875D) - 90.0F; + float f3 = (float) (-(MathHelper.d(d2, d3) * 57.2957763671875D)); - this.pitch = this.c(this.pitch, f3, f1); - this.yaw = this.c(this.yaw, f2, f); + this.pitch = this.a(this.pitch, f3, f1); + this.yaw = this.a(this.yaw, f2, f); } - private float c(float f, float f1, float f2) { + private float a(float f, float f1, float f2) { float f3 = MathHelper.g(f1 - f); if (f3 > f2) { @@ -754,24 +732,21 @@ public abstract class EntityInsentient extends EntityLiving { return f + f3; } - public boolean canSpawnHere() { return a((GeneratorAccess) this.world, false); } // Akarin - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - IBlockData iblockdata = generatoraccess.getType((new BlockPosition(this)).down()); + public static boolean a(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + BlockPosition blockposition1 = blockposition.down(); - return iblockdata.a((Entity) this); + return enummobspawn == EnumMobSpawn.SPAWNER || generatoraccess.getType(blockposition1).a((IBlockAccess) generatoraccess, blockposition1, entitytypes); } - public final boolean canSpawn() { - return this.a((IWorldReader) this.world); + public boolean a(GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn) { + return true; } - public boolean isNotColliding(IWorldReader iworldreader) { return a(iworldreader); } // Akarin public boolean a(IWorldReader iworldreader) { - return !iworldreader.containsLiquid(this.getBoundingBox()) && iworldreader.getCubes(this, this.getBoundingBox()) && iworldreader.a_(this, this.getBoundingBox()); + return !iworldreader.containsLiquid(this.getBoundingBox()) && iworldreader.i(this); } - public int maxPackSize() { return dg(); } // Akarin - public int dg() { + public int dC() { return 4; } @@ -779,7 +754,8 @@ public abstract class EntityInsentient extends EntityLiving { return false; } - public int bn() { + @Override + public int bv() { if (this.getGoalTarget() == null) { return 3; } else { @@ -794,44 +770,50 @@ public abstract class EntityInsentient extends EntityLiving { } } - public Iterable aS() { - return this.bD; + @Override + public Iterable aZ() { + return this.bA; } + @Override public Iterable getArmorItems() { - return this.bE; + return this.bB; } + @Override public ItemStack getEquipment(EnumItemSlot enumitemslot) { switch (enumitemslot.a()) { - case HAND: - return (ItemStack) this.bD.get(enumitemslot.b()); - case ARMOR: - return (ItemStack) this.bE.get(enumitemslot.b()); - default: - return ItemStack.a; + case HAND: + return (ItemStack) this.bA.get(enumitemslot.b()); + case ARMOR: + return (ItemStack) this.bB.get(enumitemslot.b()); + default: + return ItemStack.a; } } + @Override public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) { switch (enumitemslot.a()) { - case HAND: - this.bD.set(enumitemslot.b(), itemstack); - break; - case ARMOR: - this.bE.set(enumitemslot.b(), itemstack); + case HAND: + this.bA.set(enumitemslot.b(), itemstack); + break; + case ARMOR: + this.bB.set(enumitemslot.b(), itemstack); } } - protected void dropEquipment(boolean flag, int i) { + @Override + protected void dropDeathLoot(DamageSource damagesource, int i, boolean flag) { + super.dropDeathLoot(damagesource, i, flag); EnumItemSlot[] aenumitemslot = EnumItemSlot.values(); int j = aenumitemslot.length; for (int k = 0; k < j; ++k) { EnumItemSlot enumitemslot = aenumitemslot[k]; ItemStack itemstack = this.getEquipment(enumitemslot); - float f = this.c(enumitemslot); + float f = this.d(enumitemslot); boolean flag1 = f > 1.0F; if (!itemstack.isEmpty() && !EnchantmentManager.shouldNotDrop(itemstack) && (flag || flag1) && this.random.nextFloat() - (float) i * 0.01F < f) { @@ -839,24 +821,24 @@ public abstract class EntityInsentient extends EntityLiving { itemstack.setDamage(itemstack.h() - this.random.nextInt(1 + this.random.nextInt(Math.max(itemstack.h() - 3, 1)))); } - this.a_(itemstack); + this.a(itemstack); } } } - protected float c(EnumItemSlot enumitemslot) { + protected float d(EnumItemSlot enumitemslot) { float f; switch (enumitemslot.a()) { - case HAND: - f = this.dropChanceHand[enumitemslot.b()]; - break; - case ARMOR: - f = this.dropChanceArmor[enumitemslot.b()]; - break; - default: - f = 0.0F; + case HAND: + f = this.dropChanceHand[enumitemslot.b()]; + break; + case ARMOR: + f = this.dropChanceArmor[enumitemslot.b()]; + break; + default: + f = 0.0F; } return f; @@ -907,7 +889,7 @@ public abstract class EntityInsentient extends EntityLiving { } - public static EnumItemSlot e(ItemStack itemstack) { + public static EnumItemSlot h(ItemStack itemstack) { Item item = itemstack.getItem(); return item != Blocks.CARVED_PUMPKIN.getItem() && (!(item instanceof ItemBlock) || !(((ItemBlock) item).getBlock() instanceof BlockSkullAbstract)) ? (item instanceof ItemArmor ? ((ItemArmor) item).b() : (item == Items.ELYTRA ? EnumItemSlot.CHEST : (item == Items.SHIELD ? EnumItemSlot.OFFHAND : EnumItemSlot.MAINHAND))) : EnumItemSlot.HEAD; @@ -916,56 +898,56 @@ public abstract class EntityInsentient extends EntityLiving { @Nullable public static Item a(EnumItemSlot enumitemslot, int i) { switch (enumitemslot) { - case HEAD: - if (i == 0) { - return Items.LEATHER_HELMET; - } else if (i == 1) { - return Items.GOLDEN_HELMET; - } else if (i == 2) { - return Items.CHAINMAIL_HELMET; - } else if (i == 3) { - return Items.IRON_HELMET; - } else if (i == 4) { - return Items.DIAMOND_HELMET; - } - case CHEST: - if (i == 0) { - return Items.LEATHER_CHESTPLATE; - } else if (i == 1) { - return Items.GOLDEN_CHESTPLATE; - } else if (i == 2) { - return Items.CHAINMAIL_CHESTPLATE; - } else if (i == 3) { - return Items.IRON_CHESTPLATE; - } else if (i == 4) { - return Items.DIAMOND_CHESTPLATE; - } - case LEGS: - if (i == 0) { - return Items.LEATHER_LEGGINGS; - } else if (i == 1) { - return Items.GOLDEN_LEGGINGS; - } else if (i == 2) { - return Items.CHAINMAIL_LEGGINGS; - } else if (i == 3) { - return Items.IRON_LEGGINGS; - } else if (i == 4) { - return Items.DIAMOND_LEGGINGS; - } - case FEET: - if (i == 0) { - return Items.LEATHER_BOOTS; - } else if (i == 1) { - return Items.GOLDEN_BOOTS; - } else if (i == 2) { - return Items.CHAINMAIL_BOOTS; - } else if (i == 3) { - return Items.IRON_BOOTS; - } else if (i == 4) { - return Items.DIAMOND_BOOTS; - } - default: - return null; + case HEAD: + if (i == 0) { + return Items.LEATHER_HELMET; + } else if (i == 1) { + return Items.GOLDEN_HELMET; + } else if (i == 2) { + return Items.CHAINMAIL_HELMET; + } else if (i == 3) { + return Items.IRON_HELMET; + } else if (i == 4) { + return Items.DIAMOND_HELMET; + } + case CHEST: + if (i == 0) { + return Items.LEATHER_CHESTPLATE; + } else if (i == 1) { + return Items.GOLDEN_CHESTPLATE; + } else if (i == 2) { + return Items.CHAINMAIL_CHESTPLATE; + } else if (i == 3) { + return Items.IRON_CHESTPLATE; + } else if (i == 4) { + return Items.DIAMOND_CHESTPLATE; + } + case LEGS: + if (i == 0) { + return Items.LEATHER_LEGGINGS; + } else if (i == 1) { + return Items.GOLDEN_LEGGINGS; + } else if (i == 2) { + return Items.CHAINMAIL_LEGGINGS; + } else if (i == 3) { + return Items.IRON_LEGGINGS; + } else if (i == 4) { + return Items.DIAMOND_LEGGINGS; + } + case FEET: + if (i == 0) { + return Items.LEATHER_BOOTS; + } else if (i == 1) { + return Items.GOLDEN_BOOTS; + } else if (i == 2) { + return Items.CHAINMAIL_BOOTS; + } else if (i == 3) { + return Items.IRON_BOOTS; + } else if (i == 4) { + return Items.DIAMOND_BOOTS; + } + default: + return null; } } @@ -994,50 +976,60 @@ public abstract class EntityInsentient extends EntityLiving { } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).b(new AttributeModifier("Random spawn bonus", this.random.nextGaussian() * 0.05D, 1)); + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random spawn bonus", this.random.nextGaussian() * 0.05D, AttributeModifier.Operation.MULTIPLY_BASE)); if (this.random.nextFloat() < 0.05F) { - this.r(true); + this.p(true); } else { - this.r(false); + this.p(false); } return groupdataentity; } - public boolean dh() { + public boolean dD() { return false; } - public void di() { + public void setPersistent() { this.persistent = true; } public void a(EnumItemSlot enumitemslot, float f) { switch (enumitemslot.a()) { - case HAND: - this.dropChanceHand[enumitemslot.b()] = f; - break; - case ARMOR: - this.dropChanceArmor[enumitemslot.b()] = f; + case HAND: + this.dropChanceHand[enumitemslot.b()] = f; + break; + case ARMOR: + this.dropChanceArmor[enumitemslot.b()] = f; } } - public boolean dj() { + public boolean canPickupLoot() { return this.canPickUpLoot; } - public void p(boolean flag) { + public void setCanPickupLoot(boolean flag) { this.canPickUpLoot = flag; } + @Override + public boolean e(ItemStack itemstack) { + EnumItemSlot enumitemslot = h(itemstack); + + return this.getEquipment(enumitemslot).isEmpty() && this.canPickupLoot(); + } + public boolean isPersistent() { return this.persistent; } + @Override public final boolean b(EntityHuman entityhuman, EnumHand enumhand) { - if (this.isLeashed() && this.getLeashHolder() == entityhuman) { + if (!this.isAlive()) { + return false; + } else if (this.getLeashHolder() == entityhuman) { // CraftBukkit start - fire PlayerUnleashEntityEvent if (CraftEventFactory.callPlayerUnleashEntityEvent(this, entityhuman).isCancelled()) { ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(this, this.getLeashHolder())); @@ -1069,27 +1061,52 @@ public abstract class EntityInsentient extends EntityLiving { return false; } - protected void dl() { - if (this.bM != null) { - this.dr(); + public boolean dH() { + return this.a(new BlockPosition(this)); + } + + public boolean a(BlockPosition blockposition) { + return this.bL == -1.0F ? true : this.bK.m(blockposition) < (double) (this.bL * this.bL); + } + + public void a(BlockPosition blockposition, int i) { + this.bK = blockposition; + this.bL = (float) i; + } + + public BlockPosition dI() { + return this.bK; + } + + public float dJ() { + return this.bL; + } + + public boolean dL() { + return this.bL != -1.0F; + } + + protected void dM() { + if (this.bJ != null) { + this.dT(); } - if (this.bK) { - if (!this.isAlive()) { - this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.PLAYER_UNLEASH)); // CraftBukkit + if (this.leashHolder != null) { + if (!this.isAlive() || !this.leashHolder.isAlive()) { + this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), (!this.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE)); // CraftBukkit this.unleash(true, true); } - if (this.leashHolder == null || this.leashHolder.dead) { - this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.HOLDER_GONE)); // CraftBukkit - this.unleash(true, true); - } } } public void unleash(boolean flag, boolean flag1) { - if (this.bK) { - this.bK = false; + if (this.leashHolder != null) { + this.attachedToPlayer = false; + if (!(this.leashHolder instanceof EntityHuman)) { + this.leashHolder.attachedToPlayer = false; + } + this.leashHolder = null; if (!this.world.isClientSide && flag1) { this.forceDrops = true; // CraftBukkit @@ -1098,7 +1115,7 @@ public abstract class EntityInsentient extends EntityLiving { } if (!this.world.isClientSide && flag && this.world instanceof WorldServer) { - ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutAttachEntity(this, (Entity) null))); + ((WorldServer) this.world).getChunkProvider().broadcast(this, new PacketPlayOutAttachEntity(this, (Entity) null)); } } @@ -1109,18 +1126,27 @@ public abstract class EntityInsentient extends EntityLiving { } public boolean isLeashed() { - return this.bK; + return this.leashHolder != null; } + @Nullable public Entity getLeashHolder() { + if (this.leashHolder == null && this.bI != 0 && this.world.isClientSide) { + this.leashHolder = this.world.getEntity(this.bI); + } + return this.leashHolder; } public void setLeashHolder(Entity entity, boolean flag) { - this.bK = true; this.leashHolder = entity; + this.attachedToPlayer = true; + if (!(this.leashHolder instanceof EntityHuman)) { + this.leashHolder.attachedToPlayer = true; + } + if (!this.world.isClientSide && flag && this.world instanceof WorldServer) { - ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutAttachEntity(this, this.leashHolder))); + ((WorldServer) this.world).getChunkProvider().broadcast(this, new PacketPlayOutAttachEntity(this, this.leashHolder)); } if (this.isPassenger()) { @@ -1129,6 +1155,7 @@ public abstract class EntityInsentient extends EntityLiving { } + @Override public boolean a(Entity entity, boolean flag) { boolean flag1 = super.a(entity, flag); @@ -1139,40 +1166,31 @@ public abstract class EntityInsentient extends EntityLiving { return flag1; } - private void dr() { - if (this.bK && this.bM != null) { - if (this.bM.b("UUID")) { - UUID uuid = this.bM.a("UUID"); - List list = this.world.a(EntityLiving.class, this.getBoundingBox().g(10.0D)); - Iterator iterator = list.iterator(); + private void dT() { + if (this.bJ != null && this.world instanceof WorldServer) { + if (this.bJ.b("UUID")) { + UUID uuid = this.bJ.a("UUID"); + Entity entity = ((WorldServer) this.world).getEntity(uuid); - while (iterator.hasNext()) { - EntityLiving entityliving = (EntityLiving) iterator.next(); - - if (entityliving.getUniqueID().equals(uuid)) { - this.setLeashHolder(entityliving, true); - break; - } + if (entity != null) { + this.setLeashHolder(entity, true); } - } else if (this.bM.hasKeyOfType("X", 99) && this.bM.hasKeyOfType("Y", 99) && this.bM.hasKeyOfType("Z", 99)) { - BlockPosition blockposition = new BlockPosition(this.bM.getInt("X"), this.bM.getInt("Y"), this.bM.getInt("Z")); - EntityLeash entityleash = EntityLeash.b(this.world, blockposition); + } else if (this.bJ.hasKeyOfType("X", 99) && this.bJ.hasKeyOfType("Y", 99) && this.bJ.hasKeyOfType("Z", 99)) { + BlockPosition blockposition = new BlockPosition(this.bJ.getInt("X"), this.bJ.getInt("Y"), this.bJ.getInt("Z")); - if (entityleash == null) { - entityleash = EntityLeash.a(this.world, blockposition); - } - - this.setLeashHolder(entityleash, true); + this.setLeashHolder(EntityLeash.a(this.world, blockposition), true); } else { this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit this.unleash(false, true); } + + this.bJ = null; } - this.bM = null; } - public boolean c(int i, ItemStack itemstack) { + @Override + public boolean a_(int i, ItemStack itemstack) { EnumItemSlot enumitemslot; if (i == 98) { @@ -1201,85 +1219,105 @@ public abstract class EntityInsentient extends EntityLiving { } } - public boolean bT() { - return this.dh() && super.bT(); + @Override + public boolean ca() { + return this.dD() && super.ca(); } public static boolean b(EnumItemSlot enumitemslot, ItemStack itemstack) { - EnumItemSlot enumitemslot1 = e(itemstack); + EnumItemSlot enumitemslot1 = h(itemstack); return enumitemslot1 == enumitemslot || enumitemslot1 == EnumItemSlot.MAINHAND && enumitemslot == EnumItemSlot.OFFHAND || enumitemslot1 == EnumItemSlot.OFFHAND && enumitemslot == EnumItemSlot.MAINHAND; } - public boolean cP() { - return super.cP() && !this.isNoAI(); + @Override + public boolean df() { + return super.df() && !this.isNoAI(); } public void setNoAI(boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntityInsentient.a); + byte b0 = (Byte) this.datawatcher.get(EntityInsentient.b); - this.datawatcher.set(EntityInsentient.a, flag ? (byte) (b0 | 1) : (byte) (b0 & -2)); + this.datawatcher.set(EntityInsentient.b, flag ? (byte) (b0 | 1) : (byte) (b0 & -2)); } - public void r(boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntityInsentient.a); + public void p(boolean flag) { + byte b0 = (Byte) this.datawatcher.get(EntityInsentient.b); - this.datawatcher.set(EntityInsentient.a, flag ? (byte) (b0 | 2) : (byte) (b0 & -3)); + this.datawatcher.set(EntityInsentient.b, flag ? (byte) (b0 | 2) : (byte) (b0 & -3)); + } + + public boolean isArmsRaisedZombie() { return (this.datawatcher.get(EntityInsentient.b) & 4) != 0; } // Paper - OBFHELPER + public void setArmsRaisedZombie(boolean flag) { this.q(flag); } // Paper - OBFHELPER + public void q(boolean flag) { + byte b0 = (Byte) this.datawatcher.get(EntityInsentient.b); + + this.datawatcher.set(EntityInsentient.b, flag ? (byte) (b0 | 4) : (byte) (b0 & -5)); } public boolean isNoAI() { - return ((Byte) this.datawatcher.get(EntityInsentient.a) & 1) != 0; + return ((Byte) this.datawatcher.get(EntityInsentient.b) & 1) != 0; } public boolean isLeftHanded() { - return ((Byte) this.datawatcher.get(EntityInsentient.a) & 2) != 0; + return ((Byte) this.datawatcher.get(EntityInsentient.b) & 2) != 0; } + public boolean dR() { + return ((Byte) this.datawatcher.get(EntityInsentient.b) & 4) != 0; + } + + @Override public EnumMainHand getMainHand() { return this.isLeftHanded() ? EnumMainHand.LEFT : EnumMainHand.RIGHT; } - public boolean B(Entity entity) { + @Override + public boolean c(EntityLiving entityliving) { + return entityliving.getEntityType() == EntityTypes.PLAYER && ((EntityHuman) entityliving).abilities.isInvulnerable ? false : super.c(entityliving); + } + + @Override + public boolean C(Entity entity) { float f = (float) this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).getValue(); - int i = 0; + float f1 = (float) this.getAttributeInstance(GenericAttributes.ATTACK_KNOCKBACK).getValue(); if (entity instanceof EntityLiving) { f += EnchantmentManager.a(this.getItemInMainHand(), ((EntityLiving) entity).getMonsterType()); - i += EnchantmentManager.b((EntityLiving) this); + f1 += (float) EnchantmentManager.b((EntityLiving) this); + } + + int i = EnchantmentManager.getFireAspectEnchantmentLevel(this); + + if (i > 0) { + // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item + EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), i * 4); + org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); + + if (!combustEvent.isCancelled()) { + entity.setOnFire(combustEvent.getDuration(), false); + } + // CraftBukkit end } boolean flag = entity.damageEntity(DamageSource.mobAttack(this), f); if (flag) { - if (i > 0 && entity instanceof EntityLiving) { - ((EntityLiving) entity).a(this, (float) i * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F))); - this.motX *= 0.6D; - this.motZ *= 0.6D; - } - - int j = EnchantmentManager.getFireAspectEnchantmentLevel(this); - - if (j > 0) { - // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item - EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), j * 4); - org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); - - if (!combustEvent.isCancelled()) { - entity.setOnFire(combustEvent.getDuration(), false); - } - // CraftBukkit end + if (f1 > 0.0F && entity instanceof EntityLiving) { + ((EntityLiving) entity).a(this, f1 * 0.5F, (double) MathHelper.sin(this.yaw * 0.017453292F), (double) (-MathHelper.cos(this.yaw * 0.017453292F))); + this.setMot(this.getMot().d(0.6D, 1.0D, 0.6D)); } if (entity instanceof EntityHuman) { EntityHuman entityhuman = (EntityHuman) entity; ItemStack itemstack = this.getItemInMainHand(); - ItemStack itemstack1 = entityhuman.isHandRaised() ? entityhuman.cW() : ItemStack.a; + ItemStack itemstack1 = entityhuman.isHandRaised() ? entityhuman.dl() : ItemStack.a; if (!itemstack.isEmpty() && !itemstack1.isEmpty() && itemstack.getItem() instanceof ItemAxe && itemstack1.getItem() == Items.SHIELD) { - float f1 = 0.25F + (float) EnchantmentManager.getDigSpeedEnchantmentLevel(this) * 0.05F; + float f2 = 0.25F + (float) EnchantmentManager.getDigSpeedEnchantmentLevel(this) * 0.05F; - if (this.random.nextFloat() < f1) { - entityhuman.getCooldownTracker().a(Items.SHIELD, 100); + if (this.random.nextFloat() < f2) { + entityhuman.getCooldownTracker().setCooldown(Items.SHIELD, 100); this.world.broadcastEntityEffect(entityhuman, (byte) 30); } } @@ -1291,13 +1329,13 @@ public abstract class EntityInsentient extends EntityLiving { return flag; } - public boolean isInDaylight() { return dq(); } // Paper - OBFHELPER - protected boolean dq() { - if (this.world.L() && !this.world.isClientSide) { - float f = this.az(); + public boolean isInDaylight() { return this.dS(); } // Paper - OBFHELPER + protected boolean dS() { + if (this.world.J() && !this.world.isClientSide) { + float f = this.aF(); BlockPosition blockposition = this.getVehicle() instanceof EntityBoat ? (new BlockPosition(this.locX, (double) Math.round(this.locY), this.locZ)).up() : new BlockPosition(this.locX, (double) Math.round(this.locY), this.locZ); - if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.world.e(blockposition)) { + if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.world.f(blockposition)) { return true; } } @@ -1305,12 +1343,17 @@ public abstract class EntityInsentient extends EntityLiving { return false; } + @Override protected void c(Tag tag) { - if (this.getNavigation().t()) { + if (this.getNavigation().r()) { super.c(tag); } else { - this.motY += 0.30000001192092896D; + this.setMot(this.getMot().add(0.0D, 0.3D, 0.0D)); } } + + public boolean a(Item item) { + return this.getItemInMainHand().getItem() == item || this.getItemInOffHand().getItem() == item; + } } diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/java/net/minecraft/server/EntityIronGolem.java index 8efd3abc7..8e463111b 100644 --- a/src/main/java/net/minecraft/server/EntityIronGolem.java +++ b/src/main/java/net/minecraft/server/EntityIronGolem.java @@ -1,125 +1,112 @@ package net.minecraft.server; -import javax.annotation.Nullable; - public class EntityIronGolem extends EntityGolem { - protected static final DataWatcherObject a = DataWatcher.a(EntityIronGolem.class, DataWatcherRegistry.a); - private int b; - @Nullable - private Village c; - private int bC; - private int bD; + protected static final DataWatcherObject b = DataWatcher.a(EntityIronGolem.class, DataWatcherRegistry.a); + private int c; + private int d; - public EntityIronGolem(World world) { - super(EntityTypes.IRON_GOLEM, world); - this.setSize(1.4F, 2.7F); + public EntityIronGolem(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.K = 1.0F; } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, true)); this.goalSelector.a(2, new PathfinderGoalMoveTowardsTarget(this, 0.9D, 32.0F)); - this.goalSelector.a(3, new PathfinderGoalMoveThroughVillage(this, 0.6D, true)); - this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); + this.goalSelector.a(2, new PathfinderGoalStrollVillage(this, 0.6D)); + this.goalSelector.a(3, new PathfinderGoalMoveThroughVillage(this, 0.6D, false, 4, () -> { + return false; + })); this.goalSelector.a(5, new PathfinderGoalOfferFlower(this)); this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.6D)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); this.targetSelector.a(1, new PathfinderGoalDefendVillage(this)); - this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, false, new Class[0])); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 10, false, true, (entityinsentient) -> { - return entityinsentient != null && IMonster.e.test(entityinsentient) && !(entityinsentient instanceof EntityCreeper); + this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0])); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 5, false, false, (entityliving) -> { + return entityliving instanceof IMonster && !(entityliving instanceof EntityCreeper); })); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityIronGolem.a, (byte) 0); - } - - protected void mobTick() { - if (--this.b <= 0) { - this.b = 70 + this.random.nextInt(50); - this.c = this.world.af().getClosestVillage(new BlockPosition(this), 32); - if (this.c == null) { - this.dv(); - } else { - BlockPosition blockposition = this.c.a(); - - this.a(blockposition, (int) ((float) this.c.b() * 0.6F)); - } - } - - super.mobTick(); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityIronGolem.b, (byte) 0); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(100.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(100.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); - this.getAttributeInstance(GenericAttributes.c).setValue(1.0D); + this.getAttributeInstance(GenericAttributes.KNOCKBACK_RESISTANCE).setValue(1.0D); } - protected int k(int i) { + @Override + protected int l(int i) { return i; } - protected void C(Entity entity) { + @Override + protected void D(Entity entity) { if (entity instanceof IMonster && !(entity instanceof EntityCreeper) && this.getRandom().nextInt(20) == 0) { this.setGoalTarget((EntityLiving) entity, org.bukkit.event.entity.EntityTargetLivingEntityEvent.TargetReason.COLLISION, true); // CraftBukkit - set reason } - super.C(entity); + super.D(entity); } + @Override public void movementTick() { super.movementTick(); - if (this.bC > 0) { - --this.bC; + if (this.c > 0) { + --this.c; } - if (this.bD > 0) { - --this.bD; + if (this.d > 0) { + --this.d; } - // Akarin start - this handle by client - /* - if (this.motX * this.motX + this.motZ * this.motZ > 2.500000277905201E-7D && this.random.nextInt(5) == 0) { + if (b(this.getMot()) > 2.500000277905201E-7D && this.random.nextInt(5) == 0) { int i = MathHelper.floor(this.locX); int j = MathHelper.floor(this.locY - 0.20000000298023224D); int k = MathHelper.floor(this.locZ); IBlockData iblockdata = this.world.getType(new BlockPosition(i, j, k)); if (!iblockdata.isAir()) { - this.world.addParticle(new ParticleParamBlock(Particles.d, iblockdata), this.locX + ((double) this.random.nextFloat() - 0.5D) * (double) this.width, this.getBoundingBox().minY + 0.1D, this.locZ + ((double) this.random.nextFloat() - 0.5D) * (double) this.width, 4.0D * ((double) this.random.nextFloat() - 0.5D), 0.5D, ((double) this.random.nextFloat() - 0.5D) * 4.0D); + this.world.addParticle(new ParticleParamBlock(Particles.BLOCK, iblockdata), this.locX + ((double) this.random.nextFloat() - 0.5D) * (double) this.getWidth(), this.getBoundingBox().minY + 0.1D, this.locZ + ((double) this.random.nextFloat() - 0.5D) * (double) this.getWidth(), 4.0D * ((double) this.random.nextFloat() - 0.5D), 0.5D, ((double) this.random.nextFloat() - 0.5D) * 4.0D); } } - */ - // Akarin end } - public boolean b(Class oclass) { - return this.isPlayerCreated() && EntityHuman.class.isAssignableFrom(oclass) ? false : (oclass == EntityCreeper.class ? false : super.b(oclass)); + @Override + public boolean a(EntityTypes entitytypes) { + return this.isPlayerCreated() && entitytypes == EntityTypes.PLAYER ? false : (entitytypes == EntityTypes.CREEPER ? false : super.a(entitytypes)); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setBoolean("PlayerCreated", this.isPlayerCreated()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setPlayerCreated(nbttagcompound.getBoolean("PlayerCreated")); } - public boolean B(Entity entity) { - this.bC = 10; + @Override + public boolean C(Entity entity) { + this.c = 10; this.world.broadcastEntityEffect(this, (byte) 4); boolean flag = entity.damageEntity(DamageSource.mobAttack(this), (float) (7 + this.random.nextInt(15))); if (flag) { - entity.motY += 0.4000000059604645D; + entity.setMot(entity.getMot().add(0.0D, 0.4000000059604645D, 0.0D)); this.a((EntityLiving) this, entity); } @@ -127,71 +114,71 @@ public class EntityIronGolem extends EntityGolem { return flag; } - public Village l() { - return this.c; - } - - public void a(boolean flag) { + public void r(boolean flag) { if (flag) { - this.bD = 400; + this.d = 400; this.world.broadcastEntityEffect(this, (byte) 11); } else { - this.bD = 0; + this.d = 0; this.world.broadcastEntityEffect(this, (byte) 34); } } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_IRON_GOLEM_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_IRON_GOLEM_DEATH; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(SoundEffects.ENTITY_IRON_GOLEM_STEP, 1.0F, 1.0F); } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.G; - } - - public int dz() { - return this.bD; - } - public boolean isPlayerCreated() { - return ((Byte) this.datawatcher.get(EntityIronGolem.a) & 1) != 0; + return ((Byte) this.datawatcher.get(EntityIronGolem.b) & 1) != 0; } public void setPlayerCreated(boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntityIronGolem.a); + byte b0 = (Byte) this.datawatcher.get(EntityIronGolem.b); if (flag) { - this.datawatcher.set(EntityIronGolem.a, (byte) (b0 | 1)); + this.datawatcher.set(EntityIronGolem.b, (byte) (b0 | 1)); } else { - this.datawatcher.set(EntityIronGolem.a, (byte) (b0 & -2)); + this.datawatcher.set(EntityIronGolem.b, (byte) (b0 & -2)); } } + @Override public void die(DamageSource damagesource) { - if (!this.isPlayerCreated() && this.killer != null && this.c != null) { - this.c.a(this.killer.getProfile().getName(), -5); - } - super.die(damagesource); } + @Override public boolean a(IWorldReader iworldreader) { - BlockPosition blockposition = new BlockPosition(this.locX, this.locY, this.locZ); - IBlockData iblockdata = iworldreader.getType(blockposition); - IBlockData iblockdata1 = iworldreader.getType(blockposition.down()); - IBlockData iblockdata2 = iworldreader.getType(blockposition.up()); + BlockPosition blockposition = new BlockPosition(this); + BlockPosition blockposition1 = blockposition.down(); + IBlockData iblockdata = iworldreader.getType(blockposition1); - return iblockdata1.q() && SpawnerCreature.a(iblockdata2, iblockdata2.s()) && SpawnerCreature.a(iblockdata, FluidTypes.EMPTY.i()) && iworldreader.getCubes(this, this.getBoundingBox()) && iworldreader.a_(this, this.getBoundingBox()); + if (!iblockdata.a((IBlockAccess) iworldreader, blockposition1, (Entity) this)) { + return false; + } else { + for (int i = 1; i < 3; ++i) { + BlockPosition blockposition2 = blockposition.up(i); + IBlockData iblockdata1 = iworldreader.getType(blockposition2); + + if (!SpawnerCreature.a((IBlockAccess) iworldreader, blockposition2, iblockdata1, iblockdata1.p())) { + return false; + } + } + + return SpawnerCreature.a((IBlockAccess) iworldreader, blockposition, iworldreader.getType(blockposition), FluidTypes.EMPTY.i()) && iworldreader.i(this); + } } } diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java index 5f6e81372..df26cef6a 100644 --- a/src/main/java/net/minecraft/server/EntityItem.java +++ b/src/main/java/net/minecraft/server/EntityItem.java @@ -1,9 +1,11 @@ package net.minecraft.server; import java.util.Iterator; +import java.util.List; import java.util.UUID; import javax.annotation.Nullable; // CraftBukkit start +import org.bukkit.Material; // Paper import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.player.PlayerPickupItemEvent; // CraftBukkit end @@ -11,30 +13,27 @@ import org.bukkit.event.player.PlayerAttemptPickupItemEvent; // Paper public class EntityItem extends Entity { - private static final DataWatcherObject b = DataWatcher.a(EntityItem.class, DataWatcherRegistry.g); - public int age; // PAIL + private static final DataWatcherObject ITEM = DataWatcher.a(EntityItem.class, DataWatcherRegistry.g); + public int age; public int pickupDelay; - public boolean canMobPickup = true; // Paper - private int e; - private UUID f; - private UUID g; - public float a; + private int f; + private UUID thrower; + private UUID owner; + public final float b; private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit + public boolean canMobPickup = true; // Paper - public EntityItem(World world) { - super(EntityTypes.ITEM, world); - this.e = 5; - this.a = (float) (Math.random() * 3.141592653589793D * 2.0D); - this.setSize(0.25F, 0.25F); + public EntityItem(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.f = 5; + this.b = (float) (Math.random() * 3.141592653589793D * 2.0D); } public EntityItem(World world, double d0, double d1, double d2) { - this(world); + this(EntityTypes.ITEM, world); this.setPosition(d0, d1, d2); - this.yaw = (float) (Math.random() * 360.0D); - this.motX = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D)); - this.motY = 0.20000000298023224D; - this.motZ = (double) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D)); + this.yaw = this.random.nextFloat() * 360.0F; + this.setMot(this.random.nextDouble() * 0.2D - 0.1D, 0.2D, this.random.nextDouble() * 0.2D - 0.1D); } public EntityItem(World world, double d0, double d1, double d2, ItemStack itemstack) { @@ -42,14 +41,17 @@ public class EntityItem extends Entity { this.setItemStack(itemstack); } + @Override protected boolean playStepSound() { return false; } - protected void x_() { - this.getDataWatcher().register(EntityItem.b, ItemStack.a); + @Override + protected void initDatawatcher() { + this.getDataWatcher().register(EntityItem.ITEM, ItemStack.a); } + @Override public void tick() { if (this.getItemStack().isEmpty()) { this.die(); @@ -66,70 +68,67 @@ public class EntityItem extends Entity { this.lastX = this.locX; this.lastY = this.locY; this.lastZ = this.locZ; - double d0 = this.motX; - double d1 = this.motY; - double d2 = this.motZ; + Vec3D vec3d = this.getMot(); if (this.a(TagsFluid.WATER)) { - this.u(); + this.v(); } else if (!this.isNoGravity()) { - this.motY -= 0.03999999910593033D; + this.setMot(this.getMot().add(0.0D, -0.04D, 0.0D)); } if (this.world.isClientSide) { this.noclip = false; } else { - this.noclip = this.i(this.locX, (this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D, this.locZ); + this.noclip = !this.world.getCubes(this); + if (this.noclip) { + this.i(this.locX, (this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D, this.locZ); + } } - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - boolean flag = (int) this.lastX != (int) this.locX || (int) this.lastY != (int) this.locY || (int) this.lastZ != (int) this.locZ; + if (!this.onGround || b(this.getMot()) > 9.999999747378752E-6D || (this.ticksLived + this.getId()) % 4 == 0) { + this.move(EnumMoveType.SELF, this.getMot()); + float f = 0.98F; - if (flag || this.ticksLived % 25 == 0) { + if (this.onGround) { + f = this.world.getType(new BlockPosition(this.locX, this.getBoundingBox().minY - 1.0D, this.locZ)).getBlock().m() * 0.98F; + } + + this.setMot(this.getMot().d((double) f, 0.98D, (double) f)); + if (this.onGround) { + this.setMot(this.getMot().d(1.0D, -0.5D, 1.0D)); + } + } + + boolean flag = MathHelper.floor(this.lastX) != MathHelper.floor(this.locX) || MathHelper.floor(this.lastY) != MathHelper.floor(this.locY) || MathHelper.floor(this.lastZ) != MathHelper.floor(this.locZ); + int i = flag ? 2 : 40; + + if (this.ticksLived % i == 0) { if (this.world.getFluid(new BlockPosition(this)).a(TagsFluid.LAVA)) { - this.motY = 0.20000000298023224D; - this.motX = (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F); - this.motZ = (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F); + this.setMot((double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F), 0.20000000298023224D, (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F)); this.a(SoundEffects.ENTITY_GENERIC_BURN, 0.4F, 2.0F + this.random.nextFloat() * 0.4F); } - if (!this.world.isClientSide) { - this.v(); + if (!this.world.isClientSide && this.z()) { + this.mergeNearby(); } } - float f = 0.98F; - - if (this.onGround) { - f = this.world.getType(new BlockPosition(MathHelper.floor(this.locX), MathHelper.floor(this.getBoundingBox().minY) - 1, MathHelper.floor(this.locZ))).getBlock().n() * 0.98F; - } - - this.motX *= (double) f; - this.motY *= 0.9800000190734863D; - this.motZ *= (double) f; - if (this.onGround) { - this.motY *= -0.5D; - } - /* Craftbukkit start - moved up if (this.age != -32768) { ++this.age; } // Craftbukkit end */ - this.impulse |= this.at(); + this.impulse |= this.ay(); if (!this.world.isClientSide) { - double d3 = this.motX - d0; - double d4 = this.motY - d1; - double d5 = this.motZ - d2; - double d6 = d3 * d3 + d4 * d4 + d5 * d5; + double d0 = this.getMot().d(vec3d).g(); - if (d6 > 0.01D) { + if (d0 > 0.01D) { this.impulse = true; } } - if (!this.world.isClientSide && this.age >= world.spigotConfig.itemDespawnRate) { // Spigot + if (!this.world.isClientSide && this.age >= this.getDespawnRate()) { // Spigot // Paper // CraftBukkit start - fire ItemDespawnEvent if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { this.age = 0; @@ -153,7 +152,7 @@ public class EntityItem extends Entity { this.lastTick = MinecraftServer.currentTick; // CraftBukkit end - if (!this.world.isClientSide && this.age >= world.spigotConfig.itemDespawnRate) { // Spigot + if (!this.world.isClientSide && this.age >= this.getDespawnRate()) { // Spigot // Paper // CraftBukkit start - fire ItemDespawnEvent if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { this.age = 0; @@ -165,84 +164,93 @@ public class EntityItem extends Entity { } // Spigot end - private void u() { - if (this.motY < 0.05999999865889549D) { - this.motY += 5.000000237487257E-4D; - } + private void v() { + Vec3D vec3d = this.getMot(); - this.motX *= 0.9900000095367432D; - this.motZ *= 0.9900000095367432D; + this.setMot(vec3d.x * 0.9900000095367432D, vec3d.y + (double) (vec3d.y < 0.05999999865889549D ? 5.0E-4F : 0.0F), vec3d.z * 0.9900000095367432D); } - private void v() { + private void mergeNearby() { // Paper start - avoid item merge if stack size above max stack size ItemStack stack = getItemStack(); if (stack.getCount() >= stack.getMaxStackSize()) return; // Paper end // Spigot start double radius = world.spigotConfig.itemMerge; - Iterator iterator = this.world.a(EntityItem.class, this.getBoundingBox().grow(radius, radius, radius)).iterator(); - // Spigot end + List list = this.world.a(EntityItem.class, this.getBoundingBox().grow(radius, radius, radius), (entityitem) -> { + // Spigot end + return entityitem != this && entityitem.z(); + }); - while (iterator.hasNext()) { - EntityItem entityitem = (EntityItem) iterator.next(); + if (!list.isEmpty()) { + Iterator iterator = list.iterator(); - this.a(entityitem); + while (iterator.hasNext()) { + EntityItem entityitem = (EntityItem) iterator.next(); + + if (!this.z()) { + return; + } + + this.a(entityitem); + } } } - private boolean a(EntityItem entityitem) { - if (entityitem == this) { - return false; - } else if (entityitem.isAlive() && this.isAlive()) { - ItemStack itemstack = this.getItemStack(); - ItemStack itemstack1 = entityitem.getItemStack().cloneItemStack(); + private boolean z() { + ItemStack itemstack = this.getItemStack(); + + return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < 6000 && itemstack.getCount() < itemstack.getMaxStackSize(); + } + + private void a(EntityItem entityitem) { + ItemStack itemstack = this.getItemStack(); + ItemStack itemstack1 = entityitem.getItemStack(); + + if (itemstack1.getItem() == itemstack.getItem()) { + if (itemstack1.getCount() + itemstack.getCount() <= itemstack1.getMaxStackSize()) { + if (!(itemstack1.hasTag() ^ itemstack.hasTag())) { + if (!itemstack1.hasTag() || itemstack1.getTag().equals(itemstack.getTag())) { + if (true || itemstack1.getCount() < itemstack.getCount()) { // Spigot + a(this, itemstack, entityitem, itemstack1); + } else { + a(entityitem, itemstack1, this, itemstack); + } - if (this.pickupDelay != 32767 && entityitem.pickupDelay != 32767) { - if (this.age != -32768 && entityitem.age != -32768) { - if (itemstack1.getItem() != itemstack.getItem()) { - return false; - } else if (itemstack1.hasTag() ^ itemstack.hasTag()) { - return false; - } else if (itemstack1.hasTag() && !itemstack1.getTag().equals(itemstack.getTag())) { - return false; - } else if (itemstack1.getItem() == null) { - return false; - } else if (itemstack1.getCount() < itemstack.getCount()) { - return entityitem.a(this); - } else if (itemstack1.getCount() + itemstack.getCount() > itemstack1.getMaxStackSize()) { - return false; - } else { - // Spigot start - if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemMergeEvent(entityitem, this).isCancelled()) return false; // CraftBukkit - itemstack.add(itemstack1.getCount()); - this.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay); - this.age = Math.min(entityitem.age, this.age); - this.setItemStack(itemstack); - entityitem.die(); - // Spigot end - return true; } - } else { - return false; } - } else { - return false; } - } else { - return false; } } + private static void a(EntityItem entityitem, ItemStack itemstack, EntityItem entityitem1, ItemStack itemstack1) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemMergeEvent(entityitem1, entityitem).isCancelled()) return; // CraftBukkit + int i = Math.min(itemstack.getMaxStackSize() - itemstack.getCount(), itemstack1.getCount()); + ItemStack itemstack2 = itemstack.cloneItemStack(); + + itemstack2.add(i); + entityitem.setItemStack(itemstack2); + itemstack1.subtract(i); + if (!itemstack1.isEmpty()) entityitem1.setItemStack(itemstack1); // CraftBukkit - don't set empty stacks + entityitem.pickupDelay = Math.max(entityitem.pickupDelay, entityitem1.pickupDelay); + entityitem.age = Math.min(entityitem.age, entityitem1.age); + if (itemstack1.isEmpty()) { + entityitem1.die(); + } + + } + public void f() { this.age = 4800; } - protected void burn(int i) { + @Override + protected void burn(float i) { // CraftBukkit - int -> float this.damageEntity(DamageSource.FIRE, (float) i); } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -254,9 +262,9 @@ public class EntityItem extends Entity { return false; } // CraftBukkit end - this.aA(); - this.e = (int) ((float) this.e - f); - if (this.e <= 0) { + this.velocityChanged(); + this.f = (int) ((float) this.f - f); + if (this.f <= 0) { this.die(); } @@ -264,16 +272,17 @@ public class EntityItem extends Entity { } } + @Override public void b(NBTTagCompound nbttagcompound) { - nbttagcompound.setShort("Health", (short) this.e); + nbttagcompound.setShort("Health", (short) this.f); nbttagcompound.setShort("Age", (short) this.age); nbttagcompound.setShort("PickupDelay", (short) this.pickupDelay); - if (this.l() != null) { - nbttagcompound.set("Thrower", GameProfileSerializer.a(this.l())); + if (this.getThrower() != null) { + nbttagcompound.set("Thrower", GameProfileSerializer.a(this.getThrower())); } - if (this.k() != null) { - nbttagcompound.set("Owner", GameProfileSerializer.a(this.k())); + if (this.getOwner() != null) { + nbttagcompound.set("Owner", GameProfileSerializer.a(this.getOwner())); } if (!this.getItemStack().isEmpty()) { @@ -282,19 +291,20 @@ public class EntityItem extends Entity { } + @Override public void a(NBTTagCompound nbttagcompound) { - this.e = nbttagcompound.getShort("Health"); + this.f = nbttagcompound.getShort("Health"); this.age = nbttagcompound.getShort("Age"); if (nbttagcompound.hasKey("PickupDelay")) { this.pickupDelay = nbttagcompound.getShort("PickupDelay"); } if (nbttagcompound.hasKeyOfType("Owner", 10)) { - this.g = GameProfileSerializer.b(nbttagcompound.getCompound("Owner")); + this.owner = GameProfileSerializer.b(nbttagcompound.getCompound("Owner")); } if (nbttagcompound.hasKeyOfType("Thrower", 10)) { - this.f = GameProfileSerializer.b(nbttagcompound.getCompound("Thrower")); + this.thrower = GameProfileSerializer.b(nbttagcompound.getCompound("Thrower")); } NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Item"); @@ -306,7 +316,8 @@ public class EntityItem extends Entity { } - public void d(EntityHuman entityhuman) { + @Override + public void pickup(EntityHuman entityhuman) { if (!this.world.isClientSide) { ItemStack itemstack = this.getItemStack(); Item item = itemstack.getItem(); @@ -341,6 +352,7 @@ public class EntityItem extends Entity { this.world.getServer().getPluginManager().callEvent(playerEvent); flyAtPlayer = playerEvent.getFlyAtPlayer(); // Paper if (playerEvent.isCancelled()) { + itemstack.setCount(i); // SPIGOT-5294 - restore count // Paper Start if (flyAtPlayer) { entityhuman.receive(this, i); @@ -354,17 +366,21 @@ public class EntityItem extends Entity { entityEvent.setCancelled(!entityhuman.canPickUpLoot); this.world.getServer().getPluginManager().callEvent(entityEvent); if (entityEvent.isCancelled()) { + itemstack.setCount(i); // SPIGOT-5294 - restore count return; } - itemstack.setCount(canHold + remaining); + itemstack.setCount(canHold + remaining); // = i // Possibly < 0; fix here so we do not have to modify code below this.pickupDelay = 0; + } else if (this.pickupDelay == 0) { + // ensure that the code below isn't triggered if canHold says we can't pick the items up + this.pickupDelay = -1; } // CraftBukkit end - if (this.pickupDelay == 0 && (this.g == null || 6000 - this.age <= 200 || this.g.equals(entityhuman.getUniqueID())) && entityhuman.inventory.pickup(itemstack)) { + if (this.pickupDelay == 0 && (this.owner == null || 6000 - this.age <= 200 || this.owner.equals(entityhuman.getUniqueID())) && entityhuman.inventory.pickup(itemstack)) { // Paper Start if (flyAtPlayer) { entityhuman.receive(this, i); @@ -381,58 +397,59 @@ public class EntityItem extends Entity { } } + @Override public IChatBaseComponent getDisplayName() { IChatBaseComponent ichatbasecomponent = this.getCustomName(); return (IChatBaseComponent) (ichatbasecomponent != null ? ichatbasecomponent : new ChatMessage(this.getItemStack().j(), new Object[0])); } - public boolean bk() { + @Override + public boolean bs() { return false; } @Nullable + @Override public Entity a(DimensionManager dimensionmanager) { Entity entity = super.a(dimensionmanager); if (!this.world.isClientSide && entity instanceof EntityItem) { - ((EntityItem) entity).v(); + ((EntityItem) entity).mergeNearby(); } return entity; } public ItemStack getItemStack() { - return (ItemStack) this.getDataWatcher().get(EntityItem.b); + return (ItemStack) this.getDataWatcher().get(EntityItem.ITEM); } public void setItemStack(ItemStack itemstack) { com.google.common.base.Preconditions.checkArgument(!itemstack.isEmpty(), "Cannot drop air"); // CraftBukkit - this.getDataWatcher().set(EntityItem.b, itemstack); - this.getDataWatcher().markDirty(EntityItem.b); // CraftBukkit - SPIGOT-4591, must mark dirty + this.getDataWatcher().set(EntityItem.ITEM, itemstack); + this.getDataWatcher().markDirty(EntityItem.ITEM); // CraftBukkit - SPIGOT-4591, must mark dirty } - @Nullable public UUID getOwner() { return k(); } // Paper - OBFHELPER - @Nullable public UUID k() { // Paper - return this.g; + @Nullable + public UUID getOwner() { + return this.owner; } - public void setOwner(@Nullable UUID owner) { b(owner); } // Paper - OBFHELPER - public void b(@Nullable UUID uuid) { - this.g = uuid; + public void setOwner(@Nullable UUID uuid) { + this.owner = uuid; } - @Nullable public UUID getThrower() { return l(); } // Paper - OBFHELPER - @Nullable public UUID l() { // Paper - return this.f; + @Nullable + public UUID getThrower() { + return this.thrower; } - public void setThrower(@Nullable UUID thrower) { c(thrower); } // Paper - OBFHELPER - public void c(@Nullable UUID uuid) { - this.f = uuid; + public void setThrower(@Nullable UUID uuid) { + this.thrower = uuid; } - public void n() { + public void defaultPickupDelay() { this.pickupDelay = 10; } @@ -444,7 +461,7 @@ public class EntityItem extends Entity { this.pickupDelay = 32767; } - public void a(int i) { + public void setPickupDelay(int i) { this.pickupDelay = i; } @@ -456,8 +473,20 @@ public class EntityItem extends Entity { this.age = -6000; } - public void t() { + public void u() { this.p(); - this.age = world.spigotConfig.itemDespawnRate - 1; // Spigot + this.age = this.getDespawnRate() - 1; // Spigot // Paper + } + + // Paper start + public int getDespawnRate(){ + Material material = this.getItemStack().getBukkitStack().getType(); + return world.paperConfig.altItemDespawnRateMap.getOrDefault(material, world.spigotConfig.itemDespawnRate); + } + // Paper end + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); } } diff --git a/src/main/java/net/minecraft/server/EntityItemFrame.java b/src/main/java/net/minecraft/server/EntityItemFrame.java index 964509a33..b078435c6 100644 --- a/src/main/java/net/minecraft/server/EntityItemFrame.java +++ b/src/main/java/net/minecraft/server/EntityItemFrame.java @@ -7,13 +7,13 @@ import org.apache.logging.log4j.Logger; public class EntityItemFrame extends EntityHanging { - private static final Logger d = LogManager.getLogger(); - private static final DataWatcherObject e = DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.g); - private static final DataWatcherObject f = DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.b); - private float g = 1.0F; + private static final Logger LOGGER = LogManager.getLogger(); + private static final DataWatcherObject ITEM = DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.g); + private static final DataWatcherObject g = DataWatcher.a(EntityItemFrame.class, DataWatcherRegistry.b); + private float ar = 1.0F; - public EntityItemFrame(World world) { - super(EntityTypes.ITEM_FRAME, world); + public EntityItemFrame(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntityItemFrame(World world, BlockPosition blockposition, EnumDirection enumdirection) { @@ -21,15 +21,18 @@ public class EntityItemFrame extends EntityHanging { this.setDirection(enumdirection); } - public float getHeadHeight() { + @Override + protected float getHeadHeight(EntityPose entitypose, EntitySize entitysize) { return 0.0F; } - protected void x_() { - this.getDataWatcher().register(EntityItemFrame.e, ItemStack.a); - this.getDataWatcher().register(EntityItemFrame.f, 0); + @Override + protected void initDatawatcher() { + this.getDataWatcher().register(EntityItemFrame.ITEM, ItemStack.a); + this.getDataWatcher().register(EntityItemFrame.g, 0); } + @Override public void setDirection(EnumDirection enumdirection) { Validate.notNull(enumdirection); this.direction = enumdirection; @@ -46,50 +49,75 @@ public class EntityItemFrame extends EntityHanging { this.updateBoundingBox(); } + @Override protected void updateBoundingBox() { if (this.direction != null) { + // CraftBukkit start code moved in to calculateBoundingBox + this.a(calculateBoundingBox(this, this.blockPosition, this.direction, this.getHangingWidth(), this.getHangingHeight())); + // CraftBukkit end + } + } + + // CraftBukkit start - break out BB calc into own method + public static AxisAlignedBB calculateBoundingBox(@Nullable Entity entity, BlockPosition blockPosition, EnumDirection direction, int width, int height) { + { double d0 = 0.46875D; - this.locX = (double) this.blockPosition.getX() + 0.5D - (double) this.direction.getAdjacentX() * 0.46875D; - this.locY = (double) this.blockPosition.getY() + 0.5D - (double) this.direction.getAdjacentY() * 0.46875D; - this.locZ = (double) this.blockPosition.getZ() + 0.5D - (double) this.direction.getAdjacentZ() * 0.46875D; - double d1 = (double) this.getWidth(); - double d2 = (double) this.getHeight(); - double d3 = (double) this.getWidth(); - EnumDirection.EnumAxis enumdirection_enumaxis = this.direction.k(); + double locX = (double) blockPosition.getX() + 0.5D - (double) direction.getAdjacentX() * 0.46875D; + double locY = (double) blockPosition.getY() + 0.5D - (double) direction.getAdjacentY() * 0.46875D; + double locZ = (double) blockPosition.getZ() + 0.5D - (double) direction.getAdjacentZ() * 0.46875D; + if (entity != null) { + entity.locX = locX; + entity.locY = locY; + entity.locZ = locZ; + } + double d1 = (double) width; + double d2 = (double) height; + double d3 = (double) width; + EnumDirection.EnumAxis enumdirection_enumaxis = direction.k(); switch (enumdirection_enumaxis) { - case X: - d1 = 1.0D; - break; - case Y: - d2 = 1.0D; - break; - case Z: - d3 = 1.0D; + case X: + d1 = 1.0D; + break; + case Y: + d2 = 1.0D; + break; + case Z: + d3 = 1.0D; } d1 /= 32.0D; d2 /= 32.0D; d3 /= 32.0D; - this.a(new AxisAlignedBB(this.locX - d1, this.locY - d2, this.locZ - d3, this.locX + d1, this.locY + d2, this.locZ + d3)); + return new AxisAlignedBB(locX - d1, locY - d2, locZ - d3, locX + d1, locY + d2, locZ + d3); } } + // CraftBukkit end + @Override public boolean survives() { - if (!this.world.getCubes(this, this.getBoundingBox())) { + if (!this.world.getCubes(this)) { return false; } else { IBlockData iblockdata = this.world.getType(this.blockPosition.shift(this.direction.opposite())); - return !iblockdata.getMaterial().isBuildable() && (!this.direction.k().c() || !BlockDiodeAbstract.isDiode(iblockdata)) ? false : this.world.getEntities(this, this.getBoundingBox(), EntityItemFrame.a).isEmpty(); + return !iblockdata.getMaterial().isBuildable() && (!this.direction.k().c() || !BlockDiodeAbstract.isDiode(iblockdata)) ? false : this.world.getEntities(this, this.getBoundingBox(), EntityItemFrame.b).isEmpty(); } } - public float aM() { + @Override + public float aS() { return 0.0F; } + @Override + public void killEntity() { + this.c(this.getItem()); + super.killEntity(); + } + + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -110,25 +138,34 @@ public class EntityItemFrame extends EntityHanging { } } - public int getWidth() { + @Override + public int getHangingWidth() { return 12; } - public int getHeight() { + @Override + public int getHangingHeight() { return 12; } + @Override public void a(@Nullable Entity entity) { this.a(SoundEffects.ENTITY_ITEM_FRAME_BREAK, 1.0F, 1.0F); this.b(entity, true); } - public void m() { + @Override + public void playPlaceSound() { this.a(SoundEffects.ENTITY_ITEM_FRAME_PLACE, 1.0F, 1.0F); } - public void b(@Nullable Entity entity, boolean flag) { - if (this.world.getGameRules().getBoolean("doEntityDrops")) { + private void b(@Nullable Entity entity, boolean flag) { + if (!this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { + if (entity == null) { + this.c(this.getItem()); + } + + } else { ItemStack itemstack = this.getItem(); this.setItem(ItemStack.a); @@ -145,10 +182,12 @@ public class EntityItemFrame extends EntityHanging { this.a((IMaterial) Items.ITEM_FRAME); } - if (!itemstack.isEmpty() && this.random.nextFloat() < this.g) { + if (!itemstack.isEmpty()) { itemstack = itemstack.cloneItemStack(); this.c(itemstack); - this.a_(itemstack); + if (this.random.nextFloat() < this.ar) { + this.a(itemstack); + } } } @@ -159,13 +198,14 @@ public class EntityItemFrame extends EntityHanging { WorldMap worldmap = ItemWorldMap.getSavedMap(itemstack, this.world); worldmap.a(this.blockPosition, this.getId()); + worldmap.a(true); } itemstack.a((EntityItemFrame) null); } public ItemStack getItem() { - return (ItemStack) this.getDataWatcher().get(EntityItemFrame.e); + return (ItemStack) this.getDataWatcher().get(EntityItemFrame.ITEM); } public void setItem(ItemStack itemstack) { @@ -185,8 +225,8 @@ public class EntityItemFrame extends EntityHanging { itemstack.a(this); } - this.getDataWatcher().set(EntityItemFrame.e, itemstack); - if (!itemstack.isEmpty() && playSound) { // CraftBukkit + this.getDataWatcher().set(EntityItemFrame.ITEM, itemstack); + if (!itemstack.isEmpty() && flag && playSound) { // CraftBukkit // Paper - only play sound when update flag is set this.a(SoundEffects.ENTITY_ITEM_FRAME_ADD_ITEM, 1.0F, 1.0F); } @@ -196,11 +236,22 @@ public class EntityItemFrame extends EntityHanging { } + @Override + public boolean a_(int i, ItemStack itemstack) { + if (i == 0) { + this.setItem(itemstack); + return true; + } else { + return false; + } + } + + @Override public void a(DataWatcherObject datawatcherobject) { - if (datawatcherobject.equals(EntityItemFrame.e)) { + if (datawatcherobject.equals(EntityItemFrame.ITEM)) { ItemStack itemstack = this.getItem(); - if (!itemstack.isEmpty() && itemstack.y() != this) { + if (!itemstack.isEmpty() && itemstack.z() != this) { itemstack.a(this); } } @@ -208,7 +259,7 @@ public class EntityItemFrame extends EntityHanging { } public int getRotation() { - return (Integer) this.getDataWatcher().get(EntityItemFrame.f); + return (Integer) this.getDataWatcher().get(EntityItemFrame.g); } public void setRotation(int i) { @@ -216,24 +267,26 @@ public class EntityItemFrame extends EntityHanging { } private void setRotation(int i, boolean flag) { - this.getDataWatcher().set(EntityItemFrame.f, i % 8); + this.getDataWatcher().set(EntityItemFrame.g, i % 8); if (flag && this.blockPosition != null) { this.world.updateAdjacentComparators(this.blockPosition, Blocks.AIR); } } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); if (!this.getItem().isEmpty()) { nbttagcompound.set("Item", this.getItem().save(new NBTTagCompound())); nbttagcompound.setByte("ItemRotation", (byte) this.getRotation()); - nbttagcompound.setFloat("ItemDropChance", this.g); + nbttagcompound.setFloat("ItemDropChance", this.ar); } nbttagcompound.setByte("Facing", (byte) this.direction.a()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Item"); @@ -242,19 +295,26 @@ public class EntityItemFrame extends EntityHanging { ItemStack itemstack = ItemStack.a(nbttagcompound1); if (itemstack.isEmpty()) { - EntityItemFrame.d.warn("Unable to load item from: {}", nbttagcompound1); + EntityItemFrame.LOGGER.warn("Unable to load item from: {}", nbttagcompound1); + } + + ItemStack itemstack1 = this.getItem(); + + if (!itemstack1.isEmpty() && !ItemStack.matches(itemstack, itemstack1)) { + this.c(itemstack1); } this.setItem(itemstack, false); this.setRotation(nbttagcompound.getByte("ItemRotation"), false); if (nbttagcompound.hasKeyOfType("ItemDropChance", 99)) { - this.g = nbttagcompound.getFloat("ItemDropChance"); + this.ar = nbttagcompound.getFloat("ItemDropChance"); } } this.setDirection(EnumDirection.fromType1(nbttagcompound.getByte("Facing"))); } + @Override public boolean b(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -278,4 +338,9 @@ public class EntityItemFrame extends EntityHanging { public int q() { return this.getItem().isEmpty() ? 0 : this.getRotation() % 8 + 1; } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this, this.getEntityType(), this.direction.a(), this.getBlockPosition()); + } } diff --git a/src/main/java/net/minecraft/server/EntityLargeFireball.java b/src/main/java/net/minecraft/server/EntityLargeFireball.java index d707990cb..d90860eb6 100644 --- a/src/main/java/net/minecraft/server/EntityLargeFireball.java +++ b/src/main/java/net/minecraft/server/EntityLargeFireball.java @@ -2,28 +2,31 @@ package net.minecraft.server; import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit -public class EntityLargeFireball extends EntityFireball { +public class EntityLargeFireball extends EntityFireballFireball { public int yield = 1; - public EntityLargeFireball(World world) { - super(EntityTypes.FIREBALL, world, 1.0F, 1.0F); - isIncendiary = this.world.getGameRules().getBoolean("mobGriefing"); // CraftBukkit + public EntityLargeFireball(EntityTypes entitytypes, World world) { + super(entitytypes, world); + isIncendiary = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // CraftBukkit } public EntityLargeFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) { - super(EntityTypes.FIREBALL, entityliving, d0, d1, d2, world, 1.0F, 1.0F); - isIncendiary = this.world.getGameRules().getBoolean("mobGriefing"); // CraftBukkit + super(EntityTypes.FIREBALL, entityliving, d0, d1, d2, world); + isIncendiary = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // CraftBukkit } + @Override protected void a(MovingObjectPosition movingobjectposition) { if (!this.world.isClientSide) { - if (movingobjectposition.entity != null) { - movingobjectposition.entity.damageEntity(DamageSource.fireball(this, this.shooter), 6.0F); - this.a(this.shooter, movingobjectposition.entity); + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + Entity entity = ((MovingObjectPositionEntity) movingobjectposition).getEntity(); + + entity.damageEntity(DamageSource.fireball(this, this.shooter), 6.0F); + this.a(this.shooter, entity); } - boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); + boolean flag = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); // CraftBukkit start - fire ExplosionPrimeEvent ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity()); @@ -31,7 +34,7 @@ public class EntityLargeFireball extends EntityFireball { if (!event.isCancelled()) { // give 'this' instead of (Entity) null so we know what causes the damage - this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), isIncendiary); + this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), flag ? Explosion.Effect.DESTROY : Explosion.Effect.NONE); } // CraftBukkit end this.die(); @@ -39,11 +42,13 @@ public class EntityLargeFireball extends EntityFireball { } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setInt("ExplosionPower", this.yield); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKeyOfType("ExplosionPower", 99)) { diff --git a/src/main/java/net/minecraft/server/EntityLeash.java b/src/main/java/net/minecraft/server/EntityLeash.java index b5f56e0e8..230f5a1b9 100644 --- a/src/main/java/net/minecraft/server/EntityLeash.java +++ b/src/main/java/net/minecraft/server/EntityLeash.java @@ -8,8 +8,8 @@ import javax.annotation.Nullable; public class EntityLeash extends EntityHanging { - public EntityLeash(World world) { - super(EntityTypes.LEASH_KNOT, world); + public EntityLeash(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntityLeash(World world, BlockPosition blockposition) { @@ -23,39 +23,49 @@ public class EntityLeash extends EntityHanging { this.attachedToPlayer = true; } + @Override public void setPosition(double d0, double d1, double d2) { super.setPosition((double) MathHelper.floor(d0) + 0.5D, (double) MathHelper.floor(d1) + 0.5D, (double) MathHelper.floor(d2) + 0.5D); } + @Override protected void updateBoundingBox() { this.locX = (double) this.blockPosition.getX() + 0.5D; this.locY = (double) this.blockPosition.getY() + 0.5D; this.locZ = (double) this.blockPosition.getZ() + 0.5D; - if (valid) world.entityJoinedWorld(this, false); // CraftBukkit + if (valid) ((WorldServer) world).chunkCheck(this); // CraftBukkit } + @Override public void setDirection(EnumDirection enumdirection) {} - public int getWidth() { + @Override + public int getHangingWidth() { return 9; } - public int getHeight() { + @Override + public int getHangingHeight() { return 9; } - public float getHeadHeight() { + @Override + protected float getHeadHeight(EntityPose entitypose, EntitySize entitysize) { return -0.0625F; } + @Override public void a(@Nullable Entity entity) { this.a(SoundEffects.ENTITY_LEASH_KNOT_BREAK, 1.0F, 1.0F); } + @Override public void b(NBTTagCompound nbttagcompound) {} + @Override public void a(NBTTagCompound nbttagcompound) {} + @Override public boolean b(EntityHuman entityhuman, EnumHand enumhand) { if (this.world.isClientSide) { return true; @@ -69,7 +79,7 @@ public class EntityLeash extends EntityHanging { while (iterator.hasNext()) { entityinsentient = (EntityInsentient) iterator.next(); - if (entityinsentient.isLeashed() && entityinsentient.getLeashHolder() == entityhuman) { + if (entityinsentient.getLeashHolder() == entityhuman) { // CraftBukkit start if (CraftEventFactory.callPlayerLeashEntityEvent(entityinsentient, this, entityhuman).isCancelled()) { ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(entityinsentient, entityinsentient.getLeashHolder())); @@ -113,20 +123,12 @@ public class EntityLeash extends EntityHanging { } } + @Override public boolean survives() { - return this.world.getType(this.blockPosition).getBlock() instanceof BlockFence; + return this.world.getType(this.blockPosition).getBlock().a(TagsBlock.FENCES); } public static EntityLeash a(World world, BlockPosition blockposition) { - EntityLeash entityleash = new EntityLeash(world, blockposition); - - world.addEntity(entityleash); - entityleash.m(); - return entityleash; - } - - @Nullable - public static EntityLeash b(World world, BlockPosition blockposition) { int i = blockposition.getX(); int j = blockposition.getY(); int k = blockposition.getZ(); @@ -137,7 +139,11 @@ public class EntityLeash extends EntityHanging { do { if (!iterator.hasNext()) { - return null; + EntityLeash entityleash1 = new EntityLeash(world, blockposition); + + world.addEntity(entityleash1); + entityleash1.playPlaceSound(); + return entityleash1; } entityleash = (EntityLeash) iterator.next(); @@ -146,7 +152,13 @@ public class EntityLeash extends EntityHanging { return entityleash; } - public void m() { + @Override + public void playPlaceSound() { this.a(SoundEffects.ENTITY_LEASH_KNOT_PLACE, 1.0F, 1.0F); } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this, this.getEntityType(), 0, this.getBlockPosition()); + } } diff --git a/src/main/java/net/minecraft/server/EntityLightning.java b/src/main/java/net/minecraft/server/EntityLightning.java index 50f620009..27bf271bb 100644 --- a/src/main/java/net/minecraft/server/EntityLightning.java +++ b/src/main/java/net/minecraft/server/EntityLightning.java @@ -1,30 +1,32 @@ package net.minecraft.server; import java.util.Collection; +import java.util.Iterator; import java.util.List; import javax.annotation.Nullable; import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit -public class EntityLightning extends EntityWeather { +public class EntityLightning extends Entity { private int lifeTicks; - public long a; - private int c; - private final boolean d; + public long b; + private int d; + private final boolean e; @Nullable - private EntityPlayer e; + private EntityPlayer f; public boolean isEffect; // CraftBukkit public boolean isSilent = false; // Spigot public EntityLightning(World world, double d0, double d1, double d2, boolean flag) { super(EntityTypes.LIGHTNING_BOLT, world); this.isEffect = flag; // CraftBukkit + this.af = true; this.setPositionRotation(d0, d1, d2, 0.0F, 0.0F); this.lifeTicks = 2; - this.a = this.random.nextLong(); - this.c = this.random.nextInt(3) + 1; - this.d = flag; + this.b = this.random.nextLong(); + this.d = this.random.nextInt(3) + 1; + this.e = flag; EnumDifficulty enumdifficulty = world.getDifficulty(); if (enumdifficulty == EnumDifficulty.NORMAL || enumdifficulty == EnumDifficulty.HARD) { @@ -41,22 +43,24 @@ public class EntityLightning extends EntityWeather { } // Spigot end - public SoundCategory bV() { + @Override + public SoundCategory getSoundCategory() { return SoundCategory.WEATHER; } public void d(@Nullable EntityPlayer entityplayer) { - this.e = entityplayer; + this.f = entityplayer; } + @Override public void tick() { super.tick(); if (!isSilent && this.lifeTicks == 2) { // Spigot // CraftBukkit start - Use relative location for far away sounds - // this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.WEATHER, 10000.0F, 0.8F + this.random.nextFloat() * 0.2F); + // this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_LIGHTNING_BOLT_THUNDER, SoundCategory.WEATHER, 10000.0F, 0.8F + this.random.nextFloat() * 0.2F); float pitch = 0.8F + this.random.nextFloat() * 0.2F; int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; - for (EntityPlayer player : (List) (List) this.world.players) { + for (EntityPlayer player : (List) (List) this.world.getPlayers()) { double deltaX = this.locX - player.locX; double deltaZ = this.locZ - player.locZ; double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; @@ -81,36 +85,37 @@ public class EntityLightning extends EntityWeather { } } // CraftBukkit end - //this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT, SoundCategory.WEATHER, 2.0f, 0.5F + this.random.nextFloat() * 0.2F); // Paper - Limit lightning strike effect distance (the packet is now sent from inside the loop) + //this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_LIGHTNING_BOLT_IMPACT, SoundCategory.WEATHER, 2.0F, 0.5F + this.random.nextFloat() * 0.2F); // Paper - Limit lightning strike effect distance (the packet is now sent from inside the loop) } --this.lifeTicks; if (this.lifeTicks < 0) { - if (this.c == 0) { + if (this.d == 0) { this.die(); } else if (this.lifeTicks < -this.random.nextInt(10)) { - --this.c; + --this.d; this.lifeTicks = 1; - this.a = this.random.nextLong(); + this.b = this.random.nextLong(); this.a(0); } } if (this.lifeTicks >= 0 && !this.isEffect) { // CraftBukkit - add !this.isEffect if (this.world.isClientSide) { - this.world.d(2); - } else if (!this.d) { + this.world.c(2); + } else if (!this.e) { double d0 = 3.0D; - List list = this.world.getEntities(this, new AxisAlignedBB(this.locX - 3.0D, this.locY - 3.0D, this.locZ - 3.0D, this.locX + 3.0D, this.locY + 6.0D + 3.0D, this.locZ + 3.0D)); + List list = this.world.getEntities(this, new AxisAlignedBB(this.locX - 3.0D, this.locY - 3.0D, this.locZ - 3.0D, this.locX + 3.0D, this.locY + 6.0D + 3.0D, this.locZ + 3.0D), Entity::isAlive); + Iterator iterator = list.iterator(); - for (int i = 0; i < list.size(); ++i) { - Entity entity = (Entity) list.get(i); + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); entity.onLightningStrike(this); } - if (this.e != null) { - CriterionTriggers.E.a(this.e, (Collection) list); + if (this.f != null) { + CriterionTriggers.E.a(this.f, (Collection) list); } } } @@ -118,11 +123,11 @@ public class EntityLightning extends EntityWeather { } private void a(int i) { - if (!this.d && !this.world.isClientSide && this.world.getGameRules().getBoolean("doFireTick")) { + if (!this.e && !this.world.isClientSide && this.world.getGameRules().getBoolean(GameRules.DO_FIRE_TICK)) { IBlockData iblockdata = Blocks.FIRE.getBlockData(); BlockPosition blockposition = new BlockPosition(this); - if (this.world.areChunksLoaded(blockposition, 10) && this.world.getType(blockposition).isAir() && iblockdata.canPlace(this.world, blockposition)) { + if (this.world.getType(blockposition).isAir() && iblockdata.canPlace(this.world, blockposition)) { // CraftBukkit start - add "!isEffect" if (!isEffect && !CraftEventFactory.callBlockIgniteEvent(world, blockposition, this).isCancelled()) { this.world.setTypeUpdate(blockposition, iblockdata); @@ -131,7 +136,7 @@ public class EntityLightning extends EntityWeather { } for (int j = 0; j < i; ++j) { - BlockPosition blockposition1 = blockposition.a(this.random.nextInt(3) - 1, this.random.nextInt(3) - 1, this.random.nextInt(3) - 1); + BlockPosition blockposition1 = blockposition.b(this.random.nextInt(3) - 1, this.random.nextInt(3) - 1, this.random.nextInt(3) - 1); if (this.world.getType(blockposition1).isAir() && iblockdata.canPlace(this.world, blockposition1)) { // CraftBukkit start - add "!isEffect" @@ -145,9 +150,17 @@ public class EntityLightning extends EntityWeather { } } - protected void x_() {} + @Override + protected void initDatawatcher() {} + @Override protected void a(NBTTagCompound nbttagcompound) {} + @Override protected void b(NBTTagCompound nbttagcompound) {} + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntityWeather(this); + } } diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index 3f4667225..f675ad2f5 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -2,24 +2,23 @@ package net.minecraft.server; import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; import com.google.common.base.Objects; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; - -import java.util.Arrays; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.DynamicOps; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Random; import java.util.UUID; import javax.annotation.Nullable; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import org.apache.commons.lang3.tuple.Pair; // CraftBukkit start import java.util.ArrayList; -import java.util.stream.Collectors; - import com.google.common.base.Function; import com.google.common.collect.Lists; import org.bukkit.Location; @@ -41,84 +40,85 @@ import co.aikar.timings.MinecraftTimings; // Paper public abstract class EntityLiving extends Entity { - private static final Logger a = LogManager.getLogger(); private static final UUID b = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D"); - private static final AttributeModifier c = (new AttributeModifier(EntityLiving.b, "Sprinting speed boost", 0.30000001192092896D, 2)).a(false); - protected static final DataWatcherObject aw = DataWatcher.a(EntityLiving.class, DataWatcherRegistry.a); + private static final AttributeModifier c = (new AttributeModifier(EntityLiving.b, "Sprinting speed boost", 0.30000001192092896D, AttributeModifier.Operation.MULTIPLY_TOTAL)).a(false); + protected static final DataWatcherObject ar = DataWatcher.a(EntityLiving.class, DataWatcherRegistry.a); public static final DataWatcherObject HEALTH = DataWatcher.a(EntityLiving.class, DataWatcherRegistry.c); + private static final DataWatcherObject e = DataWatcher.a(EntityLiving.class, DataWatcherRegistry.b); + private static final DataWatcherObject f = DataWatcher.a(EntityLiving.class, DataWatcherRegistry.i); private static final DataWatcherObject g = DataWatcher.a(EntityLiving.class, DataWatcherRegistry.b); - private static final DataWatcherObject h = DataWatcher.a(EntityLiving.class, DataWatcherRegistry.i); - private static final DataWatcherObject bx = DataWatcher.a(EntityLiving.class, DataWatcherRegistry.b); + private static final DataWatcherObject> bs = DataWatcher.a(EntityLiving.class, DataWatcherRegistry.m); + protected static final EntitySize as = EntitySize.c(0.2F, 0.2F); private AttributeMapBase attributeMap; public CombatTracker combatTracker = new CombatTracker(this); public final Map effects = Maps.newHashMap(); - private final NonNullList bB; - private final NonNullList bC; - public boolean ax; - public EnumHand ay; - public int az; - public int aA; + private final NonNullList bw; + private final NonNullList bx; + public boolean at; + public EnumHand au; + public int av; + public int aw; public int hurtTicks; - public int aC; - public float aD; + public int hurtDuration; + public float az; public int deathTicks; + public float aB; + public float aC; + protected int aD; + public float aE; public float aF; public float aG; - protected int aH; - public float aI; - public float aJ; - public float aK; public int maxNoDamageTicks; + public final float aI; + public final float aJ; + public float aK; + public float aL; public float aM; public float aN; public float aO; - public float aP; - public float aQ; - public float aR; - public float aS; - public float aT; - public float aU; public EntityHuman killer; - public int lastDamageByPlayerTime; // Paper - public - protected boolean killed; protected void setDying(boolean dying) { this.killed = dying; } protected boolean isDying() { return this.killed; } // Paper - OBFHELPER + public int lastDamageByPlayerTime; // Paper - protected -> public + protected boolean killed; protected int ticksFarFromPlayer; - protected float aZ; - protected float ba; - protected float bb; - protected float bc; - protected float bd; - protected int be; protected int getKillCount() { return this.be; } // Paper - OBFHELPER + protected float aT; + protected float aU; + protected float aV; + protected float aW; + protected float aX; + protected int aY; protected int getKillCount() { return this.aY; } // Paper - OBFHELPER public float lastDamage; - protected boolean bg; - public float bh; - public float bi; - public float bj; - public float bk; - protected int bl; - protected double bm; - protected double bn; - protected double bo; - protected double bp; - protected double bq; - protected double br; - protected int bs; + protected boolean jumping; + public float bb; + public float bc; + public float bd; + public float be; + protected int bf; + protected double bg; + protected double bh; + protected double bi; + protected double bj; + protected double bk; + protected double bl; + protected int bm; public boolean updateEffects; + @Nullable public EntityLiving lastDamager; public int hurtTimestamp; - private EntityLiving bG; - private int bH; - private float bI; - private int bJ; - private float bK; + private EntityLiving bB; + private int bC; + private float bD; + private int jumpTicks; + private float bF; public ItemStack activeItem; // Paper - public - protected int bu; - protected int bv; - private BlockPosition bL; - private DamageSource bM; - private long bN; - protected int bw; - private float bO; - private float bP; + protected int bo; + protected int bp; + private BlockPosition bG; + private DamageSource bH; + private long bI; + protected int bq; + private float bJ; + private float bK; + protected BehaviorController br; // CraftBukkit start public int expToDrop; public int maxAirTicks = 300; @@ -143,49 +143,66 @@ public abstract class EntityLiving extends Entity { } // Spigot end - protected EntityLiving(EntityTypes entitytypes, World world) { + protected EntityLiving(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.bB = NonNullList.a(2, ItemStack.a); - this.bC = NonNullList.a(4, ItemStack.a); + this.bw = NonNullList.a(2, ItemStack.a); + this.bx = NonNullList.a(4, ItemStack.a); this.maxNoDamageTicks = 20; - this.aU = 0.02F; + this.aO = 0.02F; this.updateEffects = true; this.activeItem = ItemStack.a; this.initAttributes(); // CraftBukkit - setHealth(getMaxHealth()) inlined and simplified to skip the instanceof check for EntityPlayer, as getBukkitEntity() is not initialized in constructor - this.datawatcher.set(EntityLiving.HEALTH, (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue()); - this.j = true; - this.aP = (float) ((Math.random() + 1.0D) * 0.009999999776482582D); + this.datawatcher.set(EntityLiving.HEALTH, (float) this.getAttributeInstance(GenericAttributes.MAX_HEALTH).getValue()); + this.i = true; + this.aJ = (float) ((Math.random() + 1.0D) * 0.009999999776482582D); this.setPosition(this.locX, this.locY, this.locZ); - this.aO = (float) Math.random() * 12398.0F; + this.aI = (float) Math.random() * 12398.0F; this.yaw = (float) (Math.random() * 6.2831854820251465D); - this.aS = this.yaw; - this.Q = 0.6F; + this.aM = this.yaw; + this.K = 0.6F; + this.br = this.a(new Dynamic(DynamicOpsNBT.a, new NBTTagCompound())); } + public BehaviorController getBehaviorController() { + return this.br; + } + + protected BehaviorController a(Dynamic dynamic) { + return new BehaviorController<>(ImmutableList.of(), ImmutableList.of(), dynamic); + } + + @Override public void killEntity() { this.damageEntity(DamageSource.OUT_OF_WORLD, Float.MAX_VALUE); } - protected void x_() { - this.datawatcher.register(EntityLiving.aw, (byte) 0); + public boolean a(EntityTypes entitytypes) { + return true; + } + + @Override + protected void initDatawatcher() { + this.datawatcher.register(EntityLiving.ar, (byte) 0); + this.datawatcher.register(EntityLiving.e, 0); + this.datawatcher.register(EntityLiving.f, false); this.datawatcher.register(EntityLiving.g, 0); - this.datawatcher.register(EntityLiving.h, false); - this.datawatcher.register(EntityLiving.bx, 0); this.datawatcher.register(EntityLiving.HEALTH, 1.0F); + this.datawatcher.register(EntityLiving.bs, Optional.empty()); } protected void initAttributes() { - this.getAttributeMap().b(GenericAttributes.maxHealth); - this.getAttributeMap().b(GenericAttributes.c); + this.getAttributeMap().b(GenericAttributes.MAX_HEALTH); + this.getAttributeMap().b(GenericAttributes.KNOCKBACK_RESISTANCE); this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED); - this.getAttributeMap().b(GenericAttributes.h); - this.getAttributeMap().b(GenericAttributes.i); + this.getAttributeMap().b(GenericAttributes.ARMOR); + this.getAttributeMap().b(GenericAttributes.ARMOR_TOUGHNESS); } + @Override protected void a(double d0, boolean flag, IBlockData iblockdata, BlockPosition blockposition) { if (!this.isInWater()) { - this.at(); + this.ay(); } if (!this.world.isClientSide && this.fallDistance > 3.0F && flag) { @@ -197,9 +214,9 @@ public abstract class EntityLiving extends Entity { // CraftBukkit start - visiblity api if (this instanceof EntityPlayer) { - ((WorldServer) this.world).sendParticles((EntityPlayer) this, new ParticleParamBlock(Particles.d, iblockdata), this.locX, this.locY, this.locZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D, false); + ((WorldServer) this.world).sendParticles((EntityPlayer) this, new ParticleParamBlock(Particles.BLOCK, iblockdata), this.locX, this.locY, this.locZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D, false); } else { - ((WorldServer) this.world).a(new ParticleParamBlock(Particles.d, iblockdata), this.locX, this.locY, this.locZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D); + ((WorldServer) this.world).a(new ParticleParamBlock(Particles.BLOCK, iblockdata), this.locX, this.locY, this.locZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D); } // CraftBukkit end } @@ -208,15 +225,20 @@ public abstract class EntityLiving extends Entity { super.a(d0, flag, iblockdata, blockposition); } - public boolean canBreatheUnderwater() { return this.ca(); } // Paper - OBFHELPER - public boolean ca() { + public boolean canBreatheUnderwater() { return this.cm(); } // Paper - OBFHELPER + public boolean cm() { return this.getMonsterType() == EnumMonsterType.UNDEAD; } - public void W() { - this.aF = this.aG; - super.W(); - //this.world.methodProfiler.enter("livingEntityBaseTick"); // Akarin - remove caller + @Override + public void entityBaseTick() { + this.aB = this.aC; + if (this.justCreated) { + this.getBedPosition().ifPresent(this::a); + } + + super.entityBaseTick(); + this.world.getMethodProfiler().enter("livingEntityBaseTick"); boolean flag = this instanceof EntityHuman; if (this.isAlive()) { @@ -243,49 +265,45 @@ public abstract class EntityLiving extends Entity { if (this.isAlive()) { if (this.a(TagsFluid.WATER) && this.world.getType(new BlockPosition(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ)).getBlock() != Blocks.BUBBLE_COLUMN) { - if (!this.canBreatheUnderwater() && !MobEffectUtil.c(this) && !flag1) { // Paper - use OBFHELPER so it can be overridden - this.setAirTicks(this.k(this.getAirTicks())); + if (!this.canBreatheUnderwater() && !MobEffectUtil.c(this) && !flag1) { // Paper - use OBFHELPER so it can be overridden + this.setAirTicks(this.l(this.getAirTicks())); if (this.getAirTicks() == -20) { this.setAirTicks(0); + Vec3D vec3d = this.getMot(); - // Akarin start - this handle by client - /* for (int i = 0; i < 8; ++i) { float f = this.random.nextFloat() - this.random.nextFloat(); float f1 = this.random.nextFloat() - this.random.nextFloat(); float f2 = this.random.nextFloat() - this.random.nextFloat(); - this.world.addParticle(Particles.e, this.locX + (double) f, this.locY + (double) f1, this.locZ + (double) f2, this.motX, this.motY, this.motZ); + this.world.addParticle(Particles.BUBBLE, this.locX + (double) f, this.locY + (double) f1, this.locZ + (double) f2, vec3d.x, vec3d.y, vec3d.z); } - */ - // Akarin end this.damageEntity(DamageSource.DROWN, 2.0F); } } - if (!this.world.isClientSide && this.isPassenger() && this.getVehicle() != null && !this.getVehicle().aY()) { + if (!this.world.isClientSide && this.isPassenger() && this.getVehicle() != null && !this.getVehicle().bf()) { this.stopRiding(); } - } else if (this.getAirTicks() < this.bf()) { - this.setAirTicks(this.l(this.getAirTicks())); + } else if (this.getAirTicks() < this.bp()) { + this.setAirTicks(this.m(this.getAirTicks())); } if (!this.world.isClientSide) { BlockPosition blockposition = new BlockPosition(this); - if (!Objects.equal(this.bL, blockposition)) { - this.bL = blockposition; + if (!Objects.equal(this.bG, blockposition)) { + this.bG = blockposition; this.b(blockposition); } } } - if (this.isAlive() && this.ap()) { + if (this.isAlive() && this.au()) { this.extinguish(); } - this.aM = this.aN; if (this.hurtTicks > 0) { --this.hurtTicks; } @@ -295,7 +313,7 @@ public abstract class EntityLiving extends Entity { } if (this.getHealth() <= 0.0F) { - this.cb(); + this.co(); } if (this.lastDamageByPlayerTime > 0) { @@ -304,8 +322,8 @@ public abstract class EntityLiving extends Entity { this.killer = null; } - if (this.bG != null && !this.bG.isAlive()) { - this.bG = null; + if (this.bB != null && !this.bB.isAlive()) { + this.bB = null; } if (this.lastDamager != null) { @@ -317,19 +335,19 @@ public abstract class EntityLiving extends Entity { } this.tickPotionEffects(); - this.bc = this.bb; - this.aR = this.aQ; - this.aT = this.aS; + this.aW = this.aV; + this.aL = this.aK; + this.aN = this.aM; this.lastYaw = this.yaw; this.lastPitch = this.pitch; - //this.world.methodProfiler.exit(); // Akarin - remove caller + this.world.getMethodProfiler().exit(); } // CraftBukkit start public int getExpReward() { int exp = this.getExpValue(this.killer); - if (!this.world.isClientSide && (this.lastDamageByPlayerTime > 0 || this.alwaysGivesExp()) && this.isDropExperience() && this.world.getGameRules().getBoolean("doMobLoot")) { + if (!this.world.isClientSide && (this.lastDamageByPlayerTime > 0 || this.alwaysGivesExp()) && this.isDropExperience() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { return exp; } else { return 0; @@ -350,11 +368,16 @@ public abstract class EntityLiving extends Entity { return false; } - public boolean aY() { + public float cn() { + return this.isBaby() ? 0.5F : 1.0F; + } + + @Override + public boolean bf() { return false; } - protected void cb() { + protected void co() { ++this.deathTicks; if (this.deathTicks >= 20 && !this.dead) { // CraftBukkit - (this.deathTicks == 20) -> (this.deathTicks >= 20 && !this.dead) int i; @@ -373,17 +396,13 @@ public abstract class EntityLiving extends Entity { this.die(); - // Akarin start - this handle by client - /* for (i = 0; i < 20; ++i) { double d0 = this.random.nextGaussian() * 0.02D; double d1 = this.random.nextGaussian() * 0.02D; double d2 = this.random.nextGaussian() * 0.02D; - this.world.addParticle(Particles.J, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2); + this.world.addParticle(Particles.POOF, this.locX + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), this.locY + (double) (this.random.nextFloat() * this.getHeight()), this.locZ + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), d0, d1, d2); } - */ - // Akarin end } } @@ -392,14 +411,14 @@ public abstract class EntityLiving extends Entity { return !this.isBaby(); } - protected int k(int i) { + protected int l(int i) { int j = EnchantmentManager.getOxygenEnchantmentLevel(this); return j > 0 && this.random.nextInt(j + 1) > 0 ? i : i - 1; } - protected int l(int i) { - return Math.min(i + 4, this.bf()); + protected int m(int i) { + return Math.min(i + 4, this.bp()); } protected int getExpValue(EntityHuman entityhuman) { @@ -419,7 +438,7 @@ public abstract class EntityLiving extends Entity { return this.lastDamager; } - public int cg() { + public int ct() { return this.hurtTimestamp; } @@ -428,28 +447,33 @@ public abstract class EntityLiving extends Entity { this.hurtTimestamp = this.ticksLived; } - public EntityLiving ch() { - return this.bG; + @Nullable + public EntityLiving cu() { + return this.bB; } - public int ci() { - return this.bH; + public int cv() { + return this.bC; } public void z(Entity entity) { if (entity instanceof EntityLiving) { - this.bG = (EntityLiving) entity; + this.bB = (EntityLiving) entity; } else { - this.bG = null; + this.bB = null; } - this.bH = this.ticksLived; + this.bC = this.ticksLived; } - public int cj() { + public int cw() { return this.ticksFarFromPlayer; } + public void n(int i) { + this.ticksFarFromPlayer = i; + } + protected void b(ItemStack itemstack) { if (!itemstack.isEmpty()) { SoundEffect soundeffect = SoundEffects.ITEM_ARMOR_EQUIP_GENERIC; @@ -465,6 +489,7 @@ public abstract class EntityLiving extends Entity { } } + @Override public void b(NBTTagCompound nbttagcompound) { nbttagcompound.setFloat("Health", this.getHealth()); nbttagcompound.setShort("HurtTime", (short) this.hurtTicks); @@ -505,15 +530,22 @@ public abstract class EntityLiving extends Entity { while (iterator.hasNext()) { MobEffect mobeffect = (MobEffect) iterator.next(); - nbttaglist.add((NBTBase) mobeffect.a(new NBTTagCompound())); + nbttaglist.add(mobeffect.a(new NBTTagCompound())); } nbttagcompound.set("ActiveEffects", nbttaglist); } - nbttagcompound.setBoolean("FallFlying", this.dc()); + nbttagcompound.setBoolean("FallFlying", this.isGliding()); + this.getBedPosition().ifPresent((blockposition) -> { + nbttagcompound.setInt("SleepingX", blockposition.getX()); + nbttagcompound.setInt("SleepingY", blockposition.getY()); + nbttagcompound.setInt("SleepingZ", blockposition.getZ()); + }); + nbttagcompound.set("Brain", (NBTBase) this.br.a((DynamicOps) DynamicOpsNBT.a)); } + @Override public void a(NBTTagCompound nbttagcompound) { // Paper start - jvm keeps optimizing the setter float absorptionAmount = nbttagcompound.getFloat("AbsorptionAmount"); @@ -543,9 +575,9 @@ public abstract class EntityLiving extends Entity { if (nbttagcompound.hasKey("Bukkit.MaxHealth")) { NBTBase nbtbase = nbttagcompound.get("Bukkit.MaxHealth"); if (nbtbase.getTypeId() == 5) { - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(((NBTTagFloat) nbtbase).asDouble()); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(((NBTTagFloat) nbtbase).asDouble()); } else if (nbtbase.getTypeId() == 3) { - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(((NBTTagInt) nbtbase).asDouble()); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(((NBTTagInt) nbtbase).asDouble()); } } // CraftBukkit end @@ -561,10 +593,10 @@ public abstract class EntityLiving extends Entity { String s = nbttagcompound.getString("Team"); ScoreboardTeam scoreboardteam = this.world.getScoreboard().getTeam(s); if (!world.paperConfig.nonPlayerEntitiesOnScoreboards && !(this instanceof EntityHuman)) { scoreboardteam = null; } // Paper - boolean flag = scoreboardteam != null && this.world.getScoreboard().addPlayerToTeam(this.bu(), scoreboardteam); + boolean flag = scoreboardteam != null && this.world.getScoreboard().addPlayerToTeam(this.getUniqueIDString(), scoreboardteam); if (!flag) { - EntityLiving.a.warn("Unable to add mob to team \"{}\" (that team probably doesn't exist)", s); + EntityLiving.LOGGER.warn("Unable to add mob to team \"{}\" (that team probably doesn't exist)", s); } } @@ -572,6 +604,20 @@ public abstract class EntityLiving extends Entity { this.setFlag(7, true); } + if (nbttagcompound.hasKeyOfType("SleepingX", 99) && nbttagcompound.hasKeyOfType("SleepingY", 99) && nbttagcompound.hasKeyOfType("SleepingZ", 99)) { + BlockPosition blockposition = new BlockPosition(nbttagcompound.getInt("SleepingX"), nbttagcompound.getInt("SleepingY"), nbttagcompound.getInt("SleepingZ")); + + this.d(blockposition); + this.datawatcher.set(EntityLiving.POSE, EntityPose.SLEEPING); + if (!this.justCreated) { + this.a(blockposition); + } + } + + if (nbttagcompound.hasKeyOfType("Brain", 10)) { + this.br = this.a(new Dynamic(DynamicOpsNBT.a, nbttagcompound.get("Brain"))); + } + } // CraftBukkit start @@ -643,11 +689,9 @@ public abstract class EntityLiving extends Entity { this.updateEffects = false; } - int i = (Integer) this.datawatcher.get(EntityLiving.g); - boolean flag = (Boolean) this.datawatcher.get(EntityLiving.h); + int i = (Integer) this.datawatcher.get(EntityLiving.e); + boolean flag = (Boolean) this.datawatcher.get(EntityLiving.f); - // Akarin start - this handle by client - /* if (i > 0) { boolean flag1; @@ -666,28 +710,64 @@ public abstract class EntityLiving extends Entity { double d1 = (double) (i >> 8 & 255) / 255.0D; double d2 = (double) (i >> 0 & 255) / 255.0D; - this.world.addParticle(flag ? Particles.a : Particles.s, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, d0, d1, d2); + this.world.addParticle(flag ? Particles.AMBIENT_ENTITY_EFFECT : Particles.ENTITY_EFFECT, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.getWidth(), this.locY + this.random.nextDouble() * (double) this.getHeight(), this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.getWidth(), d0, d1, d2); } } - */ - // Akarin end } protected void C() { if (this.effects.isEmpty()) { - this.cl(); + this.cy(); this.setInvisible(false); } else { Collection collection = this.effects.values(); - this.datawatcher.set(EntityLiving.h, c(collection)); - this.datawatcher.set(EntityLiving.g, PotionUtil.a(collection)); + this.datawatcher.set(EntityLiving.f, c(collection)); + this.datawatcher.set(EntityLiving.e, PotionUtil.a(collection)); this.setInvisible(this.hasEffect(MobEffects.INVISIBILITY)); } } + public double A(@Nullable Entity entity) { + double d0 = 1.0D; + + if (this.isSneaking()) { + d0 *= 0.8D; + } + + if (this.isInvisible()) { + float f = this.cT(); + + if (f < 0.1F) { + f = 0.1F; + } + + d0 *= 0.7D * (double) f; + } + + if (entity != null) { + ItemStack itemstack = this.getEquipment(EnumItemSlot.HEAD); + Item item = itemstack.getItem(); + EntityTypes entitytypes = entity.getEntityType(); + + if (entitytypes == EntityTypes.SKELETON && item == Items.SKELETON_SKULL || entitytypes == EntityTypes.ZOMBIE && item == Items.ZOMBIE_HEAD || entitytypes == EntityTypes.CREEPER && item == Items.CREEPER_HEAD) { + d0 *= 0.5D; + } + } + + return d0; + } + + public boolean c(EntityLiving entityliving) { + return true; + } + + public boolean a(EntityLiving entityliving, PathfinderTargetCondition pathfindertargetcondition) { + return pathfindertargetcondition.a(this, entityliving); + } + public static boolean c(Collection collection) { Iterator iterator = collection.iterator(); @@ -704,9 +784,9 @@ public abstract class EntityLiving extends Entity { return false; } - protected void cl() { - this.datawatcher.set(EntityLiving.h, false); - this.datawatcher.set(EntityLiving.g, 0); + protected void cy() { + this.datawatcher.set(EntityLiving.f, false); + this.datawatcher.set(EntityLiving.e, 0); } // CraftBukkit start @@ -743,7 +823,7 @@ public abstract class EntityLiving extends Entity { return this.effects.values(); } - public Map co() { + public Map cB() { return this.effects; } @@ -762,7 +842,7 @@ public abstract class EntityLiving extends Entity { } public boolean addEffect(MobEffect mobeffect, EntityPotionEffectEvent.Cause cause) { - //org.spigotmc.AsyncCatcher.catchOp( "effect add"); // Spigot // Akarin + org.spigotmc.AsyncCatcher.catchOp("effect add"); // Spigot if (isTickingEffects) { effectsToProcess.add(new ProcessableEffect(mobeffect, cause)); return true; @@ -814,10 +894,10 @@ public abstract class EntityLiving extends Entity { return true; } - public boolean cp() { + public boolean cC() { return this.getMonsterType() == EnumMonsterType.UNDEAD; } - + // CraftBukkit start @Nullable public MobEffect c(@Nullable MobEffectList mobeffectlist) { @@ -902,8 +982,11 @@ public abstract class EntityLiving extends Entity { float f1 = this.getHealth(); if (f1 > 0.0F) { - EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), f, regainReason, isFastRegen); // Paper - Add isFastRegen - this.world.getServer().getPluginManager().callEvent(event); + EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), f, regainReason, isFastRegen); // Paper + // Suppress during worldgen + if (this.valid) { + this.world.getServer().getPluginManager().callEvent(event); + } if (!event.isCancelled()) { this.setHealth((float) (this.getHealth() + event.getAmount())); @@ -946,6 +1029,7 @@ public abstract class EntityLiving extends Entity { this.datawatcher.set(EntityLiving.HEALTH, MathHelper.a(f, 0.0F, this.getMaxHealth())); } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -956,12 +1040,18 @@ public abstract class EntityLiving extends Entity { } else if (damagesource.p() && this.hasEffect(MobEffects.FIRE_RESISTANCE)) { return false; } else { + if (this.isSleeping() && !this.world.isClientSide) { + this.dy(); + } + this.ticksFarFromPlayer = 0; float f1 = f; // CraftBukkit - Moved into damageEntity0(DamageSource, float) if (false && (damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && !this.getEquipment(EnumItemSlot.HEAD).isEmpty()) { - this.getEquipment(EnumItemSlot.HEAD).damage((int) (f * 4.0F + this.random.nextFloat() * f * 2.0F), this); + this.getEquipment(EnumItemSlot.HEAD).damage((int) (f * 4.0F + this.random.nextFloat() * f * 2.0F), this, (entityliving) -> { + entityliving.c(EnumItemSlot.HEAD); + }); f *= 0.75F; } @@ -977,17 +1067,17 @@ public abstract class EntityLiving extends Entity { Entity entity = damagesource.j(); if (entity instanceof EntityLiving) { - this.c((EntityLiving) entity); + this.shieldBlock((EntityLiving) entity); } } flag = true; } - this.aJ = 1.5F; + this.aF = 1.5F; boolean flag1 = true; - if ((float) this.noDamageTicks > (float) this.maxNoDamageTicks / 2.0F) { + if ((float) this.noDamageTicks > 10.0F) { if (f <= this.lastDamage) { this.forceExplosionKnockback = true; // CraftBukkit - SPIGOT-949 - for vanilla consistency, cooldown does not prevent explosion knockback return false; @@ -1006,11 +1096,11 @@ public abstract class EntityLiving extends Entity { return false; } this.lastDamage = f; - this.noDamageTicks = this.maxNoDamageTicks; + this.noDamageTicks = 20; // this.damageEntity0(damagesource, f); // CraftBukkit end - this.aC = 10; - this.hurtTicks = this.aC; + this.hurtDuration = 10; + this.hurtTicks = this.hurtDuration; } // CraftBukkit start @@ -1022,7 +1112,7 @@ public abstract class EntityLiving extends Entity { } // CraftBukkit end - this.aD = 0.0F; + this.az = 0.0F; Entity entity1 = damagesource.getEntity(); if (entity1 != null) { @@ -1038,7 +1128,13 @@ public abstract class EntityLiving extends Entity { if (entitywolf.isTamed()) { this.lastDamageByPlayerTime = 100; - this.killer = null; + EntityLiving entityliving = entitywolf.getOwner(); + + if (entityliving != null && entityliving.getEntityType() == EntityTypes.PLAYER) { + this.killer = (EntityHuman) entityliving; + } else { + this.killer = null; + } } } } @@ -1056,6 +1152,8 @@ public abstract class EntityLiving extends Entity { b0 = 36; } else if (damagesource.p()) { b0 = 37; + } else if (damagesource == DamageSource.SWEET_BERRY_BUSH) { + b0 = 44; } else { b0 = 2; } @@ -1065,7 +1163,7 @@ public abstract class EntityLiving extends Entity { } if (damagesource != DamageSource.DROWN && (!flag || f > 0.0F)) { - this.aA(); + this.velocityChanged(); } if (entity1 != null) { @@ -1077,22 +1175,22 @@ public abstract class EntityLiving extends Entity { d0 = (Math.random() - Math.random()) * 0.01D; } - this.aD = (float) (MathHelper.c(d1, d0) * 57.2957763671875D - (double) this.yaw); + this.az = (float) (MathHelper.d(d1, d0) * 57.2957763671875D - (double) this.yaw); this.a(entity1, 0.4F, d0, d1); } else { - this.aD = (float) ((int) (Math.random() * 2.0D) * 180); + this.az = (float) ((int) (Math.random() * 2.0D) * 180); } } if (knockbackCancelled) this.world.broadcastEntityEffect(this, (byte) 2); // Paper - Disable explosion knockback if (this.getHealth() <= 0.0F) { - if (!this.e(damagesource)) { + if (!this.f(damagesource)) { // Paper start - moved into CraftEventFactory event caller for cancellable death event - //SoundEffect soundeffect = this.cs(); + //SoundEffect soundeffect = this.getSoundDeath(); //if (flag1 && soundeffect != null) { - // this.a(soundeffect, this.cD(), this.cE()); + // this.a(soundeffect, this.getSoundVolume(), this.cV()); //} this.silentDeath = !flag1; // mark entity as dying silently // Paper end @@ -1107,8 +1205,8 @@ public abstract class EntityLiving extends Entity { boolean flag2 = !flag || f > 0.0F; if (flag2) { - this.bM = damagesource; - this.bN = this.world.getTime(); + this.bH = damagesource; + this.bI = this.world.getTime(); } if (this instanceof EntityPlayer) { @@ -1126,11 +1224,15 @@ public abstract class EntityLiving extends Entity { } } - protected void c(EntityLiving entityliving) { - entityliving.a(this, 0.5F, this.locX - entityliving.locX, this.locZ - entityliving.locZ); + protected void shieldBlock(EntityLiving entityliving) { + entityliving.e(this); } - private boolean e(DamageSource damagesource) { + protected void e(EntityLiving entityliving) { + entityliving.a(this, 0.5F, entityliving.locX - this.locX, entityliving.locZ - this.locZ); + } + + private boolean f(DamageSource damagesource) { if (damagesource.ignoresInvulnerability()) { return false; } else { @@ -1181,30 +1283,41 @@ public abstract class EntityLiving extends Entity { } @Nullable - public DamageSource cr() { - if (this.world.getTime() - this.bN > 40L) { - this.bM = null; + public DamageSource cE() { + if (this.world.getTime() - this.bI > 40L) { + this.bH = null; } - return this.bM; + return this.bH; } protected void c(DamageSource damagesource) { - SoundEffect soundeffect = this.d(damagesource); + SoundEffect soundeffect = this.getSoundHurt(damagesource); if (soundeffect != null) { - this.a(soundeffect, this.cD(), this.cE()); + this.a(soundeffect, this.getSoundVolume(), this.cV()); } } private boolean applyBlockingModifier(DamageSource damagesource) { - if (!damagesource.ignoresArmor() && this.isBlocking()) { + Entity entity = damagesource.j(); + boolean flag = false; + + if (entity instanceof EntityArrow) { + EntityArrow entityarrow = (EntityArrow) entity; + + if (entityarrow.getPierceLevel() > 0) { + flag = true; + } + } + + if (!damagesource.ignoresArmor() && this.isBlocking() && !flag) { Vec3D vec3d = damagesource.w(); if (vec3d != null) { Vec3D vec3d1 = this.f(1.0F); - Vec3D vec3d2 = vec3d.a(new Vec3D(this.locX, this.locY, this.locZ)).a(); + Vec3D vec3d2 = vec3d.a(new Vec3D(this.locX, this.locY, this.locZ)).d(); vec3d2 = new Vec3D(vec3d2.x, 0.0D, vec3d2.z); if (vec3d2.b(vec3d1) < 0.0D) { @@ -1216,150 +1329,189 @@ public abstract class EntityLiving extends Entity { return false; } - public void c(ItemStack itemstack) { - super.a(SoundEffects.ENTITY_ITEM_BREAK, 0.8F, 0.8F + this.world.random.nextFloat() * 0.4F); - this.a(itemstack, 5); - } - public void die(DamageSource damagesource) { - if (!this.killed && !this.enderTeleport) { // Akarin + if (!this.killed) { Entity entity = damagesource.getEntity(); - EntityLiving entityliving = this.cv(); + EntityLiving entityliving = this.getKillingEntity(); - // Paper start - move down to make death event cancellable - //if (this.be >= 0 && entityliving != null) { - // entityliving.a(this, this.be, damagesource); - //} + /* // Paper - move down to make death event cancellable + if (this.aY >= 0 && entityliving != null) { + entityliving.a(this, this.aY, damagesource); + } - //if (entity != null) { - // entity.b(this); - //} + if (entity != null) { + entity.b(this); + } + + if (this.isSleeping()) { + this.dy(); + } + */ // Paper this.killed = true; //this.getCombatTracker().g(); - - org.bukkit.event.entity.EntityDeathEvent deathEvent = null; - // Paper end if (!this.world.isClientSide) { - int i = 0; - - if (entity instanceof EntityHuman) { - i = EnchantmentManager.g((EntityLiving) entity); - } - - if (this.isDropExperience() && this.world.getGameRules().getBoolean("doMobLoot")) { - boolean flag = this.lastDamageByPlayerTime > 0; - - this.a(flag, i, damagesource); - // CraftBukkit start - Call death event - deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper - cancellable death event - this.drops = new ArrayList(); + org.bukkit.event.entity.EntityDeathEvent deathEvent = this.d(damagesource); + if (deathEvent == null || !deathEvent.isCancelled()) { + if (this.getKillCount() >= 0 && entityliving != null) { + entityliving.runKillTrigger(this, this.getKillCount(), damagesource); + } + if (entity != null) { + entity.onKill(this); + } + if (this.isSleeping()) { + this.dy(); + } + this.getCombatTracker().reset(); } else { - deathEvent = CraftEventFactory.callEntityDeathEvent(this); // Paper - cancellable death event - // CraftBukkit end + this.killed = false; + this.setHealth((float) deathEvent.getReviveHealth()); + } + // Paper end + + boolean flag = false; + + if (this.killed && entityliving instanceof EntityWither) { + if (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { + BlockPosition blockposition = new BlockPosition(this.locX, this.locY, this.locZ); + IBlockData iblockdata = Blocks.WITHER_ROSE.getBlockData(); + + if (this.world.getType(blockposition).isAir() && iblockdata.canPlace(this.world, blockposition)) { + this.world.setTypeAndData(blockposition, iblockdata, 3); + flag = true; + } + } + + if (!flag) { + EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY, this.locZ, new ItemStack(Items.bg)); + + this.world.addEntity(entityitem); + } } } - // Paper start - cancellable death event - if (deathEvent == null || !deathEvent.isCancelled()) { - // triggers and stats got moved down - if (this.getKillCount() >= 0 && entityliving != null) { - entityliving.runKillTrigger(this, this.getKillCount(), damagesource); - } - - if (entity != null) { - entity.onKill(this); - } - - this.getCombatTracker().reset(); - this.setDying(true); - this.world.broadcastEntityEffect(this, (byte) 3); - } else { - this.setDying(false); // Paper - reset if cancelled - this.setHealth((float) deathEvent.getReviveHealth()); - } - // Paper end + if (this.killed) { // Paper + this.world.broadcastEntityEffect(this, (byte) 3); + this.setPose(EntityPose.DYING); + } // Paper } } - protected void a(boolean flag, int i, DamageSource damagesource) { - this.dropDeathLoot(flag, i); - this.dropEquipment(flag, i); + protected org.bukkit.event.entity.EntityDeathEvent processDeath(DamageSource damagesource) { return d(damagesource); } // Paper - OBFHELPER + protected org.bukkit.event.entity.EntityDeathEvent d(DamageSource damagesource) { // Paper + Entity entity = damagesource.getEntity(); + int i; + + if (entity instanceof EntityHuman) { + i = EnchantmentManager.g((EntityLiving) entity); + } else { + i = 0; + } + + boolean flag = this.lastDamageByPlayerTime > 0; + + this.cF(); // CraftBukkit - from below // PAIL + org.bukkit.event.entity.EntityDeathEvent deathEvent; // Paper + if (this.isDropExperience() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { + this.a(damagesource, flag); + this.dropDeathLoot(damagesource, i, flag); + // CraftBukkit start - Call death event + deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper + } else { + deathEvent = CraftEventFactory.callEntityDeathEvent(this); // Paper + // CraftBukkit end + } + this.postDeathDropItems(deathEvent); // Paper + this.drops = new ArrayList<>(); // Paper + + return deathEvent; // Paper } - protected void dropEquipment(boolean flag, int i) {} + protected void cF() {} + protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled + + protected void dropDeathLoot(DamageSource damagesource, int i, boolean flag) {} + + public MinecraftKey cG() { + return this.getEntityType().h(); + } + + protected void a(DamageSource damagesource, boolean flag) { + MinecraftKey minecraftkey = this.cG(); + LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(minecraftkey); + LootTableInfo.Builder loottableinfo_builder = this.a(flag, damagesource); + + loottable.populateLoot(loottableinfo_builder.build(LootContextParameterSets.ENTITY), this::a); + } + + protected LootTableInfo.Builder a(boolean flag, DamageSource damagesource) { + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).a(this.random).set(LootContextParameters.THIS_ENTITY, this).set(LootContextParameters.POSITION, new BlockPosition(this)).set(LootContextParameters.DAMAGE_SOURCE, damagesource).setOptional(LootContextParameters.KILLER_ENTITY, damagesource.getEntity()).setOptional(LootContextParameters.DIRECT_KILLER_ENTITY, damagesource.j()); + + if (flag && this.killer != null) { + loottableinfo_builder = loottableinfo_builder.set(LootContextParameters.LAST_DAMAGE_PLAYER, this.killer).a(this.killer.eb()); + } + + return loottableinfo_builder; + } public void a(Entity entity, float f, double d0, double d1) { - if (this.random.nextDouble() >= this.getAttributeInstance(GenericAttributes.c).getValue()) { + if (this.random.nextDouble() >= this.getAttributeInstance(GenericAttributes.KNOCKBACK_RESISTANCE).getValue()) { this.impulse = true; - float f1 = MathHelper.sqrt(d0 * d0 + d1 * d1); + Vec3D vec3d = this.getMot(); + Vec3D vec3d1 = (new Vec3D(d0, 0.0D, d1)).d().a((double) f); - // Paper start - preserve old velocity - double oldMotX = this.motX; - double oldMotY = this.motY; - double oldMotZ = this.motZ; - // Paper end - - this.motX /= 2.0D; - this.motZ /= 2.0D; - this.motX -= d0 / (double) f1 * (double) f; - this.motZ -= d1 / (double) f1 * (double) f; - if (this.onGround) { - this.motY /= 2.0D; - this.motY += (double) f; - if (this.motY > 0.4000000059604645D) { - this.motY = 0.4000000059604645D; - } - } + this.setMot(vec3d.x / 2.0D - vec3d1.x, this.onGround ? Math.min(0.4D, vec3d.y / 2.0D + (double) f) : vec3d.y, vec3d.z / 2.0D - vec3d1.z); // Paper start - call EntityKnockbackByEntityEvent - org.bukkit.util.Vector delta = new org.bukkit.util.Vector(this.motX - oldMotX, this.motY - oldMotY, this.motZ - oldMotZ); + Vec3D currentMot = this.getMot(); + org.bukkit.util.Vector delta = new org.bukkit.util.Vector(currentMot.x - vec3d.x, currentMot.y - vec3d.y, currentMot.z - vec3d.z); // Restore old velocity to be able to access it in the event - this.motX = oldMotX; - this.motY = oldMotY; - this.motZ = oldMotZ; + this.setMot(vec3d); if (entity == null || new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent((LivingEntity) getBukkitEntity(), entity.getBukkitEntity(), f, delta).callEvent()) { - this.motX += delta.getX(); - this.motY += delta.getY(); - this.motZ += delta.getZ(); + this.setMot(vec3d.x + delta.getX(), vec3d.y + delta.getY(), vec3d.z + delta.getZ()); } // Paper end } } @Nullable - protected SoundEffect d(DamageSource damagesource) { + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_GENERIC_HURT; } - @Nullable public SoundEffect getDeathSoundEffect() { return cs();} // Paper - OBFHELPER + public final SoundEffect getDeathSoundEffect() { return this.getSoundDeath(); } // Paper - OBFHELPER @Nullable - protected SoundEffect cs() { + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_GENERIC_DEATH; } - protected SoundEffect m(int i) { + protected SoundEffect getSoundFall(int i) { return i > 4 ? SoundEffects.ENTITY_GENERIC_BIG_FALL : SoundEffects.ENTITY_GENERIC_SMALL_FALL; } - protected void dropDeathLoot(boolean flag, int i) {} + protected SoundEffect c(ItemStack itemstack) { + return SoundEffects.ENTITY_GENERIC_DRINK; + } - public boolean z_() { - int i = MathHelper.floor(this.locX); - int j = MathHelper.floor(this.getBoundingBox().minY); - int k = MathHelper.floor(this.locZ); + public SoundEffect d(ItemStack itemstack) { + return SoundEffects.ENTITY_GENERIC_EAT; + } - if (this instanceof EntityHuman && ((EntityHuman) this).isSpectator()) { + public boolean isClimbing() { + if (this.isSpectator()) { return false; } else { - BlockPosition blockposition = new BlockPosition(i, j, k); - IBlockData iblockdata = this.world.getType(blockposition); + IBlockData iblockdata = this.cI(); Block block = iblockdata.getBlock(); - return block != Blocks.LADDER && block != Blocks.VINE ? block instanceof BlockTrapdoor && this.b(blockposition, iblockdata) : true; + return block != Blocks.LADDER && block != Blocks.VINE && block != Blocks.SCAFFOLDING ? block instanceof BlockTrapdoor && this.b(new BlockPosition(this), iblockdata) : true; } } + public IBlockData cI() { + return this.world.getType(new BlockPosition(this)); + } + private boolean b(BlockPosition blockposition, IBlockData iblockdata) { if ((Boolean) iblockdata.get(BlockTrapdoor.OPEN)) { IBlockData iblockdata1 = this.world.getType(blockposition.down()); @@ -1372,12 +1524,14 @@ public abstract class EntityLiving extends Entity { return false; } + @Override public boolean isAlive() { return !this.dead && this.getHealth() > 0.0F; } - public void c(float f, float f1) { - super.c(f, f1); + @Override + public void b(float f, float f1) { + super.b(f, f1); MobEffect mobeffect = this.getEffect(MobEffects.JUMP); float f2 = mobeffect == null ? 0.0F : (float) (mobeffect.getAmplifier() + 1); int i = MathHelper.f((f - 3.0F - f2) * f1); @@ -1388,7 +1542,7 @@ public abstract class EntityLiving extends Entity { return; } // CraftBukkit end - this.a(this.m(i), 1.0F, 1.0F); + this.a(this.getSoundFall(i), 1.0F, 1.0F); // this.damageEntity(DamageSource.FALL, (float) i); // CraftBukkit - moved up int j = MathHelper.floor(this.locX); int k = MathHelper.floor(this.locY - 0.20000000298023224D); @@ -1396,7 +1550,7 @@ public abstract class EntityLiving extends Entity { IBlockData iblockdata = this.world.getType(new BlockPosition(j, k, l)); if (!iblockdata.isAir()) { - SoundEffectType soundeffecttype = iblockdata.getBlock().getStepSound(); + SoundEffectType soundeffecttype = iblockdata.r(); this.a(soundeffecttype.g(), soundeffecttype.a() * 0.5F, soundeffecttype.b() * 0.75F); } @@ -1405,7 +1559,7 @@ public abstract class EntityLiving extends Entity { } public int getArmorStrength() { - AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.h); + AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.ARMOR); return MathHelper.floor(attributeinstance.getValue()); } @@ -1417,7 +1571,7 @@ public abstract class EntityLiving extends Entity { protected float applyArmorModifier(DamageSource damagesource, float f) { if (!damagesource.ignoresArmor()) { // this.damageArmor(f); // CraftBukkit - Moved into damageEntity0(DamageSource, float) - f = CombatMath.a(f, (float) this.getArmorStrength(), (float) this.getAttributeInstance(GenericAttributes.i).getValue()); + f = CombatMath.a(f, (float) this.getArmorStrength(), (float) this.getAttributeInstance(GenericAttributes.ARMOR_TOUGHNESS).getValue()); } return f; @@ -1550,7 +1704,9 @@ public abstract class EntityLiving extends Entity { // Apply damage to helmet if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(EnumItemSlot.HEAD) != null) { - this.getEquipment(EnumItemSlot.HEAD).damage((int) (event.getDamage() * 4.0F + this.random.nextFloat() * event.getDamage() * 2.0F), this); + this.getEquipment(EnumItemSlot.HEAD).damage((int) (event.getDamage() * 4.0F + this.random.nextFloat() * event.getDamage() * 2.0F), this, (entityliving) -> { + entityliving.c(EnumItemSlot.HEAD); + }); } // Apply damage to armor @@ -1566,7 +1722,7 @@ public abstract class EntityLiving extends Entity { Entity entity = damagesource.j(); if (entity instanceof EntityLiving) { - this.c((EntityLiving) entity); + this.shieldBlock((EntityLiving) entity); } } @@ -1630,20 +1786,20 @@ public abstract class EntityLiving extends Entity { } @Nullable - public EntityLiving cv() { + public EntityLiving getKillingEntity() { return (EntityLiving) (this.combatTracker.c() != null ? this.combatTracker.c() : (this.killer != null ? this.killer : (this.lastDamager != null ? this.lastDamager : null))); } public final float getMaxHealth() { - return (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue(); + return (float) this.getAttributeInstance(GenericAttributes.MAX_HEALTH).getValue(); } public final int getArrowCount() { - return (Integer) this.datawatcher.get(EntityLiving.bx); + return (Integer) this.datawatcher.get(EntityLiving.g); } public final void setArrowCount(int i) { - this.datawatcher.set(EntityLiving.bx, i); + this.datawatcher.set(EntityLiving.g, i); } private int l() { @@ -1651,35 +1807,36 @@ public abstract class EntityLiving extends Entity { } public void a(EnumHand enumhand) { - if (!this.ax || this.az >= this.l() / 2 || this.az < 0) { - this.az = -1; - this.ax = true; - this.ay = enumhand; + if (!this.at || this.av >= this.l() / 2 || this.av < 0) { + this.av = -1; + this.at = true; + this.au = enumhand; if (this.world instanceof WorldServer) { - ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutAnimation(this, enumhand == EnumHand.MAIN_HAND ? 0 : 3))); + ((WorldServer) this.world).getChunkProvider().broadcast(this, new PacketPlayOutAnimation(this, enumhand == EnumHand.MAIN_HAND ? 0 : 3)); } } } - protected void aa() { + @Override + protected void af() { this.damageEntity(DamageSource.OUT_OF_WORLD, 4.0F); } - protected void cy() { + protected void cO() { int i = this.l(); - if (this.ax) { - ++this.az; - if (this.az >= i) { - this.az = 0; - this.ax = false; + if (this.at) { + ++this.av; + if (this.av >= i) { + this.av = 0; + this.at = false; } } else { - this.az = 0; + this.av = 0; } - this.aG = (float) this.az / (float) i; + this.aC = (float) this.av / (float) i; } public AttributeInstance getAttributeInstance(IAttribute iattribute) { @@ -1734,33 +1891,51 @@ public abstract class EntityLiving extends Entity { return !this.getEquipment(enumitemslot).isEmpty(); } + @Override public abstract Iterable getArmorItems(); public abstract ItemStack getEquipment(EnumItemSlot enumitemslot); public abstract void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack); + public float cT() { + Iterable iterable = this.getArmorItems(); + int i = 0; + int j = 0; + + for (Iterator iterator = iterable.iterator(); iterator.hasNext(); ++i) { + ItemStack itemstack = (ItemStack) iterator.next(); + + if (!itemstack.isEmpty()) { + ++j; + } + } + + return i > 0 ? (float) j / (float) i : 0.0F; + } + + @Override public void setSprinting(boolean flag) { super.setSprinting(flag); AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); if (attributeinstance.a(EntityLiving.b) != null) { - attributeinstance.c(EntityLiving.c); + attributeinstance.removeModifier(EntityLiving.c); } if (flag) { - attributeinstance.b(EntityLiving.c); + attributeinstance.addModifier(EntityLiving.c); } } - public float getDeathSoundVolume() { return cD();} // Paper - OBFHELPER - protected float cD() { + public final float getDeathSoundVolume() { return this.getSoundVolume(); } // Paper - OBFHELPER + protected float getSoundVolume() { return 1.0F; } - public float getDeathSoundPitch() { return cE();} // Paper - OBFHELPER - protected float cE() { + public float getSoundPitch() { return cV();} // Paper - OBFHELPER + protected float cV() { return this.isBaby() ? (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.5F : (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F; } @@ -1768,24 +1943,32 @@ public abstract class EntityLiving extends Entity { return this.getHealth() <= 0.0F; } - public void A(Entity entity) { + @Override + public void collide(Entity entity) { + if (!this.isSleeping()) { + super.collide(entity); + } + + } + + public void B(Entity entity) { double d0; if (!(entity instanceof EntityBoat) && !(entity instanceof EntityHorseAbstract)) { double d1 = entity.locX; - double d2 = entity.getBoundingBox().minY + (double) entity.length; + double d2 = entity.getBoundingBox().minY + (double) entity.getHeight(); d0 = entity.locZ; EnumDirection enumdirection = entity.getAdjustedDirection(); if (enumdirection != null) { EnumDirection enumdirection1 = enumdirection.e(); - int[][] aint = new int[][] { { 0, 1}, { 0, -1}, { -1, 1}, { -1, -1}, { 1, 1}, { 1, -1}, { -1, 0}, { 1, 0}, { 0, 1}}; + int[][] aint = new int[][]{{0, 1}, {0, -1}, {-1, 1}, {-1, -1}, {1, 1}, {1, -1}, {-1, 0}, {1, 0}, {0, 1}}; double d3 = Math.floor(this.locX) + 0.5D; double d4 = Math.floor(this.locZ) + 0.5D; double d5 = this.getBoundingBox().maxX - this.getBoundingBox().minX; double d6 = this.getBoundingBox().maxZ - this.getBoundingBox().minZ; - AxisAlignedBB axisalignedbb = new AxisAlignedBB(d3 - d5 / 2.0D, entity.getBoundingBox().minY, d4 - d6 / 2.0D, d3 + d5 / 2.0D, Math.floor(entity.getBoundingBox().minY) + (double) this.length, d4 + d6 / 2.0D); + AxisAlignedBB axisalignedbb = new AxisAlignedBB(d3 - d5 / 2.0D, entity.getBoundingBox().minY, d4 - d6 / 2.0D, d3 + d5 / 2.0D, Math.floor(entity.getBoundingBox().minY) + (double) this.getHeight(), d4 + d6 / 2.0D); int[][] aint1 = aint; int i = aint.length; @@ -1796,31 +1979,36 @@ public abstract class EntityLiving extends Entity { double d9 = d3 + d7; double d10 = d4 + d8; AxisAlignedBB axisalignedbb1 = axisalignedbb.d(d7, 0.0D, d8); + BlockPosition blockposition; if (this.world.getCubes(this, axisalignedbb1)) { - if (this.world.getType(new BlockPosition(d9, this.locY, d10)).q()) { + blockposition = new BlockPosition(d9, this.locY, d10); + if (this.world.getType(blockposition).a((IBlockAccess) this.world, blockposition, (Entity) this)) { this.enderTeleportTo(d9, this.locY + 1.0D, d10); return; } - BlockPosition blockposition = new BlockPosition(d9, this.locY - 1.0D, d10); + BlockPosition blockposition1 = new BlockPosition(d9, this.locY - 1.0D, d10); - if (this.world.getType(blockposition).q() || this.world.getFluid(blockposition).a(TagsFluid.WATER)) { + if (this.world.getType(blockposition1).a((IBlockAccess) this.world, blockposition1, (Entity) this) || this.world.getFluid(blockposition1).a(TagsFluid.WATER)) { d1 = d9; d2 = this.locY + 1.0D; d0 = d10; } - } else if (this.world.getCubes(this, axisalignedbb1.d(0.0D, 1.0D, 0.0D)) && this.world.getType(new BlockPosition(d9, this.locY + 1.0D, d10)).q()) { - d1 = d9; - d2 = this.locY + 2.0D; - d0 = d10; + } else { + blockposition = new BlockPosition(d9, this.locY + 1.0D, d10); + if (this.world.getCubes(this, axisalignedbb1.d(0.0D, 1.0D, 0.0D)) && this.world.getType(blockposition).a((IBlockAccess) this.world, blockposition, (Entity) this)) { + d1 = d9; + d2 = this.locY + 2.0D; + d0 = d10; + } } } } this.enderTeleportTo(d1, d2, d0); } else { - double d11 = (double) (this.width / 2.0F + entity.width / 2.0F) + 0.4D; + double d11 = (double) (this.getWidth() / 2.0F + entity.getWidth() / 2.0F) + 0.4D; float f; if (entity instanceof EntityBoat) { @@ -1836,160 +2024,173 @@ public abstract class EntityLiving extends Entity { double d12 = this.locX + (double) f1 * d0; double d13 = this.locZ + (double) f2 * d0; - this.setPosition(d12, entity.locY + (double) entity.length + 0.001D, d13); + this.setPosition(d12, entity.locY + (double) entity.getHeight() + 0.001D, d13); if (!this.world.getCubes(this, this.getBoundingBox().b(entity.getBoundingBox()))) { - this.setPosition(d12, entity.locY + (double) entity.length + 1.001D, d13); + this.setPosition(d12, entity.locY + (double) entity.getHeight() + 1.001D, d13); if (!this.world.getCubes(this, this.getBoundingBox().b(entity.getBoundingBox()))) { - this.setPosition(entity.locX, entity.locY + (double) this.length + 0.001D, entity.locZ); + this.setPosition(entity.locX, entity.locY + (double) this.getHeight() + 0.001D, entity.locZ); } } } } - protected float cG() { + protected float cX() { return 0.42F; } - protected void cH() { - this.motY = (double) this.cG(); + protected void jump() { + float f; + if (this.hasEffect(MobEffects.JUMP)) { - this.motY += (double) ((float) (this.getEffect(MobEffects.JUMP).getAmplifier() + 1) * 0.1F); + f = this.cX() + 0.1F * (float) (this.getEffect(MobEffects.JUMP).getAmplifier() + 1); + } else { + f = this.cX(); } - if (this.isSprinting()) { - float f = this.yaw * 0.017453292F; + Vec3D vec3d = this.getMot(); - this.motX -= (double) (MathHelper.sin(f) * 0.2F); - this.motZ += (double) (MathHelper.cos(f) * 0.2F); + this.setMot(vec3d.x, (double) f, vec3d.z); + if (this.isSprinting()) { + float f1 = this.yaw * 0.017453292F; + + this.setMot(this.getMot().add((double) (-MathHelper.sin(f1) * 0.2F), 0.0D, (double) (MathHelper.cos(f1) * 0.2F))); } this.impulse = true; } protected void c(Tag tag) { - this.motY += 0.03999999910593033D; + this.setMot(this.getMot().add(0.0D, 0.03999999910593033D, 0.0D)); } - protected float cJ() { + protected float da() { return 0.8F; } - public void a(float f, float f1, float f2) { + public void e(Vec3D vec3d) { double d0; - double d1; - float f3; - double d2; + float f; - if (this.cP() || this.bT()) { + if (this.df() || this.ca()) { d0 = 0.08D; - if (this.motY <= 0.0D && this.hasEffect(MobEffects.SLOW_FALLING)) { + boolean flag = this.getMot().y <= 0.0D; + + if (flag && this.hasEffect(MobEffects.SLOW_FALLING)) { d0 = 0.01D; this.fallDistance = 0.0F; } - float f4; + double d1; + float f1; + double d2; if (this.isInWater() && (!(this instanceof EntityHuman) || !((EntityHuman) this).abilities.isFlying)) { d1 = this.locY; - float f5 = this.isSprinting() ? 0.9F : this.cJ(); + f1 = this.isSprinting() ? 0.9F : this.da(); + f = 0.02F; + float f2 = (float) EnchantmentManager.e(this); - f4 = 0.02F; - f3 = (float) EnchantmentManager.e(this); - if (f3 > 3.0F) { - f3 = 3.0F; + if (f2 > 3.0F) { + f2 = 3.0F; } if (!this.onGround) { - f3 *= 0.5F; + f2 *= 0.5F; } - if (f3 > 0.0F) { - f5 += (0.54600006F - f5) * f3 / 3.0F; - f4 += (this.cK() - f4) * f3 / 3.0F; + if (f2 > 0.0F) { + f1 += (0.54600006F - f1) * f2 / 3.0F; + f += (this.db() - f) * f2 / 3.0F; } if (this.hasEffect(MobEffects.DOLPHINS_GRACE)) { - f5 = 0.96F; + f1 = 0.96F; } - this.a(f, f1, f2, f4); - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - this.motX *= (double) f5; - this.motY *= 0.800000011920929D; - this.motZ *= (double) f5; + this.a(f, vec3d); + this.move(EnumMoveType.SELF, this.getMot()); + Vec3D vec3d1 = this.getMot(); + + if (this.positionChanged && this.isClimbing()) { + vec3d1 = new Vec3D(vec3d1.x, 0.2D, vec3d1.z); + } + + this.setMot(vec3d1.d((double) f1, 0.800000011920929D, (double) f1)); + Vec3D vec3d2; + if (!this.isNoGravity() && !this.isSprinting()) { - if (this.motY <= 0.0D && Math.abs(this.motY - 0.005D) >= 0.003D && Math.abs(this.motY - d0 / 16.0D) < 0.003D) { - this.motY = -0.003D; + vec3d2 = this.getMot(); + if (flag && Math.abs(vec3d2.y - 0.005D) >= 0.003D && Math.abs(vec3d2.y - d0 / 16.0D) < 0.003D) { + d2 = -0.003D; } else { - this.motY -= d0 / 16.0D; + d2 = vec3d2.y - d0 / 16.0D; } + + this.setMot(vec3d2.x, d2, vec3d2.z); } - if (this.positionChanged && this.c(this.motX, this.motY + 0.6000000238418579D - this.locY + d1, this.motZ)) { - this.motY = 0.30000001192092896D; + vec3d2 = this.getMot(); + if (this.positionChanged && this.d(vec3d2.x, vec3d2.y + 0.6000000238418579D - this.locY + d1, vec3d2.z)) { + this.setMot(vec3d2.x, 0.30000001192092896D, vec3d2.z); } - } else if (this.ax() && (!(this instanceof EntityHuman) || !((EntityHuman) this).abilities.isFlying)) { + } else if (this.aD() && (!(this instanceof EntityHuman) || !((EntityHuman) this).abilities.isFlying)) { d1 = this.locY; - this.a(f, f1, f2, 0.02F); - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - this.motX *= 0.5D; - this.motY *= 0.5D; - this.motZ *= 0.5D; + this.a(0.02F, vec3d); + this.move(EnumMoveType.SELF, this.getMot()); + this.setMot(this.getMot().a(0.5D)); if (!this.isNoGravity()) { - this.motY -= d0 / 4.0D; + this.setMot(this.getMot().add(0.0D, -d0 / 4.0D, 0.0D)); } - if (this.positionChanged && this.c(this.motX, this.motY + 0.6000000238418579D - this.locY + d1, this.motZ)) { - this.motY = 0.30000001192092896D; + Vec3D vec3d3 = this.getMot(); + + if (this.positionChanged && this.d(vec3d3.x, vec3d3.y + 0.6000000238418579D - this.locY + d1, vec3d3.z)) { + this.setMot(vec3d3.x, 0.30000001192092896D, vec3d3.z); } - } else if (this.dc()) { - if (this.motY > -0.5D) { + } else if (this.isGliding()) { + Vec3D vec3d4 = this.getMot(); + + if (vec3d4.y > -0.5D) { this.fallDistance = 1.0F; } - Vec3D vec3d = this.aN(); - float f6 = this.pitch * 0.017453292F; + Vec3D vec3d5 = this.getLookDirection(); - d2 = Math.sqrt(vec3d.x * vec3d.x + vec3d.z * vec3d.z); - double d3 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); - double d4 = vec3d.b(); - float f7 = MathHelper.cos(f6); + f1 = this.pitch * 0.017453292F; + double d3 = Math.sqrt(vec3d5.x * vec3d5.x + vec3d5.z * vec3d5.z); + double d4 = Math.sqrt(b(vec3d4)); - f7 = (float) ((double) f7 * (double) f7 * Math.min(1.0D, d4 / 0.4D)); - this.motY += d0 * (-1.0D + (double) f7 * 0.75D); + d2 = vec3d5.f(); + float f3 = MathHelper.cos(f1); + + f3 = (float) ((double) f3 * (double) f3 * Math.min(1.0D, d2 / 0.4D)); + vec3d4 = this.getMot().add(0.0D, d0 * (-1.0D + (double) f3 * 0.75D), 0.0D); double d5; - if (this.motY < 0.0D && d2 > 0.0D) { - d5 = this.motY * -0.1D * (double) f7; - this.motY += d5; - this.motX += vec3d.x * d5 / d2; - this.motZ += vec3d.z * d5 / d2; + if (vec3d4.y < 0.0D && d3 > 0.0D) { + d5 = vec3d4.y * -0.1D * (double) f3; + vec3d4 = vec3d4.add(vec3d5.x * d5 / d3, d5, vec3d5.z * d5 / d3); } - if (f6 < 0.0F && d2 > 0.0D) { - d5 = d3 * (double) (-MathHelper.sin(f6)) * 0.04D; - this.motY += d5 * 3.2D; - this.motX -= vec3d.x * d5 / d2; - this.motZ -= vec3d.z * d5 / d2; + if (f1 < 0.0F && d3 > 0.0D) { + d5 = d4 * (double) (-MathHelper.sin(f1)) * 0.04D; + vec3d4 = vec3d4.add(-vec3d5.x * d5 / d3, d5 * 3.2D, -vec3d5.z * d5 / d3); } - if (d2 > 0.0D) { - this.motX += (vec3d.x / d2 * d3 - this.motX) * 0.1D; - this.motZ += (vec3d.z / d2 * d3 - this.motZ) * 0.1D; + if (d3 > 0.0D) { + vec3d4 = vec3d4.add((vec3d5.x / d3 * d4 - vec3d4.x) * 0.1D, 0.0D, (vec3d5.z / d3 * d4 - vec3d4.z) * 0.1D); } - this.motX *= 0.9900000095367432D; - this.motY *= 0.9800000190734863D; - this.motZ *= 0.9900000095367432D; - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); + this.setMot(vec3d4.d(0.9900000095367432D, 0.9800000190734863D, 0.9900000095367432D)); + this.move(EnumMoveType.SELF, this.getMot()); if (this.positionChanged && !this.world.isClientSide) { - d5 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); - double d6 = d3 - d5; - float f8 = (float) (d6 * 10.0D - 3.0D); + d5 = Math.sqrt(b(this.getMot())); + double d6 = d4 - d5; + float f4 = (float) (d6 * 10.0D - 3.0D); - if (f8 > 0.0F) { - this.a(this.m((int) f8), 1.0F, 1.0F); - this.damageEntity(DamageSource.FLY_INTO_WALL, f8); + if (f4 > 0.0F) { + this.a(this.getSoundFall((int) f4), 1.0F, 1.0F); + this.damageEntity(DamageSource.FLY_INTO_WALL, f4); } } @@ -1998,133 +2199,102 @@ public abstract class EntityLiving extends Entity { this.setFlag(7, false); } } else { - float f9 = 0.91F; - BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.d(this.locX, this.getBoundingBox().minY - 1.0D, this.locZ); - Throwable throwable = null; + BlockPosition blockposition = new BlockPosition(this.locX, this.getBoundingBox().minY - 1.0D, this.locZ); + float f5 = this.world.getType(blockposition).getBlock().m(); - try { - if (this.onGround) { - f9 = this.world.getType(blockposition_pooledblockposition).getBlock().n() * 0.91F; - } - - f4 = 0.16277137F / (f9 * f9 * f9); - if (this.onGround) { - f3 = this.cK() * f4; - } else { - f3 = this.aU; - } - - this.a(f, f1, f2, f3); - f9 = 0.91F; - if (this.onGround) { - f9 = this.world.getType(blockposition_pooledblockposition.c(this.locX, this.getBoundingBox().minY - 1.0D, this.locZ)).getBlock().n() * 0.91F; - } - - if (this.z_()) { - float f10 = 0.15F; - - this.motX = MathHelper.a(this.motX, -0.15000000596046448D, 0.15000000596046448D); - this.motZ = MathHelper.a(this.motZ, -0.15000000596046448D, 0.15000000596046448D); - this.fallDistance = 0.0F; - if (this.motY < -0.15D) { - this.motY = -0.15D; - } - - boolean flag = this.isSneaking() && this instanceof EntityHuman; - - if (flag && this.motY < 0.0D) { - this.motY = 0.0D; - } - } - - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - if (this.positionChanged && this.z_()) { - this.motY = 0.2D; - } - - if (this.hasEffect(MobEffects.LEVITATION)) { - this.motY += (0.05D * (double) (this.getEffect(MobEffects.LEVITATION).getAmplifier() + 1) - this.motY) * 0.2D; - this.fallDistance = 0.0F; - } else { - blockposition_pooledblockposition.c(this.locX, 0.0D, this.locZ); - if (this.world.isClientSide && (!this.world.isLoaded(blockposition_pooledblockposition) || !this.world.getChunkAtWorldCoords(blockposition_pooledblockposition).y())) { - if (this.locY > 0.0D) { - this.motY = -0.1D; - } else { - this.motY = 0.0D; - } - } else if (!this.isNoGravity()) { - this.motY -= d0; - } - } - - this.motY *= 0.9800000190734863D; - this.motX *= (double) f9; - this.motZ *= (double) f9; - } catch (Throwable throwable1) { - throwable = throwable1; - throw throwable1; - } finally { - if (blockposition_pooledblockposition != null) { - if (throwable != null) { - try { - blockposition_pooledblockposition.close(); - } catch (Throwable throwable2) { - throwable.addSuppressed(throwable2); - } - } else { - blockposition_pooledblockposition.close(); - } - } + f1 = this.onGround ? f5 * 0.91F : 0.91F; + this.a(this.r(f5), vec3d); + this.setMot(this.f(this.getMot())); + this.move(EnumMoveType.SELF, this.getMot()); + Vec3D vec3d6 = this.getMot(); + if ((this.positionChanged || this.jumping) && this.isClimbing()) { + vec3d6 = new Vec3D(vec3d6.x, 0.2D, vec3d6.z); } + + double d7 = vec3d6.y; + + if (this.hasEffect(MobEffects.LEVITATION)) { + d7 += (0.05D * (double) (this.getEffect(MobEffects.LEVITATION).getAmplifier() + 1) - vec3d6.y) * 0.2D; + this.fallDistance = 0.0F; + } else if (this.world.isClientSide && !this.world.isLoaded(blockposition)) { + if (this.locY > 0.0D) { + d7 = -0.1D; + } else { + d7 = 0.0D; + } + } else if (!this.isNoGravity()) { + d7 -= d0; + } + + this.setMot(vec3d6.x * (double) f1, d7 * 0.9800000190734863D, vec3d6.z * (double) f1); } } - this.aI = this.aJ; + this.aE = this.aF; d0 = this.locX - this.lastX; - d1 = this.locZ - this.lastZ; - d2 = this instanceof EntityBird ? this.locY - this.lastY : 0.0D; - f3 = MathHelper.sqrt(d0 * d0 + d2 * d2 + d1 * d1) * 4.0F; - if (f3 > 1.0F) { - f3 = 1.0F; + double d8 = this.locZ - this.lastZ; + double d9 = this instanceof EntityBird ? this.locY - this.lastY : 0.0D; + + f = MathHelper.sqrt(d0 * d0 + d9 * d9 + d8 * d8) * 4.0F; + if (f > 1.0F) { + f = 1.0F; } - this.aJ += (f3 - this.aJ) * 0.4F; - this.aK += this.aJ; + this.aF += (f - this.aF) * 0.4F; + this.aG += this.aF; } - public float cK() { - return this.bI; + private Vec3D f(Vec3D vec3d) { + if (this.isClimbing()) { + this.fallDistance = 0.0F; + float f = 0.15F; + double d0 = MathHelper.a(vec3d.x, -0.15000000596046448D, 0.15000000596046448D); + double d1 = MathHelper.a(vec3d.z, -0.15000000596046448D, 0.15000000596046448D); + double d2 = Math.max(vec3d.y, -0.15000000596046448D); + + if (d2 < 0.0D && this.cI().getBlock() != Blocks.SCAFFOLDING && this.isSneaking() && this instanceof EntityHuman) { + d2 = 0.0D; + } + + vec3d = new Vec3D(d0, d2, d1); + } + + return vec3d; + } + + private float r(float f) { + return this.onGround ? this.db() * (0.21600002F / (f * f * f)) : this.aO; + } + + public float db() { + return this.bD; } public void o(float f) { - this.bI = f; + this.bD = f; } - public boolean B(Entity entity) { + public boolean C(Entity entity) { this.z(entity); return false; } - public boolean isSleeping() { - return false; - } - + @Override public void tick() { super.tick(); - this.cV(); this.o(); + this.p(); if (!this.world.isClientSide) { int i = this.getArrowCount(); if (i > 0) { - if (this.aA <= 0) { - this.aA = 20 * (30 - i); + if (this.aw <= 0) { + this.aw = 20 * (30 - i); } - --this.aA; - if (this.aA <= 0) { + --this.aw; + if (this.aw <= 0) { this.setArrowCount(i - 1); } } @@ -2142,22 +2312,26 @@ public abstract class EntityLiving extends Entity { this.setFlag(6, flag); } } + + if (this.isSleeping() && !this.r()) { + this.dy(); + } } this.movementTick(); double d0 = this.locX - this.lastX; double d1 = this.locZ - this.lastZ; float f = (float) (d0 * d0 + d1 * d1); - float f1 = this.aQ; + float f1 = this.aK; float f2 = 0.0F; - this.aZ = this.ba; + this.aT = this.aU; float f3 = 0.0F; if (f > 0.0025000002F) { f3 = 1.0F; f2 = (float) Math.sqrt((double) f) * 3.0F; - float f4 = (float) MathHelper.c(d1, d0) * 57.295776F - 90.0F; + float f4 = (float) MathHelper.d(d1, d0) * 57.295776F - 90.0F; float f5 = MathHelper.e(MathHelper.g(this.yaw) - f4); if (95.0F < f5 && f5 < 265.0F) { @@ -2167,7 +2341,7 @@ public abstract class EntityLiving extends Entity { } } - if (this.aG > 0.0F) { + if (this.aC > 0.0F) { f1 = this.yaw; } @@ -2175,11 +2349,11 @@ public abstract class EntityLiving extends Entity { f3 = 0.0F; } - this.ba += (f3 - this.ba) * 0.3F; - //this.world.methodProfiler.enter("headTurn"); // Akarin - remove caller + this.aU += (f3 - this.aU) * 0.3F; + this.world.getMethodProfiler().enter("headTurn"); f2 = this.e(f1, f2); - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.enter("rangeChecks"); // Akarin - remove caller + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("rangeChecks"); while (this.yaw - this.lastYaw < -180.0F) { this.lastYaw -= 360.0F; @@ -2189,12 +2363,12 @@ public abstract class EntityLiving extends Entity { this.lastYaw += 360.0F; } - while (this.aQ - this.aR < -180.0F) { - this.aR -= 360.0F; + while (this.aK - this.aL < -180.0F) { + this.aL -= 360.0F; } - while (this.aQ - this.aR >= 180.0F) { - this.aR += 360.0F; + while (this.aK - this.aL >= 180.0F) { + this.aL += 360.0F; } while (this.pitch - this.lastPitch < -180.0F) { @@ -2205,20 +2379,24 @@ public abstract class EntityLiving extends Entity { this.lastPitch += 360.0F; } - while (this.aS - this.aT < -180.0F) { - this.aT -= 360.0F; + while (this.aM - this.aN < -180.0F) { + this.aN -= 360.0F; } - while (this.aS - this.aT >= 180.0F) { - this.aT += 360.0F; + while (this.aM - this.aN >= 180.0F) { + this.aN += 360.0F; } - //this.world.methodProfiler.exit(); // Akarin - remove caller - this.bb += f2; - if (this.dc()) { - ++this.bv; + this.world.getMethodProfiler().exit(); + this.aV += f2; + if (this.isGliding()) { + ++this.bp; } else { - this.bv = 0; + this.bp = 0; + } + + if (this.isSleeping()) { + this.pitch = 0.0F; } } @@ -2233,10 +2411,10 @@ public abstract class EntityLiving extends Entity { switch (enumitemslot.a()) { case HAND: - itemstack = (ItemStack) this.bB.get(enumitemslot.b()); + itemstack = (ItemStack) this.bw.get(enumitemslot.b()); break; case ARMOR: - itemstack = (ItemStack) this.bC.get(enumitemslot.b()); + itemstack = (ItemStack) this.bx.get(enumitemslot.b()); break; default: continue; @@ -2252,7 +2430,7 @@ public abstract class EntityLiving extends Entity { new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); } // Paper end - ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1))); + ((WorldServer) this.world).getChunkProvider().broadcast(this, new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1)); if (!itemstack.isEmpty()) { this.getAttributeMap().a(itemstack.a(enumitemslot)); } @@ -2263,10 +2441,10 @@ public abstract class EntityLiving extends Entity { switch (enumitemslot.a()) { case HAND: - this.bB.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); + this.bw.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); break; case ARMOR: - this.bC.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); + this.bx.set(enumitemslot.b(), itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack()); } } } @@ -2274,10 +2452,10 @@ public abstract class EntityLiving extends Entity { // Paper end protected float e(float f, float f1) { - float f2 = MathHelper.g(f - this.aQ); + float f2 = MathHelper.g(f - this.aK); - this.aQ += f2 * 0.3F; - float f3 = MathHelper.g(this.yaw - this.aQ); + this.aK += f2 * 0.3F; + float f3 = MathHelper.g(this.yaw - this.aK); boolean flag = f3 < -90.0F || f3 >= 90.0F; if (f3 < -75.0F) { @@ -2288,9 +2466,9 @@ public abstract class EntityLiving extends Entity { f3 = 75.0F; } - this.aQ = this.yaw - f3; + this.aK = this.yaw - f3; if (f3 * f3 > 2500.0F) { - this.aQ += f3 * 0.2F; + this.aK += f3 * 0.2F; } if (flag) { @@ -2301,89 +2479,93 @@ public abstract class EntityLiving extends Entity { } public void movementTick() { - if (this.bJ > 0) { - --this.bJ; + if (this.jumpTicks > 0) { + --this.jumpTicks; } - if (this.bl > 0 && !this.bT()) { - double d0 = this.locX + (this.bm - this.locX) / (double) this.bl; - double d1 = this.locY + (this.bn - this.locY) / (double) this.bl; - double d2 = this.locZ + (this.bo - this.locZ) / (double) this.bl; - double d3 = MathHelper.g(this.bp - (double) this.yaw); + if (this.bf > 0 && !this.ca()) { + double d0 = this.locX + (this.bg - this.locX) / (double) this.bf; + double d1 = this.locY + (this.bh - this.locY) / (double) this.bf; + double d2 = this.locZ + (this.bi - this.locZ) / (double) this.bf; + double d3 = MathHelper.g(this.bj - (double) this.yaw); - this.yaw = (float) ((double) this.yaw + d3 / (double) this.bl); - this.pitch = (float) ((double) this.pitch + (this.bq - (double) this.pitch) / (double) this.bl); - --this.bl; + this.yaw = (float) ((double) this.yaw + d3 / (double) this.bf); + this.pitch = (float) ((double) this.pitch + (this.bk - (double) this.pitch) / (double) this.bf); + --this.bf; this.setPosition(d0, d1, d2); this.setYawPitch(this.yaw, this.pitch); - } else if (!this.cP()) { - this.motX *= 0.98D; - this.motY *= 0.98D; - this.motZ *= 0.98D; + } else if (!this.df()) { + this.setMot(this.getMot().a(0.98D)); } - if (this.bs > 0) { - this.aS = (float) ((double) this.aS + MathHelper.g(this.br - (double) this.aS) / (double) this.bs); - --this.bs; + if (this.bm > 0) { + this.aM = (float) ((double) this.aM + MathHelper.g(this.bl - (double) this.aM) / (double) this.bm); + --this.bm; } - if (Math.abs(this.motX) < 0.003D) { - this.motX = 0.0D; + Vec3D vec3d = this.getMot(); + double d4 = vec3d.x; + double d5 = vec3d.y; + double d6 = vec3d.z; + + if (Math.abs(vec3d.x) < 0.003D) { + d4 = 0.0D; } - if (Math.abs(this.motY) < 0.003D) { - this.motY = 0.0D; + if (Math.abs(vec3d.y) < 0.003D) { + d5 = 0.0D; } - if (Math.abs(this.motZ) < 0.003D) { - this.motZ = 0.0D; + if (Math.abs(vec3d.z) < 0.003D) { + d6 = 0.0D; } - //this.world.methodProfiler.enter("ai"); // Akarin - remove caller + this.setMot(d4, d5, d6); + this.world.getMethodProfiler().enter("ai"); if (this.isFrozen()) { - this.bg = false; - this.bh = 0.0F; - this.bj = 0.0F; - this.bk = 0.0F; - } else if (this.cP()) { - //this.world.methodProfiler.enter("newAi"); // Akarin - remove caller + this.jumping = false; + this.bb = 0.0F; + this.bd = 0.0F; + this.be = 0.0F; + } else if (this.df()) { + this.world.getMethodProfiler().enter("newAi"); this.doTick(); - //this.world.methodProfiler.exit(); // Akarin - remove caller + this.world.getMethodProfiler().exit(); } - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.enter("jump"); // Akarin - remove caller - if (this.bg) { - if (this.W > 0.0D && (!this.onGround || this.W > 0.4D)) { + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("jump"); + if (this.jumping) { + if (this.Q > 0.0D && (!this.onGround || this.Q > 0.4D)) { this.c(TagsFluid.WATER); - } else if (this.ax()) { + } else if (this.aD()) { this.c(TagsFluid.LAVA); - } else if ((this.onGround || this.W > 0.0D && this.W <= 0.4D) && this.bJ == 0) { - this.cH(); - this.bJ = 10; + } else if ((this.onGround || this.Q > 0.0D && this.Q <= 0.4D) && this.jumpTicks == 0) { + this.jump(); + this.jumpTicks = 10; } } else { - this.bJ = 0; + this.jumpTicks = 0; } - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.enter("travel"); // Akarin - remove caller - this.bh *= 0.98F; - this.bj *= 0.98F; - this.bk *= 0.9F; + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("travel"); + this.bb *= 0.98F; + this.bd *= 0.98F; + this.be *= 0.9F; this.n(); AxisAlignedBB axisalignedbb = this.getBoundingBox(); - this.a(this.bh, this.bi, this.bj); - //this.world.methodProfiler.exit(); // Akarin - remove caller - //this.world.methodProfiler.enter("push"); // Akarin - remove caller - if (this.bw > 0) { - --this.bw; + this.e(new Vec3D((double) this.bb, (double) this.bc, (double) this.bd)); + this.world.getMethodProfiler().exit(); + this.world.getMethodProfiler().enter("push"); + if (this.bq > 0) { + --this.bq; this.a(axisalignedbb, this.getBoundingBox()); } - this.cN(); - //this.world.methodProfiler.exit(); // Akarin - remove caller + this.collideNearby(); + this.world.getMethodProfiler().exit(); } private void n() { @@ -2394,8 +2576,10 @@ public abstract class EntityLiving extends Entity { if (itemstack.getItem() == Items.ELYTRA && ItemElytra.e(itemstack)) { flag = true; - if (!this.world.isClientSide && (this.bv + 1) % 20 == 0) { - itemstack.damage(1, this); + if (!this.world.isClientSide && (this.bp + 1) % 20 == 0) { + itemstack.damage(1, this, (entityliving) -> { + entityliving.c(EnumItemSlot.CHEST); + }); } } else { flag = false; @@ -2413,11 +2597,11 @@ public abstract class EntityLiving extends Entity { protected void doTick() {} - protected void cN() { + protected void collideNearby() { List list = this.world.getEntities(this, this.getBoundingBox(), IEntitySelector.a(this)); if (!list.isEmpty()) { - int i = this.world.getGameRules().c("maxEntityCramming"); + int i = this.world.getGameRules().getInt(GameRules.MAX_ENTITY_CRAMMING); int j; if (i > 0 && list.size() > i - 1 && this.random.nextInt(4) == 0) { @@ -2440,7 +2624,7 @@ public abstract class EntityLiving extends Entity { entity.numCollisions++; // Paper numCollisions++; // Paper - this.C(entity); + this.D(entity); } } @@ -2455,32 +2639,30 @@ public abstract class EntityLiving extends Entity { Entity entity = (Entity) list.get(i); if (entity instanceof EntityLiving) { - this.d((EntityLiving) entity); - this.bw = 0; - this.motX *= -0.2D; - this.motY *= -0.2D; - this.motZ *= -0.2D; + this.f((EntityLiving) entity); + this.bq = 0; + this.setMot(this.getMot().a(-0.2D)); break; } } } else if (this.positionChanged) { - this.bw = 0; + this.bq = 0; } - if (!this.world.isClientSide && this.bw <= 0) { + if (!this.world.isClientSide && this.bq <= 0) { this.c(4, false); } } - protected void C(Entity entity) { + protected void D(Entity entity) { entity.collide(this); } - protected void d(EntityLiving entityliving) {} + protected void f(EntityLiving entityliving) {} - public void o(int i) { - this.bw = i; + public void q(int i) { + this.bq = i; if (!this.world.isClientSide) { this.c(4, true); } @@ -2488,82 +2670,89 @@ public abstract class EntityLiving extends Entity { } public boolean isRiptiding() { - return ((Byte) this.datawatcher.get(EntityLiving.aw) & 4) != 0; + return ((Byte) this.datawatcher.get(EntityLiving.ar) & 4) != 0; } // Paper start - public void stopRiding() { stopRiding(false); } - public void stopRiding(boolean suppressCancellation) { + @Override public void stopRiding() { stopRiding(false); } + @Override public void stopRiding(boolean suppressCancellation) { // Paper end Entity entity = this.getVehicle(); super.stopRiding(suppressCancellation); // Paper - suppress if (entity != null && entity != this.getVehicle() && !this.world.isClientSide) { - this.A(entity); + this.B(entity); } } - public void aH() { - super.aH(); - this.aZ = this.ba; - this.ba = 0.0F; + @Override + public void passengerTick() { + super.passengerTick(); + this.aT = this.aU; + this.aU = 0.0F; this.fallDistance = 0.0F; } - public void o(boolean flag) { - this.bg = flag; + public void setJumping(boolean flag) { + this.jumping = flag; } public void receive(Entity entity, int i) { - if (!entity.dead && !this.world.isClientSide) { - EntityTracker entitytracker = ((WorldServer) this.world).getTracker(); - - if (entity instanceof EntityItem || entity instanceof EntityArrow || entity instanceof EntityExperienceOrb) { - entitytracker.a(entity, (Packet) (new PacketPlayOutCollect(entity.getId(), this.getId(), i))); - } + if (!entity.dead && !this.world.isClientSide && (entity instanceof EntityItem || entity instanceof EntityArrow || entity instanceof EntityExperienceOrb)) { + ((WorldServer) this.world).getChunkProvider().broadcast(entity, new PacketPlayOutCollect(entity.getId(), this.getId(), i)); } } public boolean hasLineOfSight(Entity entity) { - return this.world.rayTrace(new Vec3D(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ), new Vec3D(entity.locX, entity.locY + (double) entity.getHeadHeight(), entity.locZ), FluidCollisionOption.NEVER, true, false) == null; + Vec3D vec3d = new Vec3D(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ); + Vec3D vec3d1 = new Vec3D(entity.locX, entity.locY + (double) entity.getHeadHeight(), entity.locZ); + + return this.world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS; } + @Override public float h(float f) { - return f == 1.0F ? this.aS : this.aT + (this.aS - this.aT) * f; + return f == 1.0F ? this.aM : MathHelper.g(f, this.aN, this.aM); } - public boolean cP() { + public boolean df() { return !this.world.isClientSide; } + @Override public boolean isInteractable() { return !this.dead && this.collides; // CraftBukkit } + @Override public boolean isCollidable() { - return this.isAlive() && !this.z_() && this.collides; // CraftBukkit + return this.isAlive() && !this.isClimbing() && this.collides; // CraftBukkit } - protected void aA() { - this.velocityChanged = this.random.nextDouble() >= this.getAttributeInstance(GenericAttributes.c).getValue(); + @Override + protected void velocityChanged() { + this.velocityChanged = this.random.nextDouble() >= this.getAttributeInstance(GenericAttributes.KNOCKBACK_RESISTANCE).getValue(); } + @Override public float getHeadRotation() { - return this.aS; + return this.aM; } + @Override public void setHeadRotation(float f) { - this.aS = f; + this.aM = f; } - public void k(float f) { - this.aQ = f; + @Override + public void l(float f) { + this.aK = f; } public float getAbsorptionHearts() { - return this.bK; + return this.bF; } public void setAbsorptionHearts(float f) { @@ -2571,56 +2760,57 @@ public abstract class EntityLiving extends Entity { f = 0.0F; } - this.bK = f; + this.bF = f; } public void enterCombat() {} public void exitCombat() {} - protected void cR() { + protected void dh() { this.updateEffects = true; } public abstract EnumMainHand getMainHand(); public boolean isHandRaised() { - return ((Byte) this.datawatcher.get(EntityLiving.aw) & 1) > 0; + return ((Byte) this.datawatcher.get(EntityLiving.ar) & 1) > 0; } - public EnumHand cU() { - return ((Byte) this.datawatcher.get(EntityLiving.aw) & 2) > 0 ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND; + public EnumHand getRaisedHand() { + return ((Byte) this.datawatcher.get(EntityLiving.ar) & 2) > 0 ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND; } - protected void cV() { + private void o() { if (this.isHandRaised()) { - if (this.b(this.cU()) == this.activeItem) { - if (this.cX() <= 25 && this.cX() % 4 == 0) { + if (ItemStack.d(this.b(this.getRaisedHand()), this.activeItem)) { + this.activeItem.b(this.world, this, this.dm()); + if (this.dm() <= 25 && this.dm() % 4 == 0) { this.b(this.activeItem, 5); } - if (--this.bu == 0 && !this.world.isClientSide) { + if (--this.bo == 0 && !this.world.isClientSide && !this.activeItem.m()) { this.q(); } } else { - this.da(); + this.dp(); } } } - private void o() { - this.bP = this.bO; - if (this.isSwimming()) { - this.bO = Math.min(1.0F, this.bO + 0.09F); + private void p() { + this.bK = this.bJ; + if (this.bk()) { + this.bJ = Math.min(1.0F, this.bJ + 0.09F); } else { - this.bO = Math.max(0.0F, this.bO - 0.09F); + this.bJ = Math.max(0.0F, this.bJ - 0.09F); } } protected void c(int i, boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntityLiving.aw); + byte b0 = (Byte) this.datawatcher.get(EntityLiving.ar); int j; if (flag) { @@ -2629,15 +2819,18 @@ public abstract class EntityLiving extends Entity { j = b0 & ~i; } - this.datawatcher.set(EntityLiving.aw, (byte) j); + this.datawatcher.set(EntityLiving.ar, (byte) j); } - public void c(EnumHand enumhand) { + // Paper start -- OBFHELPER and forwarder to method with forceUpdate parameter + public void c(EnumHand enumhand) { this.updateActiveItem(enumhand, false); } + public void updateActiveItem(EnumHand enumhand, boolean forceUpdate) { + // Paper end ItemStack itemstack = this.b(enumhand); - if (!itemstack.isEmpty() && !this.isHandRaised()) { + if (!itemstack.isEmpty() && !this.isHandRaised() || forceUpdate) { // Paper use override flag this.activeItem = itemstack; - this.bu = itemstack.k(); + this.bo = itemstack.k(); if (!this.world.isClientSide) { this.c(1, true); this.c(2, enumhand == EnumHand.OFF_HAND); @@ -2646,46 +2839,50 @@ public abstract class EntityLiving extends Entity { } } + @Override public void a(DataWatcherObject datawatcherobject) { super.a(datawatcherobject); - if (EntityLiving.aw.equals(datawatcherobject) && this.world.isClientSide) { + if (EntityLiving.bs.equals(datawatcherobject)) { + if (this.world.isClientSide) { + this.getBedPosition().ifPresent(this::a); + } + } else if (EntityLiving.ar.equals(datawatcherobject) && this.world.isClientSide) { if (this.isHandRaised() && this.activeItem.isEmpty()) { - this.activeItem = this.b(this.cU()); + this.activeItem = this.b(this.getRaisedHand()); if (!this.activeItem.isEmpty()) { - this.bu = this.activeItem.k(); + this.bo = this.activeItem.k(); } } else if (!this.isHandRaised() && !this.activeItem.isEmpty()) { this.activeItem = ItemStack.a; - this.bu = 0; + this.bo = 0; } } } + @Override public void a(ArgumentAnchor.Anchor argumentanchor_anchor, Vec3D vec3d) { super.a(argumentanchor_anchor, vec3d); - this.aT = this.aS; - this.aQ = this.aS; - this.aR = this.aQ; + this.aN = this.aM; + this.aK = this.aM; + this.aL = this.aK; } protected void b(ItemStack itemstack, int i) { if (!itemstack.isEmpty() && this.isHandRaised()) { if (itemstack.l() == EnumAnimation.DRINK) { - this.a(SoundEffects.ENTITY_GENERIC_DRINK, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + this.a(this.c(itemstack), 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); } if (itemstack.l() == EnumAnimation.EAT) { this.a(itemstack, i); - this.a(SoundEffects.ENTITY_GENERIC_EAT, 0.5F + 0.5F * (float) this.random.nextInt(2), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + this.a(this.d(itemstack), 0.5F + 0.5F * (float) this.random.nextInt(2), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); } } } private void a(ItemStack itemstack, int i) { - // Akarin start - this handle by client - /* for (int j = 0; j < i; ++j) { Vec3D vec3d = new Vec3D(((double) this.random.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D); @@ -2697,15 +2894,14 @@ public abstract class EntityLiving extends Entity { vec3d1 = vec3d1.a(-this.pitch * 0.017453292F); vec3d1 = vec3d1.b(-this.yaw * 0.017453292F); vec3d1 = vec3d1.add(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ); - this.world.addParticle(new ParticleParamItem(Particles.C, itemstack), vec3d1.x, vec3d1.y, vec3d1.z, vec3d.x, vec3d.y + 0.05D, vec3d.z); + this.world.addParticle(new ParticleParamItem(Particles.ITEM, itemstack), vec3d1.x, vec3d1.y, vec3d1.z, vec3d.x, vec3d.y + 0.05D, vec3d.z); } - */ - // Akarin end } protected void q() { if (!this.activeItem.isEmpty() && this.isHandRaised()) { + this.updateActiveItem(this.getRaisedHand(), true); // Paper PlayerItemConsumeEvent event = null; // Paper this.b(this.activeItem, 16); // CraftBukkit start - fire PlayerItemConsumeEvent @@ -2733,11 +2929,11 @@ public abstract class EntityLiving extends Entity { itemstack = CraftItemStack.asNMSCopy(event.getReplacement()); } // Paper end - this.a(this.cU(), itemstack); + this.a(this.getRaisedHand(), itemstack); // CraftBukkit end - this.da(); - // Paper start - if the replacement is anything but the default, update the client inventory - if (this instanceof EntityPlayer && !com.google.common.base.Objects.equal(defaultReplacement, itemstack)) { + this.dp(); + // Paper start + if (this instanceof EntityPlayer) { ((EntityPlayer) this).getBukkitEntity().updateInventory(); } // Paper end @@ -2745,52 +2941,60 @@ public abstract class EntityLiving extends Entity { } - public ItemStack cW() { + public ItemStack dl() { return this.activeItem; } - public int getItemUseRemainingTime() { return cX(); } // Paper - OBFHELPER - public int cX() { - return this.bu; + public int getItemUseRemainingTime() { return this.dm(); } // Paper - OBFHELPER + public int dm() { + return this.bo; } - public int getHandRaisedTime() { return cY(); } // Paper - OBFHELPER - public int cY() { - return this.isHandRaised() ? this.activeItem.k() - this.cX() : 0; + public int getHandRaisedTime() { return this.dn(); } // Paper - OBFHELPER + public int dn() { + return this.isHandRaised() ? this.activeItem.k() - this.dm() : 0; } public void clearActiveItem() { if (!this.activeItem.isEmpty()) { - this.activeItem.a(this.world, this, this.cX()); + this.activeItem.a(this.world, this, this.dm()); + if (this.activeItem.m()) { + this.o(); + } } - this.da(); + this.dp(); } - public void da() { + public void dp() { if (!this.world.isClientSide) { this.c(1, false); } this.activeItem = ItemStack.a; - this.bu = 0; + this.bo = 0; } public boolean isBlocking() { if (this.isHandRaised() && !this.activeItem.isEmpty()) { Item item = this.activeItem.getItem(); - return item.d(this.activeItem) != EnumAnimation.BLOCK ? false : item.c(this.activeItem) - this.bu >= getShieldBlockingDelay(); // Paper - shieldBlockingDelay + return item.e_(this.activeItem) != EnumAnimation.BLOCK ? false : item.f_(this.activeItem) - this.bo >= getShieldBlockingDelay(); // Paper - shieldBlockingDelay } else { return false; } } - public boolean dc() { + public boolean isGliding() { return this.getFlag(7); } - public boolean j(double d0, double d1, double d2) { + @Override + public boolean bk() { + return super.bk() || !this.isGliding() && this.getPose() == EntityPose.FALL_FLYING; + } + + public boolean a(double d0, double d1, double d2, boolean flag) { double d3 = this.locX; double d4 = this.locY; double d5 = this.locZ; @@ -2798,28 +3002,26 @@ public abstract class EntityLiving extends Entity { this.locX = d0; this.locY = d1; this.locZ = d2; - boolean flag = false; + boolean flag1 = false; BlockPosition blockposition = new BlockPosition(this); World world = this.world; - Random random = this.getRandom(); - boolean flag1; if (world.isLoaded(blockposition)) { - flag1 = false; + boolean flag2 = false; - while (!flag1 && blockposition.getY() > 0) { + while (!flag2 && blockposition.getY() > 0) { BlockPosition blockposition1 = blockposition.down(); IBlockData iblockdata = world.getType(blockposition1); if (iblockdata.getMaterial().isSolid()) { - flag1 = true; + flag2 = true; } else { --this.locY; blockposition = blockposition1; } } - if (flag1) { + if (flag2) { // CraftBukkit start - Teleport event // this.enderTeleportTo(this.locX, this.locY, this.locZ); EntityTeleportEvent teleport = new EntityTeleportEvent(this.getBukkitEntity(), new Location(this.world.getWorld(), d3, d4, d5), new Location(this.world.getWorld(), this.locX, this.locY, this.locZ)); @@ -2827,58 +3029,198 @@ public abstract class EntityLiving extends Entity { if (!teleport.isCancelled()) { Location to = teleport.getTo(); this.enderTeleportTo(to.getX(), to.getY(), to.getZ()); - if (world.getCubes((Entity) this, this.getBoundingBox()) && !world.containsLiquid(this.getBoundingBox())) { - flag = true; + if (world.getCubes(this) && !world.containsLiquid(this.getBoundingBox())) { + flag1 = true; } } // CraftBukkit end } } - if (!flag) { + if (!flag1) { this.enderTeleportTo(d3, d4, d5); return false; } else { - flag1 = true; - - // Akarin start - this handle by client - /* - for (int i = 0; i < 128; ++i) { - double d6 = (double) i / 127.0D; - float f = (random.nextFloat() - 0.5F) * 0.2F; - float f1 = (random.nextFloat() - 0.5F) * 0.2F; - float f2 = (random.nextFloat() - 0.5F) * 0.2F; - double d7 = d3 + (this.locX - d3) * d6 + (random.nextDouble() - 0.5D) * (double) this.width * 2.0D; - double d8 = d4 + (this.locY - d4) * d6 + random.nextDouble() * (double) this.length; - double d9 = d5 + (this.locZ - d5) * d6 + (random.nextDouble() - 0.5D) * (double) this.width * 2.0D; - - world.addParticle(Particles.K, d7, d8, d9, (double) f, (double) f1, (double) f2); + if (flag) { + world.broadcastEntityEffect(this, (byte) 46); } - */ - // Akarin end if (this instanceof EntityCreature) { - ((EntityCreature) this).getNavigation().q(); + ((EntityCreature) this).getNavigation().o(); } return true; } } - public boolean de() { + public boolean dt() { return true; } - public boolean df() { + public boolean du() { return true; } + public boolean e(ItemStack itemstack) { + return false; + } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntityLiving(this); + } + + @Override + public EntitySize a(EntityPose entitypose) { + return entitypose == EntityPose.SLEEPING ? EntityLiving.as : super.a(entitypose).a(this.cn()); + } + + public Optional getBedPosition() { + return (Optional) this.datawatcher.get(EntityLiving.bs); + } + + public void d(BlockPosition blockposition) { + this.datawatcher.set(EntityLiving.bs, Optional.of(blockposition)); + } + + public void dw() { + this.datawatcher.set(EntityLiving.bs, Optional.empty()); + } + + public boolean isSleeping() { + return this.getBedPosition().isPresent(); + } + + public void e(BlockPosition blockposition) { + if (this.isPassenger()) { + this.stopRiding(); + } + + IBlockData iblockdata = this.world.getType(blockposition); + + if (iblockdata.getBlock() instanceof BlockBed) { + this.world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockBed.OCCUPIED, true), 3); + } + + this.setPose(EntityPose.SLEEPING); + this.a(blockposition); + this.d(blockposition); + this.setMot(Vec3D.a); + this.impulse = true; + } + + private void a(BlockPosition blockposition) { + this.setPosition((double) blockposition.getX() + 0.5D, (double) ((float) blockposition.getY() + 0.6875F), (double) blockposition.getZ() + 0.5D); + } + + private boolean r() { + return (Boolean) this.getBedPosition().map((blockposition) -> { + return this.world.getType(blockposition).getBlock() instanceof BlockBed; + }).orElse(false); + } + + public void dy() { + Optional optional = this.getBedPosition(); // CraftBukkit - decompile error + World world = this.world; + + this.world.getClass(); + optional.filter(world::isLoaded).ifPresent((blockposition) -> { + IBlockData iblockdata = this.world.getType(blockposition); + + if (iblockdata.getBlock() instanceof BlockBed) { + this.world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockBed.OCCUPIED, false), 3); + Vec3D vec3d = (Vec3D) BlockBed.a(this.getEntityType(), (IWorldReader) this.world, blockposition, 0).orElseGet(() -> { + BlockPosition blockposition1 = blockposition.up(); + + return new Vec3D((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.1D, (double) blockposition1.getZ() + 0.5D); + }); + + this.setPosition(vec3d.x, vec3d.y, vec3d.z); + } + + }); + this.setPose(EntityPose.STANDING); + this.dw(); + } + + @Override + public boolean inBlock() { + return !this.isSleeping() && super.inBlock(); + } + + @Override + protected final float getHeadHeight(EntityPose entitypose, EntitySize entitysize) { + return entitypose == EntityPose.SLEEPING ? 0.2F : this.b(entitypose, entitysize); + } + + protected float b(EntityPose entitypose, EntitySize entitysize) { + return super.getHeadHeight(entitypose, entitysize); + } + + public ItemStack f(ItemStack itemstack) { + return ItemStack.a; + } + + public ItemStack a(World world, ItemStack itemstack) { + if (itemstack.E()) { + world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, this.d(itemstack), SoundCategory.NEUTRAL, 1.0F, 1.0F + (world.random.nextFloat() - world.random.nextFloat()) * 0.4F); + this.a(itemstack, world, this); + itemstack.subtract(1); + } + + return itemstack; + } + + private void a(ItemStack itemstack, World world, EntityLiving entityliving) { + Item item = itemstack.getItem(); + + if (item.isFood()) { + List> list = item.getFoodInfo().f(); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + Pair pair = (Pair) iterator.next(); + + if (!world.isClientSide && pair.getLeft() != null && world.random.nextFloat() < (Float) pair.getRight()) { + entityliving.addEffect(new MobEffect((MobEffect) pair.getLeft()), EntityPotionEffectEvent.Cause.FOOD); // CraftBukkit + } + } + } + + } + + private static byte d(EnumItemSlot enumitemslot) { + switch (enumitemslot) { + case MAINHAND: + return 47; + case OFFHAND: + return 48; + case HEAD: + return 49; + case CHEST: + return 50; + case FEET: + return 52; + case LEGS: + return 51; + default: + return 47; + } + } + + public void c(EnumItemSlot enumitemslot) { + this.world.broadcastEntityEffect(this, d(enumitemslot)); + } + + public void d(EnumHand enumhand) { + this.c(enumhand == EnumHand.MAIN_HAND ? EnumItemSlot.MAINHAND : EnumItemSlot.OFFHAND); + } // Paper start public MovingObjectPosition getRayTrace(int maxDistance) { - return getRayTrace(maxDistance, FluidCollisionOption.NEVER); + return getRayTrace(maxDistance, RayTrace.FluidCollisionOption.NONE); } - public MovingObjectPosition getRayTrace(int maxDistance, FluidCollisionOption fluidCollisionOption) { + public MovingObjectPosition getRayTrace(int maxDistance, RayTrace.FluidCollisionOption fluidCollisionOption) { if (maxDistance < 1 || maxDistance > 120) { throw new IllegalArgumentException("maxDistance must be between 1-120"); } @@ -2886,38 +3228,40 @@ public abstract class EntityLiving extends Entity { Vec3D start = new Vec3D(locX, locY + getHeadHeight(), locZ); org.bukkit.util.Vector dir = getBukkitEntity().getLocation().getDirection().multiply(maxDistance); Vec3D end = new Vec3D(start.x + dir.getX(), start.y + dir.getY(), start.z + dir.getZ()); + RayTrace raytrace = new RayTrace(start, end, RayTrace.BlockCollisionOption.OUTLINE, fluidCollisionOption, this); - return world.rayTrace(start, end, fluidCollisionOption); + return world.rayTrace(raytrace); } - public MovingObjectPosition getTargetEntity(int maxDistance) { + public MovingObjectPositionEntity getTargetEntity(int maxDistance) { if (maxDistance < 1 || maxDistance > 120) { throw new IllegalArgumentException("maxDistance must be between 1-120"); } - Vec3D start = getEyePosition(1.0F); - Vec3D direction = getLookVec(); + Vec3D start = this.getEyePosition(1.0F); + Vec3D direction = this.getLookDirection(); Vec3D end = start.add(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance); List entityList = world.getEntities(this, getBoundingBox().expand(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance).grow(1.0D, 1.0D, 1.0D), IEntitySelector.notSpectator().and(Entity::isInteractable)); double distance = 0.0D; - MovingObjectPosition rayTraceResult = null; + MovingObjectPositionEntity result = null; for (Entity entity : entityList) { AxisAlignedBB aabb = entity.getBoundingBox().grow((double) entity.getCollisionBorderSize()); - MovingObjectPosition rayTrace = aabb.calculateIntercept(start, end); + Optional rayTraceResult = aabb.calculateIntercept(start, end); - if (rayTrace != null) { - double distanceTo = start.distanceSquared(rayTrace.pos); + if (rayTraceResult.isPresent()) { + Vec3D rayTrace = rayTraceResult.get(); + double distanceTo = start.distanceSquared(rayTrace); if (distanceTo < distance || distance == 0.0D) { - rayTraceResult = new MovingObjectPosition(entity, rayTrace.pos); + result = new MovingObjectPositionEntity(entity, rayTrace); distance = distanceTo; } } } - return rayTraceResult; + return result; } public int shieldBlockingDelay = world.paperConfig.shieldBlockingDelay; diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java deleted file mode 100644 index b7fe7dad0..000000000 --- a/src/main/java/net/minecraft/server/EntityLlama.java +++ /dev/null @@ -1,445 +0,0 @@ -package net.minecraft.server; - -import java.util.Iterator; -import java.util.function.Predicate; -import javax.annotation.Nullable; - -public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEntity { - - private static final DataWatcherObject bM = DataWatcher.a(EntityLlama.class, DataWatcherRegistry.b); - private static final DataWatcherObject bN = DataWatcher.a(EntityLlama.class, DataWatcherRegistry.b); - private static final DataWatcherObject bO = DataWatcher.a(EntityLlama.class, DataWatcherRegistry.b); - private boolean bP; - @Nullable - private EntityLlama bQ; - @Nullable - private EntityLlama bR; - - public EntityLlama(World world) { - super(EntityTypes.LLAMA, world); - this.setSize(0.9F, 1.87F); - } - - public void setStrength(int i) { - this.datawatcher.set(EntityLlama.bM, Math.max(1, Math.min(5, i))); - } - - private void eo() { - int i = this.random.nextFloat() < 0.04F ? 5 : 3; - - this.setStrength(1 + this.random.nextInt(i)); - } - - public int getStrength() { - return (Integer) this.datawatcher.get(EntityLlama.bM); - } - - public void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); - nbttagcompound.setInt("Variant", this.getVariant()); - nbttagcompound.setInt("Strength", this.getStrength()); - if (!this.inventoryChest.getItem(1).isEmpty()) { - nbttagcompound.set("DecorItem", this.inventoryChest.getItem(1).save(new NBTTagCompound())); - } - - } - - public void a(NBTTagCompound nbttagcompound) { - this.setStrength(nbttagcompound.getInt("Strength")); - super.a(nbttagcompound); - this.setVariant(nbttagcompound.getInt("Variant")); - if (nbttagcompound.hasKeyOfType("DecorItem", 10)) { - this.inventoryChest.setItem(1, ItemStack.a(nbttagcompound.getCompound("DecorItem"))); - } - - this.dS(); - } - - protected void n() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); - this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D)); - this.goalSelector.a(2, new PathfinderGoalLlamaFollow(this, 2.0999999046325684D)); - this.goalSelector.a(3, new PathfinderGoalArrowAttack(this, 1.25D, 40, 20.0F)); - this.goalSelector.a(3, new PathfinderGoalPanic(this, 1.2D)); - this.goalSelector.a(4, new PathfinderGoalBreed(this, 1.0D)); - this.goalSelector.a(5, new PathfinderGoalFollowParent(this, 1.0D)); - this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.7D)); - this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, new EntityLlama.c(this)); - this.targetSelector.a(2, new EntityLlama.a(this)); - } - - protected void initAttributes() { - super.initAttributes(); - this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(40.0D); - } - - protected void x_() { - super.x_(); - this.datawatcher.register(EntityLlama.bM, 0); - this.datawatcher.register(EntityLlama.bN, -1); - this.datawatcher.register(EntityLlama.bO, 0); - } - - public int getVariant() { - return MathHelper.clamp((Integer) this.datawatcher.get(EntityLlama.bO), 0, 3); - } - - public void setVariant(int i) { - this.datawatcher.set(EntityLlama.bO, i); - } - - protected int dA() { - return this.isCarryingChest() ? 2 + 3 * this.dH() : super.dA(); - } - - public void k(Entity entity) { - if (this.w(entity)) { - float f = MathHelper.cos(this.aQ * 0.017453292F); - float f1 = MathHelper.sin(this.aQ * 0.017453292F); - float f2 = 0.3F; - - entity.setPosition(this.locX + (double) (0.3F * f1), this.locY + this.aJ() + entity.aI(), this.locZ - (double) (0.3F * f)); - } - } - - public double aJ() { - return (double) this.length * 0.67D; - } - - public boolean dh() { - return false; - } - - protected boolean b(EntityHuman entityhuman, ItemStack itemstack) { - byte b0 = 0; - byte b1 = 0; - float f = 0.0F; - boolean flag = false; - Item item = itemstack.getItem(); - - if (item == Items.WHEAT) { - b0 = 10; - b1 = 3; - f = 2.0F; - } else if (item == Blocks.HAY_BLOCK.getItem()) { - b0 = 90; - b1 = 6; - f = 10.0F; - if (this.isTamed() && this.getAge() == 0 && this.dD()) { - flag = true; - this.f(entityhuman); - } - } - - if (this.getHealth() < this.getMaxHealth() && f > 0.0F) { - this.heal(f); - flag = true; - } - - if (this.isBaby() && b0 > 0) { - //this.world.addParticle(Particles.z, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, 0.0D, 0.0D, 0.0D); // Akarin - this handle by client - if (!this.world.isClientSide) { - this.setAge(b0); - } - - flag = true; - } - - if (b1 > 0 && (flag || !this.isTamed()) && this.getTemper() < this.getMaxDomestication()) { - flag = true; - if (!this.world.isClientSide) { - this.r(b1); - } - } - - if (flag && !this.isSilent()) { - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_LLAMA_EAT, this.bV(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); - } - - return flag; - } - - protected boolean isFrozen() { - return this.getHealth() <= 0.0F || this.dN(); - } - - @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - Object object = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); - - this.eo(); - int i; - - if (object instanceof EntityLlama.b) { - i = ((EntityLlama.b) object).a; - } else { - i = this.random.nextInt(4); - object = new EntityLlama.b(i); - } - - this.setVariant(i); - return (GroupDataEntity) object; - } - - protected SoundEffect dB() { - return SoundEffects.ENTITY_LLAMA_ANGRY; - } - - protected SoundEffect D() { - return SoundEffects.ENTITY_LLAMA_AMBIENT; - } - - protected SoundEffect d(DamageSource damagesource) { - return SoundEffects.ENTITY_LLAMA_HURT; - } - - protected SoundEffect cs() { - return SoundEffects.ENTITY_LLAMA_DEATH; - } - - protected void a(BlockPosition blockposition, IBlockData iblockdata) { - this.a(SoundEffects.ENTITY_LLAMA_STEP, 0.15F, 1.0F); - } - - protected void dC() { - this.a(SoundEffects.ENTITY_LLAMA_CHEST, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); - } - - public void dZ() { - SoundEffect soundeffect = this.dB(); - - if (soundeffect != null) { - this.a(soundeffect, this.cD(), this.cE()); - } - - } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aD; - } - - public int dH() { - return this.getStrength(); - } - - public boolean ef() { - return true; - } - - public boolean g(ItemStack itemstack) { - Item item = itemstack.getItem(); - - return TagsItem.CARPETS.isTagged(item); - } - - public boolean dU() { - return false; - } - - public void a(IInventory iinventory) { - EnumColor enumcolor = this.ej(); - - super.a(iinventory); - EnumColor enumcolor1 = this.ej(); - - if (this.ticksLived > 20 && enumcolor1 != null && enumcolor1 != enumcolor) { - this.a(SoundEffects.ENTITY_LLAMA_SWAG, 0.5F, 1.0F); - } - - } - - protected void dS() { - if (!this.world.isClientSide) { - super.dS(); - this.a(h(this.inventoryChest.getItem(1))); - } - } - - private void a(@Nullable EnumColor enumcolor) { - this.datawatcher.set(EntityLlama.bN, enumcolor == null ? -1 : enumcolor.getColorIndex()); - } - - @Nullable - private static EnumColor h(ItemStack itemstack) { - Block block = Block.asBlock(itemstack.getItem()); - - return block instanceof BlockCarpet ? ((BlockCarpet) block).d() : null; - } - - @Nullable - public EnumColor ej() { - int i = (Integer) this.datawatcher.get(EntityLlama.bN); - - return i == -1 ? null : EnumColor.fromColorIndex(i); - } - - public int getMaxDomestication() { - return 30; - } - - public boolean mate(EntityAnimal entityanimal) { - return entityanimal != this && entityanimal instanceof EntityLlama && this.eb() && ((EntityLlama) entityanimal).eb(); - } - - public EntityLlama createChild(EntityAgeable entityageable) { - EntityLlama entityllama = EntityTypes.LLAMA.create(world); // Paper - - this.a(entityageable, (EntityHorseAbstract) entityllama); - EntityLlama entityllama1 = (EntityLlama) entityageable; - int i = this.random.nextInt(Math.max(this.getStrength(), entityllama1.getStrength())) + 1; - - if (this.random.nextFloat() < 0.03F) { - ++i; - } - - entityllama.setStrength(i); - entityllama.setVariant(this.random.nextBoolean() ? this.getVariant() : entityllama1.getVariant()); - return entityllama; - } - - private void f(EntityLiving entityliving) { - EntityLlamaSpit entityllamaspit = new EntityLlamaSpit(this.world, this); - double d0 = entityliving.locX - this.locX; - double d1 = entityliving.getBoundingBox().minY + (double) (entityliving.length / 3.0F) - entityllamaspit.locY; - double d2 = entityliving.locZ - this.locZ; - float f = MathHelper.sqrt(d0 * d0 + d2 * d2) * 0.2F; - - entityllamaspit.shoot(d0, d1 + (double) f, d2, 1.5F, 10.0F); - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_LLAMA_SPIT, this.bV(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); - this.world.addEntity(entityllamaspit); - this.bP = true; - } - - private void B(boolean flag) { - this.bP = flag; - } - - public void c(float f, float f1) { - int i = MathHelper.f((f * 0.5F - 3.0F) * f1); - - if (i > 0) { - if (f >= 6.0F) { - this.damageEntity(DamageSource.FALL, (float) i); - if (this.isVehicle()) { - Iterator iterator = this.getAllPassengers().iterator(); - - while (iterator.hasNext()) { - Entity entity = (Entity) iterator.next(); - - entity.damageEntity(DamageSource.FALL, (float) i); - } - } - } - - IBlockData iblockdata = this.world.getType(new BlockPosition(this.locX, this.locY - 0.2D - (double) this.lastYaw, this.locZ)); - Block block = iblockdata.getBlock(); - - if (!iblockdata.isAir() && !this.isSilent()) { - SoundEffectType soundeffecttype = block.getStepSound(); - - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, soundeffecttype.d(), this.bV(), soundeffecttype.a() * 0.5F, soundeffecttype.b() * 0.75F); - } - - } - } - - public void ek() { - if (this.bQ != null) { - this.bQ.bR = null; - } - - this.bQ = null; - } - - public void a(EntityLlama entityllama) { - this.bQ = entityllama; - this.bQ.bR = this; - } - - public boolean el() { - return this.bR != null; - } - - public boolean inCaravan() { return this.em(); } // Paper - OBFHELPER - public boolean em() { - return this.bQ != null; - } - - @Nullable - public EntityLlama en() { - return this.bQ; - } - - protected double dx() { - return 2.0D; - } - - protected void dX() { - if (!this.em() && this.isBaby()) { - super.dX(); - } - - } - - public boolean dY() { - return false; - } - - public void a(EntityLiving entityliving, float f) { - this.f(entityliving); - } - - public void s(boolean flag) {} - - static class a extends PathfinderGoalNearestAttackableTarget { - - public a(EntityLlama entityllama) { - super(entityllama, EntityWolf.class, 16, false, true, (Predicate) null); - } - - public boolean a() { - if (super.a() && this.d != null && !((EntityWolf) this.d).isTamed()) { - return true; - } else { - this.e.setGoalTarget((EntityLiving) null); - return false; - } - } - - protected double i() { - return super.i() * 0.25D; - } - } - - static class c extends PathfinderGoalHurtByTarget { - - public c(EntityLlama entityllama) { - super(entityllama, false); - } - - public boolean b() { - if (this.e instanceof EntityLlama) { - EntityLlama entityllama = (EntityLlama) this.e; - - if (entityllama.bP) { - entityllama.B(false); - return false; - } - } - - return super.b(); - } - } - - static class b implements GroupDataEntity { - - public int a; - - private b(int i) { - this.a = i; - } - } -} diff --git a/src/main/java/net/minecraft/server/EntityLlamaSpit.java b/src/main/java/net/minecraft/server/EntityLlamaSpit.java index 58e1ed795..6c4ebd643 100644 --- a/src/main/java/net/minecraft/server/EntityLlamaSpit.java +++ b/src/main/java/net/minecraft/server/EntityLlamaSpit.java @@ -3,58 +3,46 @@ package net.minecraft.server; import java.util.Iterator; import java.util.List; import java.util.UUID; -import javax.annotation.Nullable; public class EntityLlamaSpit extends Entity implements IProjectile { public EntityLiving shooter; // CraftBukkit - type - private NBTTagCompound b; + private NBTTagCompound c; - public EntityLlamaSpit(World world) { - super(EntityTypes.LLAMA_SPIT, world); - this.setSize(0.25F, 0.25F); + public EntityLlamaSpit(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntityLlamaSpit(World world, EntityLlama entityllama) { - this(world); + this(EntityTypes.LLAMA_SPIT, world); this.shooter = entityllama; - this.setPosition(entityllama.locX - (double) (entityllama.width + 1.0F) * 0.5D * (double) MathHelper.sin(entityllama.aQ * 0.017453292F), entityllama.locY + (double) entityllama.getHeadHeight() - 0.10000000149011612D, entityllama.locZ + (double) (entityllama.width + 1.0F) * 0.5D * (double) MathHelper.cos(entityllama.aQ * 0.017453292F)); + this.setPosition(entityllama.locX - (double) (entityllama.getWidth() + 1.0F) * 0.5D * (double) MathHelper.sin(entityllama.aK * 0.017453292F), entityllama.locY + (double) entityllama.getHeadHeight() - 0.10000000149011612D, entityllama.locZ + (double) (entityllama.getWidth() + 1.0F) * 0.5D * (double) MathHelper.cos(entityllama.aK * 0.017453292F)); } + @Override public void tick() { super.tick(); - if (this.b != null) { + if (this.c != null) { this.f(); } - Vec3D vec3d = new Vec3D(this.locX, this.locY, this.locZ); - Vec3D vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); - MovingObjectPosition movingobjectposition = this.world.rayTrace(vec3d, vec3d1); - - vec3d = new Vec3D(this.locX, this.locY, this.locZ); - vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); - if (movingobjectposition != null) { - vec3d1 = new Vec3D(movingobjectposition.pos.x, movingobjectposition.pos.y, movingobjectposition.pos.z); - } - - Entity entity = this.a(vec3d, vec3d1); - - if (entity != null) { - movingobjectposition = new MovingObjectPosition(entity); - } + Vec3D vec3d = this.getMot(); + MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, this.getBoundingBox().a(vec3d).g(1.0D), (entity) -> { + return !entity.isSpectator() && entity != this.shooter; + }, RayTrace.BlockCollisionOption.OUTLINE, true); if (movingobjectposition != null) { this.a(movingobjectposition); } - this.locX += this.motX; - this.locY += this.motY; - this.locZ += this.motZ; - float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + this.locX += vec3d.x; + this.locY += vec3d.y; + this.locZ += vec3d.z; + float f = MathHelper.sqrt(b(vec3d)); - this.yaw = (float) (MathHelper.c(this.motX, this.motZ) * 57.2957763671875D); + this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); - for (this.pitch = (float) (MathHelper.c(this.motY, (double) f) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + for (this.pitch = (float) (MathHelper.d(vec3d.y, (double) f) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { ; } @@ -70,99 +58,62 @@ public class EntityLlamaSpit extends Entity implements IProjectile { this.lastYaw += 360.0F; } - this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; - this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; + this.pitch = MathHelper.g(0.2F, this.lastPitch, this.pitch); + this.yaw = MathHelper.g(0.2F, this.lastYaw, this.yaw); float f1 = 0.99F; float f2 = 0.06F; if (!this.world.a(this.getBoundingBox(), Material.AIR)) { this.die(); - } else if (this.aq()) { + } else if (this.av()) { this.die(); } else { - this.motX *= 0.9900000095367432D; - this.motY *= 0.9900000095367432D; - this.motZ *= 0.9900000095367432D; + this.setMot(vec3d.a(0.9900000095367432D)); if (!this.isNoGravity()) { - this.motY -= 0.05999999865889549D; + this.setMot(this.getMot().add(0.0D, -0.05999999865889549D, 0.0D)); } this.setPosition(this.locX, this.locY, this.locZ); } } - @Nullable - private Entity a(Vec3D vec3d, Vec3D vec3d1) { - Entity entity = null; - List list = this.world.getEntities(this, this.getBoundingBox().b(this.motX, this.motY, this.motZ).g(1.0D)); - double d0 = 0.0D; - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - Entity entity1 = (Entity) iterator.next(); - - if (entity1 != this.shooter) { - AxisAlignedBB axisalignedbb = entity1.getBoundingBox().g(0.30000001192092896D); - MovingObjectPosition movingobjectposition = axisalignedbb.b(vec3d, vec3d1); - - if (movingobjectposition != null) { - double d1 = vec3d.distanceSquared(movingobjectposition.pos); - - if (d1 < d0 || d0 == 0.0D) { - entity = entity1; - d0 = d1; - } - } - } - } - - return entity; - } - + @Override public void shoot(double d0, double d1, double d2, float f, float f1) { - float f2 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + Vec3D vec3d = (new Vec3D(d0, d1, d2)).d().add(this.random.nextGaussian() * 0.007499999832361937D * (double) f1, this.random.nextGaussian() * 0.007499999832361937D * (double) f1, this.random.nextGaussian() * 0.007499999832361937D * (double) f1).a((double) f); - d0 /= (double) f2; - d1 /= (double) f2; - d2 /= (double) f2; - d0 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; - d1 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; - d2 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; - d0 *= (double) f; - d1 *= (double) f; - d2 *= (double) f; - this.motX = d0; - this.motY = d1; - this.motZ = d2; - float f3 = MathHelper.sqrt(d0 * d0 + d2 * d2); + this.setMot(vec3d); + float f2 = MathHelper.sqrt(b(vec3d)); - this.yaw = (float) (MathHelper.c(d0, d2) * 57.2957763671875D); - this.pitch = (float) (MathHelper.c(d1, (double) f3) * 57.2957763671875D); + this.yaw = (float) (MathHelper.d(vec3d.x, d2) * 57.2957763671875D); + this.pitch = (float) (MathHelper.d(vec3d.y, (double) f2) * 57.2957763671875D); this.lastYaw = this.yaw; this.lastPitch = this.pitch; } public void a(MovingObjectPosition movingobjectposition) { org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition); // Craftbukkit - Call event - if (movingobjectposition.entity != null && this.shooter != null) { - movingobjectposition.entity.damageEntity(DamageSource.a(this, (EntityLiving) this.shooter).c(), 1.0F); - } + MovingObjectPosition.EnumMovingObjectType movingobjectposition_enummovingobjecttype = movingobjectposition.getType(); - if (!this.world.isClientSide) { + if (movingobjectposition_enummovingobjecttype == MovingObjectPosition.EnumMovingObjectType.ENTITY && this.shooter != null) { + ((MovingObjectPositionEntity) movingobjectposition).getEntity().damageEntity(DamageSource.a(this, (EntityLiving) this.shooter).c(), 1.0F); + } else if (movingobjectposition_enummovingobjecttype == MovingObjectPosition.EnumMovingObjectType.BLOCK && !this.world.isClientSide) { this.die(); } } - protected void x_() {} + @Override + protected void initDatawatcher() {} + @Override protected void a(NBTTagCompound nbttagcompound) { if (nbttagcompound.hasKeyOfType("Owner", 10)) { - this.b = nbttagcompound.getCompound("Owner"); + this.c = nbttagcompound.getCompound("Owner"); } } + @Override protected void b(NBTTagCompound nbttagcompound) { if (this.shooter != null) { NBTTagCompound nbttagcompound1 = new NBTTagCompound(); @@ -175,8 +126,8 @@ public class EntityLlamaSpit extends Entity implements IProjectile { } private void f() { - if (this.b != null && this.b.b("OwnerUUID")) { - UUID uuid = this.b.a("OwnerUUID"); + if (this.c != null && this.c.b("OwnerUUID")) { + UUID uuid = this.c.a("OwnerUUID"); List list = this.world.a(EntityLlama.class, this.getBoundingBox().g(15.0D)); Iterator iterator = list.iterator(); @@ -190,6 +141,11 @@ public class EntityLlamaSpit extends Entity implements IProjectile { } } - this.b = null; + this.c = null; + } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); } } diff --git a/src/main/java/net/minecraft/server/EntityLlamaTrader.java b/src/main/java/net/minecraft/server/EntityLlamaTrader.java new file mode 100644 index 000000000..b60a167f8 --- /dev/null +++ b/src/main/java/net/minecraft/server/EntityLlamaTrader.java @@ -0,0 +1,138 @@ +package net.minecraft.server; + +import java.util.EnumSet; +import javax.annotation.Nullable; + +public class EntityLlamaTrader extends EntityLlama { + + private int bI = 47999; + + public EntityLlamaTrader(EntityTypes entitytypes, World world) { + super(entitytypes, world); + } + + @Override + protected EntityLlama eF() { + return (EntityLlama) EntityTypes.TRADER_LLAMA.a(this.world); + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("DespawnDelay", this.bI); + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("DespawnDelay", 99)) { + this.bI = nbttagcompound.getInt("DespawnDelay"); + } + + } + + @Override + protected void initPathfinder() { + super.initPathfinder(); + this.goalSelector.a(1, new PathfinderGoalPanic(this, 2.0D)); + this.targetSelector.a(1, new EntityLlamaTrader.a(this)); + } + + @Override + protected void g(EntityHuman entityhuman) { + Entity entity = this.getLeashHolder(); + + if (!(entity instanceof EntityVillagerTrader)) { + super.g(entityhuman); + } + } + + @Override + public void movementTick() { + super.movementTick(); + if (!this.world.isClientSide) { + this.eK(); + } + + } + + private void eK() { + if (this.eL()) { + this.bI = this.eM() ? ((EntityVillagerTrader) this.getLeashHolder()).ef() - 1 : this.bI - 1; + if (this.bI <= 0) { + this.unleash(true, false); + this.die(); + } + + } + } + + private boolean eL() { + return !this.isTamed() && !this.eN() && !this.hasSinglePlayerPassenger(); + } + + private boolean eM() { + return this.getLeashHolder() instanceof EntityVillagerTrader; + } + + private boolean eN() { + return this.isLeashed() && !this.eM(); + } + + @Nullable + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + GroupDataEntity groupdataentity1 = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + + if (enummobspawn == EnumMobSpawn.EVENT) { + this.setAgeRaw(0); + } + + return groupdataentity1; + } + + public class a extends PathfinderGoalTarget { + + private final EntityLlama b; + private EntityLiving c; + private int d; + + public a(EntityLlama entityllama) { + super(entityllama, false); + this.b = entityllama; + this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); + } + + @Override + public boolean a() { + if (!this.b.isLeashed()) { + return false; + } else { + Entity entity = this.b.getLeashHolder(); + + if (!(entity instanceof EntityVillagerTrader)) { + return false; + } else { + EntityVillagerTrader entityvillagertrader = (EntityVillagerTrader) entity; + + this.c = entityvillagertrader.getLastDamager(); + int i = entityvillagertrader.ct(); + + return i != this.d && this.a(this.c, PathfinderTargetCondition.a); + } + } + } + + @Override + public void c() { + this.e.setGoalTarget(this.c, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_OWNER, true); // CraftBukkit + Entity entity = this.b.getLeashHolder(); + + if (entity instanceof EntityVillagerTrader) { + this.d = ((EntityVillagerTrader) entity).ct(); + } + + super.c(); + } + } +} diff --git a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java index 62d04fc9b..6df2930e2 100644 --- a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java +++ b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java @@ -1,7 +1,5 @@ package net.minecraft.server; -import java.util.Arrays; -import java.util.Comparator; import java.util.Iterator; import java.util.List; import javax.annotation.Nullable; @@ -15,22 +13,22 @@ import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; import org.bukkit.util.Vector; // CraftBukkit end -public abstract class EntityMinecartAbstract extends Entity implements INamableTileEntity { +public abstract class EntityMinecartAbstract extends Entity { - private static final DataWatcherObject a = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.b); private static final DataWatcherObject b = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.b); - private static final DataWatcherObject c = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.c); - private static final DataWatcherObject d = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.b); + private static final DataWatcherObject c = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.b); + private static final DataWatcherObject d = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.c); private static final DataWatcherObject e = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.b); - private static final DataWatcherObject f = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.i); - private boolean g; - private static final int[][][] h = new int[][][] { { { 0, 0, -1}, { 0, 0, 1}}, { { -1, 0, 0}, { 1, 0, 0}}, { { -1, -1, 0}, { 1, 0, 0}}, { { -1, 0, 0}, { 1, -1, 0}}, { { 0, 0, -1}, { 0, -1, 1}}, { { 0, -1, -1}, { 0, 0, 1}}, { { 0, 0, 1}, { 1, 0, 0}}, { { 0, 0, 1}, { -1, 0, 0}}, { { 0, 0, -1}, { -1, 0, 0}}, { { 0, 0, -1}, { 1, 0, 0}}}; - private int aw; + private static final DataWatcherObject f = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.b); + private static final DataWatcherObject g = DataWatcher.a(EntityMinecartAbstract.class, DataWatcherRegistry.i); + private boolean ar; + private static final int[][][] as = new int[][][]{{{0, 0, -1}, {0, 0, 1}}, {{-1, 0, 0}, {1, 0, 0}}, {{-1, -1, 0}, {1, 0, 0}}, {{-1, 0, 0}, {1, -1, 0}}, {{0, 0, -1}, {0, -1, 1}}, {{0, -1, -1}, {0, 0, 1}}, {{0, 0, 1}, {1, 0, 0}}, {{0, 0, 1}, {-1, 0, 0}}, {{0, 0, -1}, {-1, 0, 0}}, {{0, 0, -1}, {1, 0, 0}}}; + private int at; + private double au; + private double av; + private double aw; private double ax; private double ay; - private double az; - private double aA; - private double aB; // CraftBukkit start public boolean slowWhenEmpty = true; @@ -45,66 +43,54 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT protected EntityMinecartAbstract(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.j = true; - this.setSize(0.98F, 0.7F); + this.i = true; } protected EntityMinecartAbstract(EntityTypes entitytypes, World world, double d0, double d1, double d2) { this(entitytypes, world); this.setPosition(d0, d1, d2); - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; + this.setMot(Vec3D.a); this.lastX = d0; this.lastY = d1; this.lastZ = d2; } public static EntityMinecartAbstract a(World world, double d0, double d1, double d2, EntityMinecartAbstract.EnumMinecartType entityminecartabstract_enumminecarttype) { - switch (entityminecartabstract_enumminecarttype) { - case CHEST: - return new EntityMinecartChest(world, d0, d1, d2); - case FURNACE: - return new EntityMinecartFurnace(world, d0, d1, d2); - case TNT: - return new EntityMinecartTNT(world, d0, d1, d2); - case SPAWNER: - return new EntityMinecartMobSpawner(world, d0, d1, d2); - case HOPPER: - return new EntityMinecartHopper(world, d0, d1, d2); - case COMMAND_BLOCK: - return new EntityMinecartCommandBlock(world, d0, d1, d2); - default: - return new EntityMinecartRideable(world, d0, d1, d2); - } + return (EntityMinecartAbstract) (entityminecartabstract_enumminecarttype == EntityMinecartAbstract.EnumMinecartType.CHEST ? new EntityMinecartChest(world, d0, d1, d2) : (entityminecartabstract_enumminecarttype == EntityMinecartAbstract.EnumMinecartType.FURNACE ? new EntityMinecartFurnace(world, d0, d1, d2) : (entityminecartabstract_enumminecarttype == EntityMinecartAbstract.EnumMinecartType.TNT ? new EntityMinecartTNT(world, d0, d1, d2) : (entityminecartabstract_enumminecarttype == EntityMinecartAbstract.EnumMinecartType.SPAWNER ? new EntityMinecartMobSpawner(world, d0, d1, d2) : (entityminecartabstract_enumminecarttype == EntityMinecartAbstract.EnumMinecartType.HOPPER ? new EntityMinecartHopper(world, d0, d1, d2) : (entityminecartabstract_enumminecarttype == EntityMinecartAbstract.EnumMinecartType.COMMAND_BLOCK ? new EntityMinecartCommandBlock(world, d0, d1, d2) : new EntityMinecartRideable(world, d0, d1, d2))))))); } + @Override protected boolean playStepSound() { return false; } - protected void x_() { - this.datawatcher.register(EntityMinecartAbstract.a, 0); - this.datawatcher.register(EntityMinecartAbstract.b, 1); - this.datawatcher.register(EntityMinecartAbstract.c, 0.0F); - this.datawatcher.register(EntityMinecartAbstract.d, Block.getCombinedId(Blocks.AIR.getBlockData())); - this.datawatcher.register(EntityMinecartAbstract.e, 6); - this.datawatcher.register(EntityMinecartAbstract.f, false); + @Override + protected void initDatawatcher() { + this.datawatcher.register(EntityMinecartAbstract.b, 0); + this.datawatcher.register(EntityMinecartAbstract.c, 1); + this.datawatcher.register(EntityMinecartAbstract.d, 0.0F); + this.datawatcher.register(EntityMinecartAbstract.e, Block.getCombinedId(Blocks.AIR.getBlockData())); + this.datawatcher.register(EntityMinecartAbstract.f, 6); + this.datawatcher.register(EntityMinecartAbstract.g, false); } @Nullable + @Override public AxisAlignedBB j(Entity entity) { return entity.isCollidable() ? entity.getBoundingBox() : null; } + @Override public boolean isCollidable() { return true; } - public double aJ() { + @Override + public double aP() { return 0.0D; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (!this.world.isClientSide && !this.dead) { if (this.isInvulnerable(damagesource)) { @@ -123,9 +109,9 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT f = (float) event.getDamage(); // CraftBukkit end - this.k(-this.u()); - this.d(10); - this.aA(); + this.d(-this.n()); + this.c(10); + this.velocityChanged(); this.setDamage(this.getDamage() + f * 10.0F); boolean flag = damagesource.getEntity() instanceof EntityHuman && ((EntityHuman) damagesource.getEntity()).abilities.canInstantlyBuild; @@ -156,26 +142,29 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT public void a(DamageSource damagesource) { this.die(); - if (this.world.getGameRules().getBoolean("doEntityDrops")) { + if (this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { ItemStack itemstack = new ItemStack(Items.MINECART); if (this.hasCustomName()) { itemstack.a(this.getCustomName()); } - this.a_(itemstack); + this.a(itemstack); } } + @Override public boolean isInteractable() { return !this.dead; } + @Override public EnumDirection getAdjustedDirection() { - return this.g ? this.getDirection().opposite().e() : this.getDirection().e(); + return this.ar ? this.getDirection().opposite().e() : this.getDirection().e(); } + @Override public void tick() { // CraftBukkit start double prevX = this.locX; @@ -186,7 +175,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT // CraftBukkit end if (this.getType() > 0) { - this.d(this.getType() - 1); + this.c(this.getType() - 1); } if (this.getDamage() > 0.0F) { @@ -197,67 +186,23 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT // Extracted to own function /* if (this.locY < -64.0D) { - this.aa(); + this.af(); } */ this.performVoidDamage(); // Paper end - int i; - - // CraftBukkit - handled in postTick - /* - if (!this.world.isClientSide && this.world instanceof WorldServer) { - this.world.methodProfiler.enter("portal"); - MinecraftServer minecraftserver = this.world.getMinecraftServer(); - - i = this.X(); - if (this.an) { - if (minecraftserver.getAllowNether()) { - if (!this.isPassenger() && this.ao++ >= i) { - this.ao = i; - this.portalCooldown = this.aQ(); - DimensionManager dimensionmanager; - - if (this.world.worldProvider.getDimensionManager() == DimensionManager.NETHER) { - dimensionmanager = DimensionManager.OVERWORLD; - } else { - dimensionmanager = DimensionManager.NETHER; - } - - this.a(dimensionmanager); - } - - this.an = false; - } - } else { - if (this.ao > 0) { - this.ao -= 4; - } - - if (this.ao < 0) { - this.ao = 0; - } - } - - if (this.portalCooldown > 0) { - --this.portalCooldown; - } - - //this.world.methodProfiler.exit(); // Akarin - remove caller - } - */ - + // this.doPortalTick(); // CraftBukkit - handled in postTick if (this.world.isClientSide) { - if (this.aw > 0) { - double d0 = this.locX + (this.ax - this.locX) / (double) this.aw; - double d1 = this.locY + (this.ay - this.locY) / (double) this.aw; - double d2 = this.locZ + (this.az - this.locZ) / (double) this.aw; - double d3 = MathHelper.g(this.aA - (double) this.yaw); + if (this.at > 0) { + double d0 = this.locX + (this.au - this.locX) / (double) this.at; + double d1 = this.locY + (this.av - this.locY) / (double) this.at; + double d2 = this.locZ + (this.aw - this.locZ) / (double) this.at; + double d3 = MathHelper.g(this.ax - (double) this.yaw); - this.yaw = (float) ((double) this.yaw + d3 / (double) this.aw); - this.pitch = (float) ((double) this.pitch + (this.aB - (double) this.pitch) / (double) this.aw); - --this.aw; + this.yaw = (float) ((double) this.yaw + d3 / (double) this.at); + this.pitch = (float) ((double) this.pitch + (this.ay - (double) this.pitch) / (double) this.at); + --this.at; this.setPosition(d0, d1, d2); this.setYawPitch(this.yaw, this.pitch); } else { @@ -270,28 +215,27 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT this.lastY = this.locY; this.lastZ = this.locZ; if (!this.isNoGravity()) { - this.motY -= 0.03999999910593033D; + this.setMot(this.getMot().add(0.0D, -0.04D, 0.0D)); } - int j = MathHelper.floor(this.locX); - - i = MathHelper.floor(this.locY); + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY); int k = MathHelper.floor(this.locZ); - if (this.world.getType(new BlockPosition(j, i - 1, k)).a(TagsBlock.RAILS)) { - --i; + if (this.world.getType(new BlockPosition(i, j - 1, k)).a(TagsBlock.RAILS)) { + --j; } - BlockPosition blockposition = new BlockPosition(j, i, k); + BlockPosition blockposition = new BlockPosition(i, j, k); IBlockData iblockdata = this.world.getType(blockposition); if (iblockdata.a(TagsBlock.RAILS)) { this.b(blockposition, iblockdata); if (iblockdata.getBlock() == Blocks.ACTIVATOR_RAIL) { - this.a(j, i, k, (Boolean) iblockdata.get(BlockPoweredRail.POWERED)); + this.a(i, j, k, (Boolean) iblockdata.get(BlockPoweredRail.POWERED)); } } else { - this.q(); + this.i(); } this.checkBlockCollisions(); @@ -300,8 +244,8 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT double d5 = this.lastZ - this.locZ; if (d4 * d4 + d5 * d5 > 0.001D) { - this.yaw = (float) (MathHelper.c(d5, d4) * 180.0D / 3.141592653589793D); - if (this.g) { + this.yaw = (float) (MathHelper.d(d5, d4) * 180.0D / 3.141592653589793D); + if (this.ar) { this.yaw += 180.0F; } } @@ -310,7 +254,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT if (d6 < -170.0D || d6 >= 170.0D) { this.yaw += 180.0F; - this.g = !this.g; + this.ar = !this.ar; } this.setYawPitch(this.yaw, this.pitch); @@ -326,7 +270,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, from, to)); } // CraftBukkit end - if (this.v() == EntityMinecartAbstract.EnumMinecartType.RIDEABLE && this.motX * this.motX + this.motZ * this.motZ > 0.01D) { + if (this.getMinecartType() == EntityMinecartAbstract.EnumMinecartType.RIDEABLE && b(this.getMot()) > 0.01D) { List list = this.world.getEntities(this, this.getBoundingBox().grow(0.20000000298023224D, 0.0D, 0.20000000298023224D), IEntitySelector.a(this)); if (!list.isEmpty()) { @@ -376,35 +320,31 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT } } - this.at(); + this.ay(); } } - protected double p() { + protected double getMaxSpeed() { return this.maxSpeed; // CraftBukkit } public void a(int i, int j, int k, boolean flag) {} - protected void q() { - double d0 = this.p(); + protected void i() { + double d0 = this.getMaxSpeed(); + Vec3D vec3d = this.getMot(); - this.motX = MathHelper.a(this.motX, -d0, d0); - this.motZ = MathHelper.a(this.motZ, -d0, d0); + this.setMot(MathHelper.a(vec3d.x, -d0, d0), vec3d.y, MathHelper.a(vec3d.z, -d0, d0)); if (this.onGround) { // CraftBukkit start - replace magic numbers with our variables - this.motX *= this.derailedX; - this.motY *= this.derailedY; - this.motZ *= this.derailedZ; + this.setMot(new Vec3D(this.getMot().x * this.derailedX, this.getMot().y * this.derailedY, this.getMot().z * this.derailedZ)); // CraftBukkit end } - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); + this.move(EnumMoveType.SELF, this.getMot()); if (!this.onGround) { // CraftBukkit start - replace magic numbers with our variables - this.motX *= this.flyingX; - this.motY *= this.flyingY; - this.motZ *= this.flyingZ; + this.setMot(new Vec3D(this.getMot().x * this.flyingX, this.getMot().y * this.flyingY, this.getMot().z * this.flyingZ)); // CraftBukkit end } @@ -412,7 +352,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT protected void b(BlockPosition blockposition, IBlockData iblockdata) { this.fallDistance = 0.0F; - Vec3D vec3d = this.j(this.locX, this.locY, this.locZ); + Vec3D vec3d = this.l(this.locX, this.locY, this.locZ); this.locY = (double) blockposition.getY(); boolean flag = false; @@ -425,195 +365,177 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT } double d0 = 0.0078125D; + Vec3D vec3d1 = this.getMot(); BlockPropertyTrackPosition blockpropertytrackposition = (BlockPropertyTrackPosition) iblockdata.get(blockminecarttrackabstract.e()); switch (blockpropertytrackposition) { - case ASCENDING_EAST: - this.motX -= 0.0078125D; - ++this.locY; - break; - case ASCENDING_WEST: - this.motX += 0.0078125D; - ++this.locY; - break; - case ASCENDING_NORTH: - this.motZ += 0.0078125D; - ++this.locY; - break; - case ASCENDING_SOUTH: - this.motZ -= 0.0078125D; - ++this.locY; + case ASCENDING_EAST: + this.setMot(vec3d1.add(-0.0078125D, 0.0D, 0.0D)); + ++this.locY; + break; + case ASCENDING_WEST: + this.setMot(vec3d1.add(0.0078125D, 0.0D, 0.0D)); + ++this.locY; + break; + case ASCENDING_NORTH: + this.setMot(vec3d1.add(0.0D, 0.0D, 0.0078125D)); + ++this.locY; + break; + case ASCENDING_SOUTH: + this.setMot(vec3d1.add(0.0D, 0.0D, -0.0078125D)); + ++this.locY; } - int[][] aint = EntityMinecartAbstract.h[blockpropertytrackposition.a()]; + vec3d1 = this.getMot(); + int[][] aint = EntityMinecartAbstract.as[blockpropertytrackposition.a()]; double d1 = (double) (aint[1][0] - aint[0][0]); double d2 = (double) (aint[1][2] - aint[0][2]); double d3 = Math.sqrt(d1 * d1 + d2 * d2); - double d4 = this.motX * d1 + this.motZ * d2; + double d4 = vec3d1.x * d1 + vec3d1.z * d2; if (d4 < 0.0D) { d1 = -d1; d2 = -d2; } - double d5 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); + double d5 = Math.min(2.0D, Math.sqrt(b(vec3d1))); - if (d5 > 2.0D) { - d5 = 2.0D; - } - - this.motX = d5 * d1 / d3; - this.motZ = d5 * d2 / d3; - Entity entity = this.bP().isEmpty() ? null : (Entity) this.bP().get(0); - double d6; - double d7; - double d8; - double d9; + vec3d1 = new Vec3D(d5 * d1 / d3, vec3d1.y, d5 * d2 / d3); + this.setMot(vec3d1); + Entity entity = this.getPassengers().isEmpty() ? null : (Entity) this.getPassengers().get(0); if (entity instanceof EntityHuman) { - d6 = (double) ((EntityHuman) entity).bj; - if (d6 > 0.0D) { - d7 = -Math.sin((double) (entity.yaw * 0.017453292F)); - d8 = Math.cos((double) (entity.yaw * 0.017453292F)); - d9 = this.motX * this.motX + this.motZ * this.motZ; - if (d9 < 0.01D) { - this.motX += d7 * 0.1D; - this.motZ += d8 * 0.1D; - flag1 = false; - } + Vec3D vec3d2 = entity.getMot(); + double d6 = b(vec3d2); + double d7 = b(this.getMot()); + + if (d6 > 1.0E-4D && d7 < 0.01D) { + this.setMot(this.getMot().add(vec3d2.x * 0.1D, 0.0D, vec3d2.z * 0.1D)); + flag1 = false; } } + double d8; + if (flag1) { - d6 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); - if (d6 < 0.03D) { - this.motX *= 0.0D; - this.motY *= 0.0D; - this.motZ *= 0.0D; + d8 = Math.sqrt(b(this.getMot())); + if (d8 < 0.03D) { + this.setMot(Vec3D.a); } else { - this.motX *= 0.5D; - this.motY *= 0.0D; - this.motZ *= 0.5D; + this.setMot(this.getMot().d(0.5D, 0.0D, 0.5D)); } } - d6 = (double) blockposition.getX() + 0.5D + (double) aint[0][0] * 0.5D; - d7 = (double) blockposition.getZ() + 0.5D + (double) aint[0][2] * 0.5D; - d8 = (double) blockposition.getX() + 0.5D + (double) aint[1][0] * 0.5D; - d9 = (double) blockposition.getZ() + 0.5D + (double) aint[1][2] * 0.5D; - d1 = d8 - d6; - d2 = d9 - d7; - double d10; - double d11; + d8 = (double) blockposition.getX() + 0.5D + (double) aint[0][0] * 0.5D; + double d9 = (double) blockposition.getZ() + 0.5D + (double) aint[0][2] * 0.5D; + double d10 = (double) blockposition.getX() + 0.5D + (double) aint[1][0] * 0.5D; + double d11 = (double) blockposition.getZ() + 0.5D + (double) aint[1][2] * 0.5D; + + d1 = d10 - d8; + d2 = d11 - d9; double d12; + double d13; + double d14; if (d1 == 0.0D) { this.locX = (double) blockposition.getX() + 0.5D; - d10 = this.locZ - (double) blockposition.getZ(); + d12 = this.locZ - (double) blockposition.getZ(); } else if (d2 == 0.0D) { this.locZ = (double) blockposition.getZ() + 0.5D; - d10 = this.locX - (double) blockposition.getX(); + d12 = this.locX - (double) blockposition.getX(); } else { - d11 = this.locX - d6; - d12 = this.locZ - d7; - d10 = (d11 * d1 + d12 * d2) * 2.0D; + d13 = this.locX - d8; + d14 = this.locZ - d9; + d12 = (d13 * d1 + d14 * d2) * 2.0D; } - this.locX = d6 + d1 * d10; - this.locZ = d7 + d2 * d10; + this.locX = d8 + d1 * d12; + this.locZ = d9 + d2 * d12; this.setPosition(this.locX, this.locY, this.locZ); - d11 = this.motX; - d12 = this.motZ; - if (this.isVehicle()) { - d11 *= 0.75D; - d12 *= 0.75D; - } - - double d13 = this.p(); - - d11 = MathHelper.a(d11, -d13, d13); - d12 = MathHelper.a(d12, -d13, d13); - this.move(EnumMoveType.SELF, d11, 0.0D, d12); + d13 = this.isVehicle() ? 0.75D : 1.0D; + d14 = this.getMaxSpeed(); + vec3d1 = this.getMot(); + this.move(EnumMoveType.SELF, new Vec3D(MathHelper.a(d13 * vec3d1.x, -d14, d14), 0.0D, MathHelper.a(d13 * vec3d1.z, -d14, d14))); if (aint[0][1] != 0 && MathHelper.floor(this.locX) - blockposition.getX() == aint[0][0] && MathHelper.floor(this.locZ) - blockposition.getZ() == aint[0][2]) { this.setPosition(this.locX, this.locY + (double) aint[0][1], this.locZ); } else if (aint[1][1] != 0 && MathHelper.floor(this.locX) - blockposition.getX() == aint[1][0] && MathHelper.floor(this.locZ) - blockposition.getZ() == aint[1][2]) { this.setPosition(this.locX, this.locY + (double) aint[1][1], this.locZ); } - this.r(); - Vec3D vec3d1 = this.j(this.locX, this.locY, this.locZ); + this.decelerate(); + Vec3D vec3d3 = this.l(this.locX, this.locY, this.locZ); + Vec3D vec3d4; + double d15; - if (vec3d1 != null && vec3d != null) { - double d14 = (vec3d.y - vec3d1.y) * 0.05D; + if (vec3d3 != null && vec3d != null) { + double d16 = (vec3d.y - vec3d3.y) * 0.05D; - d5 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); - if (d5 > 0.0D) { - this.motX = this.motX / d5 * (d5 + d14); - this.motZ = this.motZ / d5 * (d5 + d14); + vec3d4 = this.getMot(); + d15 = Math.sqrt(b(vec3d4)); + if (d15 > 0.0D) { + this.setMot(vec3d4.d((d15 + d16) / d15, 1.0D, (d15 + d16) / d15)); } - this.setPosition(this.locX, vec3d1.y, this.locZ); + this.setPosition(this.locX, vec3d3.y, this.locZ); } int i = MathHelper.floor(this.locX); int j = MathHelper.floor(this.locZ); if (i != blockposition.getX() || j != blockposition.getZ()) { - d5 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); - this.motX = d5 * (double) (i - blockposition.getX()); - this.motZ = d5 * (double) (j - blockposition.getZ()); + vec3d4 = this.getMot(); + d15 = Math.sqrt(b(vec3d4)); + this.setMot(d15 * (double) (i - blockposition.getX()), vec3d4.y, d15 * (double) (j - blockposition.getZ())); } if (flag) { - double d15 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); - + vec3d4 = this.getMot(); + d15 = Math.sqrt(b(vec3d4)); if (d15 > 0.01D) { - double d16 = 0.06D; + double d17 = 0.06D; - this.motX += this.motX / d15 * 0.06D; - this.motZ += this.motZ / d15 * 0.06D; - } else if (blockpropertytrackposition == BlockPropertyTrackPosition.EAST_WEST) { - if (this.world.getType(blockposition.west()).isOccluding()) { - this.motX = 0.02D; - } else if (this.world.getType(blockposition.east()).isOccluding()) { - this.motX = -0.02D; - } - } else if (blockpropertytrackposition == BlockPropertyTrackPosition.NORTH_SOUTH) { - if (this.world.getType(blockposition.north()).isOccluding()) { - this.motZ = 0.02D; - } else if (this.world.getType(blockposition.south()).isOccluding()) { - this.motZ = -0.02D; + this.setMot(vec3d4.add(vec3d4.x / d15 * 0.06D, 0.0D, vec3d4.z / d15 * 0.06D)); + } else { + Vec3D vec3d5 = this.getMot(); + double d18 = vec3d5.x; + double d19 = vec3d5.z; + + if (blockpropertytrackposition == BlockPropertyTrackPosition.EAST_WEST) { + if (this.a(blockposition.west())) { + d18 = 0.02D; + } else if (this.a(blockposition.east())) { + d18 = -0.02D; + } + } else { + if (blockpropertytrackposition != BlockPropertyTrackPosition.NORTH_SOUTH) { + return; + } + + if (this.a(blockposition.north())) { + d19 = 0.02D; + } else if (this.a(blockposition.south())) { + d19 = -0.02D; + } } + + this.setMot(d18, vec3d5.y, d19); } } } - protected void r() { - if (this.isVehicle() || !this.slowWhenEmpty) { // CraftBukkit - add !this.slowWhenEmpty - this.motX *= 0.996999979019165D; - this.motY *= 0.0D; - this.motZ *= 0.996999979019165D; - } else { - this.motX *= 0.9599999785423279D; - this.motY *= 0.0D; - this.motZ *= 0.9599999785423279D; - } - + private boolean a(BlockPosition blockposition) { + return this.world.getType(blockposition).isOccluding(this.world, blockposition); } - public void setPosition(double d0, double d1, double d2) { - this.locX = d0; - this.locY = d1; - this.locZ = d2; - float f = this.width / 2.0F; - float f1 = this.length; + protected void decelerate() { + double d0 = this.isVehicle() || !this.slowWhenEmpty ? 0.997D : 0.96D; // CraftBukkit - add !this.slowWhenEmpty - this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); + this.setMot(this.getMot().d(d0, 0.0D, d0)); } @Nullable - public Vec3D j(double d0, double d1, double d2) { + public Vec3D l(double d0, double d1, double d2) { int i = MathHelper.floor(d0); int j = MathHelper.floor(d1); int k = MathHelper.floor(d2); @@ -626,7 +548,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT if (iblockdata.a(TagsBlock.RAILS)) { BlockPropertyTrackPosition blockpropertytrackposition = (BlockPropertyTrackPosition) iblockdata.get(((BlockMinecartTrackAbstract) iblockdata.getBlock()).e()); - int[][] aint = EntityMinecartAbstract.h[blockpropertytrackposition.a()]; + int[][] aint = EntityMinecartAbstract.as[blockpropertytrackposition.a()]; double d3 = (double) i + 0.5D + (double) aint[0][0] * 0.5D; double d4 = (double) j + 0.0625D + (double) aint[0][1] * 0.5D; double d5 = (double) k + 0.5D + (double) aint[0][2] * 0.5D; @@ -666,6 +588,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT } } + @Override protected void a(NBTTagCompound nbttagcompound) { if (nbttagcompound.getBoolean("CustomDisplayTile")) { this.setDisplayBlock(GameProfileSerializer.d(nbttagcompound.getCompound("DisplayState"))); @@ -674,8 +597,9 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT } + @Override protected void b(NBTTagCompound nbttagcompound) { - if (this.C()) { + if (this.u()) { nbttagcompound.setBoolean("CustomDisplayTile", true); nbttagcompound.set("DisplayState", GameProfileSerializer.a(this.getDisplayBlock())); nbttagcompound.setInt("DisplayOffset", this.getDisplayBlockOffset()); @@ -683,6 +607,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT } + @Override public void collide(Entity entity) { if (!this.world.isClientSide) { if (!entity.noclip && !this.noclip) { @@ -713,44 +638,39 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT d1 *= d3; d0 *= 0.10000000149011612D; d1 *= 0.10000000149011612D; - d0 *= (double) (1.0F - this.S); - d1 *= (double) (1.0F - this.S); + d0 *= (double) (1.0F - this.M); + d1 *= (double) (1.0F - this.M); d0 *= 0.5D; d1 *= 0.5D; if (entity instanceof EntityMinecartAbstract) { double d4 = entity.locX - this.locX; double d5 = entity.locZ - this.locZ; - Vec3D vec3d = (new Vec3D(d4, 0.0D, d5)).a(); - Vec3D vec3d1 = (new Vec3D((double) MathHelper.cos(this.yaw * 0.017453292F), 0.0D, (double) MathHelper.sin(this.yaw * 0.017453292F))).a(); + Vec3D vec3d = (new Vec3D(d4, 0.0D, d5)).d(); + Vec3D vec3d1 = (new Vec3D((double) MathHelper.cos(this.yaw * 0.017453292F), 0.0D, (double) MathHelper.sin(this.yaw * 0.017453292F))).d(); double d6 = Math.abs(vec3d.b(vec3d1)); if (d6 < 0.800000011920929D) { return; } - double d7 = entity.motX + this.motX; - double d8 = entity.motZ + this.motZ; + Vec3D vec3d2 = this.getMot(); + Vec3D vec3d3 = entity.getMot(); - if (((EntityMinecartAbstract) entity).v() == EntityMinecartAbstract.EnumMinecartType.FURNACE && this.v() != EntityMinecartAbstract.EnumMinecartType.FURNACE) { - this.motX *= 0.20000000298023224D; - this.motZ *= 0.20000000298023224D; - this.f(entity.motX - d0, 0.0D, entity.motZ - d1); - entity.motX *= 0.949999988079071D; - entity.motZ *= 0.949999988079071D; - } else if (((EntityMinecartAbstract) entity).v() != EntityMinecartAbstract.EnumMinecartType.FURNACE && this.v() == EntityMinecartAbstract.EnumMinecartType.FURNACE) { - entity.motX *= 0.20000000298023224D; - entity.motZ *= 0.20000000298023224D; - entity.f(this.motX + d0, 0.0D, this.motZ + d1); - this.motX *= 0.949999988079071D; - this.motZ *= 0.949999988079071D; + if (((EntityMinecartAbstract) entity).getMinecartType() == EntityMinecartAbstract.EnumMinecartType.FURNACE && this.getMinecartType() != EntityMinecartAbstract.EnumMinecartType.FURNACE) { + this.setMot(vec3d2.d(0.2D, 1.0D, 0.2D)); + this.f(vec3d3.x - d0, 0.0D, vec3d3.z - d1); + entity.setMot(vec3d3.d(0.95D, 1.0D, 0.95D)); + } else if (((EntityMinecartAbstract) entity).getMinecartType() != EntityMinecartAbstract.EnumMinecartType.FURNACE && this.getMinecartType() == EntityMinecartAbstract.EnumMinecartType.FURNACE) { + entity.setMot(vec3d3.d(0.2D, 1.0D, 0.2D)); + entity.f(vec3d2.x + d0, 0.0D, vec3d2.z + d1); + this.setMot(vec3d2.d(0.95D, 1.0D, 0.95D)); } else { - d7 /= 2.0D; - d8 /= 2.0D; - this.motX *= 0.20000000298023224D; - this.motZ *= 0.20000000298023224D; + double d7 = (vec3d3.x + vec3d2.x) / 2.0D; + double d8 = (vec3d3.z + vec3d2.z) / 2.0D; + + this.setMot(vec3d2.d(0.2D, 1.0D, 0.2D)); this.f(d7 - d0, 0.0D, d8 - d1); - entity.motX *= 0.20000000298023224D; - entity.motZ *= 0.20000000298023224D; + entity.setMot(vec3d3.d(0.2D, 1.0D, 0.2D)); entity.f(d7 + d0, 0.0D, d8 + d1); } } else { @@ -765,81 +685,75 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT } public void setDamage(float f) { - this.datawatcher.set(EntityMinecartAbstract.c, f); + this.datawatcher.set(EntityMinecartAbstract.d, f); } public float getDamage() { - return (Float) this.datawatcher.get(EntityMinecartAbstract.c); + return (Float) this.datawatcher.get(EntityMinecartAbstract.d); } - public void d(int i) { - this.datawatcher.set(EntityMinecartAbstract.a, i); - } - - public int getType() { - return (Integer) this.datawatcher.get(EntityMinecartAbstract.a); - } - - public void k(int i) { + public void c(int i) { this.datawatcher.set(EntityMinecartAbstract.b, i); } - public int u() { + public int getType() { return (Integer) this.datawatcher.get(EntityMinecartAbstract.b); } - public abstract EntityMinecartAbstract.EnumMinecartType v(); - - public IBlockData getDisplayBlock() { - return !this.C() ? this.z() : Block.getByCombinedId((Integer) this.getDataWatcher().get(EntityMinecartAbstract.d)); + public void d(int i) { + this.datawatcher.set(EntityMinecartAbstract.c, i); } - public IBlockData z() { + public int n() { + return (Integer) this.datawatcher.get(EntityMinecartAbstract.c); + } + + public abstract EntityMinecartAbstract.EnumMinecartType getMinecartType(); + + public IBlockData getDisplayBlock() { + return !this.u() ? this.q() : Block.getByCombinedId((Integer) this.getDataWatcher().get(EntityMinecartAbstract.e)); + } + + public IBlockData q() { return Blocks.AIR.getBlockData(); } public int getDisplayBlockOffset() { - return !this.C() ? this.B() : (Integer) this.getDataWatcher().get(EntityMinecartAbstract.e); + return !this.u() ? this.s() : (Integer) this.getDataWatcher().get(EntityMinecartAbstract.f); } - public int B() { + public int s() { return 6; } public void setDisplayBlock(IBlockData iblockdata) { - this.getDataWatcher().set(EntityMinecartAbstract.d, Block.getCombinedId(iblockdata)); + this.getDataWatcher().set(EntityMinecartAbstract.e, Block.getCombinedId(iblockdata)); this.a(true); } public void setDisplayBlockOffset(int i) { - this.getDataWatcher().set(EntityMinecartAbstract.e, i); + this.getDataWatcher().set(EntityMinecartAbstract.f, i); this.a(true); } - public boolean C() { - return (Boolean) this.getDataWatcher().get(EntityMinecartAbstract.f); + public boolean u() { + return (Boolean) this.getDataWatcher().get(EntityMinecartAbstract.g); } public void a(boolean flag) { - this.getDataWatcher().set(EntityMinecartAbstract.f, flag); + this.getDataWatcher().set(EntityMinecartAbstract.g, flag); + } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); } public static enum EnumMinecartType { - RIDEABLE(0), CHEST(1), FURNACE(2), TNT(3), SPAWNER(4), HOPPER(5), COMMAND_BLOCK(6); + RIDEABLE, CHEST, FURNACE, TNT, SPAWNER, HOPPER, COMMAND_BLOCK; - private static final EntityMinecartAbstract.EnumMinecartType[] h = (EntityMinecartAbstract.EnumMinecartType[]) Arrays.stream(values()).sorted(Comparator.comparingInt(EntityMinecartAbstract.EnumMinecartType::a)).toArray((i) -> { - return new EntityMinecartAbstract.EnumMinecartType[i]; - }); - private final int i; - - private EnumMinecartType(int i) { - this.i = i; - } - - public int a() { - return this.i; - } + private EnumMinecartType() {} } // CraftBukkit start - Methods for getting and setting flying and derailed velocity modifiers diff --git a/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java b/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java index 61f11c90d..9ef7eadeb 100644 --- a/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java +++ b/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java @@ -3,76 +3,85 @@ package net.minecraft.server; public class EntityMinecartCommandBlock extends EntityMinecartAbstract { public static final DataWatcherObject COMMAND = DataWatcher.a(EntityMinecartCommandBlock.class, DataWatcherRegistry.d); - private static final DataWatcherObject b = DataWatcher.a(EntityMinecartCommandBlock.class, DataWatcherRegistry.e); - private final CommandBlockListenerAbstract c = new EntityMinecartCommandBlock.a(); - private int d; + private static final DataWatcherObject c = DataWatcher.a(EntityMinecartCommandBlock.class, DataWatcherRegistry.e); + private final CommandBlockListenerAbstract d = new EntityMinecartCommandBlock.a(); + private int e; - public EntityMinecartCommandBlock(World world) { - super(EntityTypes.COMMAND_BLOCK_MINECART, world); + public EntityMinecartCommandBlock(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntityMinecartCommandBlock(World world, double d0, double d1, double d2) { super(EntityTypes.COMMAND_BLOCK_MINECART, world, d0, d1, d2); } - protected void x_() { - super.x_(); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); this.getDataWatcher().register(EntityMinecartCommandBlock.COMMAND, ""); - this.getDataWatcher().register(EntityMinecartCommandBlock.b, new ChatComponentText("")); + this.getDataWatcher().register(EntityMinecartCommandBlock.c, new ChatComponentText("")); } + @Override protected void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.c.b(nbttagcompound); + this.d.b(nbttagcompound); this.getDataWatcher().set(EntityMinecartCommandBlock.COMMAND, this.getCommandBlock().getCommand()); - this.getDataWatcher().set(EntityMinecartCommandBlock.b, this.getCommandBlock().j()); + this.getDataWatcher().set(EntityMinecartCommandBlock.c, this.getCommandBlock().j()); } + @Override protected void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - this.c.a(nbttagcompound); + this.d.a(nbttagcompound); } - public EntityMinecartAbstract.EnumMinecartType v() { + @Override + public EntityMinecartAbstract.EnumMinecartType getMinecartType() { return EntityMinecartAbstract.EnumMinecartType.COMMAND_BLOCK; } - public IBlockData z() { + @Override + public IBlockData q() { return Blocks.COMMAND_BLOCK.getBlockData(); } public CommandBlockListenerAbstract getCommandBlock() { - return this.c; + return this.d; } + @Override public void a(int i, int j, int k, boolean flag) { - if (flag && this.ticksLived - this.d >= 4) { + if (flag && this.ticksLived - this.e >= 4) { this.getCommandBlock().a(this.world); - this.d = this.ticksLived; + this.e = this.ticksLived; } } + @Override public boolean b(EntityHuman entityhuman, EnumHand enumhand) { - this.c.a(entityhuman); + this.d.a(entityhuman); return true; } + @Override public void a(DataWatcherObject datawatcherobject) { super.a(datawatcherobject); - if (EntityMinecartCommandBlock.b.equals(datawatcherobject)) { + if (EntityMinecartCommandBlock.c.equals(datawatcherobject)) { try { - this.c.c((IChatBaseComponent) this.getDataWatcher().get(EntityMinecartCommandBlock.b)); + this.d.c((IChatBaseComponent) this.getDataWatcher().get(EntityMinecartCommandBlock.c)); } catch (Throwable throwable) { ; } } else if (EntityMinecartCommandBlock.COMMAND.equals(datawatcherobject)) { - this.c.setCommand((String) this.getDataWatcher().get(EntityMinecartCommandBlock.COMMAND)); + this.d.setCommand((String) this.getDataWatcher().get(EntityMinecartCommandBlock.COMMAND)); } } - public boolean bM() { + @Override + public boolean bT() { return true; } @@ -80,17 +89,20 @@ public class EntityMinecartCommandBlock extends EntityMinecartAbstract { public a() {} + @Override public WorldServer d() { return (WorldServer) EntityMinecartCommandBlock.this.world; } + @Override public void e() { EntityMinecartCommandBlock.this.getDataWatcher().set(EntityMinecartCommandBlock.COMMAND, this.getCommand()); - EntityMinecartCommandBlock.this.getDataWatcher().set(EntityMinecartCommandBlock.b, this.j()); + EntityMinecartCommandBlock.this.getDataWatcher().set(EntityMinecartCommandBlock.c, this.j()); } + @Override public CommandListenerWrapper getWrapper() { - return new CommandListenerWrapper(this, new Vec3D(EntityMinecartCommandBlock.this.locX, EntityMinecartCommandBlock.this.locY, EntityMinecartCommandBlock.this.locZ), EntityMinecartCommandBlock.this.aO(), this.d(), 2, this.getName().getString(), EntityMinecartCommandBlock.this.getScoreboardDisplayName(), this.d().getMinecraftServer(), EntityMinecartCommandBlock.this); + return new CommandListenerWrapper(this, new Vec3D(EntityMinecartCommandBlock.this.locX, EntityMinecartCommandBlock.this.locY, EntityMinecartCommandBlock.this.locZ), EntityMinecartCommandBlock.this.aU(), this.d(), 2, this.getName().getString(), EntityMinecartCommandBlock.this.getScoreboardDisplayName(), this.d().getMinecraftServer(), EntityMinecartCommandBlock.this); } // CraftBukkit start diff --git a/src/main/java/net/minecraft/server/EntityMinecartContainer.java b/src/main/java/net/minecraft/server/EntityMinecartContainer.java index e228fc853..8e6e7ed60 100644 --- a/src/main/java/net/minecraft/server/EntityMinecartContainer.java +++ b/src/main/java/net/minecraft/server/EntityMinecartContainer.java @@ -1,7 +1,6 @@ package net.minecraft.server; import java.util.Iterator; -import java.util.Random; import javax.annotation.Nullable; // CraftBukkit start import java.util.List; @@ -11,15 +10,16 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.InventoryHolder; // CraftBukkit end -public abstract class EntityMinecartContainer extends EntityMinecartAbstract implements ITileInventory, ILootable { +public abstract class EntityMinecartContainer extends EntityMinecartAbstract implements IInventory, ITileInventory { private NonNullList items; - private boolean b; - private MinecraftKey c; public MinecraftKey getLootTableKey() { return c; } public void setLootTable(MinecraftKey key) { c = key; } // Paper - OBFHELPER + private boolean c; + @Nullable + public MinecraftKey lootTable; public MinecraftKey getLootTableKey() { return this.lootTable; } public void setLootTable(final MinecraftKey key) { this.lootTable = key; } // Paper - OBFHELPER public long lootTableSeed; // CraftBukkit start - { lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(new com.destroystokyo.paper.loottable.PaperMinecartLootableInventory(this)); } // Paper + { this.lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(new com.destroystokyo.paper.loottable.PaperMinecartLootableInventory(this)); } // Paper public List transaction = new java.util.ArrayList(); private int maxStack = MAX_STACK; @@ -45,6 +45,11 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp return null; } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; } @@ -58,24 +63,26 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp protected EntityMinecartContainer(EntityTypes entitytypes, World world) { super(entitytypes, world); this.items = NonNullList.a(this.getSize(), ItemStack.a); // CraftBukkit - SPIGOT-3513 - this.b = true; + this.c = true; } protected EntityMinecartContainer(EntityTypes entitytypes, double d0, double d1, double d2, World world) { super(entitytypes, world, d0, d1, d2); this.items = NonNullList.a(this.getSize(), ItemStack.a); // CraftBukkit - SPIGOT-3513 - this.b = true; + this.c = true; } + @Override public void a(DamageSource damagesource) { super.a(damagesource); - if (this.world.getGameRules().getBoolean("doEntityDrops")) { + if (this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { InventoryUtils.dropEntity(this.world, this, this); } } - public boolean P_() { + @Override + public boolean isNotEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -91,18 +98,21 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp return false; } + @Override public ItemStack getItem(int i) { - this.f((EntityHuman) null); + this.d((EntityHuman) null); return (ItemStack) this.items.get(i); } + @Override public ItemStack splitStack(int i, int j) { - this.f((EntityHuman) null); + this.d((EntityHuman) null); return ContainerUtil.a(this.items, i, j); } + @Override public ItemStack splitWithoutUpdate(int i) { - this.f((EntityHuman) null); + this.d((EntityHuman) null); ItemStack itemstack = (ItemStack) this.items.get(i); if (itemstack.isEmpty()) { @@ -113,8 +123,9 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp } } + @Override public void setItem(int i, ItemStack itemstack) { - this.f((EntityHuman) null); + this.d((EntityHuman) null); this.items.set(i, itemstack); if (!itemstack.isEmpty() && itemstack.getCount() > this.getMaxStackSize()) { itemstack.setCount(this.getMaxStackSize()); @@ -122,7 +133,8 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp } - public boolean c(int i, ItemStack itemstack) { + @Override + public boolean a_(int i, ItemStack itemstack) { if (i >= 0 && i < this.getSize()) { this.setItem(i, itemstack); return true; @@ -131,47 +143,36 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp } } + @Override public void update() {} + @Override public boolean a(EntityHuman entityhuman) { - return this.dead ? false : entityhuman.h(this) <= 64.0D; - } - - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - - public boolean b(int i, ItemStack itemstack) { - return true; - } - - public int getMaxStackSize() { - return maxStack; // CraftBukkit + return this.dead ? false : entityhuman.h((Entity) this) <= 64.0D; } @Nullable + @Override public Entity a(DimensionManager dimensionmanager) { - this.b = false; + this.c = false; return super.a(dimensionmanager); } + @Override public void die() { - if (this.b) { + if (!this.world.isClientSide && this.c) { InventoryUtils.dropEntity(this.world, this, this); } super.die(); } - public void b(boolean flag) { - this.b = flag; - } - + @Override protected void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - lootableData.saveNbt(nbttagcompound); // Paper - if (this.c != null) { - nbttagcompound.setString("LootTable", this.c.toString()); + this.lootableData.saveNbt(nbttagcompound); // Paper + if (this.lootTable != null) { + nbttagcompound.setString("LootTable", this.lootTable.toString()); if (this.lootTableSeed != 0L) { nbttagcompound.setLong("LootTableSeed", this.lootTableSeed); } @@ -181,12 +182,13 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp } + @Override protected void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - lootableData.loadNbt(nbttagcompound); // Paper + this.lootableData.loadNbt(nbttagcompound); // Paper this.items = NonNullList.a(this.getSize(), ItemStack.a); if (nbttagcompound.hasKeyOfType("LootTable", 8)) { - this.c = new MinecraftKey(nbttagcompound.getString("LootTable")); + this.lootTable = new MinecraftKey(nbttagcompound.getString("LootTable")); this.lootTableSeed = nbttagcompound.getLong("LootTableSeed"); } if (true) { // Paper - always load the items, table may still remain ContainerUtil.b(nbttagcompound, this.items); @@ -194,83 +196,62 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp } + @Override public boolean b(EntityHuman entityhuman, EnumHand enumhand) { - if (!this.world.isClientSide) { - entityhuman.openContainer(this); - } - + entityhuman.openContainer(this); return true; } - protected void r() { + @Override + protected void decelerate() { float f = 0.98F; - if (this.c == null) { + if (this.lootTable == null) { int i = 15 - Container.b((IInventory) this); f += (float) i * 0.001F; } - this.motX *= (double) f; - this.motY *= 0.0D; - this.motZ *= (double) f; + this.setMot(this.getMot().d((double) f, 0.0D, (double) f)); } - public int getProperty(int i) { - return 0; - } + public void d(@Nullable EntityHuman entityhuman) { + if (this.lootableData.shouldReplenish(entityhuman) && this.world.getMinecraftServer() != null) { // Paper + LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(this.lootTable); - public void setProperty(int i, int j) {} - - public int h() { - return 0; - } - - public boolean isLocked() { - return false; - } - - public void setLock(ChestLock chestlock) {} - - public ChestLock getLock() { - return ChestLock.a; - } - - public void f(@Nullable EntityHuman entityhuman) { - if (lootableData.shouldReplenish(entityhuman) && this.world.getMinecraftServer() != null) { // Paper - LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(this.c); - - lootableData.processRefill(entityhuman); // Paper - Random random; - - if (this.lootTableSeed == 0L) { - random = new Random(); - } else { - random = new Random(this.lootTableSeed); - } - - LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).position(new BlockPosition(this)); + this.lootableData.processRefill(entityhuman); // Paper + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).set(LootContextParameters.POSITION, new BlockPosition(this)).a(this.lootTableSeed); if (entityhuman != null) { - loottableinfo_builder.luck(entityhuman.dJ()); + loottableinfo_builder.a(entityhuman.eb()).set(LootContextParameters.THIS_ENTITY, entityhuman); } - loottable.fillInventory(this, random, loottableinfo_builder.build()); + loottable.fillInventory(this, loottableinfo_builder.build(LootContextParameterSets.CHEST)); } } + @Override public void clear() { - this.f((EntityHuman) null); + this.d((EntityHuman) null); this.items.clear(); } - public void a(MinecraftKey minecraftkey, long i) { - this.c = minecraftkey; + public void setLootTable(MinecraftKey minecraftkey, long i) { + this.lootTable = minecraftkey; this.lootTableSeed = i; } - public MinecraftKey getLootTable() { - return this.c; + @Nullable + @Override + public Container createMenu(int i, PlayerInventory playerinventory, EntityHuman entityhuman) { + if (this.lootTable != null && entityhuman.isSpectator()) { + return null; + } else { + this.d(playerinventory.player); + return this.a(i, playerinventory); + } } + + protected abstract Container a(int i, PlayerInventory playerinventory); } diff --git a/src/main/java/net/minecraft/server/EntityMonster.java b/src/main/java/net/minecraft/server/EntityMonster.java index dc61263a3..e0609e7e9 100644 --- a/src/main/java/net/minecraft/server/EntityMonster.java +++ b/src/main/java/net/minecraft/server/EntityMonster.java @@ -1,29 +1,38 @@ package net.minecraft.server; +import java.util.Random; +import java.util.function.Predicate; + public abstract class EntityMonster extends EntityCreature implements IMonster { public org.bukkit.craftbukkit.entity.CraftMonster getBukkitMonster() { return (org.bukkit.craftbukkit.entity.CraftMonster) super.getBukkitEntity(); } // Paper - protected EntityMonster(EntityTypes entitytypes, World world) { + protected EntityMonster(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.b_ = 5; + this.f = 5; } - public SoundCategory getSoundCategory() { return bV(); } // Paper - OBFHELPER - public SoundCategory bV() { + @Override + public SoundCategory getSoundCategory() { return SoundCategory.HOSTILE; } + @Override public void movementTick() { - this.cy(); - float f = this.az(); + this.cO(); + this.eb(); + super.movementTick(); + } + + protected void eb() { + float f = this.aF(); if (f > 0.5F) { this.ticksFarFromPlayer += 2; } - super.movementTick(); } + @Override public void tick() { super.tick(); if (!this.world.isClientSide && this.world.getDifficulty() == EnumDifficulty.PEACEFUL) { @@ -32,69 +41,83 @@ public abstract class EntityMonster extends EntityCreature implements IMonster { } - protected SoundEffect ad() { + @Override + protected SoundEffect getSoundSwim() { return SoundEffects.ENTITY_HOSTILE_SWIM; } - protected SoundEffect ae() { + @Override + protected SoundEffect getSoundSplash() { return SoundEffects.ENTITY_HOSTILE_SPLASH; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { return this.isInvulnerable(damagesource) ? false : super.damageEntity(damagesource, f); } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_HOSTILE_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_HOSTILE_DEATH; } - protected SoundEffect m(int i) { + @Override + protected SoundEffect getSoundFall(int i) { return i > 4 ? SoundEffects.ENTITY_HOSTILE_BIG_FALL : SoundEffects.ENTITY_HOSTILE_SMALL_FALL; } + @Override public float a(BlockPosition blockposition, IWorldReader iworldreader) { - return 0.5F - iworldreader.A(blockposition); + return 0.5F - iworldreader.v(blockposition); } - protected boolean K_() { - BlockPosition blockposition = new BlockPosition(this.locX, this.getBoundingBox().minY, this.locZ); - - if (this.world.getBrightness(EnumSkyBlock.SKY, blockposition) > this.random.nextInt(32)) { + public static boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition, Random random) { + if (generatoraccess.getBrightness(EnumSkyBlock.SKY, blockposition) > random.nextInt(32)) { return false; } else { - // Paper start - optimized light check, returns faster - boolean passes; - if (this.world.Y()) { - final int orig = world.getSkylightSubtracted(); - world.setSkylightSubtracted(10); - passes = !this.world.isLightLevel(blockposition, this.random.nextInt(8)); - world.setSkylightSubtracted(orig); - } else { - passes = !this.world.isLightLevel(blockposition, this.random.nextInt(8)); - } - return passes; - // Paper end + int i = generatoraccess.getMinecraftWorld().U() ? generatoraccess.d(blockposition, 10) : generatoraccess.getLightLevel(blockposition); + + return i <= random.nextInt(8); } } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - return generatoraccess.getDifficulty() != EnumDifficulty.PEACEFUL && this.K_() && super.a(generatoraccess, flag); + public static boolean c(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return generatoraccess.getDifficulty() != EnumDifficulty.PEACEFUL && a(generatoraccess, blockposition, random) && a(entitytypes, generatoraccess, enummobspawn, blockposition, random); } + public static boolean d(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return generatoraccess.getDifficulty() != EnumDifficulty.PEACEFUL && a(entitytypes, generatoraccess, enummobspawn, blockposition, random); + } + + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE); } + @Override protected boolean isDropExperience() { return true; } - public boolean c(EntityHuman entityhuman) { + public boolean e(EntityHuman entityhuman) { return true; } + + @Override + public ItemStack f(ItemStack itemstack) { + if (itemstack.getItem() instanceof ItemProjectileWeapon) { + Predicate predicate = ((ItemProjectileWeapon) itemstack.getItem()).d(); + ItemStack itemstack1 = ItemProjectileWeapon.a((EntityLiving) this, predicate); + + return itemstack1.isEmpty() ? new ItemStack(Items.ARROW) : itemstack1; + } else { + return ItemStack.a; + } + } } diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java index f442bc59b..1363069ff 100644 --- a/src/main/java/net/minecraft/server/EntityMushroomCow.java +++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java @@ -1,7 +1,8 @@ package net.minecraft.server; -import javax.annotation.Nullable; - +import java.util.Random; +import java.util.UUID; +import org.apache.commons.lang3.tuple.Pair; // CraftBukkit start import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.entity.EntityTransformEvent; @@ -10,75 +11,236 @@ import org.bukkit.event.player.PlayerShearEntityEvent; public class EntityMushroomCow extends EntityCow { - public EntityMushroomCow(World world) { - super(EntityTypes.MOOSHROOM, world); - this.setSize(0.9F, 1.4F); - this.bF = Blocks.MYCELIUM; + private static final DataWatcherObject bz = DataWatcher.a(EntityMushroomCow.class, DataWatcherRegistry.d); + private MobEffectList bA; + private int bB; + private UUID bC; + + public EntityMushroomCow(EntityTypes entitytypes, World world) { + super(entitytypes, world); } + @Override + public float a(BlockPosition blockposition, IWorldReader iworldreader) { + return iworldreader.getType(blockposition.down()).getBlock() == Blocks.MYCELIUM ? 10.0F : iworldreader.v(blockposition) - 0.5F; + } + + public static boolean c(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return generatoraccess.getType(blockposition.down()).getBlock() == Blocks.MYCELIUM && generatoraccess.getLightLevel(blockposition, 0) > 8; + } + + @Override + public void onLightningStrike(EntityLightning entitylightning) { + UUID uuid = entitylightning.getUniqueID(); + + if (!uuid.equals(this.bC)) { + this.setVariant(this.getVariant() == EntityMushroomCow.Type.RED ? EntityMushroomCow.Type.BROWN : EntityMushroomCow.Type.RED); + this.bC = uuid; + this.a(SoundEffects.ENTITY_MOOSHROOM_CONVERT, 2.0F, 1.0F); + } + + } + + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityMushroomCow.bz, EntityMushroomCow.Type.RED.c); + } + + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); if (itemstack.getItem() == Items.BOWL && this.getAge() >= 0 && !entityhuman.abilities.canInstantlyBuild) { itemstack.subtract(1); + boolean flag = false; + ItemStack itemstack1; + + if (this.bA != null) { + flag = true; + itemstack1 = new ItemStack(Items.SUSPICIOUS_STEW); + ItemSuspiciousStew.a(itemstack1, this.bA, this.bB); + this.bA = null; + this.bB = 0; + } else { + itemstack1 = new ItemStack(Items.MUSHROOM_STEW); + } + if (itemstack.isEmpty()) { - entityhuman.a(enumhand, new ItemStack(Items.MUSHROOM_STEW)); - } else if (!entityhuman.inventory.pickup(new ItemStack(Items.MUSHROOM_STEW))) { - entityhuman.drop(new ItemStack(Items.MUSHROOM_STEW), false); + entityhuman.a(enumhand, itemstack1); + } else if (!entityhuman.inventory.pickup(itemstack1)) { + entityhuman.drop(itemstack1, false); } - return true; - } else if (itemstack.getItem() == Items.SHEARS && this.getAge() >= 0) { - // CraftBukkit start - PlayerShearEntityEvent event = new PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); - this.world.getServer().getPluginManager().callEvent(event); + SoundEffect soundeffect; - if (event.isCancelled()) { - return false; - } - // CraftBukkit end - //this.world.addParticle(Particles.u, this.locX, this.locY + (double) (this.length / 2.0F), this.locZ, 0.0D, 0.0D, 0.0D); // Akarin start - this handle by client - if (!this.world.isClientSide) { - // this.die(); // CraftBukkit - moved down - EntityCow entitycow = EntityTypes.COW.create(world); // Paper - - entitycow.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); - entitycow.setHealth(this.getHealth()); - entitycow.aQ = this.aQ; - if (this.hasCustomName()) { - entitycow.setCustomName(this.getCustomName()); - } - - // CraftBukkit start - if (CraftEventFactory.callEntityTransformEvent(this, entitycow, EntityTransformEvent.TransformReason.SHEARED).isCancelled()) { - return false; - } - if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entitycow.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.SHEARED).callEvent()) return false; // Paper - this.world.addEntity(entitycow, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); - - this.die(); // CraftBukkit - from above - // CraftBukkit end - - for (int i = 0; i < 5; ++i) { - this.world.addEntity(new EntityItem(this.world, this.locX, this.locY + (double) this.length, this.locZ, new ItemStack(Blocks.RED_MUSHROOM))); - } - - itemstack.damage(1, entityhuman); - this.a(SoundEffects.ENTITY_MOOSHROOM_SHEAR, 1.0F, 1.0F); + if (flag) { + soundeffect = SoundEffects.ENTITY_MOOSHROOM_SUSPICIOUS_MILK; + } else { + soundeffect = SoundEffects.ENTITY_MOOSHROOM_MILK; } + this.a(soundeffect, 1.0F, 1.0F); return true; } else { - return super.a(entityhuman, enumhand); + int i; + + if (itemstack.getItem() == Items.SHEARS && this.getAge() >= 0) { + // CraftBukkit start + PlayerShearEntityEvent event = new PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return false; + } + // CraftBukkit end + this.world.addParticle(Particles.EXPLOSION, this.locX, this.locY + (double) (this.getHeight() / 2.0F), this.locZ, 0.0D, 0.0D, 0.0D); + if (!this.world.isClientSide) { + // this.die(); // CraftBukkit - moved down + EntityCow entitycow = (EntityCow) EntityTypes.COW.a(this.world); + + entitycow.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + entitycow.setHealth(this.getHealth()); + entitycow.aK = this.aK; + if (this.hasCustomName()) { + entitycow.setCustomName(this.getCustomName()); + } + + // CraftBukkit start + if (CraftEventFactory.callEntityTransformEvent(this, entitycow, EntityTransformEvent.TransformReason.SHEARED).isCancelled()) { + return false; + } + if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entitycow.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.SHEARED).callEvent()) return false; // Paper + this.world.addEntity(entitycow, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); + + this.die(); // CraftBukkit - from above + // CraftBukkit end + + for (i = 0; i < 5; ++i) { + this.world.addEntity(new EntityItem(this.world, this.locX, this.locY + (double) this.getHeight(), this.locZ, new ItemStack(this.getVariant().d.getBlock()))); + } + + itemstack.damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(enumhand); + }); + this.a(SoundEffects.ENTITY_MOOSHROOM_SHEAR, 1.0F, 1.0F); + } + + return true; + } else { + if (this.getVariant() == EntityMushroomCow.Type.BROWN && itemstack.getItem().a(TagsItem.SMALL_FLOWERS)) { + if (this.bA != null) { + for (int j = 0; j < 2; ++j) { + this.world.addParticle(Particles.SMOKE, this.locX + (double) (this.random.nextFloat() / 2.0F), this.locY + (double) (this.getHeight() / 2.0F), this.locZ + (double) (this.random.nextFloat() / 2.0F), 0.0D, (double) (this.random.nextFloat() / 5.0F), 0.0D); + } + } else { + Pair pair = this.j(itemstack); + + if (!entityhuman.abilities.canInstantlyBuild) { + itemstack.subtract(1); + } + + for (i = 0; i < 4; ++i) { + this.world.addParticle(Particles.EFFECT, this.locX + (double) (this.random.nextFloat() / 2.0F), this.locY + (double) (this.getHeight() / 2.0F), this.locZ + (double) (this.random.nextFloat() / 2.0F), 0.0D, (double) (this.random.nextFloat() / 5.0F), 0.0D); + } + + this.bA = (MobEffectList) pair.getLeft(); + this.bB = (Integer) pair.getRight(); + this.a(SoundEffects.ENTITY_MOOSHROOM_EAT, 2.0F, 1.0F); + } + } + + return super.a(entityhuman, enumhand); + } } } - public EntityMushroomCow createChild(EntityAgeable entityageable) { - return EntityTypes.MOOSHROOM.create(world); // Paper + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setString("Type", this.getVariant().c); + if (this.bA != null) { + nbttagcompound.setByte("EffectId", (byte) MobEffectList.getId(this.bA)); + nbttagcompound.setInt("EffectDuration", this.bB); + } + } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.T; + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setVariant(EntityMushroomCow.Type.b(nbttagcompound.getString("Type"))); + if (nbttagcompound.hasKeyOfType("EffectId", 1)) { + this.bA = MobEffectList.fromId(nbttagcompound.getByte("EffectId")); + } + + if (nbttagcompound.hasKeyOfType("EffectDuration", 3)) { + this.bB = nbttagcompound.getInt("EffectDuration"); + } + + } + + private Pair j(ItemStack itemstack) { + BlockFlowers blockflowers = (BlockFlowers) ((ItemBlock) itemstack.getItem()).getBlock(); + + return Pair.of(blockflowers.d(), blockflowers.e()); + } + + public void setVariant(EntityMushroomCow.Type entitymushroomcow_type) { + this.datawatcher.set(EntityMushroomCow.bz, entitymushroomcow_type.c); + } + + public EntityMushroomCow.Type getVariant() { + return EntityMushroomCow.Type.b((String) this.datawatcher.get(EntityMushroomCow.bz)); + } + + @Override + public EntityMushroomCow createChild(EntityAgeable entityageable) { + EntityMushroomCow entitymushroomcow = (EntityMushroomCow) EntityTypes.MOOSHROOM.a(this.world); + + entitymushroomcow.setVariant(this.a((EntityMushroomCow) entityageable)); + return entitymushroomcow; + } + + private EntityMushroomCow.Type a(EntityMushroomCow entitymushroomcow) { + EntityMushroomCow.Type entitymushroomcow_type = this.getVariant(); + EntityMushroomCow.Type entitymushroomcow_type1 = entitymushroomcow.getVariant(); + EntityMushroomCow.Type entitymushroomcow_type2; + + if (entitymushroomcow_type == entitymushroomcow_type1 && this.random.nextInt(1024) == 0) { + entitymushroomcow_type2 = entitymushroomcow_type == EntityMushroomCow.Type.BROWN ? EntityMushroomCow.Type.RED : EntityMushroomCow.Type.BROWN; + } else { + entitymushroomcow_type2 = this.random.nextBoolean() ? entitymushroomcow_type : entitymushroomcow_type1; + } + + return entitymushroomcow_type2; + } + + public static enum Type { + + RED("red", Blocks.RED_MUSHROOM.getBlockData()), BROWN("brown", Blocks.BROWN_MUSHROOM.getBlockData()); + + private final String c; + private final IBlockData d; + + private Type(String s, IBlockData iblockdata) { + this.c = s; + this.d = iblockdata; + } + + private static EntityMushroomCow.Type b(String s) { + EntityMushroomCow.Type[] aentitymushroomcow_type = values(); + int i = aentitymushroomcow_type.length; + + for (int j = 0; j < i; ++j) { + EntityMushroomCow.Type entitymushroomcow_type = aentitymushroomcow_type[j]; + + if (entitymushroomcow_type.c.equals(s)) { + return entitymushroomcow_type; + } + } + + return EntityMushroomCow.Type.RED; + } } } diff --git a/src/main/java/net/minecraft/server/EntityOcelot.java b/src/main/java/net/minecraft/server/EntityOcelot.java index 13c84bda8..edc5f696c 100644 --- a/src/main/java/net/minecraft/server/EntityOcelot.java +++ b/src/main/java/net/minecraft/server/EntityOcelot.java @@ -1,44 +1,64 @@ package net.minecraft.server; +import java.util.Random; import java.util.function.Predicate; import javax.annotation.Nullable; -public class EntityOcelot extends EntityTameableAnimal { +public class EntityOcelot extends EntityAnimal { - private static final RecipeItemStack bG = RecipeItemStack.a(Items.COD, Items.SALMON, Items.TROPICAL_FISH, Items.PUFFERFISH); - private static final DataWatcherObject bH = DataWatcher.a(EntityOcelot.class, DataWatcherRegistry.b); - private static final MinecraftKey bI = new MinecraftKey("cat"); - private PathfinderGoalAvoidTarget bJ; - private PathfinderGoalTempt bK; + private static final RecipeItemStack bz = RecipeItemStack.a(Items.COD, Items.SALMON); + private static final DataWatcherObject bA = DataWatcher.a(EntityOcelot.class, DataWatcherRegistry.i); + private EntityOcelot.a bB; + private EntityOcelot.b bC; public boolean spawnBonus = true; // Spigot - public EntityOcelot(World world) { - super(EntityTypes.OCELOT, world); - this.setSize(0.6F, 0.7F); + public EntityOcelot(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.dV(); } - protected void n() { - this.goalSit = new PathfinderGoalSit(this); - this.bK = new PathfinderGoalTempt(this, 0.6D, EntityOcelot.bG, true); + private boolean isTrusting() { + return (Boolean) this.datawatcher.get(EntityOcelot.bA); + } + + private void setTrusting(boolean flag) { + this.datawatcher.set(EntityOcelot.bA, flag); + this.dV(); + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setBoolean("Trusting", this.isTrusting()); + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setTrusting(nbttagcompound.getBoolean("Trusting")); + } + + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityOcelot.bA, false); + } + + @Override + protected void initPathfinder() { + this.bC = new EntityOcelot.b(this, 0.6D, EntityOcelot.bz, true); this.goalSelector.a(1, new PathfinderGoalFloat(this)); - this.goalSelector.a(2, this.goalSit); - this.goalSelector.a(3, this.bK); - this.goalSelector.a(5, new PathfinderGoalFollowOwner(this, 1.0D, 10.0F, 5.0F)); - this.goalSelector.a(6, new PathfinderGoalJumpOnBlock(this, 0.8D)); + this.goalSelector.a(3, this.bC); this.goalSelector.a(7, new PathfinderGoalLeapAtTarget(this, 0.3F)); this.goalSelector.a(8, new PathfinderGoalOcelotAttack(this)); this.goalSelector.a(9, new PathfinderGoalBreed(this, 0.8D)); this.goalSelector.a(10, new PathfinderGoalRandomStrollLand(this, 0.8D, 1.0000001E-5F)); this.goalSelector.a(11, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); - this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityChicken.class, false, (Predicate) null)); - this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityTurtle.class, false, EntityTurtle.bC)); - } - - protected void x_() { - super.x_(); - this.datawatcher.register(EntityOcelot.bH, 0); + this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityChicken.class, false)); + this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, false, false, EntityTurtle.bz)); } + @Override public void mobTick() { if (this.getControllerMove().b()) { double d0 = this.getControllerMove().c(); @@ -60,143 +80,122 @@ public class EntityOcelot extends EntityTameableAnimal { } - public boolean isTypeNotPersistent() { - return !this.isTamed() && !this.hasCustomName() && !this.isLeashed() /*&& this.ticksLived > 2400*/; // CraftBukkit - Paper (honor name and leash) + @Override + public boolean isTypeNotPersistent(double d0) { + return !this.isTrusting() && !this.hasCustomName() && !this.isLeashed() /*&& this.ticksLived > 2400*/; // CraftBukkit // Paper - honor name and leash } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); } - public void c(float f, float f1) {} - - public void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); - nbttagcompound.setInt("CatType", this.getCatType()); - } - - public void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - this.setCatType(nbttagcompound.getInt("CatType")); - } + @Override + public void b(float f, float f1) {} @Nullable - protected SoundEffect D() { - return this.isTamed() ? (this.isInLove() ? SoundEffects.ENTITY_CAT_PURR : (this.random.nextInt(4) == 0 ? SoundEffects.ENTITY_CAT_PURREOW : SoundEffects.ENTITY_CAT_AMBIENT)) : null; + @Override + protected SoundEffect getSoundAmbient() { + return SoundEffects.ENTITY_OCELOT_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { - return SoundEffects.ENTITY_CAT_HURT; + @Override + public int A() { + return 900; } - protected SoundEffect cs() { - return SoundEffects.ENTITY_CAT_DEATH; + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return SoundEffects.ENTITY_OCELOT_HURT; } - protected float cD() { - return 0.4F; + @Override + protected SoundEffect getSoundDeath() { + return SoundEffects.ENTITY_OCELOT_DEATH; } - public boolean B(Entity entity) { + @Override + public boolean C(Entity entity) { return entity.damageEntity(DamageSource.mobAttack(this), 3.0F); } + @Override public boolean damageEntity(DamageSource damagesource, float f) { - if (this.isInvulnerable(damagesource)) { - return false; - } else { - if (this.goalSit != null) { - // CraftBukkit - moved into EntityLiving.d(DamageSource, float) - // this.goalSit.setSitting(false); - } - - return super.damageEntity(damagesource, f); - } - } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.V; + return this.isInvulnerable(damagesource) ? false : super.damageEntity(damagesource, f); } + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); - if (this.isTamed()) { - if (this.f((EntityLiving) entityhuman) && !this.world.isClientSide && !this.f(itemstack)) { - this.goalSit.setSitting(!this.isSitting()); - } - } else if ((this.bK == null || this.bK.g()) && EntityOcelot.bG.test(itemstack) && entityhuman.h(this) < 9.0D) { - if (!entityhuman.abilities.canInstantlyBuild) { - itemstack.subtract(1); - } - + if ((this.bC == null || this.bC.h()) && !this.isTrusting() && this.i(itemstack) && entityhuman.h((Entity) this) < 9.0D) { + this.a(entityhuman, itemstack); if (!this.world.isClientSide) { // CraftBukkit - added event call and isCancelled check if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { - this.c(entityhuman); - this.setCatType(1 + this.world.random.nextInt(3)); + this.setTrusting(true); this.s(true); - this.goalSit.setSitting(true); - this.world.broadcastEntityEffect(this, (byte) 7); + this.world.broadcastEntityEffect(this, (byte) 41); } else { this.s(false); - this.world.broadcastEntityEffect(this, (byte) 6); + this.world.broadcastEntityEffect(this, (byte) 40); } } return true; - } - - return super.a(entityhuman, enumhand); - } - - public EntityOcelot createChild(EntityAgeable entityageable) { - EntityOcelot entityocelot = EntityTypes.OCELOT.create(world); // Paper - - if (this.isTamed()) { - entityocelot.setOwnerUUID(this.getOwnerUUID()); - entityocelot.setTamed(true); - entityocelot.setCatType(this.getCatType()); - } - - return entityocelot; - } - - public boolean f(ItemStack itemstack) { - return EntityOcelot.bG.test(itemstack); - } - - public boolean mate(EntityAnimal entityanimal) { - if (entityanimal == this) { - return false; - } else if (!this.isTamed()) { - return false; - } else if (!(entityanimal instanceof EntityOcelot)) { - return false; } else { - EntityOcelot entityocelot = (EntityOcelot) entityanimal; - - return !entityocelot.isTamed() ? false : this.isInLove() && entityocelot.isInLove(); + return super.a(entityhuman, enumhand); } } - public int getCatType() { - return (Integer) this.datawatcher.get(EntityOcelot.bH); + private void s(boolean flag) { + ParticleType particletype = Particles.HEART; + + if (!flag) { + particletype = Particles.SMOKE; + } + + for (int i = 0; i < 7; ++i) { + double d0 = this.random.nextGaussian() * 0.02D; + double d1 = this.random.nextGaussian() * 0.02D; + double d2 = this.random.nextGaussian() * 0.02D; + + this.world.addParticle(particletype, this.locX + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), this.locY + 0.5D + (double) (this.random.nextFloat() * this.getHeight()), this.locZ + (double) (this.random.nextFloat() * this.getWidth() * 2.0F) - (double) this.getWidth(), d0, d1, d2); + } + } - public void setCatType(int i) { - this.datawatcher.set(EntityOcelot.bH, i); + protected void dV() { + if (this.bB == null) { + this.bB = new EntityOcelot.a<>(this, EntityHuman.class, 16.0F, 0.8D, 1.33D); + } + + this.goalSelector.a((PathfinderGoal) this.bB); + if (!this.isTrusting()) { + this.goalSelector.a(4, this.bB); + } + } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - return this.random.nextInt(3) != 0; + @Override + public EntityOcelot createChild(EntityAgeable entityageable) { + return (EntityOcelot) EntityTypes.OCELOT.a(this.world); } + @Override + public boolean i(ItemStack itemstack) { + return EntityOcelot.bz.test(itemstack); + } + + public static boolean c(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return random.nextInt(3) != 0; + } + + @Override public boolean a(IWorldReader iworldreader) { - if (iworldreader.a_(this, this.getBoundingBox()) && iworldreader.getCubes(this, this.getBoundingBox()) && !iworldreader.containsLiquid(this.getBoundingBox())) { + if (iworldreader.i(this) && !iworldreader.containsLiquid(this.getBoundingBox())) { BlockPosition blockposition = new BlockPosition(this.locX, this.getBoundingBox().minY, this.locZ); if (blockposition.getY() < iworldreader.getSeaLevel()) { @@ -214,37 +213,62 @@ public class EntityOcelot extends EntityTameableAnimal { return false; } - public IChatBaseComponent getDisplayName() { - IChatBaseComponent ichatbasecomponent = this.getCustomName(); + protected void dW() { + for (int i = 0; i < 2; ++i) { + EntityOcelot entityocelot = (EntityOcelot) EntityTypes.OCELOT.a(this.world); - return (IChatBaseComponent) (ichatbasecomponent != null ? ichatbasecomponent : (this.isTamed() ? new ChatMessage(SystemUtils.a("entity", EntityOcelot.bI), new Object[0]) : super.getDisplayName())); - } - - protected void dz() { - if (this.bJ == null) { - this.bJ = new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 16.0F, 0.8D, 1.33D); - } - - this.goalSelector.a((PathfinderGoal) this.bJ); - if (!this.isTamed()) { - this.goalSelector.a(4, this.bJ); + entityocelot.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); + entityocelot.setAgeRaw(-24000); + this.world.addEntity(entityocelot, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.OCELOT_BABY); // CraftBukkit - add SpawnReason } } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - groupdataentity = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); - if (spawnBonus && this.getCatType() == 0 && this.world.random.nextInt(7) == 0) { // Spigot - for (int i = 0; i < 2; ++i) { - EntityOcelot entityocelot = EntityTypes.OCELOT.create(world); // Paper - - entityocelot.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); - entityocelot.setAgeRaw(-24000); - this.world.addEntity(entityocelot, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.OCELOT_BABY); // CraftBukkit - add SpawnReason - } + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + groupdataentity = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + if (spawnBonus && generatoraccess.getRandom().nextInt(7) == 0) { // Spigot + this.dW(); } return groupdataentity; } + + static class b extends PathfinderGoalTempt { + + private final EntityOcelot c; + + public b(EntityOcelot entityocelot, double d0, RecipeItemStack recipeitemstack, boolean flag) { + super(entityocelot, d0, recipeitemstack, flag); + this.c = entityocelot; + } + + @Override + protected boolean g() { + return super.g() && !this.c.isTrusting(); + } + } + + static class a extends PathfinderGoalAvoidTarget { + + private final EntityOcelot i; + + public a(EntityOcelot entityocelot, Class oclass, float f, double d0, double d1) { + // Predicate predicate = IEntitySelector.e; // CraftBukkit - decompile error + + super(entityocelot, oclass, f, d0, d1, IEntitySelector.e::test); // CraftBukkit - decompile error + this.i = entityocelot; + } + + @Override + public boolean a() { + return !this.i.isTrusting() && super.a(); + } + + @Override + public boolean b() { + return !this.i.isTrusting() && super.b(); + } + } } diff --git a/src/main/java/net/minecraft/server/EntityPainting.java b/src/main/java/net/minecraft/server/EntityPainting.java index deceabf3f..fe2beede2 100644 --- a/src/main/java/net/minecraft/server/EntityPainting.java +++ b/src/main/java/net/minecraft/server/EntityPainting.java @@ -9,8 +9,8 @@ public class EntityPainting extends EntityHanging { public Paintings art; - public EntityPainting(World world) { - super(EntityTypes.PAINTING, world); + public EntityPainting(EntityTypes entitytypes, World world) { + super(entitytypes, world); // CraftBukkit start - generate a non-null painting List list = Lists.newArrayList(Paintings.a); this.art = (Paintings) list.get(this.random.nextInt(list.size())); @@ -31,7 +31,7 @@ public class EntityPainting extends EntityHanging { this.setDirection(enumdirection); if (this.survives()) { list.add(paintings); - int j = paintings.b() * paintings.c(); + int j = paintings.getWidth() * paintings.getHeight(); if (j > i) { i = j; @@ -44,7 +44,7 @@ public class EntityPainting extends EntityHanging { while (iterator.hasNext()) { paintings = (Paintings) iterator.next(); - if (paintings.b() * paintings.c() < i) { + if (paintings.getWidth() * paintings.getHeight() < i) { iterator.remove(); } } @@ -55,26 +55,31 @@ public class EntityPainting extends EntityHanging { this.setDirection(enumdirection); } + @Override public void b(NBTTagCompound nbttagcompound) { nbttagcompound.setString("Motive", IRegistry.MOTIVE.getKey(this.art).toString()); super.b(nbttagcompound); } + @Override public void a(NBTTagCompound nbttagcompound) { - this.art = (Paintings) IRegistry.MOTIVE.getOrDefault(MinecraftKey.a(nbttagcompound.getString("Motive"))); + this.art = (Paintings) IRegistry.MOTIVE.get(MinecraftKey.a(nbttagcompound.getString("Motive"))); super.a(nbttagcompound); } - public int getWidth() { - return this.art.b(); + @Override + public int getHangingWidth() { + return this.art == null ? 1 : this.art.getWidth(); } - public int getHeight() { - return this.art.c(); + @Override + public int getHangingHeight() { + return this.art == null ? 1 : this.art.getHeight(); } + @Override public void a(@Nullable Entity entity) { - if (this.world.getGameRules().getBoolean("doEntityDrops")) { + if (this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { this.a(SoundEffects.ENTITY_PAINTING_BREAK, 1.0F, 1.0F); if (entity instanceof EntityHuman) { EntityHuman entityhuman = (EntityHuman) entity; @@ -88,11 +93,18 @@ public class EntityPainting extends EntityHanging { } } - public void m() { + @Override + public void playPlaceSound() { this.a(SoundEffects.ENTITY_PAINTING_PLACE, 1.0F, 1.0F); } + @Override public void setPositionRotation(double d0, double d1, double d2, float f, float f1) { this.setPosition(d0, d1, d2); } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntityPainting(this); + } } diff --git a/src/main/java/net/minecraft/server/EntityPanda.java b/src/main/java/net/minecraft/server/EntityPanda.java new file mode 100644 index 000000000..479ef6b92 --- /dev/null +++ b/src/main/java/net/minecraft/server/EntityPanda.java @@ -0,0 +1,1039 @@ +package net.minecraft.server; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.function.Predicate; +import javax.annotation.Nullable; + +import org.bukkit.event.entity.EntityTargetEvent; // CraftBukkit + +public class EntityPanda extends EntityAnimal { + + private static final DataWatcherObject bA = DataWatcher.a(EntityPanda.class, DataWatcherRegistry.b); + private static final DataWatcherObject bB = DataWatcher.a(EntityPanda.class, DataWatcherRegistry.b); + private static final DataWatcherObject bC = DataWatcher.a(EntityPanda.class, DataWatcherRegistry.b); + private static final DataWatcherObject bD = DataWatcher.a(EntityPanda.class, DataWatcherRegistry.a); + private static final DataWatcherObject bE = DataWatcher.a(EntityPanda.class, DataWatcherRegistry.a); + private static final DataWatcherObject bF = DataWatcher.a(EntityPanda.class, DataWatcherRegistry.a); + private boolean bG; + private boolean bH; + public int bz; + private Vec3D bI; + private float bJ; + private float bK; + private float bL; + private float bM; + private float bN; + private float bO; + private static final Predicate PICKUP_PREDICATE = (entityitem) -> { + Item item = entityitem.getItemStack().getItem(); + + return (item == Blocks.BAMBOO.getItem() || item == Blocks.CAKE.getItem()) && entityitem.isAlive() && !entityitem.q(); + }; + + public EntityPanda(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.moveController = new EntityPanda.i(this); + if (!this.isBaby()) { + this.setCanPickupLoot(true); + } + + } + + @Override + public boolean e(ItemStack itemstack) { + EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); + + return !this.getEquipment(enumitemslot).isEmpty() ? false : enumitemslot == EnumItemSlot.MAINHAND && super.e(itemstack); + } + + public int dV() { + return (Integer) this.datawatcher.get(EntityPanda.bA); + } + + public void s(int i) { + this.datawatcher.set(EntityPanda.bA, i); + } + + public boolean dW() { + return this.v(2); + } + + public boolean dX() { + return this.v(8); + } + + public void r(boolean flag) { + this.d(8, flag); + } + + public boolean dY() { + return this.v(16); + } + + public void s(boolean flag) { + this.d(16, flag); + } + + public boolean dZ() { + return (Integer) this.datawatcher.get(EntityPanda.bC) > 0; + } + + public void t(boolean flag) { + this.datawatcher.set(EntityPanda.bC, flag ? 1 : 0); + } + + private int es() { + return (Integer) this.datawatcher.get(EntityPanda.bC); + } + + private void u(int i) { + this.datawatcher.set(EntityPanda.bC, i); + } + + public void u(boolean flag) { + this.d(2, flag); + if (!flag) { + this.t(0); + } + + } + + public int ee() { + return (Integer) this.datawatcher.get(EntityPanda.bB); + } + + public void t(int i) { + this.datawatcher.set(EntityPanda.bB, i); + } + + public EntityPanda.Gene getMainGene() { + return EntityPanda.Gene.a((Byte) this.datawatcher.get(EntityPanda.bD)); + } + + public void setMainGene(EntityPanda.Gene entitypanda_gene) { + if (entitypanda_gene.a() > 6) { + entitypanda_gene = EntityPanda.Gene.a(this.random); + } + + this.datawatcher.set(EntityPanda.bD, (byte) entitypanda_gene.a()); + } + + public EntityPanda.Gene getHiddenGene() { + return EntityPanda.Gene.a((Byte) this.datawatcher.get(EntityPanda.bE)); + } + + public void setHiddenGene(EntityPanda.Gene entitypanda_gene) { + if (entitypanda_gene.a() > 6) { + entitypanda_gene = EntityPanda.Gene.a(this.random); + } + + this.datawatcher.set(EntityPanda.bE, (byte) entitypanda_gene.a()); + } + + public boolean eh() { + return this.v(4); + } + + public void v(boolean flag) { + this.d(4, flag); + } + + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityPanda.bA, 0); + this.datawatcher.register(EntityPanda.bB, 0); + this.datawatcher.register(EntityPanda.bD, (byte) 0); + this.datawatcher.register(EntityPanda.bE, (byte) 0); + this.datawatcher.register(EntityPanda.bF, (byte) 0); + this.datawatcher.register(EntityPanda.bC, 0); + } + + private boolean v(int i) { + return ((Byte) this.datawatcher.get(EntityPanda.bF) & i) != 0; + } + + private void d(int i, boolean flag) { + byte b0 = (Byte) this.datawatcher.get(EntityPanda.bF); + + if (flag) { + this.datawatcher.set(EntityPanda.bF, (byte) (b0 | i)); + } else { + this.datawatcher.set(EntityPanda.bF, (byte) (b0 & ~i)); + } + + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setString("MainGene", this.getMainGene().b()); + nbttagcompound.setString("HiddenGene", this.getHiddenGene().b()); + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setMainGene(EntityPanda.Gene.a(nbttagcompound.getString("MainGene"))); + this.setHiddenGene(EntityPanda.Gene.a(nbttagcompound.getString("HiddenGene"))); + } + + @Nullable + @Override + public EntityAgeable createChild(EntityAgeable entityageable) { + EntityPanda entitypanda = (EntityPanda) EntityTypes.PANDA.a(this.world); + + if (entityageable instanceof EntityPanda) { + entitypanda.a(this, (EntityPanda) entityageable); + } + + entitypanda.ep(); + return entitypanda; + } + + @Override + protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, new EntityPanda.j(this, 2.0D)); + this.goalSelector.a(2, new EntityPanda.d(this, 1.0D)); + this.goalSelector.a(3, new EntityPanda.b(this, 1.2000000476837158D, true)); + this.goalSelector.a(4, new PathfinderGoalTempt(this, 1.0D, RecipeItemStack.a(Blocks.BAMBOO.getItem()), false)); + this.goalSelector.a(6, new EntityPanda.c<>(this, EntityHuman.class, 8.0F, 2.0D, 2.0D)); + this.goalSelector.a(6, new EntityPanda.c<>(this, EntityMonster.class, 4.0F, 2.0D, 2.0D)); + this.goalSelector.a(7, new EntityPanda.l()); + this.goalSelector.a(8, new EntityPanda.g(this)); + this.goalSelector.a(8, new EntityPanda.m(this)); + this.goalSelector.a(9, new EntityPanda.h(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(10, new PathfinderGoalRandomLookaround(this)); + this.goalSelector.a(12, new EntityPanda.k(this)); + this.goalSelector.a(13, new PathfinderGoalFollowParent(this, 1.25D)); + this.goalSelector.a(14, new PathfinderGoalRandomStrollLand(this, 1.0D)); + this.targetSelector.a(1, (new EntityPanda.f(this, new Class[0])).a(new Class[0])); + } + + @Override + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.15000000596046448D); + this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(6.0D); + } + + public EntityPanda.Gene ei() { + return EntityPanda.Gene.b(this.getMainGene(), this.getHiddenGene()); + } + + public boolean ej() { + return this.ei() == EntityPanda.Gene.LAZY; + } + + public boolean ek() { + return this.ei() == EntityPanda.Gene.WORRIED; + } + + public boolean el() { + return this.ei() == EntityPanda.Gene.PLAYFUL; + } + + public boolean en() { + return this.ei() == EntityPanda.Gene.WEAK; + } + + @Override + public boolean dR() { + return this.ei() == EntityPanda.Gene.AGGRESSIVE; + } + + @Override + public boolean a(EntityHuman entityhuman) { + return false; + } + + @Override + public boolean C(Entity entity) { + this.a(SoundEffects.ENTITY_PANDA_BITE, 1.0F, 1.0F); + if (!this.dR()) { + this.bH = true; + } + + return super.C(entity); + } + + @Override + public void tick() { + super.tick(); + if (this.ek()) { + if (this.world.U() && !this.isInWater()) { + this.r(true); + this.t(false); + } else if (!this.dZ()) { + this.r(false); + } + } + + if (this.getGoalTarget() == null) { + this.bG = false; + this.bH = false; + } + + if (this.dV() > 0) { + if (this.getGoalTarget() != null) { + this.a((Entity) this.getGoalTarget(), 90.0F, 90.0F); + } + + if (this.dV() == 29 || this.dV() == 14) { + this.a(SoundEffects.ENTITY_PANDA_CANT_BREED, 1.0F, 1.0F); + } + + this.s(this.dV() - 1); + } + + if (this.dW()) { + this.t(this.ee() + 1); + if (this.ee() > 20) { + this.u(false); + this.ez(); + } else if (this.ee() == 1) { + this.a(SoundEffects.ENTITY_PANDA_PRE_SNEEZE, 1.0F, 1.0F); + } + } + + if (this.eh()) { + this.ey(); + } else { + this.bz = 0; + } + + if (this.dX()) { + this.pitch = 0.0F; + } + + this.ev(); + this.et(); + this.ew(); + this.ex(); + } + + public boolean eo() { + return this.ek() && this.world.U(); + } + + private void et() { + if (!this.dZ() && this.dX() && !this.eo() && !this.getEquipment(EnumItemSlot.MAINHAND).isEmpty() && this.random.nextInt(80) == 1) { + this.t(true); + } else if (this.getEquipment(EnumItemSlot.MAINHAND).isEmpty() || !this.dX()) { + this.t(false); + } + + if (this.dZ()) { + this.eu(); + if (!this.world.isClientSide && this.es() > 80 && this.random.nextInt(20) == 1) { + if (this.es() > 100 && this.j(this.getEquipment(EnumItemSlot.MAINHAND))) { + if (!this.world.isClientSide) { + this.setSlot(EnumItemSlot.MAINHAND, ItemStack.a); + } + + this.r(false); + } + + this.t(false); + return; + } + + this.u(this.es() + 1); + } + + } + + private void eu() { + if (this.es() % 5 == 0) { + this.a(SoundEffects.ENTITY_PANDA_EAT, 0.5F + 0.5F * (float) this.random.nextInt(2), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + + for (int i = 0; i < 6; ++i) { + Vec3D vec3d = new Vec3D(((double) this.random.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, ((double) this.random.nextFloat() - 0.5D) * 0.1D); + + vec3d = vec3d.a(-this.pitch * 0.017453292F); + vec3d = vec3d.b(-this.yaw * 0.017453292F); + double d0 = (double) (-this.random.nextFloat()) * 0.6D - 0.3D; + Vec3D vec3d1 = new Vec3D(((double) this.random.nextFloat() - 0.5D) * 0.8D, d0, 1.0D + ((double) this.random.nextFloat() - 0.5D) * 0.4D); + + vec3d1 = vec3d1.b(-this.aK * 0.017453292F); + vec3d1 = vec3d1.add(this.locX, this.locY + (double) this.getHeadHeight() + 1.0D, this.locZ); + this.world.addParticle(new ParticleParamItem(Particles.ITEM, this.getEquipment(EnumItemSlot.MAINHAND)), vec3d1.x, vec3d1.y, vec3d1.z, vec3d.x, vec3d.y + 0.05D, vec3d.z); + } + } + + } + + private void ev() { + this.bK = this.bJ; + if (this.dX()) { + this.bJ = Math.min(1.0F, this.bJ + 0.15F); + } else { + this.bJ = Math.max(0.0F, this.bJ - 0.19F); + } + + } + + private void ew() { + this.bM = this.bL; + if (this.dY()) { + this.bL = Math.min(1.0F, this.bL + 0.15F); + } else { + this.bL = Math.max(0.0F, this.bL - 0.19F); + } + + } + + private void ex() { + this.bO = this.bN; + if (this.eh()) { + this.bN = Math.min(1.0F, this.bN + 0.15F); + } else { + this.bN = Math.max(0.0F, this.bN - 0.19F); + } + + } + + private void ey() { + ++this.bz; + if (this.bz > 32) { + this.v(false); + } else { + if (!this.world.isClientSide) { + Vec3D vec3d = this.getMot(); + + if (this.bz == 1) { + float f = this.yaw * 0.017453292F; + float f1 = this.isBaby() ? 0.1F : 0.2F; + + this.bI = new Vec3D(vec3d.x + (double) (-MathHelper.sin(f) * f1), 0.0D, vec3d.z + (double) (MathHelper.cos(f) * f1)); + this.setMot(this.bI.add(0.0D, 0.27D, 0.0D)); + } else if ((float) this.bz != 7.0F && (float) this.bz != 15.0F && (float) this.bz != 23.0F) { + this.setMot(this.bI.x, vec3d.y, this.bI.z); + } else { + this.setMot(0.0D, this.onGround ? 0.27D : vec3d.y, 0.0D); + } + } + + } + } + + private void ez() { + Vec3D vec3d = this.getMot(); + + this.world.addParticle(Particles.SNEEZE, this.locX - (double) (this.getWidth() + 1.0F) * 0.5D * (double) MathHelper.sin(this.aK * 0.017453292F), this.locY + (double) this.getHeadHeight() - 0.10000000149011612D, this.locZ + (double) (this.getWidth() + 1.0F) * 0.5D * (double) MathHelper.cos(this.aK * 0.017453292F), vec3d.x, 0.0D, vec3d.z); + this.a(SoundEffects.ENTITY_PANDA_SNEEZE, 1.0F, 1.0F); + List list = this.world.a(EntityPanda.class, this.getBoundingBox().g(10.0D)); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityPanda entitypanda = (EntityPanda) iterator.next(); + + if (!entitypanda.isBaby() && entitypanda.onGround && !entitypanda.isInWater() && entitypanda.eq()) { + entitypanda.jump(); + } + } + + if (!this.world.e() && this.random.nextInt(700) == 0 && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { + this.a((IMaterial) Items.SLIME_BALL); + } + + } + + @Override + protected void a(EntityItem entityitem) { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, entityitem, 0, !(this.getEquipment(EnumItemSlot.MAINHAND).isEmpty() && EntityPanda.PICKUP_PREDICATE.test(entityitem))).isCancelled()) { // CraftBukkit + ItemStack itemstack = entityitem.getItemStack(); + + this.setSlot(EnumItemSlot.MAINHAND, itemstack); + this.dropChanceHand[EnumItemSlot.MAINHAND.b()] = 2.0F; + this.receive(entityitem, itemstack.getCount()); + entityitem.die(); + } + + } + + @Override + public boolean damageEntity(DamageSource damagesource, float f) { + this.r(false); + return super.damageEntity(damagesource, f); + } + + @Nullable + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + Object object = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + + this.setMainGene(EntityPanda.Gene.a(this.random)); + this.setHiddenGene(EntityPanda.Gene.a(this.random)); + this.ep(); + if (object instanceof EntityPanda.e) { + if (this.random.nextInt(5) == 0) { + this.setAgeRaw(-24000); + } + } else { + object = new EntityPanda.e(); + } + + return (GroupDataEntity) object; + } + + public void a(EntityPanda entitypanda, @Nullable EntityPanda entitypanda1) { + if (entitypanda1 == null) { + if (this.random.nextBoolean()) { + this.setMainGene(entitypanda.eA()); + this.setHiddenGene(EntityPanda.Gene.a(this.random)); + } else { + this.setMainGene(EntityPanda.Gene.a(this.random)); + this.setHiddenGene(entitypanda.eA()); + } + } else if (this.random.nextBoolean()) { + this.setMainGene(entitypanda.eA()); + this.setHiddenGene(entitypanda1.eA()); + } else { + this.setMainGene(entitypanda1.eA()); + this.setHiddenGene(entitypanda.eA()); + } + + if (this.random.nextInt(32) == 0) { + this.setMainGene(EntityPanda.Gene.a(this.random)); + } + + if (this.random.nextInt(32) == 0) { + this.setHiddenGene(EntityPanda.Gene.a(this.random)); + } + + } + + private EntityPanda.Gene eA() { + return this.random.nextBoolean() ? this.getMainGene() : this.getHiddenGene(); + } + + public void ep() { + if (this.en()) { + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); + } + + if (this.ej()) { + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.07000000029802322D); + } + + } + + private void eB() { + if (!this.isInWater()) { + this.r(0.0F); + this.getNavigation().o(); + this.r(true); + } + + } + + @Override + public boolean a(EntityHuman entityhuman, EnumHand enumhand) { + ItemStack itemstack = entityhuman.b(enumhand); + + if (itemstack.getItem() instanceof ItemMonsterEgg) { + return super.a(entityhuman, enumhand); + } else if (this.eo()) { + return false; + } else if (this.dY()) { + this.s(false); + return true; + } else if (this.i(itemstack)) { + if (this.getGoalTarget() != null) { + this.bG = true; + } + + if (this.isBaby()) { + this.a(entityhuman, itemstack); + this.setAge((int) ((float) (-this.getAge() / 20) * 0.1F), true); + } else if (!this.world.isClientSide && this.getAge() == 0 && this.ea()) { + this.a(entityhuman, itemstack); + this.f(entityhuman); + } else { + if (this.world.isClientSide || this.dX() || this.isInWater()) { + return false; + } + + this.eB(); + this.t(true); + ItemStack itemstack1 = this.getEquipment(EnumItemSlot.MAINHAND); + + if (!itemstack1.isEmpty() && !entityhuman.abilities.canInstantlyBuild) { + this.a(itemstack1); + } + + this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(itemstack.getItem(), 1)); + this.a(entityhuman, itemstack); + } + + return true; + } else { + return false; + } + } + + @Nullable + @Override + protected SoundEffect getSoundAmbient() { + return this.dR() ? SoundEffects.ENTITY_PANDA_AGGRESSIVE_AMBIENT : (this.ek() ? SoundEffects.ENTITY_PANDA_WORRIED_AMBIENT : SoundEffects.ENTITY_PANDA_AMBIENT); + } + + @Override + protected void a(BlockPosition blockposition, IBlockData iblockdata) { + this.a(SoundEffects.ENTITY_PANDA_STEP, 0.15F, 1.0F); + } + + @Override + public boolean i(ItemStack itemstack) { + return itemstack.getItem() == Blocks.BAMBOO.getItem(); + } + + private boolean j(ItemStack itemstack) { + return this.i(itemstack) || itemstack.getItem() == Blocks.CAKE.getItem(); + } + + @Nullable + @Override + protected SoundEffect getSoundDeath() { + return SoundEffects.ENTITY_PANDA_DEATH; + } + + @Nullable + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return SoundEffects.ENTITY_PANDA_HURT; + } + + public boolean eq() { + return !this.dY() && !this.eo() && !this.dZ() && !this.eh() && !this.dX(); + } + + static class j extends PathfinderGoalPanic { + + private final EntityPanda f; + + public j(EntityPanda entitypanda, double d0) { + super(entitypanda, d0); + this.f = entitypanda; + } + + @Override + public boolean a() { + if (!this.f.isBurning()) { + return false; + } else { + BlockPosition blockposition = this.a(this.a.world, this.a, 5, 4); + + if (blockposition != null) { + this.c = (double) blockposition.getX(); + this.d = (double) blockposition.getY(); + this.e = (double) blockposition.getZ(); + return true; + } else { + return this.g(); + } + } + } + + @Override + public boolean b() { + if (this.f.dX()) { + this.f.getNavigation().o(); + return false; + } else { + return super.b(); + } + } + } + + static class f extends PathfinderGoalHurtByTarget { + + private final EntityPanda a; + + public f(EntityPanda entitypanda, Class... aclass) { + super(entitypanda, aclass); + this.a = entitypanda; + } + + @Override + public boolean b() { + if (!this.a.bG && !this.a.bH) { + return super.b(); + } else { + this.a.setGoalTarget((EntityLiving) null); + return false; + } + } + + @Override + protected void a(EntityInsentient entityinsentient, EntityLiving entityliving) { + if (entityinsentient instanceof EntityPanda && ((EntityPanda) entityinsentient).dR()) { + entityinsentient.setGoalTarget(entityliving, EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit + } + + } + } + + static class g extends PathfinderGoal { + + private final EntityPanda a; + private int b; + + public g(EntityPanda entitypanda) { + this.a = entitypanda; + } + + @Override + public boolean a() { + return this.b < this.a.ticksLived && this.a.ej() && this.a.eq() && this.a.random.nextInt(400) == 1; + } + + @Override + public boolean b() { + return !this.a.isInWater() && (this.a.ej() || this.a.random.nextInt(600) != 1) ? this.a.random.nextInt(2000) != 1 : false; + } + + @Override + public void c() { + this.a.s(true); + this.b = 0; + } + + @Override + public void d() { + this.a.s(false); + this.b = this.a.ticksLived + 200; + } + } + + class l extends PathfinderGoal { + + private int b; + + public l() { + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); + } + + @Override + public boolean a() { + if (this.b <= EntityPanda.this.ticksLived && !EntityPanda.this.isBaby() && !EntityPanda.this.isInWater() && EntityPanda.this.eq() && EntityPanda.this.dV() <= 0) { + List list = EntityPanda.this.world.a(EntityItem.class, EntityPanda.this.getBoundingBox().grow(6.0D, 6.0D, 6.0D), EntityPanda.PICKUP_PREDICATE); + + return !list.isEmpty() || !EntityPanda.this.getEquipment(EnumItemSlot.MAINHAND).isEmpty(); + } else { + return false; + } + } + + @Override + public boolean b() { + return !EntityPanda.this.isInWater() && (EntityPanda.this.ej() || EntityPanda.this.random.nextInt(600) != 1) ? EntityPanda.this.random.nextInt(2000) != 1 : false; + } + + @Override + public void e() { + if (!EntityPanda.this.dX() && !EntityPanda.this.getEquipment(EnumItemSlot.MAINHAND).isEmpty()) { + EntityPanda.this.eB(); + } + + } + + @Override + public void c() { + List list = EntityPanda.this.world.a(EntityItem.class, EntityPanda.this.getBoundingBox().grow(8.0D, 8.0D, 8.0D), EntityPanda.PICKUP_PREDICATE); + + if (!list.isEmpty() && EntityPanda.this.getEquipment(EnumItemSlot.MAINHAND).isEmpty()) { + EntityPanda.this.getNavigation().a((Entity) list.get(0), 1.2000000476837158D); + } else if (!EntityPanda.this.getEquipment(EnumItemSlot.MAINHAND).isEmpty()) { + EntityPanda.this.eB(); + } + + this.b = 0; + } + + @Override + public void d() { + ItemStack itemstack = EntityPanda.this.getEquipment(EnumItemSlot.MAINHAND); + + if (!itemstack.isEmpty()) { + EntityPanda.this.a(itemstack); + EntityPanda.this.setSlot(EnumItemSlot.MAINHAND, ItemStack.a); + int i = EntityPanda.this.ej() ? EntityPanda.this.random.nextInt(50) + 10 : EntityPanda.this.random.nextInt(150) + 10; + + this.b = EntityPanda.this.ticksLived + i * 20; + } + + EntityPanda.this.r(false); + } + } + + static class c extends PathfinderGoalAvoidTarget { + + private final EntityPanda i; + + public c(EntityPanda entitypanda, Class oclass, float f, double d0, double d1) { + // Predicate predicate = IEntitySelector.f; // CraftBukkit - decompile error + + super(entitypanda, oclass, f, d0, d1, IEntitySelector.f::test); // CraftBukkit - decompile error + this.i = entitypanda; + } + + @Override + public boolean a() { + return this.i.ek() && this.i.eq() && super.a(); + } + } + + static class d extends PathfinderGoalBreed { + + private static final PathfinderTargetCondition d = (new PathfinderTargetCondition()).a(8.0D).b().a(); + private final EntityPanda e; + private int f; + + public d(EntityPanda entitypanda, double d0) { + super(entitypanda, d0); + this.e = entitypanda; + } + + @Override + public boolean a() { + if (super.a() && this.e.dV() == 0) { + if (!this.h()) { + if (this.f <= this.e.ticksLived) { + this.e.s(32); + this.f = this.e.ticksLived + 600; + if (this.e.df()) { + EntityHuman entityhuman = this.b.a(d, (EntityLiving) this.e); // CraftBukkit - decompile error + + this.e.setGoalTarget(entityhuman, EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit + } + } + + return false; + } else { + return true; + } + } else { + return false; + } + } + + private boolean h() { + BlockPosition blockposition = new BlockPosition(this.e); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 8; ++j) { + for (int k = 0; k <= j; k = k > 0 ? -k : 1 - k) { + for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { + blockposition_mutableblockposition.g(blockposition).e(k, i, l); + if (this.b.getType(blockposition_mutableblockposition).getBlock() == Blocks.BAMBOO) { + return true; + } + } + } + } + } + + return false; + } + } + + static class m extends PathfinderGoal { + + private final EntityPanda a; + + public m(EntityPanda entitypanda) { + this.a = entitypanda; + } + + @Override + public boolean a() { + return this.a.isBaby() && this.a.eq() ? (this.a.en() && this.a.random.nextInt(500) == 1 ? true : this.a.random.nextInt(6000) == 1) : false; + } + + @Override + public boolean b() { + return false; + } + + @Override + public void c() { + this.a.u(true); + } + } + + static class k extends PathfinderGoal { + + private final EntityPanda a; + + public k(EntityPanda entitypanda) { + this.a = entitypanda; + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK, PathfinderGoal.Type.JUMP)); + } + + @Override + public boolean a() { + if ((this.a.isBaby() || this.a.el()) && this.a.onGround) { + if (!this.a.eq()) { + return false; + } else { + float f = this.a.yaw * 0.017453292F; + int i = 0; + int j = 0; + float f1 = -MathHelper.sin(f); + float f2 = MathHelper.cos(f); + + if ((double) Math.abs(f1) > 0.5D) { + i = (int) ((float) i + f1 / Math.abs(f1)); + } + + if ((double) Math.abs(f2) > 0.5D) { + j = (int) ((float) j + f2 / Math.abs(f2)); + } + + return this.a.world.getType((new BlockPosition(this.a)).b(i, -1, j)).isAir() ? true : (this.a.el() && this.a.random.nextInt(60) == 1 ? true : this.a.random.nextInt(500) == 1); + } + } else { + return false; + } + } + + @Override + public boolean b() { + return false; + } + + @Override + public void c() { + this.a.v(true); + } + + @Override + public boolean C_() { + return false; + } + } + + static class h extends PathfinderGoalLookAtPlayer { + + private final EntityPanda f; + + public h(EntityPanda entitypanda, Class oclass, float f) { + super(entitypanda, oclass, f); + this.f = entitypanda; + } + + @Override + public boolean a() { + return this.f.eq() && super.a(); + } + } + + static class b extends PathfinderGoalMeleeAttack { + + private final EntityPanda d; + + public b(EntityPanda entitypanda, double d0, boolean flag) { + super(entitypanda, d0, flag); + this.d = entitypanda; + } + + @Override + public boolean a() { + return this.d.eq() && super.a(); + } + } + + static class e implements GroupDataEntity { + + private e() {} + } + + static class i extends ControllerMove { + + private final EntityPanda i; + + public i(EntityPanda entitypanda) { + super(entitypanda); + this.i = entitypanda; + } + + @Override + public void a() { + if (this.i.eq()) { + super.a(); + } + } + } + + public static enum Gene { + + NORMAL(0, "normal", false), LAZY(1, "lazy", false), WORRIED(2, "worried", false), PLAYFUL(3, "playful", false), BROWN(4, "brown", true), WEAK(5, "weak", true), AGGRESSIVE(6, "aggressive", false); + + private static final EntityPanda.Gene[] h = (EntityPanda.Gene[]) Arrays.stream(values()).sorted(Comparator.comparingInt(EntityPanda.Gene::a)).toArray((i) -> { + return new EntityPanda.Gene[i]; + }); + private final int i; + private final String j; + private final boolean k; + + private Gene(int i, String s, boolean flag) { + this.i = i; + this.j = s; + this.k = flag; + } + + public int a() { + return this.i; + } + + public String b() { + return this.j; + } + + public boolean isRecessive() { + return this.k; + } + + private static EntityPanda.Gene b(EntityPanda.Gene entitypanda_gene, EntityPanda.Gene entitypanda_gene1) { + return entitypanda_gene.isRecessive() ? (entitypanda_gene == entitypanda_gene1 ? entitypanda_gene : EntityPanda.Gene.NORMAL) : entitypanda_gene; + } + + public static EntityPanda.Gene a(int i) { + if (i < 0 || i >= EntityPanda.Gene.h.length) { + i = 0; + } + + return EntityPanda.Gene.h[i]; + } + + public static EntityPanda.Gene a(String s) { + EntityPanda.Gene[] aentitypanda_gene = values(); + int i = aentitypanda_gene.length; + + for (int j = 0; j < i; ++j) { + EntityPanda.Gene entitypanda_gene = aentitypanda_gene[j]; + + if (entitypanda_gene.j.equals(s)) { + return entitypanda_gene; + } + } + + return EntityPanda.Gene.NORMAL; + } + + public static EntityPanda.Gene a(Random random) { + int i = random.nextInt(16); + + return i == 0 ? EntityPanda.Gene.LAZY : (i == 1 ? EntityPanda.Gene.WORRIED : (i == 2 ? EntityPanda.Gene.PLAYFUL : (i == 4 ? EntityPanda.Gene.AGGRESSIVE : (i < 9 ? EntityPanda.Gene.WEAK : (i < 11 ? EntityPanda.Gene.BROWN : EntityPanda.Gene.NORMAL))))); + } + } +} diff --git a/src/main/java/net/minecraft/server/EntityParrot.java b/src/main/java/net/minecraft/server/EntityParrot.java index 6acad3520..a7cdb5e7a 100644 --- a/src/main/java/net/minecraft/server/EntityParrot.java +++ b/src/main/java/net/minecraft/server/EntityParrot.java @@ -13,15 +13,15 @@ import javax.annotation.Nullable; public class EntityParrot extends EntityPerchable implements EntityBird { - private static final DataWatcherObject bL = DataWatcher.a(EntityParrot.class, DataWatcherRegistry.b); - private static final Predicate bM = new Predicate() { + private static final DataWatcherObject bH = DataWatcher.a(EntityParrot.class, DataWatcherRegistry.b); + private static final Predicate bI = new Predicate() { public boolean test(@Nullable EntityInsentient entityinsentient) { - return entityinsentient != null && EntityParrot.bP.containsKey(entityinsentient.P()); + return entityinsentient != null && EntityParrot.bL.containsKey(entityinsentient.getEntityType()); } }; - private static final Item bN = Items.COOKIE; - private static final Set bO = Sets.newHashSet(new Item[] { Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS}); - private static final Map, SoundEffect> bP = (Map) SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // CraftBukkit - decompile error + private static final Item bJ = Items.COOKIE; + private static final Set bK = Sets.newHashSet(new Item[]{Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS}); + private static final Map, SoundEffect> bL = (Map) SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // CraftBukkit - decompile error hashmap.put(EntityTypes.BLAZE, SoundEffects.ENTITY_PARROT_IMITATE_BLAZE); hashmap.put(EntityTypes.CAVE_SPIDER, SoundEffects.ENTITY_PARROT_IMITATE_SPIDER); hashmap.put(EntityTypes.CREEPER, SoundEffects.ENTITY_PARROT_IMITATE_CREEPER); @@ -32,12 +32,16 @@ public class EntityParrot extends EntityPerchable implements EntityBird { hashmap.put(EntityTypes.ENDERMITE, SoundEffects.ENTITY_PARROT_IMITATE_ENDERMITE); hashmap.put(EntityTypes.EVOKER, SoundEffects.ENTITY_PARROT_IMITATE_EVOKER); hashmap.put(EntityTypes.GHAST, SoundEffects.ENTITY_PARROT_IMITATE_GHAST); + hashmap.put(EntityTypes.GUARDIAN, SoundEffects.ENTITY_PARROT_IMITATE_GUARDIAN); hashmap.put(EntityTypes.HUSK, SoundEffects.ENTITY_PARROT_IMITATE_HUSK); hashmap.put(EntityTypes.ILLUSIONER, SoundEffects.ENTITY_PARROT_IMITATE_ILLUSIONER); hashmap.put(EntityTypes.MAGMA_CUBE, SoundEffects.ENTITY_PARROT_IMITATE_MAGMA_CUBE); hashmap.put(EntityTypes.ZOMBIE_PIGMAN, SoundEffects.ENTITY_PARROT_IMITATE_ZOMBIE_PIGMAN); + hashmap.put(EntityTypes.PANDA, SoundEffects.ENTITY_PARROT_IMITATE_PANDA); hashmap.put(EntityTypes.PHANTOM, SoundEffects.ENTITY_PARROT_IMITATE_PHANTOM); + hashmap.put(EntityTypes.PILLAGER, SoundEffects.ENTITY_PARROT_IMITATE_PILLAGER); hashmap.put(EntityTypes.POLAR_BEAR, SoundEffects.ENTITY_PARROT_IMITATE_POLAR_BEAR); + hashmap.put(EntityTypes.RAVAGER, SoundEffects.ENTITY_PARROT_IMITATE_RAVAGER); hashmap.put(EntityTypes.SHULKER, SoundEffects.ENTITY_PARROT_IMITATE_SHULKER); hashmap.put(EntityTypes.SILVERFISH, SoundEffects.ENTITY_PARROT_IMITATE_SILVERFISH); hashmap.put(EntityTypes.SKELETON, SoundEffects.ENTITY_PARROT_IMITATE_SKELETON); @@ -53,27 +57,28 @@ public class EntityParrot extends EntityPerchable implements EntityBird { hashmap.put(EntityTypes.ZOMBIE, SoundEffects.ENTITY_PARROT_IMITATE_ZOMBIE); hashmap.put(EntityTypes.ZOMBIE_VILLAGER, SoundEffects.ENTITY_PARROT_IMITATE_ZOMBIE_VILLAGER); }); - public float bG; - public float bH; - public float bI; - public float bJ; - public float bK = 1.0F; - private boolean bQ; - private BlockPosition bR; + public float bC; + public float bD; + public float bE; + public float bF; + public float bG = 1.0F; + private boolean bM; + private BlockPosition bN; - public EntityParrot(World world) { - super(EntityTypes.PARROT, world); - this.setSize(0.5F, 0.9F); + public EntityParrot(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.moveController = new ControllerMoveFlying(this); } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { this.setVariant(this.random.nextInt(5)); - return super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSit = new PathfinderGoalSit(this); this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); this.goalSelector.a(0, new PathfinderGoalFloat(this)); @@ -85,14 +90,16 @@ public class EntityParrot extends EntityPerchable implements EntityBird { this.goalSelector.a(3, new PathfinderGoalFollowEntity(this, 1.0D, 3.0F, 7.0F)); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeMap().b(GenericAttributes.e); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(6.0D); - this.getAttributeInstance(GenericAttributes.e).setValue(0.4000000059604645D); + this.getAttributeMap().b(GenericAttributes.FLYING_SPEED); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(6.0D); + this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.4000000059604645D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.20000000298023224D); } + @Override protected NavigationAbstract b(World world) { NavigationFlying navigationflying = new NavigationFlying(this, world); @@ -102,49 +109,53 @@ public class EntityParrot extends EntityPerchable implements EntityBird { return navigationflying; } - public float getHeadHeight() { - return this.length * 0.6F; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height * 0.6F; } + @Override public void movementTick() { b(this.world, (Entity) this); - if (this.bR == null || this.bR.distanceSquared(this.locX, this.locY, this.locZ) > 12.0D || this.world.getType(this.bR).getBlock() != Blocks.JUKEBOX) { - this.bQ = false; - this.bR = null; + if (this.bN == null || !this.bN.a((IPosition) this.getPositionVector(), 3.46D) || this.world.getType(this.bN).getBlock() != Blocks.JUKEBOX) { + this.bM = false; + this.bN = null; } super.movementTick(); - this.dL(); + this.ei(); } - private void dL() { - this.bJ = this.bG; - this.bI = this.bH; - this.bH = (float) ((double) this.bH + (double) (this.onGround ? -1 : 4) * 0.3D); - this.bH = MathHelper.a(this.bH, 0.0F, 1.0F); - if (!this.onGround && this.bK < 1.0F) { - this.bK = 1.0F; + private void ei() { + this.bF = this.bC; + this.bE = this.bD; + this.bD = (float) ((double) this.bD + (double) (!this.onGround && !this.isPassenger() ? 4 : -1) * 0.3D); + this.bD = MathHelper.a(this.bD, 0.0F, 1.0F); + if (!this.onGround && this.bG < 1.0F) { + this.bG = 1.0F; } - this.bK = (float) ((double) this.bK * 0.9D); - if (!this.onGround && this.motY < 0.0D) { - this.motY *= 0.6D; + this.bG = (float) ((double) this.bG * 0.9D); + Vec3D vec3d = this.getMot(); + + if (!this.onGround && vec3d.y < 0.0D) { + this.setMot(vec3d.d(1.0D, 0.6D, 1.0D)); } - this.bG += this.bK * 2.0F; + this.bC += this.bG * 2.0F; } private static boolean b(World world, Entity entity) { - if (!entity.isSilent() && world.random.nextInt(50) == 0) { - List list = world.a(EntityInsentient.class, entity.getBoundingBox().g(20.0D), EntityParrot.bM); + if (entity.isAlive() && !entity.isSilent() && world.random.nextInt(50) == 0) { + List list = world.a(EntityInsentient.class, entity.getBoundingBox().g(20.0D), EntityParrot.bI); if (!list.isEmpty()) { EntityInsentient entityinsentient = (EntityInsentient) list.get(world.random.nextInt(list.size())); if (!entityinsentient.isSilent()) { - SoundEffect soundeffect = a(entityinsentient.P()); + SoundEffect soundeffect = b(entityinsentient.getEntityType()); - world.a((EntityHuman) null, entity.locX, entity.locY, entity.locZ, soundeffect, entity.bV(), 0.7F, b(world.random)); + world.playSound((EntityHuman) null, entity.locX, entity.locY, entity.locZ, soundeffect, entity.getSoundCategory(), 0.7F, b(world.random)); return true; } } @@ -155,43 +166,44 @@ public class EntityParrot extends EntityPerchable implements EntityBird { } } + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); - if (!this.isTamed() && EntityParrot.bO.contains(itemstack.getItem())) { + if (!this.isTamed() && EntityParrot.bK.contains(itemstack.getItem())) { if (!entityhuman.abilities.canInstantlyBuild) { itemstack.subtract(1); } if (!this.isSilent()) { - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PARROT_EAT, this.bV(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); + this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PARROT_EAT, this.getSoundCategory(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); } if (!this.world.isClientSide) { if (this.random.nextInt(10) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { // CraftBukkit - this.c(entityhuman); - this.s(true); + this.tame(entityhuman); + this.r(true); this.world.broadcastEntityEffect(this, (byte) 7); } else { - this.s(false); + this.r(false); this.world.broadcastEntityEffect(this, (byte) 6); } } return true; - } else if (itemstack.getItem() == EntityParrot.bN) { + } else if (itemstack.getItem() == EntityParrot.bJ) { if (!entityhuman.abilities.canInstantlyBuild) { itemstack.subtract(1); } this.addEffect(new MobEffect(MobEffects.POISON, 900), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); // CraftBukkit - if (entityhuman.u() || !this.bl()) { + if (entityhuman.isCreative() || !this.isInvulnerable()) { this.damageEntity(DamageSource.playerAttack(entityhuman), Float.MAX_VALUE); } return true; } else { - if (!this.world.isClientSide && !this.F_() && this.isTamed() && this.f((EntityLiving) entityhuman)) { + if (!this.world.isClientSide && !this.E_() && this.isTamed() && this.h((EntityLiving) entityhuman)) { this.goalSit.setSitting(!this.isSitting()); } @@ -199,85 +211,94 @@ public class EntityParrot extends EntityPerchable implements EntityBird { } } - public boolean f(ItemStack itemstack) { + @Override + public boolean i(ItemStack itemstack) { return false; } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - int i = MathHelper.floor(this.locX); - int j = MathHelper.floor(this.getBoundingBox().minY); - int k = MathHelper.floor(this.locZ); - BlockPosition blockposition = new BlockPosition(i, j, k); + public static boolean c(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { Block block = generatoraccess.getType(blockposition.down()).getBlock(); - return block instanceof BlockLeaves || block == Blocks.GRASS || block instanceof BlockLogAbstract || block == Blocks.AIR && super.a(generatoraccess, flag); + return (block.a(TagsBlock.LEAVES) || block == Blocks.GRASS_BLOCK || block instanceof BlockLogAbstract || block == Blocks.AIR) && generatoraccess.getLightLevel(blockposition, 0) > 8; } - public void c(float f, float f1) {} + @Override + public void b(float f, float f1) {} + @Override protected void a(double d0, boolean flag, IBlockData iblockdata, BlockPosition blockposition) {} + @Override public boolean mate(EntityAnimal entityanimal) { return false; } @Nullable + @Override public EntityAgeable createChild(EntityAgeable entityageable) { return null; } public static void a(World world, Entity entity) { if (!entity.isSilent() && !b(world, entity) && world.random.nextInt(200) == 0) { - world.a((EntityHuman) null, entity.locX, entity.locY, entity.locZ, a(world.random), entity.bV(), 1.0F, b(world.random)); + world.playSound((EntityHuman) null, entity.locX, entity.locY, entity.locZ, a(world.random), entity.getSoundCategory(), 1.0F, b(world.random)); } } - public boolean B(Entity entity) { + @Override + public boolean C(Entity entity) { return entity.damageEntity(DamageSource.mobAttack(this), 3.0F); } @Nullable - public SoundEffect D() { + @Override + public SoundEffect getSoundAmbient() { return a(this.random); } private static SoundEffect a(Random random) { if (random.nextInt(1000) == 0) { - List> list = Lists.newArrayList(EntityParrot.bP.keySet()); + List> list = Lists.newArrayList(EntityParrot.bL.keySet()); - return a((EntityTypes) list.get(random.nextInt(list.size()))); + return b((EntityTypes) list.get(random.nextInt(list.size()))); } else { return SoundEffects.ENTITY_PARROT_AMBIENT; } } - public static SoundEffect a(EntityTypes entitytypes) { - return (SoundEffect) EntityParrot.bP.getOrDefault(entitytypes, SoundEffects.ENTITY_PARROT_AMBIENT); + public static SoundEffect b(EntityTypes entitytypes) { + return (SoundEffect) EntityParrot.bL.getOrDefault(entitytypes, SoundEffects.ENTITY_PARROT_AMBIENT); } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_PARROT_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_PARROT_DEATH; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(SoundEffects.ENTITY_PARROT_STEP, 0.15F, 1.0F); } + @Override protected float e(float f) { this.a(SoundEffects.ENTITY_PARROT_FLY, 0.15F, 1.0F); - return f + this.bH / 2.0F; + return f + this.bD / 2.0F; } - protected boolean ah() { + @Override + protected boolean am() { return true; } - protected float cE() { + @Override + protected float cV() { return b(this.random); } @@ -285,20 +306,24 @@ public class EntityParrot extends EntityPerchable implements EntityBird { return (random.nextFloat() - random.nextFloat()) * 0.2F + 1.0F; } - public SoundCategory bV() { + @Override + public SoundCategory getSoundCategory() { return SoundCategory.NEUTRAL; } + @Override public boolean isCollidable() { return true; } - protected void C(Entity entity) { + @Override + protected void D(Entity entity) { if (!(entity instanceof EntityHuman)) { - super.C(entity); + super.D(entity); } } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -313,34 +338,32 @@ public class EntityParrot extends EntityPerchable implements EntityBird { } public int getVariant() { - return MathHelper.clamp((Integer) this.datawatcher.get(EntityParrot.bL), 0, 4); + return MathHelper.clamp((Integer) this.datawatcher.get(EntityParrot.bH), 0, 4); } public void setVariant(int i) { - this.datawatcher.set(EntityParrot.bL, i); + this.datawatcher.set(EntityParrot.bH, i); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityParrot.bL, 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityParrot.bH, 0); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setInt("Variant", this.getVariant()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setVariant(nbttagcompound.getInt("Variant")); } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aE; - } - - public boolean F_() { + public boolean E_() { return !this.onGround; } } diff --git a/src/main/java/net/minecraft/server/EntityPhantom.java b/src/main/java/net/minecraft/server/EntityPhantom.java index da6e344a1..e5d032d02 100644 --- a/src/main/java/net/minecraft/server/EntityPhantom.java +++ b/src/main/java/net/minecraft/server/EntityPhantom.java @@ -1,82 +1,80 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.Iterator; import java.util.List; import javax.annotation.Nullable; public class EntityPhantom extends EntityFlying implements IMonster { - private static final DataWatcherObject a = DataWatcher.a(EntityPhantom.class, DataWatcherRegistry.b); - private Vec3D b; - private BlockPosition c; - private EntityPhantom.AttackPhase bC; + private static final DataWatcherObject b = DataWatcher.a(EntityPhantom.class, DataWatcherRegistry.b); + private Vec3D c; + private BlockPosition d; + private EntityPhantom.AttackPhase bz; - public EntityPhantom(World world) { - super(EntityTypes.PHANTOM, world); - this.b = Vec3D.a; - this.c = BlockPosition.ZERO; - this.bC = EntityPhantom.AttackPhase.CIRCLE; - this.b_ = 5; - this.setSize(0.9F, 0.5F); + public EntityPhantom(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.c = Vec3D.a; + this.d = BlockPosition.ZERO; + this.bz = EntityPhantom.AttackPhase.CIRCLE; + this.f = 5; this.moveController = new EntityPhantom.g(this); this.lookController = new EntityPhantom.f(this); } + @Override protected EntityAIBodyControl o() { return new EntityPhantom.d(this); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(1, new EntityPhantom.c()); this.goalSelector.a(2, new EntityPhantom.i()); this.goalSelector.a(3, new EntityPhantom.e()); this.targetSelector.a(1, new EntityPhantom.b()); } + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityPhantom.a, 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityPhantom.b, 0); } public void setSize(int i) { - if (i < 0) { - i = 0; - } else if (i > 64) { - i = 64; - } - - this.datawatcher.set(EntityPhantom.a, i); - this.l(); + this.datawatcher.set(EntityPhantom.b, MathHelper.clamp(i, 0, 64)); } - public void l() { - int i = (Integer) this.datawatcher.get(EntityPhantom.a); - - this.setSize(0.9F + 0.2F * (float) i, 0.5F + 0.1F * (float) i); - this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue((double) (6 + i)); + private void dU() { + this.updateSize(); + this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue((double) (6 + this.getSize())); } public int getSize() { - return (Integer) this.datawatcher.get(EntityPhantom.a); + return (Integer) this.datawatcher.get(EntityPhantom.b); } - public float getHeadHeight() { - return this.length * 0.35F; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height * 0.35F; } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntityPhantom.a.equals(datawatcherobject)) { - this.l(); + if (EntityPhantom.b.equals(datawatcherobject)) { + this.dU(); } super.a(datawatcherobject); } + @Override public void tick() { super.tick(); if (this.world.isClientSide) { @@ -84,20 +82,16 @@ public class EntityPhantom extends EntityFlying implements IMonster { float f1 = MathHelper.cos((float) (this.getId() * 3 + this.ticksLived + 1) * 0.13F + 3.1415927F); if (f > 0.0F && f1 <= 0.0F) { - this.world.a(this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PHANTOM_FLAP, this.bV(), 0.95F + this.random.nextFloat() * 0.05F, 0.95F + this.random.nextFloat() * 0.05F, false); + this.world.a(this.locX, this.locY, this.locZ, SoundEffects.ENTITY_PHANTOM_FLAP, this.getSoundCategory(), 0.95F + this.random.nextFloat() * 0.05F, 0.95F + this.random.nextFloat() * 0.05F, false); } - // Akarin start - this handle by client - /* int i = this.getSize(); float f2 = MathHelper.cos(this.yaw * 0.017453292F) * (1.3F + 0.21F * (float) i); float f3 = MathHelper.sin(this.yaw * 0.017453292F) * (1.3F + 0.21F * (float) i); float f4 = (0.3F + f * 0.45F) * ((float) i * 0.2F + 1.0F); - this.world.addParticle(Particles.H, this.locX + (double) f2, this.locY + (double) f4, this.locZ + (double) f3, 0.0D, 0.0D, 0.0D); - this.world.addParticle(Particles.H, this.locX - (double) f2, this.locY + (double) f4, this.locZ - (double) f3, 0.0D, 0.0D, 0.0D); - */ - // Akarin end + this.world.addParticle(Particles.MYCELIUM, this.locX + (double) f2, this.locY + (double) f4, this.locZ + (double) f3, 0.0D, 0.0D, 0.0D); + this.world.addParticle(Particles.MYCELIUM, this.locX - (double) f2, this.locY + (double) f4, this.locZ - (double) f3, 0.0D, 0.0D, 0.0D); } if (!this.world.isClientSide && this.world.getDifficulty() == EnumDifficulty.PEACEFUL) { @@ -106,28 +100,32 @@ public class EntityPhantom extends EntityFlying implements IMonster { } + @Override public void movementTick() { - if (this.dq()) { + if (this.isAlive() && this.dS()) { this.setOnFire(8); } super.movementTick(); } + @Override protected void mobTick() { super.mobTick(); } - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - this.c = (new BlockPosition(this)).up(5); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.d = (new BlockPosition(this)).up(5); this.setSize(0); - return super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKey("AX")) { - this.c = new BlockPosition(nbttagcompound.getInt("AX"), nbttagcompound.getInt("AY"), nbttagcompound.getInt("AZ")); + this.d = new BlockPosition(nbttagcompound.getInt("AX"), nbttagcompound.getInt("AY"), nbttagcompound.getInt("AZ")); } this.setSize(nbttagcompound.getInt("Size")); @@ -138,11 +136,12 @@ public class EntityPhantom extends EntityFlying implements IMonster { // Paper end } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setInt("AX", this.c.getX()); - nbttagcompound.setInt("AY", this.c.getY()); - nbttagcompound.setInt("AZ", this.c.getZ()); + nbttagcompound.setInt("AX", this.d.getX()); + nbttagcompound.setInt("AY", this.d.getY()); + nbttagcompound.setInt("AZ", this.d.getZ()); nbttagcompound.setInt("Size", this.getSize()); // Paper start if (this.spawningEntity != null) { @@ -151,39 +150,50 @@ public class EntityPhantom extends EntityFlying implements IMonster { // Paper end } - public SoundCategory bV() { + @Override + public SoundCategory getSoundCategory() { return SoundCategory.HOSTILE; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_PHANTOM_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_PHANTOM_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_PHANTOM_DEATH; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.K; - } - + @Override public EnumMonsterType getMonsterType() { return EnumMonsterType.UNDEAD; } - protected float cD() { + @Override + protected float getSoundVolume() { return 1.0F; } - public boolean b(Class oclass) { + @Override + public boolean a(EntityTypes entitytypes) { return true; } + @Override + public EntitySize a(EntityPose entitypose) { + int i = this.getSize(); + EntitySize entitysize = super.a(entitypose); + float f = (entitysize.width + 0.2F * (float) i) / entitysize.width; + + return entitysize.a(f); + } + // Paper start java.util.UUID spawningEntity; @@ -194,20 +204,22 @@ public class EntityPhantom extends EntityFlying implements IMonster { class b extends PathfinderGoal { - private int b; + private final PathfinderTargetCondition b; + private int c; private b() { - this.b = 20; + this.b = (new PathfinderTargetCondition()).a(64.0D); + this.c = 20; } + @Override public boolean a() { - if (this.b > 0) { - --this.b; + if (this.c > 0) { + --this.c; return false; } else { - this.b = 60; - AxisAlignedBB axisalignedbb = EntityPhantom.this.getBoundingBox().grow(16.0D, 64.0D, 16.0D); - List list = EntityPhantom.this.world.a(EntityHuman.class, axisalignedbb); + this.c = 60; + List list = EntityPhantom.this.world.a(this.b, (EntityLiving) EntityPhantom.this, EntityPhantom.this.getBoundingBox().grow(16.0D, 64.0D, 16.0D)); if (!list.isEmpty()) { list.sort((entityhuman, entityhuman1) -> { @@ -218,7 +230,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { while (iterator.hasNext()) { EntityHuman entityhuman = (EntityHuman) iterator.next(); - if (PathfinderGoalTarget.a(EntityPhantom.this, entityhuman, false, false)) { + if (EntityPhantom.this.a((EntityLiving) entityhuman, PathfinderTargetCondition.a)) { EntityPhantom.this.setGoalTarget(entityhuman, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit - reason return true; } @@ -229,8 +241,11 @@ public class EntityPhantom extends EntityFlying implements IMonster { } } + @Override public boolean b() { - return PathfinderGoalTarget.a(EntityPhantom.this, EntityPhantom.this.getGoalTarget(), false, false); + EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); + + return entityliving != null ? EntityPhantom.this.a(entityliving, PathfinderTargetCondition.a) : false; } } @@ -240,25 +255,31 @@ public class EntityPhantom extends EntityFlying implements IMonster { private c() {} + @Override public boolean a() { - return PathfinderGoalTarget.a(EntityPhantom.this, EntityPhantom.this.getGoalTarget(), false, false); + EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); + + return entityliving != null ? EntityPhantom.this.a(EntityPhantom.this.getGoalTarget(), PathfinderTargetCondition.a) : false; } + @Override public void c() { this.b = 10; - EntityPhantom.this.bC = EntityPhantom.AttackPhase.CIRCLE; + EntityPhantom.this.bz = EntityPhantom.AttackPhase.CIRCLE; this.g(); } + @Override public void d() { - EntityPhantom.this.c = EntityPhantom.this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, EntityPhantom.this.c).up(10 + EntityPhantom.this.random.nextInt(20)); + EntityPhantom.this.d = EntityPhantom.this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, EntityPhantom.this.d).up(10 + EntityPhantom.this.random.nextInt(20)); } + @Override public void e() { - if (EntityPhantom.this.bC == EntityPhantom.AttackPhase.CIRCLE) { + if (EntityPhantom.this.bz == EntityPhantom.AttackPhase.CIRCLE) { --this.b; if (this.b <= 0) { - EntityPhantom.this.bC = EntityPhantom.AttackPhase.SWOOP; + EntityPhantom.this.bz = EntityPhantom.AttackPhase.SWOOP; this.g(); this.b = (8 + EntityPhantom.this.random.nextInt(4)) * 20; EntityPhantom.this.a(SoundEffects.ENTITY_PHANTOM_SWOOP, 10.0F, 0.95F + EntityPhantom.this.random.nextFloat() * 0.1F); @@ -268,9 +289,9 @@ public class EntityPhantom extends EntityFlying implements IMonster { } private void g() { - EntityPhantom.this.c = (new BlockPosition(EntityPhantom.this.getGoalTarget())).up(20 + EntityPhantom.this.random.nextInt(20)); - if (EntityPhantom.this.c.getY() < EntityPhantom.this.world.getSeaLevel()) { - EntityPhantom.this.c = new BlockPosition(EntityPhantom.this.c.getX(), EntityPhantom.this.world.getSeaLevel() + 1, EntityPhantom.this.c.getZ()); + EntityPhantom.this.d = (new BlockPosition(EntityPhantom.this.getGoalTarget())).up(20 + EntityPhantom.this.random.nextInt(20)); + if (EntityPhantom.this.d.getY() < EntityPhantom.this.world.getSeaLevel()) { + EntityPhantom.this.d = new BlockPosition(EntityPhantom.this.d.getX(), EntityPhantom.this.world.getSeaLevel() + 1, EntityPhantom.this.d.getZ()); } } @@ -282,33 +303,64 @@ public class EntityPhantom extends EntityFlying implements IMonster { super(); } + @Override public boolean a() { - return EntityPhantom.this.getGoalTarget() != null && EntityPhantom.this.bC == EntityPhantom.AttackPhase.SWOOP; + return EntityPhantom.this.getGoalTarget() != null && EntityPhantom.this.bz == EntityPhantom.AttackPhase.SWOOP; } + @Override public boolean b() { EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); - return entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof EntityHuman && (((EntityHuman) entityliving).isSpectator() || ((EntityHuman) entityliving).u()) ? false : this.a())); + if (entityliving == null) { + return false; + } else if (!entityliving.isAlive()) { + return false; + } else if (entityliving instanceof EntityHuman && (((EntityHuman) entityliving).isSpectator() || ((EntityHuman) entityliving).isCreative())) { + return false; + } else if (!this.a()) { + return false; + } else { + if (EntityPhantom.this.ticksLived % 20 == 0) { + List list = EntityPhantom.this.world.a(EntityCat.class, EntityPhantom.this.getBoundingBox().g(16.0D), IEntitySelector.a); + + if (!list.isEmpty()) { + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityCat entitycat = (EntityCat) iterator.next(); + + entitycat.ej(); + } + + return false; + } + } + + return true; + } } + @Override public void c() {} + @Override public void d() { EntityPhantom.this.setGoalTarget((EntityLiving) null); - EntityPhantom.this.bC = EntityPhantom.AttackPhase.CIRCLE; + EntityPhantom.this.bz = EntityPhantom.AttackPhase.CIRCLE; } + @Override public void e() { EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); - EntityPhantom.this.b = new Vec3D(entityliving.locX, entityliving.locY + (double) entityliving.length * 0.5D, entityliving.locZ); + EntityPhantom.this.c = new Vec3D(entityliving.locX, entityliving.locY + (double) entityliving.getHeight() * 0.5D, entityliving.locZ); if (EntityPhantom.this.getBoundingBox().g(0.20000000298023224D).c(entityliving.getBoundingBox())) { - EntityPhantom.this.B(entityliving); - EntityPhantom.this.bC = EntityPhantom.AttackPhase.CIRCLE; + EntityPhantom.this.C(entityliving); + EntityPhantom.this.bz = EntityPhantom.AttackPhase.CIRCLE; EntityPhantom.this.world.triggerEffect(1039, new BlockPosition(EntityPhantom.this), 0); } else if (EntityPhantom.this.positionChanged || EntityPhantom.this.hurtTicks > 0) { - EntityPhantom.this.bC = EntityPhantom.AttackPhase.CIRCLE; + EntityPhantom.this.bz = EntityPhantom.AttackPhase.CIRCLE; } } @@ -325,17 +377,20 @@ public class EntityPhantom extends EntityFlying implements IMonster { super(); } + @Override public boolean a() { - return EntityPhantom.this.getGoalTarget() == null || EntityPhantom.this.bC == EntityPhantom.AttackPhase.CIRCLE; + return EntityPhantom.this.getGoalTarget() == null || EntityPhantom.this.bz == EntityPhantom.AttackPhase.CIRCLE; } + @Override public void c() { this.d = 5.0F + EntityPhantom.this.random.nextFloat() * 10.0F; this.e = -4.0F + EntityPhantom.this.random.nextFloat() * 9.0F; this.f = EntityPhantom.this.random.nextBoolean() ? 1.0F : -1.0F; - this.i(); + this.h(); } + @Override public void e() { if (EntityPhantom.this.random.nextInt(350) == 0) { this.e = -4.0F + EntityPhantom.this.random.nextFloat() * 9.0F; @@ -351,43 +406,43 @@ public class EntityPhantom extends EntityFlying implements IMonster { if (EntityPhantom.this.random.nextInt(450) == 0) { this.c = EntityPhantom.this.random.nextFloat() * 2.0F * 3.1415927F; - this.i(); + this.h(); } if (this.g()) { - this.i(); + this.h(); } - if (EntityPhantom.this.b.y < EntityPhantom.this.locY && !EntityPhantom.this.world.isEmpty((new BlockPosition(EntityPhantom.this)).down(1))) { + if (EntityPhantom.this.c.y < EntityPhantom.this.locY && !EntityPhantom.this.world.isEmpty((new BlockPosition(EntityPhantom.this)).down(1))) { this.e = Math.max(1.0F, this.e); - this.i(); + this.h(); } - if (EntityPhantom.this.b.y > EntityPhantom.this.locY && !EntityPhantom.this.world.isEmpty((new BlockPosition(EntityPhantom.this)).up(1))) { + if (EntityPhantom.this.c.y > EntityPhantom.this.locY && !EntityPhantom.this.world.isEmpty((new BlockPosition(EntityPhantom.this)).up(1))) { this.e = Math.min(-1.0F, this.e); - this.i(); + this.h(); } } - private void i() { - if (BlockPosition.ZERO.equals(EntityPhantom.this.c)) { - EntityPhantom.this.c = new BlockPosition(EntityPhantom.this); + private void h() { + if (BlockPosition.ZERO.equals(EntityPhantom.this.d)) { + EntityPhantom.this.d = new BlockPosition(EntityPhantom.this); } this.c += this.f * 15.0F * 0.017453292F; - EntityPhantom.this.b = (new Vec3D(EntityPhantom.this.c)).add((double) (this.d * MathHelper.cos(this.c)), (double) (-4.0F + this.e), (double) (this.d * MathHelper.sin(this.c))); + EntityPhantom.this.c = (new Vec3D(EntityPhantom.this.d)).add((double) (this.d * MathHelper.cos(this.c)), (double) (-4.0F + this.e), (double) (this.d * MathHelper.sin(this.c))); } } abstract class h extends PathfinderGoal { public h() { - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); } protected boolean g() { - return EntityPhantom.this.b.c(EntityPhantom.this.locX, EntityPhantom.this.locY, EntityPhantom.this.locZ) < 4.0D; + return EntityPhantom.this.c.c(EntityPhantom.this.locX, EntityPhantom.this.locY, EntityPhantom.this.locZ) < 4.0D; } } @@ -397,18 +452,20 @@ public class EntityPhantom extends EntityFlying implements IMonster { super(entityinsentient); } + @Override public void a() {} } class d extends EntityAIBodyControl { - public d(EntityLiving entityliving) { - super(entityliving); + public d(EntityInsentient entityinsentient) { + super(entityinsentient); } + @Override public void a() { - EntityPhantom.this.aS = EntityPhantom.this.aQ; - EntityPhantom.this.aQ = EntityPhantom.this.yaw; + EntityPhantom.this.aM = EntityPhantom.this.aK; + EntityPhantom.this.aK = EntityPhantom.this.yaw; } } @@ -420,15 +477,16 @@ public class EntityPhantom extends EntityFlying implements IMonster { super(entityinsentient); } + @Override public void a() { if (EntityPhantom.this.positionChanged) { EntityPhantom.this.yaw += 180.0F; this.j = 0.1F; } - float f = (float) (EntityPhantom.this.b.x - EntityPhantom.this.locX); - float f1 = (float) (EntityPhantom.this.b.y - EntityPhantom.this.locY); - float f2 = (float) (EntityPhantom.this.b.z - EntityPhantom.this.locZ); + float f = (float) (EntityPhantom.this.c.x - EntityPhantom.this.locX); + float f1 = (float) (EntityPhantom.this.c.y - EntityPhantom.this.locY); + float f2 = (float) (EntityPhantom.this.c.z - EntityPhantom.this.locZ); double d0 = (double) MathHelper.c(f * f + f2 * f2); double d1 = 1.0D - (double) MathHelper.e(f1 * 0.7F) / d0; @@ -437,29 +495,28 @@ public class EntityPhantom extends EntityFlying implements IMonster { d0 = (double) MathHelper.c(f * f + f2 * f2); double d2 = (double) MathHelper.c(f * f + f2 * f2 + f1 * f1); float f3 = EntityPhantom.this.yaw; - float f4 = (float) MathHelper.c((double) f2, (double) f); + float f4 = (float) MathHelper.d((double) f2, (double) f); float f5 = MathHelper.g(EntityPhantom.this.yaw + 90.0F); float f6 = MathHelper.g(f4 * 57.295776F); - EntityPhantom.this.yaw = MathHelper.c(f5, f6, 4.0F) - 90.0F; - EntityPhantom.this.aQ = EntityPhantom.this.yaw; + EntityPhantom.this.yaw = MathHelper.d(f5, f6, 4.0F) - 90.0F; + EntityPhantom.this.aK = EntityPhantom.this.yaw; if (MathHelper.d(f3, EntityPhantom.this.yaw) < 3.0F) { - this.j = MathHelper.b(this.j, 1.8F, 0.005F * (1.8F / this.j)); + this.j = MathHelper.c(this.j, 1.8F, 0.005F * (1.8F / this.j)); } else { - this.j = MathHelper.b(this.j, 0.2F, 0.025F); + this.j = MathHelper.c(this.j, 0.2F, 0.025F); } - float f7 = (float) (-(MathHelper.c((double) (-f1), d0) * 57.2957763671875D)); + float f7 = (float) (-(MathHelper.d((double) (-f1), d0) * 57.2957763671875D)); EntityPhantom.this.pitch = f7; float f8 = EntityPhantom.this.yaw + 90.0F; double d3 = (double) (this.j * MathHelper.cos(f8 * 0.017453292F)) * Math.abs((double) f / d2); double d4 = (double) (this.j * MathHelper.sin(f8 * 0.017453292F)) * Math.abs((double) f2 / d2); double d5 = (double) (this.j * MathHelper.sin(f7 * 0.017453292F)) * Math.abs((double) f1 / d2); + Vec3D vec3d = EntityPhantom.this.getMot(); - EntityPhantom.this.motX += (d3 - EntityPhantom.this.motX) * 0.2D; - EntityPhantom.this.motY += (d5 - EntityPhantom.this.motY) * 0.2D; - EntityPhantom.this.motZ += (d4 - EntityPhantom.this.motZ) * 0.2D; + EntityPhantom.this.setMot(vec3d.e((new Vec3D(d3, d5, d4)).d(vec3d).a(0.2D))); } } diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/net/minecraft/server/EntityPig.java index d1689dc33..7136e274a 100644 --- a/src/main/java/net/minecraft/server/EntityPig.java +++ b/src/main/java/net/minecraft/server/EntityPig.java @@ -4,48 +4,50 @@ import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.craftbukkit.event.CraftEventFactory; -import org.bukkit.event.entity.EntityTransformEvent; // CraftBukkit end public class EntityPig extends EntityAnimal { - private static final DataWatcherObject bC = DataWatcher.a(EntityPig.class, DataWatcherRegistry.i); - private static final DataWatcherObject bD = DataWatcher.a(EntityPig.class, DataWatcherRegistry.b); - private static final RecipeItemStack bE = RecipeItemStack.a(Items.CARROT, Items.POTATO, Items.BEETROOT); - private boolean bG; - private int bH; - private int bI; + private static final DataWatcherObject bz = DataWatcher.a(EntityPig.class, DataWatcherRegistry.i); + private static final DataWatcherObject bA = DataWatcher.a(EntityPig.class, DataWatcherRegistry.b); + private static final RecipeItemStack bB = RecipeItemStack.a(Items.CARROT, Items.POTATO, Items.BEETROOT); + private boolean bC; + private int bD; + private int bE; - public EntityPig(World world) { - super(EntityTypes.PIG, world); - this.setSize(0.9F, 0.9F); + public EntityPig(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); this.goalSelector.a(3, new PathfinderGoalBreed(this, 1.0D)); this.goalSelector.a(4, new PathfinderGoalTempt(this, 1.2D, RecipeItemStack.a(Items.CARROT_ON_A_STICK), false)); - this.goalSelector.a(4, new PathfinderGoalTempt(this, 1.2D, false, EntityPig.bE)); + this.goalSelector.a(4, new PathfinderGoalTempt(this, 1.2D, false, EntityPig.bB)); this.goalSelector.a(5, new PathfinderGoalFollowParent(this, 1.1D)); this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); } @Nullable - public Entity bO() { - return this.bP().isEmpty() ? null : (Entity) this.bP().get(0); + @Override + public Entity getRidingPassenger() { + return this.getPassengers().isEmpty() ? null : (Entity) this.getPassengers().get(0); } - public boolean dh() { - Entity entity = this.bO(); + @Override + public boolean dD() { + Entity entity = this.getRidingPassenger(); if (!(entity instanceof EntityHuman)) { return false; @@ -56,48 +58,57 @@ public class EntityPig extends EntityAnimal { } } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntityPig.bD.equals(datawatcherobject) && this.world.isClientSide) { - this.bG = true; - this.bH = 0; - this.bI = (Integer) this.datawatcher.get(EntityPig.bD); + if (EntityPig.bA.equals(datawatcherobject) && this.world.isClientSide) { + this.bC = true; + this.bD = 0; + this.bE = (Integer) this.datawatcher.get(EntityPig.bA); } super.a(datawatcherobject); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityPig.bC, false); - this.datawatcher.register(EntityPig.bD, 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityPig.bz, false); + this.datawatcher.register(EntityPig.bA, 0); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setBoolean("Saddle", this.hasSaddle()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setSaddle(nbttagcompound.getBoolean("Saddle")); } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_PIG_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_PIG_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_PIG_DEATH; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(SoundEffects.ENTITY_PIG_STEP, 0.15F, 1.0F); } + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { if (!super.a(entityhuman, enumhand)) { ItemStack itemstack = entityhuman.b(enumhand); @@ -122,130 +133,125 @@ public class EntityPig extends EntityAnimal { } } - public void die(DamageSource damagesource) { - // super.die(damagesource); // CraftBukkit - Moved to end - if (!this.world.isClientSide) { - if (this.hasSaddle()) { - this.a((IMaterial) Items.SADDLE); - } - + @Override + protected void cF() { + super.cF(); + if (this.hasSaddle()) { + this.a((IMaterial) Items.SADDLE); } - super.die(damagesource); // CraftBukkit - Moved from above - } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.L; } public boolean hasSaddle() { - return (Boolean) this.datawatcher.get(EntityPig.bC); + return (Boolean) this.datawatcher.get(EntityPig.bz); } public void setSaddle(boolean flag) { if (flag) { - this.datawatcher.set(EntityPig.bC, true); + this.datawatcher.set(EntityPig.bz, true); } else { - this.datawatcher.set(EntityPig.bC, false); + this.datawatcher.set(EntityPig.bz, false); } } + @Override public void onLightningStrike(EntityLightning entitylightning) { - if (!this.world.isClientSide && !this.dead) { - EntityPigZombie entitypigzombie = EntityTypes.ZOMBIE_PIGMAN.create(world); // Paper + EntityPigZombie entitypigzombie = (EntityPigZombie) EntityTypes.ZOMBIE_PIGMAN.a(this.world); - entitypigzombie.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD)); - entitypigzombie.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); - entitypigzombie.setNoAI(this.isNoAI()); - if (this.hasCustomName()) { - entitypigzombie.setCustomName(this.getCustomName()); - entitypigzombie.setCustomNameVisible(this.getCustomNameVisible()); - } - - // Paper start - if (CraftEventFactory.callEntityZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { - return; - } - // Paper end - - // CraftBukkit start - if (CraftEventFactory.callPigZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { - return; - } - // CraftBukkit - added a reason for spawning this creature - this.world.addEntity(entitypigzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); - // CraftBukkit end - this.die(); + entitypigzombie.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD)); + entitypigzombie.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + entitypigzombie.setNoAI(this.isNoAI()); + if (this.hasCustomName()) { + entitypigzombie.setCustomName(this.getCustomName()); + entitypigzombie.setCustomNameVisible(this.getCustomNameVisible()); } + + // Paper start + if (CraftEventFactory.callEntityZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { + return; + } + // Paper end + + // CraftBukkit start + if (CraftEventFactory.callPigZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { + return; + } + // CraftBukkit - added a reason for spawning this creature + this.world.addEntity(entitypigzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); + // CraftBukkit end + this.die(); } - public void a(float f, float f1, float f2) { - Entity entity = this.bP().isEmpty() ? null : (Entity) this.bP().get(0); + @Override + public void e(Vec3D vec3d) { + if (this.isAlive()) { + Entity entity = this.getPassengers().isEmpty() ? null : (Entity) this.getPassengers().get(0); - if (this.isVehicle() && this.dh()) { - this.yaw = entity.yaw; - this.lastYaw = this.yaw; - this.pitch = entity.pitch * 0.5F; - this.setYawPitch(this.yaw, this.pitch); - this.aQ = this.yaw; - this.aS = this.yaw; - this.Q = 1.0F; - this.aU = this.cK() * 0.1F; - if (this.bG && this.bH++ > this.bI) { - this.bG = false; - } - - if (this.bT()) { - float f3 = (float) this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 0.225F; - - if (this.bG) { - f3 += f3 * 1.15F * MathHelper.sin((float) this.bH / (float) this.bI * 3.1415927F); + if (this.isVehicle() && this.dD()) { + this.yaw = entity.yaw; + this.lastYaw = this.yaw; + this.pitch = entity.pitch * 0.5F; + this.setYawPitch(this.yaw, this.pitch); + this.aK = this.yaw; + this.aM = this.yaw; + this.K = 1.0F; + this.aO = this.db() * 0.1F; + if (this.bC && this.bD++ > this.bE) { + this.bC = false; } - this.o(f3); - super.a(0.0F, 0.0F, 1.0F); + if (this.ca()) { + float f = (float) this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 0.225F; + + if (this.bC) { + f += f * 1.15F * MathHelper.sin((float) this.bD / (float) this.bE * 3.1415927F); + } + + this.o(f); + super.e(new Vec3D(0.0D, 0.0D, 1.0D)); + } else { + this.setMot(Vec3D.a); + } + + this.aE = this.aF; + double d0 = this.locX - this.lastX; + double d1 = this.locZ - this.lastZ; + float f1 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F; + + if (f1 > 1.0F) { + f1 = 1.0F; + } + + this.aF += (f1 - this.aF) * 0.4F; + this.aG += this.aF; } else { - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; + this.K = 0.5F; + this.aO = 0.02F; + super.e(vec3d); } - - this.aI = this.aJ; - double d0 = this.locX - this.lastX; - double d1 = this.locZ - this.lastZ; - float f4 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F; - - if (f4 > 1.0F) { - f4 = 1.0F; - } - - this.aJ += (f4 - this.aJ) * 0.4F; - this.aK += this.aJ; - } else { - this.Q = 0.5F; - this.aU = 0.02F; - super.a(f, f1, f2); } } - public boolean dz() { - if (this.bG) { + public boolean dW() { + if (this.bC) { return false; } else { - this.bG = true; - this.bH = 0; - this.bI = this.getRandom().nextInt(841) + 140; - this.getDataWatcher().set(EntityPig.bD, this.bI); + this.bC = true; + this.bD = 0; + this.bE = this.getRandom().nextInt(841) + 140; + this.getDataWatcher().set(EntityPig.bA, this.bE); return true; } } + @Override public EntityPig createChild(EntityAgeable entityageable) { - return EntityTypes.PIG.create(world); // Paper + return (EntityPig) EntityTypes.PIG.a(this.world); } - public boolean f(ItemStack itemstack) { - return EntityPig.bE.test(itemstack); + @Override + public boolean i(ItemStack itemstack) { + return EntityPig.bB.test(itemstack); } } diff --git a/src/main/java/net/minecraft/server/EntityPigZombie.java b/src/main/java/net/minecraft/server/EntityPigZombie.java index 56dab7667..4f260f814 100644 --- a/src/main/java/net/minecraft/server/EntityPigZombie.java +++ b/src/main/java/net/minecraft/server/EntityPigZombie.java @@ -1,21 +1,23 @@ package net.minecraft.server; +import java.util.Random; import java.util.UUID; import javax.annotation.Nullable; public class EntityPigZombie extends EntityZombie { - private static final UUID a = UUID.fromString("49455A49-7EC5-45BA-B886-3B90B23A1718"); - private static final AttributeModifier b = (new AttributeModifier(EntityPigZombie.a, "Attacking speed boost", 0.05D, 0)).a(false); + private static final UUID b = UUID.fromString("49455A49-7EC5-45BA-B886-3B90B23A1718"); + private static final AttributeModifier c = (new AttributeModifier(EntityPigZombie.b, "Attacking speed boost", 0.05D, AttributeModifier.Operation.ADDITION)).a(false); public int angerLevel; private int soundDelay; private UUID hurtBy; - public EntityPigZombie(World world) { - super(EntityTypes.ZOMBIE_PIGMAN, world); - this.fireProof = true; + public EntityPigZombie(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.a(PathType.LAVA, 8.0F); } + @Override public void setLastDamager(@Nullable EntityLiving entityliving) { super.setLastDamager(entityliving); if (entityliving != null) { @@ -24,6 +26,7 @@ public class EntityPigZombie extends EntityZombie { } + @Override protected void l() { this.goalSelector.a(2, new PathfinderGoalZombieAttack(this, 1.0D, false)); this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D)); @@ -31,53 +34,69 @@ public class EntityPigZombie extends EntityZombie { this.targetSelector.a(2, new EntityPigZombie.PathfinderGoalAnger(this)); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(EntityPigZombie.c).setValue(0.0D); + this.getAttributeInstance(EntityPigZombie.d).setValue(0.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.23000000417232513D); this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(5.0D); } - protected boolean dC() { + @Override + protected boolean dY() { return false; } + @Override protected void mobTick() { AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); + EntityLiving entityliving = this.getLastDamager(); - if (this.dF()) { - if (!this.isBaby() && !attributeinstance.a(EntityPigZombie.b)) { - attributeinstance.b(EntityPigZombie.b); + if (this.ef()) { + if (!this.isBaby() && !attributeinstance.a(EntityPigZombie.c)) { + attributeinstance.addModifier(EntityPigZombie.c); } --this.angerLevel; - } else if (attributeinstance.a(EntityPigZombie.b)) { - attributeinstance.c(EntityPigZombie.b); + EntityLiving entityliving1 = entityliving != null ? entityliving : this.getGoalTarget(); + + if (!this.ef() && entityliving1 != null) { + if (!this.hasLineOfSight(entityliving1)) { + this.setLastDamager((EntityLiving) null); + this.setGoalTarget((EntityLiving) null); + } else { + this.angerLevel = this.ee(); + } + } + } else if (attributeinstance.a(EntityPigZombie.c)) { + attributeinstance.removeModifier(EntityPigZombie.c); } if (this.soundDelay > 0 && --this.soundDelay == 0) { - this.a(SoundEffects.ENTITY_ZOMBIE_PIGMAN_ANGRY, this.cD() * 2.0F, ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) * 1.8F); + this.a(SoundEffects.ENTITY_ZOMBIE_PIGMAN_ANGRY, this.getSoundVolume() * 2.0F, ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) * 1.8F); } - if (this.angerLevel > 0 && this.hurtBy != null && this.getLastDamager() == null) { + if (this.ef() && this.hurtBy != null && entityliving == null) { EntityHuman entityhuman = this.world.b(this.hurtBy); this.setLastDamager(entityhuman); this.killer = entityhuman; - this.lastDamageByPlayerTime = this.cg(); + this.lastDamageByPlayerTime = this.ct(); } super.mobTick(); } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { return generatoraccess.getDifficulty() != EnumDifficulty.PEACEFUL; } + @Override public boolean a(IWorldReader iworldreader) { - return iworldreader.a_(this, this.getBoundingBox()) && iworldreader.getCubes(this, this.getBoundingBox()) && !iworldreader.containsLiquid(this.getBoundingBox()); + return iworldreader.i(this) && !iworldreader.containsLiquid(this.getBoundingBox()); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setShort("Anger", (short) this.angerLevel); @@ -89,6 +108,7 @@ public class EntityPigZombie extends EntityZombie { } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.angerLevel = nbttagcompound.getShort("Anger"); @@ -101,12 +121,13 @@ public class EntityPigZombie extends EntityZombie { this.setLastDamager(entityhuman); if (entityhuman != null) { this.killer = entityhuman; - this.lastDamageByPlayerTime = this.cg(); + this.lastDamageByPlayerTime = this.ct(); } } } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -116,7 +137,7 @@ public class EntityPigZombie extends EntityZombie { // CraftBukkit start boolean result = super.damageEntity(damagesource, f); - if (result && entity instanceof EntityHuman && !((EntityHuman) entity).u()) { + if (result && entity instanceof EntityHuman && !((EntityHuman) entity).isCreative() && this.hasLineOfSight(entity)) { this.a(entity); } @@ -125,12 +146,12 @@ public class EntityPigZombie extends EntityZombie { } } - private void a(Entity entity) { + private boolean a(Entity entity) { // CraftBukkit start - org.bukkit.event.entity.PigZombieAngerEvent event = new org.bukkit.event.entity.PigZombieAngerEvent((org.bukkit.entity.PigZombie) this.getBukkitEntity(), (entity == null) ? null : entity.getBukkitEntity(), 400 + this.random.nextInt(400)); + org.bukkit.event.entity.PigZombieAngerEvent event = new org.bukkit.event.entity.PigZombieAngerEvent((org.bukkit.entity.PigZombie) this.getBukkitEntity(), (entity == null) ? null : entity.getBukkitEntity(), this.ee()); this.world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { - return; + return false; } this.angerLevel = event.getNewAnger(); // CraftBukkit end @@ -139,43 +160,50 @@ public class EntityPigZombie extends EntityZombie { this.setLastDamager((EntityLiving) entity); } + return true; } - public boolean dF() { + private int ee() { + return 400 + this.random.nextInt(400); + } + + private boolean ef() { return this.angerLevel > 0; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_ZOMBIE_PIGMAN_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_ZOMBIE_PIGMAN_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_ZOMBIE_PIGMAN_DEATH; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.au; - } - + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { return false; } + @Override protected void a(DifficultyDamageScaler difficultydamagescaler) { this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD)); } - protected ItemStack dB() { + @Override + protected ItemStack dX() { return ItemStack.a; } - public boolean c(EntityHuman entityhuman) { - return this.dF(); + @Override + public boolean e(EntityHuman entityhuman) { + return this.ef(); } static class PathfinderGoalAnger extends PathfinderGoalNearestAttackableTarget { @@ -184,21 +212,23 @@ public class EntityPigZombie extends EntityZombie { super(entitypigzombie, EntityHuman.class, true); } + @Override public boolean a() { - return ((EntityPigZombie) this.e).dF() && super.a(); + return ((EntityPigZombie) this.e).ef() && super.a(); } } static class PathfinderGoalAngerOther extends PathfinderGoalHurtByTarget { public PathfinderGoalAngerOther(EntityPigZombie entitypigzombie) { - super(entitypigzombie, true); + super(entitypigzombie); + this.a(new Class[]{EntityZombie.class}); } - protected void a(EntityCreature entitycreature, EntityLiving entityliving) { - super.a(entitycreature, entityliving); - if (entitycreature instanceof EntityPigZombie) { - ((EntityPigZombie) entitycreature).a((Entity) entityliving); + @Override + protected void a(EntityInsentient entityinsentient, EntityLiving entityliving) { + if (entityinsentient instanceof EntityPigZombie && this.e.hasLineOfSight(entityliving) && ((EntityPigZombie) entityinsentient).a((Entity) entityliving)) { + entityinsentient.setGoalTarget(entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true); // CraftBukkit } } diff --git a/src/main/java/net/minecraft/server/EntityPillager.java b/src/main/java/net/minecraft/server/EntityPillager.java new file mode 100644 index 000000000..79a330650 --- /dev/null +++ b/src/main/java/net/minecraft/server/EntityPillager.java @@ -0,0 +1,263 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.Map; +import javax.annotation.Nullable; + +public class EntityPillager extends EntityIllagerAbstract implements ICrossbow, IRangedEntity { + + private static final DataWatcherObject b = DataWatcher.a(EntityPillager.class, DataWatcherRegistry.i); + private final InventorySubcontainer inventory = new InventorySubcontainer(5); + + public EntityPillager(EntityTypes entitytypes, World world) { + super(entitytypes, world); + } + + @Override + protected void initPathfinder() { + super.initPathfinder(); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, new EntityRaider.a(this, 10.0F)); + this.goalSelector.a(3, new PathfinderGoalCrossbowAttack<>(this, 1.0D, 8.0F)); + this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); + this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 15.0F, 1.0F)); + this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 15.0F)); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); + } + + @Override + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.3499999940395355D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D); + this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(5.0D); + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D); + } + + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityPillager.b, false); + } + + @Override + public void a(boolean flag) { + this.datawatcher.set(EntityPillager.b, flag); + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.inventory.getSize(); ++i) { + ItemStack itemstack = this.inventory.getItem(i); + + if (!itemstack.isEmpty()) { + nbttaglist.add(itemstack.save(new NBTTagCompound())); + } + } + + nbttagcompound.set("Inventory", nbttaglist); + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getList("Inventory", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + ItemStack itemstack = ItemStack.a(nbttaglist.getCompound(i)); + + if (!itemstack.isEmpty()) { + this.inventory.a(itemstack); + } + } + + this.setCanPickupLoot(true); + } + + @Override + public float a(BlockPosition blockposition, IWorldReader iworldreader) { + Block block = iworldreader.getType(blockposition.down()).getBlock(); + + return block != Blocks.GRASS_BLOCK && block != Blocks.SAND ? 0.5F - iworldreader.v(blockposition) : 10.0F; + } + + @Override + public int dC() { + return 1; + } + + @Nullable + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.a(difficultydamagescaler); + this.b(difficultydamagescaler); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + } + + @Override + protected void a(DifficultyDamageScaler difficultydamagescaler) { + ItemStack itemstack = new ItemStack(Items.CROSSBOW); + + if (this.random.nextInt(300) == 0) { + Map map = Maps.newHashMap(); + + map.put(Enchantments.PIERCING, 1); + EnchantmentManager.a((Map) map, itemstack); + } + + this.setSlot(EnumItemSlot.MAINHAND, itemstack); + } + + @Override + public boolean r(Entity entity) { + return super.r(entity) ? true : (entity instanceof EntityLiving && ((EntityLiving) entity).getMonsterType() == EnumMonsterType.ILLAGER ? this.getScoreboardTeam() == null && entity.getScoreboardTeam() == null : false); + } + + @Override + protected SoundEffect getSoundAmbient() { + return SoundEffects.ENTITY_PILLAGER_AMBIENT; + } + + @Override + protected SoundEffect getSoundDeath() { + return SoundEffects.ENTITY_PILLAGER_DEATH; + } + + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return SoundEffects.ENTITY_PILLAGER_HURT; + } + + @Override + public void a(EntityLiving entityliving, float f) { + EnumHand enumhand = ProjectileHelper.a(this, Items.CROSSBOW); + ItemStack itemstack = this.b(enumhand); + + if (this.a(Items.CROSSBOW)) { + ItemCrossbow.a(this.world, this, enumhand, itemstack, 1.6F, (float) (14 - this.world.getDifficulty().a() * 4)); + } + + this.ticksFarFromPlayer = 0; + } + + @Override + public void a(EntityLiving entityliving, ItemStack itemstack, IProjectile iprojectile, float f) { + Entity entity = (Entity) iprojectile; + double d0 = entityliving.locX - this.locX; + double d1 = entityliving.locZ - this.locZ; + double d2 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1); + double d3 = entityliving.getBoundingBox().minY + (double) (entityliving.getHeight() / 3.0F) - entity.locY + d2 * 0.20000000298023224D; + Vector3fa vector3fa = this.a(new Vec3D(d0, d3, d1), f); + + iprojectile.shoot((double) vector3fa.a(), (double) vector3fa.b(), (double) vector3fa.c(), 1.6F, (float) (14 - this.world.getDifficulty().a() * 4)); + this.a(SoundEffects.ITEM_CROSSBOW_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F)); + } + + private Vector3fa a(Vec3D vec3d, float f) { + Vec3D vec3d1 = vec3d.d(); + Vec3D vec3d2 = vec3d1.c(new Vec3D(0.0D, 1.0D, 0.0D)); + + if (vec3d2.g() <= 1.0E-7D) { + vec3d2 = vec3d1.c(this.i(1.0F)); + } + + Quaternion quaternion = new Quaternion(new Vector3fa(vec3d2), 90.0F, true); + Vector3fa vector3fa = new Vector3fa(vec3d1); + + vector3fa.a(quaternion); + Quaternion quaternion1 = new Quaternion(vector3fa, f, true); + Vector3fa vector3fa1 = new Vector3fa(vec3d1); + + vector3fa1.a(quaternion1); + return vector3fa1; + } + + public InventorySubcontainer getInventory() { + return this.inventory; + } + + @Override + protected void a(EntityItem entityitem) { + ItemStack itemstack = entityitem.getItemStack(); + + if (itemstack.getItem() instanceof ItemBanner) { + super.a(entityitem); + } else { + Item item = itemstack.getItem(); + + if (this.b(item)) { + ItemStack itemstack1 = this.inventory.a(itemstack); + + if (itemstack1.isEmpty()) { + entityitem.die(); + } else { + itemstack.setCount(itemstack1.getCount()); + } + } + } + + } + + private boolean b(Item item) { + return this.ek() && item == Items.WHITE_BANNER; + } + + @Override + public boolean a_(int i, ItemStack itemstack) { + if (super.a_(i, itemstack)) { + return true; + } else { + int j = i - 300; + + if (j >= 0 && j < this.inventory.getSize()) { + this.inventory.setItem(j, itemstack); + return true; + } else { + return false; + } + } + } + + @Override + public void a(int i, boolean flag) { + Raid raid = this.ej(); + boolean flag1 = this.random.nextFloat() <= raid.w(); + + if (flag1) { + ItemStack itemstack = new ItemStack(Items.CROSSBOW); + Map map = Maps.newHashMap(); + + if (i > raid.a(EnumDifficulty.NORMAL)) { + map.put(Enchantments.QUICK_CHARGE, 2); + } else if (i > raid.a(EnumDifficulty.EASY)) { + map.put(Enchantments.QUICK_CHARGE, 1); + } + + map.put(Enchantments.MULTISHOT, 1); + EnchantmentManager.a((Map) map, itemstack); + this.setSlot(EnumItemSlot.MAINHAND, itemstack); + } + + } + + @Override + public boolean I() { + return super.I() && this.getInventory().isNotEmpty(); + } + + @Override + public SoundEffect dV() { + return SoundEffects.ENTITY_PILLAGER_CELEBRATE; + } + + @Override + public boolean isTypeNotPersistent(double d0) { + return super.isTypeNotPersistent(d0) && this.getInventory() != null && this.getInventory().isNotEmpty(); // CraftBukkit - null in constructor + } +} diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index d4c847423..fa79d0bed 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -2,13 +2,14 @@ package net.minecraft.server; import com.google.common.collect.Lists; import com.mojang.authlib.GameProfile; -import io.netty.buffer.Unpooled; +import com.mojang.datafixers.util.Either; import io.netty.util.concurrent.Future; import java.util.ArrayDeque; // Paper import java.util.Collection; import java.util.Deque; // Paper import java.util.Iterator; import java.util.List; +import java.util.OptionalInt; import java.util.Random; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; @@ -26,49 +27,51 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.PlayerChangedMainHandEvent; +import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerLocaleChangeEvent; +import org.bukkit.event.player.PlayerPortalEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.inventory.MainHand; // CraftBukkit end public class EntityPlayer extends EntityHuman implements ICrafting { - private static final Logger cc = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public String locale = null; // CraftBukkit - lowercase // Paper - default to null - public long lastSave = MinecraftServer.currentTick; // Paper public PlayerConnection playerConnection; public final MinecraftServer server; public final PlayerInteractManager playerInteractManager; - public double d; - public double e; public final Deque removeQueue = new ArrayDeque<>(); // Paper - private final AdvancementDataPlayer cf; - private final ServerStatisticManager cg; - private float ch = Float.MIN_VALUE; - private int ci = Integer.MIN_VALUE; - private int cj = Integer.MIN_VALUE; - private int ck = Integer.MIN_VALUE; - private int cl = Integer.MIN_VALUE; - private int cm = Integer.MIN_VALUE; + private final AdvancementDataPlayer advancementDataPlayer; + private final ServerStatisticManager serverStatisticManager; + private float lastHealthScored = Float.MIN_VALUE; + private int lastFoodScored = Integer.MIN_VALUE; + private int lastAirScored = Integer.MIN_VALUE; + private int lastArmorScored = Integer.MIN_VALUE; + private int lastExpLevelScored = Integer.MIN_VALUE; + private int lastExpTotalScored = Integer.MIN_VALUE; private float lastHealthSent = -1.0E8F; private int lastFoodSent = -99999999; - private boolean cp = true; + private boolean lastSentSaturationZero = true; public int lastSentExp = -99999999; public int invulnerableTicks = 60; - private EntityHuman.EnumChatVisibility cs; - private boolean ct = true; - private long cu = SystemUtils.getMonotonicMillis(); + private EnumChatVisibility ck; + private boolean cl = true; + private long cm = SystemUtils.getMonotonicMillis(); private Entity spectatedEntity; private void setSpectatorTargetField(Entity e) { this.spectatedEntity = e; } // Paper - OBFHELPER public boolean worldChangeInvuln; - private boolean cx; private void setHasSeenCredits(boolean has) { this.cx = has; } // Paper - OBFHELPER + private boolean cp; private void setHasSeenCredits(boolean has) { this.cp = has; } // Paper - OBFHELPER private final RecipeBookServer recipeBook; - private Vec3D cz; - private int cA; - private boolean cB; - private Vec3D cC; + private Vec3D cr; + private int cs; + private boolean ct; + @Nullable + private Vec3D cu; + private SectionPosition cv = SectionPosition.a(0, 0, 0); private int containerCounter; - public boolean f; + public boolean e; public int ping; public boolean viewingCredits; private int containerUpdateDelay; // Paper @@ -77,6 +80,11 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public boolean queueHealthUpdatePacket = false; public net.minecraft.server.PacketPlayOutUpdateHealth queuedHealthUpdatePacket; // Paper end + // Paper start - mob spawning rework + public static final int ENUMCREATURETYPE_TOTAL_ENUMS = EnumCreatureType.values().length; + public final int[] mobCounts = new int[ENUMCREATURETYPE_TOTAL_ENUMS]; // Paper + public final com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet cachedSingleMobDistanceMap; + // Paper end // CraftBukkit start public String displayName; @@ -98,15 +106,16 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.playerInteractManager = playerinteractmanager; this.server = minecraftserver; this.recipeBook = new RecipeBookServer(minecraftserver.getCraftingManager()); - this.cg = minecraftserver.getPlayerList().getStatisticManager(this); - this.cf = minecraftserver.getPlayerList().h(this); - this.Q = 1.0F; + this.serverStatisticManager = minecraftserver.getPlayerList().getStatisticManager(this); + this.advancementDataPlayer = minecraftserver.getPlayerList().f(this); + this.K = 1.0F; this.a(worldserver); // CraftBukkit start this.displayName = this.getName(); this.canPickUpLoot = true; this.maxHealthCache = this.getMaxHealth(); + this.cachedSingleMobDistanceMap = new com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper } // Yes, this doesn't match Vanilla, but it's the best we can do for now. @@ -127,14 +136,14 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } int k = (i * 2 + 1) * (i * 2 + 1); - int l = this.r(k); + int l = this.t(k); int i1 = (new Random()).nextInt(k); for (int j1 = 0; j1 < k; ++j1) { int k1 = (i1 + l * j1) % k; int l1 = k1 % (i * 2 + 1); int i2 = k1 / (i * 2 + 1); - BlockPosition blockposition1 = worldserver.o().a(blockposition.getX() + l1 - i, blockposition.getZ() + i2 - i, false); + BlockPosition blockposition1 = worldserver.getWorldProvider().a(blockposition.getX() + l1 - i, blockposition.getZ() + i2 - i, false); if (blockposition1 != null) { return blockposition1; @@ -161,19 +170,21 @@ public class EntityPlayer extends EntityHuman implements ICrafting { i = 1; } - int k = (i * 2 + 1) * (i * 2 + 1); - int l = this.r(k); - int i1 = (new Random()).nextInt(k); + long k = (long) (i * 2 + 1); + long l = k * k; + int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l; + int j1 = this.t(i1); + int k1 = (new Random()).nextInt(i1); - for (int j1 = 0; j1 < k; ++j1) { - int k1 = (i1 + l * j1) % k; - int l1 = k1 % (i * 2 + 1); - int i2 = k1 / (i * 2 + 1); - BlockPosition blockposition1 = worldserver.o().a(blockposition.getX() + l1 - i, blockposition.getZ() + i2 - i, false); + for (int l1 = 0; l1 < i1; ++l1) { + int i2 = (k1 + j1 * l1) % i1; + int j2 = i2 % (i * 2 + 1); + int k2 = i2 / (i * 2 + 1); + BlockPosition blockposition1 = worldserver.getWorldProvider().a(blockposition.getX() + j2 - i, blockposition.getZ() + k2 - i, false); if (blockposition1 != null) { this.setPositionRotation(blockposition1, 0.0F, 0.0F); - if (worldserver.getCubes(this, this.getBoundingBox())) { + if (worldserver.getCubes(this)) { break; } } @@ -181,23 +192,24 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } else { this.setPositionRotation(blockposition, 0.0F, 0.0F); - while (!worldserver.getCubes(this, this.getBoundingBox()) && this.locY < 255.0D) { + while (!worldserver.getCubes(this) && this.locY < 255.0D) { this.setPosition(this.locX, this.locY + 1.0D, this.locZ); } } } - private int r(int i) { + private int t(int i) { return i <= 16 ? i - 1 : 17; } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (this.locY > 300) this.locY = 257; // Paper - bring down to a saner Y level if out of world if (nbttagcompound.hasKeyOfType("playerGameType", 99)) { - if (this.bK().getForceGamemode()) { - this.playerInteractManager.setGameMode(this.bK().getGamemode()); + if (this.getMinecraftServer().getForceGamemode()) { + this.playerInteractManager.setGameMode(this.getMinecraftServer().getGamemode()); } else { this.playerInteractManager.setGameMode(EnumGamemode.getById(nbttagcompound.getInt("playerGameType"))); } @@ -206,27 +218,32 @@ public class EntityPlayer extends EntityHuman implements ICrafting { if (nbttagcompound.hasKeyOfType("enteredNetherPosition", 10)) { NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("enteredNetherPosition"); - this.cC = new Vec3D(nbttagcompound1.getDouble("x"), nbttagcompound1.getDouble("y"), nbttagcompound1.getDouble("z")); + this.cu = new Vec3D(nbttagcompound1.getDouble("x"), nbttagcompound1.getDouble("y"), nbttagcompound1.getDouble("z")); } - this.cx = nbttagcompound.getBoolean("seenCredits"); + this.cp = nbttagcompound.getBoolean("seenCredits"); if (nbttagcompound.hasKeyOfType("recipeBook", 10)) { this.recipeBook.a(nbttagcompound.getCompound("recipeBook")); } this.getBukkitEntity().readExtraData(nbttagcompound); // CraftBukkit + if (this.isSleeping()) { + this.dy(); + } + } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setInt("playerGameType", this.playerInteractManager.getGameMode().getId()); - nbttagcompound.setBoolean("seenCredits", this.cx); - if (this.cC != null) { + nbttagcompound.setBoolean("seenCredits", this.cp); + if (this.cu != null) { NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - nbttagcompound1.setDouble("x", this.cC.x); - nbttagcompound1.setDouble("y", this.cC.y); - nbttagcompound1.setDouble("z", this.cC.z); + nbttagcompound1.setDouble("x", this.cu.x); + nbttagcompound1.setDouble("y", this.cu.y); + nbttagcompound1.setDouble("z", this.cu.z); nbttagcompound.set("enteredNetherPosition", nbttagcompound1); } @@ -245,7 +262,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } } - if (persistVehicle && entity1 != null && entity != this && entity.bR()) { + if (persistVehicle && entity1 != null && entity != this && entity.hasSinglePlayerPassenger()) { // CraftBukkit end NBTTagCompound nbttagcompound2 = new NBTTagCompound(); NBTTagCompound nbttagcompound3 = new NBTTagCompound(); @@ -256,7 +273,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { nbttagcompound.set("RootVehicle", nbttagcompound2); } - nbttagcompound.set("recipeBook", this.recipeBook.e()); + nbttagcompound.set("recipeBook", this.recipeBook.save()); this.getBukkitEntity().setExtraData(nbttagcompound); // CraftBukkit } @@ -265,22 +282,22 @@ public class EntityPlayer extends EntityHuman implements ICrafting { super.spawnIn(world); if (world == null) { this.dead = false; - BlockPosition position = null; + Vec3D position = null; if (this.spawnWorld != null && !this.spawnWorld.equals("")) { CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(this.spawnWorld); if (cworld != null && this.getBed() != null) { world = cworld.getHandle(); - position = EntityHuman.getBed(cworld.getHandle(), this.getBed(), false); + position = EntityHuman.getBed(cworld.getHandle(), this.getBed(), false).orElse(null); } } if (world == null || position == null) { world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(); - position = world.getSpawn(); + position = new Vec3D(world.getSpawn()); } this.world = world; - this.setPosition(position.getX() + 0.5, position.getY(), position.getZ() + 0.5); + this.setPosition(position.getX(), position.getY(), position.getZ()); } - this.dimension = ((WorldServer) this.world).dimension; + this.dimension = ((WorldServer) this.world).getWorldProvider().getDimensionManager(); this.playerInteractManager.a((WorldServer) world); } // CraftBukkit end @@ -298,11 +315,13 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.lastSentExp = -1; } + @Override public void levelDown(int i) { super.levelDown(i); this.lastSentExp = -1; } + @Override public void enchantDone(ItemStack itemstack, int i) { super.enchantDone(itemstack, i); this.lastSentExp = -1; @@ -312,24 +331,29 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.activeContainer.addSlotListener(this); } + @Override public void enterCombat() { super.enterCombat(); this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTER_COMBAT)); } + @Override public void exitCombat() { super.exitCombat(); this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.END_COMBAT)); } + @Override protected void a(IBlockData iblockdata) { CriterionTriggers.d.a(this, iblockdata); } + @Override protected ItemCooldown g() { return new ItemCooldownPlayer(this); } + @Override public void tick() { // CraftBukkit start if (this.joining) { @@ -344,7 +368,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { // Paper start - Configurable container update tick rate if (--containerUpdateDelay <= 0) { - this.activeContainer.b(); + this.activeContainer.c(); containerUpdateDelay = world.paperConfig.containerUpdateTickRate; } // Paper end @@ -379,7 +403,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { if (entity != this) { if (entity.isAlive()) { this.setLocation(entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch); - this.server.getPlayerList().updateChunks(this); + this.getWorldServer().getChunkProvider().movePlayer(this); if (this.isSneaking()) { this.setSpectatorTarget(this); } @@ -389,21 +413,23 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } CriterionTriggers.w.a(this); - if (this.cz != null) { - CriterionTriggers.u.a(this, this.cz, this.ticksLived - this.cA); + if (this.cr != null) { + CriterionTriggers.u.a(this, this.cr, this.ticksLived - this.cs); } - this.cf.b(this); + this.advancementDataPlayer.b(this); } public void playerTick() { try { - super.tick(); + if (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this))) { + super.tick(); + } for (int i = 0; i < this.inventory.getSize(); ++i) { ItemStack itemstack = this.inventory.getItem(i); - if (itemstack.getItem().W_()) { + if (itemstack.getItem().O_()) { Packet packet = ((ItemWorldMapBase) itemstack.getItem()).a(itemstack, this.world, (EntityHuman) this); if (packet != null) { @@ -412,36 +438,36 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } } - if (this.getHealth() != this.lastHealthSent || this.lastFoodSent != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.cp) { + if (this.getHealth() != this.lastHealthSent || this.lastFoodSent != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.lastSentSaturationZero) { this.playerConnection.sendPacket(new PacketPlayOutUpdateHealth(this.getBukkitEntity().getScaledHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel())); // CraftBukkit this.lastHealthSent = this.getHealth(); this.lastFoodSent = this.foodData.getFoodLevel(); - this.cp = this.foodData.getSaturationLevel() == 0.0F; + this.lastSentSaturationZero = this.foodData.getSaturationLevel() == 0.0F; } - if (this.getHealth() + this.getAbsorptionHearts() != this.ch) { - this.ch = this.getHealth() + this.getAbsorptionHearts(); - this.a(IScoreboardCriteria.HEALTH, MathHelper.f(this.ch)); + if (this.getHealth() + this.getAbsorptionHearts() != this.lastHealthScored) { + this.lastHealthScored = this.getHealth() + this.getAbsorptionHearts(); + this.a(IScoreboardCriteria.HEALTH, MathHelper.f(this.lastHealthScored)); } - if (this.foodData.getFoodLevel() != this.ci) { - this.ci = this.foodData.getFoodLevel(); - this.a(IScoreboardCriteria.FOOD, MathHelper.f((float) this.ci)); + if (this.foodData.getFoodLevel() != this.lastFoodScored) { + this.lastFoodScored = this.foodData.getFoodLevel(); + this.a(IScoreboardCriteria.FOOD, MathHelper.f((float) this.lastFoodScored)); } - if (this.getAirTicks() != this.cj) { - this.cj = this.getAirTicks(); - this.a(IScoreboardCriteria.AIR, MathHelper.f((float) this.cj)); + if (this.getAirTicks() != this.lastAirScored) { + this.lastAirScored = this.getAirTicks(); + this.a(IScoreboardCriteria.AIR, MathHelper.f((float) this.lastAirScored)); } - if (this.getArmorStrength() != this.ck) { - this.ck = this.getArmorStrength(); - this.a(IScoreboardCriteria.ARMOR, MathHelper.f((float) this.ck)); + if (this.getArmorStrength() != this.lastArmorScored) { + this.lastArmorScored = this.getArmorStrength(); + this.a(IScoreboardCriteria.ARMOR, MathHelper.f((float) this.lastArmorScored)); } - if (this.expTotal != this.cm) { - this.cm = this.expTotal; - this.a(IScoreboardCriteria.XP, MathHelper.f((float) this.cm)); + if (this.expTotal != this.lastExpTotalScored) { + this.lastExpTotalScored = this.expTotal; + this.a(IScoreboardCriteria.XP, MathHelper.f((float) this.lastExpTotalScored)); } // CraftBukkit start - Force max health updates @@ -450,9 +476,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } // CraftBukkit end - if (this.expLevel != this.cl) { - this.cl = this.expLevel; - this.a(IScoreboardCriteria.LEVEL, MathHelper.f((float) this.cl)); + if (this.expLevel != this.lastExpLevelScored) { + this.lastExpLevelScored = this.expLevel; + this.a(IScoreboardCriteria.LEVEL, MathHelper.f((float) this.lastExpLevelScored)); } if (this.expTotal != this.lastSentExp) { @@ -530,14 +556,15 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } // Paper end + @Override public void die(DamageSource damagesource) { - boolean flag = this.world.getGameRules().getBoolean("showDeathMessages"); + boolean flag = this.world.getGameRules().getBoolean(GameRules.SHOW_DEATH_MESSAGES); // CraftBukkit start - fire PlayerDeathEvent if (this.dead) { return; } java.util.List loot = new java.util.ArrayList(this.inventory.getSize()); - boolean keepInventory = this.world.getGameRules().getBoolean("keepInventory") || this.isSpectator(); + boolean keepInventory = this.world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY) || this.isSpectator(); if (!keepInventory) { for (ItemStack item : this.inventory.getContents()) { @@ -546,6 +573,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } } } + // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule) + this.a(damagesource, this.lastDamageByPlayerTime > 0); + for (org.bukkit.inventory.ItemStack item : this.drops) { + loot.add(item); + } + this.drops.clear(); // SPIGOT-5188: make sure to clear IChatBaseComponent defaultMessage = this.getCombatTracker().getDeathMessage(); @@ -563,7 +596,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { // SPIGOT-943 - only call if they have an inventory open if (this.activeContainer != this.defaultContainer) { - this.closeInventory(); + this.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper } String deathMessage = event.getDeathMessage(); @@ -580,8 +613,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting { if (!future.isSuccess()) { boolean flag1 = true; String s = ichatbasecomponent.a(256); - ChatMessage chatmessage = new ChatMessage("death.attack.message_too_long", new Object[] { (new ChatComponentText(s)).a(EnumChatFormat.YELLOW)}); - IChatBaseComponent ichatbasecomponent1 = (new ChatMessage("death.attack.even_more_magic", new Object[] { this.getScoreboardDisplayName()})).a((chatmodifier) -> { + ChatMessage chatmessage = new ChatMessage("death.attack.message_too_long", new Object[]{(new ChatComponentText(s)).a(EnumChatFormat.YELLOW)}); + IChatBaseComponent ichatbasecomponent1 = (new ChatMessage("death.attack.even_more_magic", new Object[]{this.getScoreboardDisplayName()})).a((chatmodifier) -> { chatmodifier.setChatHoverable(new ChatHoverable(ChatHoverable.EnumHoverAction.SHOW_TEXT, chatmessage)); }); @@ -595,7 +628,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { if (scoreboardteambase.getDeathMessageVisibility() == ScoreboardTeamBase.EnumNameTagVisibility.HIDE_FOR_OTHER_TEAMS) { this.server.getPlayerList().a((EntityHuman) this, ichatbasecomponent); } else if (scoreboardteambase.getDeathMessageVisibility() == ScoreboardTeamBase.EnumNameTagVisibility.HIDE_FOR_OWN_TEAM) { - this.server.getPlayerList().b((EntityHuman) this, ichatbasecomponent); + this.server.getPlayerList().b(this, ichatbasecomponent); } } else { this.server.getPlayerList().sendMessage(ichatbasecomponent); @@ -615,17 +648,35 @@ public class EntityPlayer extends EntityHuman implements ICrafting { // Paper end } - this.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper this.setSpectatorTarget(this); // Remove spectated target // CraftBukkit end // CraftBukkit - Get our scores instead this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.DEATH_COUNT, this.getName(), ScoreboardScore::incrementScore); - EntityLiving entityliving = this.cv(); + EntityLiving entityliving = this.getKillingEntity(); if (entityliving != null) { - this.b(StatisticList.ENTITY_KILLED_BY.b(entityliving.P())); - entityliving.a(this, this.be, damagesource); + this.b(StatisticList.ENTITY_KILLED_BY.b(entityliving.getEntityType())); + entityliving.a(this, this.aY, damagesource); + if (!this.world.isClientSide && entityliving instanceof EntityWither) { + boolean flag1 = false; + + if (this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { + BlockPosition blockposition = new BlockPosition(this.locX, this.locY, this.locZ); + IBlockData iblockdata = Blocks.WITHER_ROSE.getBlockData(); + + if (this.world.getType(blockposition).isAir() && iblockdata.canPlace(this.world, blockposition)) { + this.world.setTypeAndData(blockposition, iblockdata, 3); + flag1 = true; + } + } + + if (!flag1) { + EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY, this.locZ, new ItemStack(Items.bg)); + + this.world.addEntity(entityitem); + } + } } this.a(StatisticList.DEATHS); @@ -636,6 +687,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.getCombatTracker().g(); } + @Override public void a(Entity entity, int i, DamageSource damagesource) { if (entity != this) { super.a(entity, i, damagesource); @@ -673,11 +725,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; } else { - boolean flag = this.server.Q() && this.canPvP() && "fall".equals(damagesource.translationIndex); + boolean flag = this.server.S() && this.canPvP() && "fall".equals(damagesource.translationIndex); if (!flag && this.invulnerableTicks > 0 && damagesource != DamageSource.OUT_OF_WORLD) { return false; @@ -713,6 +766,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } } + @Override public boolean a(EntityHuman entityhuman) { return !this.canPvP() ? false : super.a(entityhuman); } @@ -723,43 +777,216 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } @Nullable + @Override public Entity a(DimensionManager dimensionmanager) { + // CraftBukkit start + return a(dimensionmanager, TeleportCause.UNKNOWN); + } + + @Nullable + public Entity a(DimensionManager dimensionmanager, PlayerTeleportEvent.TeleportCause cause) { + // CraftBukkit end if (this.isSleeping()) return this; // CraftBukkit - SPIGOT-3154 // this.worldChangeInvuln = true; // CraftBukkit - Moved down and into PlayerList#changeDimension - if (this.dimension == DimensionManager.OVERWORLD && dimensionmanager == DimensionManager.NETHER) { - this.cC = new Vec3D(this.locX, this.locY, this.locZ); - } else if (this.dimension != DimensionManager.NETHER && dimensionmanager != DimensionManager.OVERWORLD) { - this.cC = null; - } + DimensionManager dimensionmanager1 = this.dimension; - if (this.dimension == DimensionManager.THE_END && dimensionmanager == DimensionManager.THE_END) { + if (dimensionmanager1.getType() == DimensionManager.THE_END && dimensionmanager.getType() == DimensionManager.OVERWORLD) { // CraftBukkit - getType() this.worldChangeInvuln = true; // CraftBukkit - Moved down from above - this.world.kill(this); + this.decouple(); + this.getWorldServer().removePlayer(this); if (!this.viewingCredits) { this.viewingCredits = true; if (world.paperConfig.disableEndCredits) this.setHasSeenCredits(true); // Paper - Toggle to always disable end credits - this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(4, this.cx ? 0.0F : 1.0F)); - this.cx = true; + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(4, this.cp ? 0.0F : 1.0F)); + this.cp = true; } return this; } else { - if (this.dimension == DimensionManager.OVERWORLD && dimensionmanager == DimensionManager.THE_END) { - dimensionmanager = DimensionManager.THE_END; + WorldServer worldserver = this.server.getWorldServer(dimensionmanager1); + + // this.dimension = dimensionmanager; // CraftBukkit + WorldServer worldserver1 = this.server.getWorldServer(dimensionmanager); + WorldData worlddata = this.world.getWorldData(); + + // CraftBukkit start + /* + this.playerConnection.sendPacket(new PacketPlayOutRespawn(dimensionmanager, worlddata.getType(), this.playerInteractManager.getGameMode())); + this.playerConnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); + PlayerList playerlist = this.server.getPlayerList(); + + playerlist.d(this); + worldserver.removePlayer(this); + this.dead = false; + */ + // CraftBukkit end + double d0 = this.locX; + double d1 = this.locY; + double d2 = this.locZ; + float f = this.pitch; + float f1 = this.yaw; + double d3 = 8.0D; + float f2 = f1; + + worldserver.getMethodProfiler().enter("moving"); + if (worldserver1 == null) { } else // CraftBukkit - empty to fall through to null to event + if (dimensionmanager1 == DimensionManager.OVERWORLD && dimensionmanager == DimensionManager.NETHER) { + this.cu = new Vec3D(this.locX, this.locY, this.locZ); + d0 /= 8.0D; + d2 /= 8.0D; + } else if (dimensionmanager1 == DimensionManager.NETHER && dimensionmanager == DimensionManager.OVERWORLD) { + d0 *= 8.0D; + d2 *= 8.0D; + } else if (dimensionmanager1 == DimensionManager.OVERWORLD && dimensionmanager == DimensionManager.THE_END) { + BlockPosition blockposition = worldserver1.getDimensionSpawn(); + + d0 = (double) blockposition.getX(); + d1 = (double) blockposition.getY(); + d2 = (double) blockposition.getZ(); + f1 = 90.0F; + f = 0.0F; } // CraftBukkit start - TeleportCause cause = (this.dimension == DimensionManager.THE_END || dimensionmanager == DimensionManager.THE_END) ? TeleportCause.END_PORTAL : TeleportCause.NETHER_PORTAL; - this.server.getPlayerList().changeDimension(this, dimensionmanager, cause); // PAIL: check all this + Location enter = this.getBukkitEntity().getLocation(); + Location exit = (worldserver1 == null) ? null : new Location(worldserver1.getWorld(), d0, d1, d2, f1, f); + PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled() || event.getTo() == null) { + return null; + } + + exit = event.getTo(); + if (exit == null) { + return null; + } + + PlayerTeleportEvent tpEvent = new PlayerTeleportEvent(this.getBukkitEntity(), enter, exit, cause); + Bukkit.getServer().getPluginManager().callEvent(tpEvent); + if (tpEvent.isCancelled() || tpEvent.getTo() == null) { + return null; + } + + exit = tpEvent.getTo(); + if (exit == null) { + return null; + } + worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); + d0 = exit.getX(); + d1 = exit.getY(); + d2 = exit.getZ(); + f1 = exit.getYaw(); + f = exit.getPitch(); + this.worldChangeInvuln = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds + dimensionmanager = worldserver1.getWorldProvider().getDimensionManager(); // CraftBukkit end + + // CraftBukkit start + this.dimension = dimensionmanager; + + this.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver1.worldProvider.getDimensionManager().getType(), this.world.getWorldData().getType(), this.playerInteractManager.getGameMode())); + this.playerConnection.sendPacket(new PacketPlayOutServerDifficulty(this.world.getDifficulty(), this.world.getWorldData().isDifficultyLocked())); + PlayerList playerlist = this.server.getPlayerList(); + + playerlist.d(this); + worldserver.removePlayer(this); + this.dead = false; + // CraftBukkit end + + this.setPositionRotation(d0, d1, d2, f1, f); + worldserver.getMethodProfiler().exit(); + worldserver.getMethodProfiler().enter("placing"); + double d4 = Math.min(-2.9999872E7D, worldserver1.getWorldBorder().c() + 16.0D); + double d5 = Math.min(-2.9999872E7D, worldserver1.getWorldBorder().d() + 16.0D); + double d6 = Math.min(2.9999872E7D, worldserver1.getWorldBorder().e() - 16.0D); + double d7 = Math.min(2.9999872E7D, worldserver1.getWorldBorder().f() - 16.0D); + + d0 = MathHelper.a(d0, d4, d6); + d2 = MathHelper.a(d2, d5, d7); + this.setPositionRotation(d0, d1, d2, f1, f); + if (dimensionmanager.getType() == DimensionManager.THE_END) { // CraftBukkit - getType() + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY) - 1; + int k = MathHelper.floor(this.locZ); + boolean flag = true; + boolean flag1 = false; + org.bukkit.craftbukkit.util.BlockStateListPopulator blockList = new org.bukkit.craftbukkit.util.BlockStateListPopulator(worldserver1); // CraftBukkit - Use BlockStateListPopulator + + for (int l = -2; l <= 2; ++l) { + for (int i1 = -2; i1 <= 2; ++i1) { + for (int j1 = -1; j1 < 3; ++j1) { + int k1 = i + i1 * 1 + l * 0; + int l1 = j + j1; + int i2 = k + i1 * 0 - l * 1; + boolean flag2 = j1 < 0; + + blockList.setTypeAndData(new BlockPosition(k1, l1, i2), flag2 ? Blocks.OBSIDIAN.getBlockData() : Blocks.AIR.getBlockData(), 3); // CraftBukkit + } + } + } + + // CraftBukkit start + org.bukkit.World bworld = worldserver1.getWorld(); + org.bukkit.event.world.PortalCreateEvent portalEvent = new org.bukkit.event.world.PortalCreateEvent((List) (List) blockList.getList(), bworld, this.getBukkitEntity(), org.bukkit.event.world.PortalCreateEvent.CreateReason.END_PLATFORM); + + this.world.getServer().getPluginManager().callEvent(portalEvent); + if (!portalEvent.isCancelled()) { + blockList.updateList(); + } + // CraftBukkit end + this.setPositionRotation((double) i, (double) j, (double) k, f1, 0.0F); + this.setMot(Vec3D.a); + } else if (!worldserver1.getTravelAgent().a(this, f2)) { + worldserver1.getTravelAgent().a((Entity) this); + worldserver1.getTravelAgent().a(this, f2); + } + + worldserver.getMethodProfiler().exit(); + this.spawnIn(worldserver1); + worldserver1.addPlayerPortal(this); + this.b(worldserver); + this.playerConnection.a(this.locX, this.locY, this.locZ, f1, f); + this.playerInteractManager.a(worldserver1); + this.playerConnection.sendPacket(new PacketPlayOutAbilities(this.abilities)); + playerlist.a(this, worldserver1); + playerlist.updateClient(this); + Iterator iterator = this.getEffects().iterator(); + + while (iterator.hasNext()) { + MobEffect mobeffect = (MobEffect) iterator.next(); + + this.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.getId(), mobeffect)); + } + this.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1032, BlockPosition.ZERO, 0, false)); this.lastSentExp = -1; this.lastHealthSent = -1.0F; this.lastFoodSent = -1; + + // CraftBukkit start + PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver.getWorld()); + this.world.getServer().getPluginManager().callEvent(changeEvent); + // CraftBukkit end return this; } } + public void b(WorldServer worldserver) { // PAIL + DimensionManager dimensionmanager = worldserver.worldProvider.getDimensionManager(); + DimensionManager dimensionmanager1 = this.world.worldProvider.getDimensionManager(); + + CriterionTriggers.v.a(this, dimensionmanager, dimensionmanager1); + if (dimensionmanager == DimensionManager.NETHER && dimensionmanager1 == DimensionManager.OVERWORLD && this.cu != null) { + CriterionTriggers.C.a(this, this.cu); + } + + if (dimensionmanager1 != DimensionManager.NETHER) { + this.cu = null; + } + + } + + @Override public boolean a(EntityPlayer entityplayer) { return entityplayer.isSpectator() ? this.getSpecatorTarget() == this : (this.isSpectator() ? false : super.a(entityplayer)); } @@ -775,46 +1002,42 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } + @Override public void receive(Entity entity, int i) { super.receive(entity, i); - this.activeContainer.b(); + this.activeContainer.c(); } - public EntityHuman.EnumBedResult a(BlockPosition blockposition) { + @Override + public Either sleep(BlockPosition blockposition) { // CraftBukkit start - add force parameter - return this.a(blockposition, false); + return this.sleep(blockposition, false); } - public EntityHuman.EnumBedResult a(BlockPosition blockposition, boolean force) { - EntityHuman.EnumBedResult entityhuman_enumbedresult = super.a(blockposition, force); + @Override + public Either sleep(BlockPosition blockposition, boolean force) { // CraftBukkit end - - if (entityhuman_enumbedresult == EntityHuman.EnumBedResult.OK) { + return super.sleep(blockposition, force).ifRight((unit) -> { this.a(StatisticList.SLEEP_IN_BED); - Packet packet = new PacketPlayOutBed(this, blockposition); - - this.getWorldServer().getTracker().a((Entity) this, (Packet) packet); - this.playerConnection.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); - this.playerConnection.sendPacket(packet); CriterionTriggers.q.a(this); - } - - return entityhuman_enumbedresult; + }); } - public void a(boolean flag, boolean flag1, boolean flag2) { - if (!this.sleeping) return; // CraftBukkit - Can't leave bed if not in one! + @Override + public void wakeup(boolean flag, boolean flag1, boolean flag2) { + if (!this.isSleeping()) return; // CraftBukkit - Can't leave bed if not in one! if (this.isSleeping()) { - this.getWorldServer().getTracker().sendPacketToEntity(this, new PacketPlayOutAnimation(this, 2)); + this.getWorldServer().getChunkProvider().broadcastIncludingSelf(this, new PacketPlayOutAnimation(this, 2)); } - super.a(flag, flag1, flag2); + super.wakeup(flag, flag1, flag2); if (this.playerConnection != null) { this.playerConnection.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); } } + @Override public boolean a(Entity entity, boolean flag) { Entity entity1 = this.getVehicle(); @@ -832,9 +1055,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } // Paper start - public void stopRiding() { stopRiding(false); } - public void stopRiding(boolean suppressCancellation) { - // paper end + @Override public void stopRiding() { stopRiding(false); } + @Override public void stopRiding(boolean suppressCancellation) { + // paper end Entity entity = this.getVehicle(); super.stopRiding(suppressCancellation); // Paper @@ -845,20 +1068,24 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } // Paper start - "Fixes" an issue in which the vehicle player would not be notified that the passenger dismounted if (entity instanceof EntityPlayer) { + // TODO verify this solution WorldServer worldServer = (WorldServer) entity.getWorld(); - worldServer.tracker.untrackEntity(this); - worldServer.tracker.track(this); + worldServer.getChunkProvider().playerChunkMap.removeEntity(this); + worldServer.getChunkProvider().playerChunkMap.addEntity(this); } // Paper end } + @Override public boolean isInvulnerable(DamageSource damagesource) { - return super.isInvulnerable(damagesource) || this.H(); + return super.isInvulnerable(damagesource) || this.H() || this.abilities.isInvulnerable && damagesource == DamageSource.WITHER; } + @Override protected void a(double d0, boolean flag, IBlockData iblockdata, BlockPosition blockposition) {} + @Override protected void b(BlockPosition blockposition) { if (!this.isSpectator()) { super.b(blockposition); @@ -871,24 +1098,27 @@ public class EntityPlayer extends EntityHuman implements ICrafting { int j = MathHelper.floor(this.locY - 0.20000000298023224D); int k = MathHelper.floor(this.locZ); BlockPosition blockposition = new BlockPosition(i, j, k); - IBlockData iblockdata = this.world.getType(blockposition); - if (iblockdata.isAir()) { - BlockPosition blockposition1 = blockposition.down(); - IBlockData iblockdata1 = this.world.getType(blockposition1); - Block block = iblockdata1.getBlock(); + if (this.world.isLoaded(blockposition)) { + IBlockData iblockdata = this.world.getType(blockposition); - if (block instanceof BlockFence || block instanceof BlockCobbleWall || block instanceof BlockFenceGate) { - blockposition = blockposition1; - iblockdata = iblockdata1; + if (iblockdata.isAir()) { + BlockPosition blockposition1 = blockposition.down(); + IBlockData iblockdata1 = this.world.getType(blockposition1); + Block block = iblockdata1.getBlock(); + + if (block.a(TagsBlock.FENCES) || block.a(TagsBlock.WALLS) || block instanceof BlockFenceGate) { + blockposition = blockposition1; + iblockdata = iblockdata1; + } } - } - super.a(d0, flag, iblockdata, blockposition); + super.a(d0, flag, iblockdata, blockposition); + } } + @Override public void openSign(TileEntitySign tileentitysign) { - if (tileentitysign == null) return; // Akarin - fixes a NPE tileentitysign.a((EntityHuman) this); this.playerConnection.sendPacket(new PacketPlayOutOpenSignEditor(tileentitysign.getPosition())); } @@ -898,121 +1128,66 @@ public class EntityPlayer extends EntityHuman implements ICrafting { return containerCounter; // CraftBukkit } - public void openTileEntity(ITileEntityContainer itileentitycontainer) { - // CraftBukkit start - Inventory open hook - if (false && itileentitycontainer instanceof ILootable && ((ILootable) itileentitycontainer).getLootTable() != null && this.isSpectator()) { - this.a((new ChatMessage("container.spectatorCantOpen", new Object[0])).a(EnumChatFormat.RED), true); - } else { - boolean cancelled = itileentitycontainer instanceof ILootable && ((ILootable) itileentitycontainer).getLootTable()!= null && this.isSpectator(); - Container container = CraftEventFactory.callInventoryOpenEvent(this, itileentitycontainer.createContainer(this.inventory, this), cancelled); - if (container == null) { - return; - } - this.nextContainerCounter(); - this.activeContainer = container; - this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, itileentitycontainer.getContainerName(), itileentitycontainer.getScoreboardDisplayName())); - // CraftBukkit end - this.activeContainer.windowId = this.containerCounter; - this.activeContainer.addSlotListener(this); - } - } - - public void openContainer(IInventory iinventory) { - // CraftBukkit start - Inventory open hook - // Copied from below - boolean cancelled = false; - if (iinventory instanceof ITileInventory) { - ITileInventory itileinventory = (ITileInventory) iinventory; - cancelled = itileinventory.isLocked() && !this.a(itileinventory.getLock()) && !this.isSpectator(); - } - - Container container; - if (iinventory instanceof ITileEntityContainer) { - if (iinventory instanceof TileEntity) { - Preconditions.checkArgument(((TileEntity) iinventory).getWorld() != null, "Container must have world to be opened"); - } - container = ((ITileEntityContainer) iinventory).createContainer(this.inventory, this); - } else { - container = new ContainerChest(this.inventory, iinventory, this); - } - container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled); - if (container == null && !cancelled) { // Let pre-cancelled events fall through - iinventory.closeContainer(this); - return; - } - // CraftBukkit end - - if (iinventory instanceof ILootable && ((ILootable) iinventory).getLootTable() != null && this.isSpectator()) { - this.a((new ChatMessage("container.spectatorCantOpen", new Object[0])).a(EnumChatFormat.RED), true); + @Override + public OptionalInt openContainer(@Nullable ITileInventory itileinventory) { + if (itileinventory == null) { + return OptionalInt.empty(); } else { if (this.activeContainer != this.defaultContainer) { this.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper } - if (iinventory instanceof ITileInventory) { - ITileInventory itileinventory = (ITileInventory) iinventory; + this.nextContainerCounter(); + Container container = itileinventory.createMenu(this.containerCounter, this.inventory, this); - if (itileinventory.isLocked() && !this.a(itileinventory.getLock()) && !this.isSpectator()) { - this.playerConnection.sendPacket(new PacketPlayOutChat(new ChatMessage("container.isLocked", new Object[] { iinventory.getScoreboardDisplayName()}), ChatMessageType.GAME_INFO)); - this.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(SoundEffects.BLOCK_CHEST_LOCKED, SoundCategory.BLOCKS, this.locX, this.locY, this.locZ, 1.0F, 1.0F)); - iinventory.closeContainer(this); // CraftBukkit - return; + // CraftBukkit start - Inventory open hook + if (container != null) { + container.setTitle(itileinventory.getScoreboardDisplayName()); + + boolean cancelled = false; + container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled); + if (container == null && !cancelled) { // Let pre-cancelled events fall through + // SPIGOT-5263 - close chest if cancelled + if (itileinventory instanceof IInventory) { + ((IInventory) itileinventory).closeContainer(this); + } else if (itileinventory instanceof BlockChest.DoubleInventory) { + // SPIGOT-5355 - double chests too :( + ((BlockChest.DoubleInventory) itileinventory).inventorylargechest.closeContainer(this); + } + return OptionalInt.empty(); } } - - this.nextContainerCounter(); - // CraftBukkit start - if (iinventory instanceof ITileEntityContainer) { - this.activeContainer = container; - this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, ((ITileEntityContainer) iinventory).getContainerName(), iinventory.getScoreboardDisplayName(), iinventory.getSize())); - } else { - this.activeContainer = container; - this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "minecraft:container", iinventory.getScoreboardDisplayName(), iinventory.getSize())); - } // CraftBukkit end + if (container == null) { + if (this.isSpectator()) { + this.a((new ChatMessage("container.spectatorCantOpen", new Object[0])).a(EnumChatFormat.RED), true); + } - this.activeContainer.windowId = this.containerCounter; - this.activeContainer.addSlotListener(this); + return OptionalInt.empty(); + } else { + // CraftBukkit start + this.activeContainer = container; + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), container.getTitle())); + // CraftBukkit end + container.addSlotListener(this); + return OptionalInt.of(this.containerCounter); + } } } - public void openTrade(IMerchant imerchant) { - // CraftBukkit start - Inventory open hook - Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerMerchant(this.inventory, imerchant, this.world)); - if (container == null) { - return; - } - // CraftBukkit end - this.nextContainerCounter(); - this.activeContainer = container; // CraftBukkit - // CraftBukkit start - moved down (SPIGOT-4619) - // this.activeContainer.windowId = this.containerCounter; - // this.activeContainer.addSlotListener(this); - // CraftBukkit end - - InventoryMerchant inventorymerchant = ((ContainerMerchant) this.activeContainer).d(); - IChatBaseComponent ichatbasecomponent = imerchant.getScoreboardDisplayName(); - - this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "minecraft:villager", ichatbasecomponent, inventorymerchant.getSize())); - // CraftBukkit start - this.activeContainer.windowId = this.containerCounter; - this.activeContainer.addSlotListener(this); - // CraftBukkit end - MerchantRecipeList merchantrecipelist = imerchant.getOffers(this); - - if (merchantrecipelist != null) { - PacketDataSerializer packetdataserializer = new PacketDataSerializer(Unpooled.buffer()); - - packetdataserializer.writeInt(this.containerCounter); - merchantrecipelist.a(packetdataserializer); - this.playerConnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, packetdataserializer)); - } - + @Override + public void openTrade(int i, MerchantRecipeList merchantrecipelist, int j, int k, boolean flag, boolean flag1) { + this.playerConnection.sendPacket(new PacketPlayOutOpenWindowMerchant(i, merchantrecipelist, j, k, flag, flag1)); } + @Override public void openHorseInventory(EntityHorseAbstract entityhorseabstract, IInventory iinventory) { // CraftBukkit start - Inventory open hook - Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHorse(this.inventory, iinventory, entityhorseabstract, this)); + this.nextContainerCounter(); + Container container = new ContainerHorse(this.containerCounter, this.inventory, iinventory, entityhorseabstract); + container.setTitle(entityhorseabstract.getScoreboardDisplayName()); + container = CraftEventFactory.callInventoryOpenEvent(this, container); + if (container == null) { iinventory.closeContainer(this); return; @@ -1022,48 +1197,53 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper } - this.nextContainerCounter(); - this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "EntityHorse", iinventory.getScoreboardDisplayName(), iinventory.getSize(), entityhorseabstract.getId())); + // this.nextContainerCounter(); // CraftBukkit - moved up + this.playerConnection.sendPacket(new PacketPlayOutOpenWindowHorse(this.containerCounter, iinventory.getSize(), entityhorseabstract.getId())); this.activeContainer = container; // CraftBukkit - this.activeContainer.windowId = this.containerCounter; this.activeContainer.addSlotListener(this); } - public void a(ItemStack itemstack, EnumHand enumhand) { + @Override + public void openBook(ItemStack itemstack, EnumHand enumhand) { Item item = itemstack.getItem(); if (item == Items.WRITTEN_BOOK) { - PacketDataSerializer packetdataserializer = new PacketDataSerializer(Unpooled.buffer()); + if (ItemWrittenBook.a(itemstack, this.getCommandListener(), (EntityHuman) this)) { + this.activeContainer.c(); + } - packetdataserializer.a((Enum) enumhand); - this.playerConnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.c, packetdataserializer)); + this.playerConnection.sendPacket(new PacketPlayOutOpenBook(enumhand)); } } + @Override public void a(TileEntityCommand tileentitycommand) { tileentitycommand.c(true); this.a((TileEntity) tileentitycommand); } + @Override public void a(Container container, int i, ItemStack itemstack) { if (!(container.getSlot(i) instanceof SlotResult)) { if (container == this.defaultContainer) { CriterionTriggers.e.a(this, this.inventory); } - if (!this.f) { + if (!this.e) { this.playerConnection.sendPacket(new PacketPlayOutSetSlot(container.windowId, i, itemstack)); } } } public void updateInventory(Container container) { - this.a(container, container.a()); + this.a(container, container.b()); } + @Override public void a(Container container, NonNullList nonnulllist) { - this.playerConnection.sendPackets(new PacketPlayOutWindowItems(container.windowId, nonnulllist), new PacketPlayOutSetSlot(-1, -1, this.inventory.getCarried())); // Akarin + this.playerConnection.sendPacket(new PacketPlayOutWindowItems(container.windowId, nonnulllist)); + this.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.inventory.getCarried())); // CraftBukkit start - Send a Set Slot to update the crafting result slot if (java.util.EnumSet.of(InventoryType.CRAFTING,InventoryType.WORKBENCH).contains(container.getBukkitView().getType())) { this.playerConnection.sendPacket(new PacketPlayOutSetSlot(container.windowId, 0, container.getSlot(0).getItem())); @@ -1071,17 +1251,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting { // CraftBukkit end } + @Override public void setContainerData(Container container, int i, int j) { this.playerConnection.sendPacket(new PacketPlayOutWindowData(container.windowId, i, j)); } - public void setContainerData(Container container, IInventory iinventory) { - for (int i = 0; i < iinventory.h(); ++i) { - this.playerConnection.sendPacket(new PacketPlayOutWindowData(container.windowId, i, iinventory.getProperty(i))); - } - - } - + @Override public void closeInventory() { // Paper start closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN); @@ -1094,7 +1269,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } public void broadcastCarriedItem() { - if (!this.f) { + if (!this.e) { this.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.inventory.getCarried())); } } @@ -1107,63 +1282,66 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public void a(float f, float f1, boolean flag, boolean flag1) { if (this.isPassenger()) { if (f >= -1.0F && f <= 1.0F) { - this.bh = f; + this.bb = f; } if (f1 >= -1.0F && f1 <= 1.0F) { - this.bj = f1; + this.bd = f1; } - this.bg = flag; + this.jumping = flag; this.setSneaking(flag1); } } + @Override public void a(Statistic statistic, int i) { - this.cg.b(this, statistic, i); + this.serverStatisticManager.b(this, statistic, i); this.world.getServer().getScoreboardManager().getScoreboardScores(statistic, this.getName(), (scoreboardscore) -> { // CraftBukkit - Get our scores instead scoreboardscore.addScore(i); }); } + @Override public void a(Statistic statistic) { - this.cg.setStatistic(this, statistic, 0); + this.serverStatisticManager.setStatistic(this, statistic, 0); this.world.getServer().getScoreboardManager().getScoreboardScores(statistic, this.getName(), ScoreboardScore::c); // CraftBukkit - Get our scores instead } - public int discoverRecipes(Collection collection) { + @Override + public int discoverRecipes(Collection> collection) { return this.recipeBook.a(collection, this); } + @Override public void a(MinecraftKey[] aminecraftkey) { - List list = Lists.newArrayList(); + List> list = Lists.newArrayList(); MinecraftKey[] aminecraftkey1 = aminecraftkey; int i = aminecraftkey.length; for (int j = 0; j < i; ++j) { MinecraftKey minecraftkey = aminecraftkey1[j]; - IRecipe irecipe = this.server.getCraftingManager().a(minecraftkey); - if (irecipe != null) { - list.add(irecipe); - } + this.server.getCraftingManager().a(minecraftkey).ifPresent(list::add); } this.discoverRecipes(list); } - public int undiscoverRecipes(Collection collection) { + @Override + public int undiscoverRecipes(Collection> collection) { return this.recipeBook.b(collection, this); } + @Override public void giveExp(int i) { super.giveExp(i); this.lastSentExp = -1; } public void n() { - this.cB = true; + this.ct = true; this.ejectPassengers(); // Paper start - Workaround an issue where the vehicle doesn't track the passenger disconnection dismount. @@ -1172,14 +1350,14 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } // Paper end - if (this.sleeping) { - this.a(true, false, false); + if (this.isSleeping()) { + this.wakeup(true, false, false); } } public boolean o() { - return this.cB; + return this.ct; } public void triggerHealthUpdate() { @@ -1195,10 +1373,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } // CraftBukkit end + @Override public void a(IChatBaseComponent ichatbasecomponent, boolean flag) { this.playerConnection.sendPacket(new PacketPlayOutChat(ichatbasecomponent, flag ? ChatMessageType.GAME_INFO : ChatMessageType.CHAT)); } + @Override protected void q() { if (!this.activeItem.isEmpty() && this.isHandRaised()) { this.playerConnection.sendPacket(new PacketPlayOutEntityStatus(this, (byte) 9)); @@ -1207,6 +1387,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } + @Override public void a(ArgumentAnchor.Anchor argumentanchor_anchor, Vec3D vec3d) { super.a(argumentanchor_anchor, vec3d); this.playerConnection.sendPacket(new PacketPlayOutLookAt(argumentanchor_anchor, vec3d.x, vec3d.y, vec3d.z)); @@ -1228,10 +1409,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.expTotal = entityplayer.expTotal; this.exp = entityplayer.exp; this.setScore(entityplayer.getScore()); - this.aq = entityplayer.aq; - this.ar = entityplayer.ar; - this.as = entityplayer.as; - } else if (this.world.getGameRules().getBoolean("keepInventory") || entityplayer.isSpectator()) { + this.al = entityplayer.al; + this.am = entityplayer.am; + this.an = entityplayer.an; + } else if (this.world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY) || entityplayer.isSpectator()) { this.inventory.a(entityplayer.inventory); this.expLevel = entityplayer.expLevel; this.expTotal = entityplayer.expTotal; @@ -1239,9 +1420,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.setScore(entityplayer.getScore()); } - this.bZ = entityplayer.bZ; + this.bR = entityplayer.bR; this.enderChest = entityplayer.enderChest; - this.getDataWatcher().set(EntityPlayer.bx, entityplayer.getDataWatcher().get(EntityPlayer.bx)); + this.getDataWatcher().set(EntityPlayer.bt, entityplayer.getDataWatcher().get(EntityPlayer.bt)); this.lastSentExp = -1; this.lastHealthSent = -1.0F; this.lastFoodSent = -1; @@ -1254,51 +1435,60 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.removeQueue.addAll(entityplayer.removeQueue); } // Paper end - this.cx = entityplayer.cx; - this.cC = entityplayer.cC; + this.cp = entityplayer.cp; + this.cu = entityplayer.cu; this.setShoulderEntityLeft(entityplayer.getShoulderEntityLeft()); this.setShoulderEntityRight(entityplayer.getShoulderEntityRight()); + + this.inLava = false; // SPIGOT-4767 } + @Override protected void a(MobEffect mobeffect) { super.a(mobeffect); this.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.getId(), mobeffect)); if (mobeffect.getMobEffect() == MobEffects.LEVITATION) { - this.cA = this.ticksLived; - this.cz = new Vec3D(this.locX, this.locY, this.locZ); + this.cs = this.ticksLived; + this.cr = new Vec3D(this.locX, this.locY, this.locZ); } CriterionTriggers.A.a(this); } + @Override protected void a(MobEffect mobeffect, boolean flag) { super.a(mobeffect, flag); this.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.getId(), mobeffect)); CriterionTriggers.A.a(this); } + @Override protected void b(MobEffect mobeffect) { super.b(mobeffect); this.playerConnection.sendPacket(new PacketPlayOutRemoveEntityEffect(this.getId(), mobeffect.getMobEffect())); if (mobeffect.getMobEffect() == MobEffects.LEVITATION) { - this.cz = null; + this.cr = null; } CriterionTriggers.A.a(this); } + @Override public void enderTeleportTo(double d0, double d1, double d2) { this.playerConnection.a(d0, d1, d2, this.yaw, this.pitch); } + @Override public void a(Entity entity) { - this.getWorldServer().getTracker().sendPacketToEntity(this, new PacketPlayOutAnimation(entity, 4)); + this.getWorldServer().getChunkProvider().broadcastIncludingSelf(this, new PacketPlayOutAnimation(entity, 4)); } + @Override public void b(Entity entity) { - this.getWorldServer().getTracker().sendPacketToEntity(this, new PacketPlayOutAnimation(entity, 5)); + this.getWorldServer().getChunkProvider().broadcastIncludingSelf(this, new PacketPlayOutAnimation(entity, 5)); } + @Override public void updateAbilities() { if (this.playerConnection != null) { this.playerConnection.sendPacket(new PacketPlayOutAbilities(this.abilities)); @@ -1310,6 +1500,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { return (WorldServer) this.world; } + @Override public void a(EnumGamemode enumgamemode) { // CraftBukkit start if (enumgamemode == this.playerInteractManager.getGameMode()) { @@ -1333,17 +1524,20 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } this.updateAbilities(); - this.cR(); + this.dh(); } + @Override public boolean isSpectator() { return this.playerInteractManager.getGameMode() == EnumGamemode.SPECTATOR; } - public boolean u() { + @Override + public boolean isCreative() { return this.playerInteractManager.getGameMode() == EnumGamemode.CREATIVE; } + @Override public void sendMessage(IChatBaseComponent ichatbasecomponent) { this.a(ichatbasecomponent, ChatMessageType.SYSTEM); } @@ -1355,7 +1549,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { String s = ichatbasecomponent.a(256); IChatBaseComponent ichatbasecomponent1 = (new ChatComponentText(s)).a(EnumChatFormat.YELLOW); - this.playerConnection.sendPacket(new PacketPlayOutChat((new ChatMessage("multiplayer.message_not_delivered", new Object[] { ichatbasecomponent1})).a(EnumChatFormat.RED), ChatMessageType.SYSTEM)); + this.playerConnection.sendPacket(new PacketPlayOutChat((new ChatMessage("multiplayer.message_not_delivered", new Object[]{ichatbasecomponent1})).a(EnumChatFormat.RED), ChatMessageType.SYSTEM)); } }); @@ -1389,30 +1583,31 @@ public class EntityPlayer extends EntityHuman implements ICrafting { new com.destroystokyo.paper.event.player.PlayerLocaleChangeEvent(this.getBukkitEntity(), oldLocale, this.locale).callEvent(); } // Paper end - this.cs = packetplayinsettings.d(); - this.ct = packetplayinsettings.e(); - this.getDataWatcher().set(EntityPlayer.bx, (byte) packetplayinsettings.f()); - this.getDataWatcher().set(EntityPlayer.by, (byte) (packetplayinsettings.getMainHand() == EnumMainHand.LEFT ? 0 : 1)); + this.ck = packetplayinsettings.d(); + this.cl = packetplayinsettings.e(); + this.getDataWatcher().set(EntityPlayer.bt, (byte) packetplayinsettings.f()); + this.getDataWatcher().set(EntityPlayer.bu, (byte) (packetplayinsettings.getMainHand() == EnumMainHand.LEFT ? 0 : 1)); } - public EntityHuman.EnumChatVisibility getChatFlags() { - return this.cs; + public EnumChatVisibility getChatFlags() { + return this.ck; } public void setResourcePack(String s, String s1) { this.playerConnection.sendPacket(new PacketPlayOutResourcePackSend(s, s1)); } + @Override protected int y() { return this.server.a(this.getProfile()); } public void resetIdleTimer() { - this.cu = SystemUtils.getMonotonicMillis(); + this.cm = SystemUtils.getMonotonicMillis(); } public ServerStatisticManager getStatisticManager() { - return this.cg; + return this.serverStatisticManager; } public RecipeBookServer B() { @@ -1421,7 +1616,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public void c(Entity entity) { if (entity instanceof EntityHuman) { - this.playerConnection.sendPacket(new PacketPlayOutEntityDestroy(new int[] { entity.getId()})); + this.playerConnection.sendPacket(new PacketPlayOutEntityDestroy(new int[]{entity.getId()})); } else { this.removeQueue.add((Integer) entity.getId()); // CraftBukkit - decompile error } @@ -1432,15 +1627,15 @@ public class EntityPlayer extends EntityHuman implements ICrafting { this.removeQueue.remove((Integer) entity.getId()); // CraftBukkit - decompile error } + @Override protected void C() { if (this.isSpectator()) { - this.cl(); + this.cy(); this.setInvisible(true); } else { super.C(); } - this.getWorldServer().getTracker().a(this); } public Entity getSpecatorTarget() { @@ -1478,6 +1673,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { // Paper end } + @Override protected void E() { if (this.portalCooldown > 0 && !this.worldChangeInvuln) { --this.portalCooldown; @@ -1485,6 +1681,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } + @Override public void attack(Entity entity) { if (this.playerInteractManager.getGameMode() == EnumGamemode.SPECTATOR) { this.setSpectatorTarget(entity); @@ -1495,7 +1692,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } public long F() { - return this.cu; + return this.cm; } @Nullable @@ -1503,9 +1700,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting { return listName; // CraftBukkit } + @Override public void a(EnumHand enumhand) { super.a(enumhand); - this.dH(); + this.dZ(); } public boolean H() { @@ -1531,12 +1729,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } public AdvancementDataPlayer getAdvancementData() { - return this.cf; - } - - @Nullable - public Vec3D M() { - return this.cC; + return this.advancementDataPlayer; } // CraftBukkit start @@ -1555,22 +1748,20 @@ public class EntityPlayer extends EntityHuman implements ICrafting { WorldServer worldserver1 = this.getWorldServer(); this.dimension = worldserver.worldProvider.getDimensionManager(); - this.playerConnection.sendPacket(new PacketPlayOutRespawn(this.dimension, worldserver1.getDifficulty(), worldserver1.getWorldData().getType(), this.playerInteractManager.getGameMode())); - this.server.getPlayerList().f(this); - worldserver1.removeEntity(this); + WorldData worlddata = worldserver.getWorldData(); + + this.playerConnection.sendPacket(new PacketPlayOutRespawn(this.dimension, worlddata.getType(), this.playerInteractManager.getGameMode())); + this.playerConnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); + this.server.getPlayerList().d(this); + worldserver1.removePlayer(this); this.dead = false; this.setPositionRotation(d0, d1, d2, f, f1); - if (this.isAlive()) { - worldserver1.entityJoinedWorld(this, false); - worldserver.addEntity(this); - worldserver.entityJoinedWorld(this, false); - } - this.spawnIn(worldserver); - this.server.getPlayerList().a(this, worldserver1); + worldserver.addPlayerCommand(this); + this.b(worldserver1); this.playerConnection.a(d0, d1, d2, f, f1); this.playerInteractManager.a(worldserver); - this.server.getPlayerList().b(this, worldserver); + this.server.getPlayerList().a(this, worldserver); this.server.getPlayerList().updateClient(this); } */ @@ -1579,6 +1770,56 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } + public void a(ChunkCoordIntPair chunkcoordintpair, Packet packet, Packet packet1) { + this.playerConnection.sendPacket(packet1); + this.playerConnection.sendPacket(packet); + } + + public void a(ChunkCoordIntPair chunkcoordintpair) { + this.playerConnection.sendPacket(new PacketPlayOutUnloadChunk(chunkcoordintpair.x, chunkcoordintpair.z)); + } + + public SectionPosition getPlayerMapSection() { return this.M(); } // Paper - OBFHELPER + public SectionPosition M() { + return this.cv; + } + + public void a(SectionPosition sectionposition) { + this.cv = sectionposition; + } + + @Override + public void a(SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) { + this.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(soundeffect, soundcategory, this.locX, this.locY, this.locZ, f, f1)); + } + + @Override + public Packet N() { + return new PacketPlayOutNamedEntitySpawn(this); + } + + @Override + public EntityItem a(ItemStack itemstack, boolean flag, boolean flag1) { + EntityItem entityitem = super.a(itemstack, flag, flag1); + + if (entityitem == null) { + return null; + } else { + this.world.addEntity(entityitem); + ItemStack itemstack1 = entityitem.getItemStack(); + + if (flag1) { + if (!itemstack1.isEmpty()) { + this.a(StatisticList.ITEM_DROPPED.b(itemstack1.getItem()), itemstack.getCount()); + } + + this.a(StatisticList.DROP); + } + + return entityitem; + } + } + // CraftBukkit start - Add per-player time and weather. public long timeOffset = 0; public boolean relativeTime = true; @@ -1681,7 +1922,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public void reset() { float exp = 0; - boolean keepInventory = this.world.getGameRules().getBoolean("keepInventory"); + boolean keepInventory = this.world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY); if (this.keepLevel || keepInventory) { exp = this.exp; diff --git a/src/main/java/net/minecraft/server/EntityPolarBear.java b/src/main/java/net/minecraft/server/EntityPolarBear.java deleted file mode 100644 index dbb534c9c..000000000 --- a/src/main/java/net/minecraft/server/EntityPolarBear.java +++ /dev/null @@ -1,261 +0,0 @@ -package net.minecraft.server; - -import java.util.Iterator; -import java.util.List; -import java.util.function.Predicate; -import javax.annotation.Nullable; - -public class EntityPolarBear extends EntityAnimal { - - private static final DataWatcherObject bC = DataWatcher.a(EntityPolarBear.class, DataWatcherRegistry.i); - private float bD; - private float bE; - private int bG; - - public EntityPolarBear(World world) { - super(EntityTypes.POLAR_BEAR, world); - this.setSize(1.3F, 1.4F); - } - - public EntityAgeable createChild(EntityAgeable entityageable) { - return EntityTypes.POLAR_BEAR.create(world); // Paper - } - - public boolean f(ItemStack itemstack) { - return false; - } - - protected void n() { - super.n(); - this.goalSelector.a(0, new PathfinderGoalFloat(this)); - this.goalSelector.a(1, new EntityPolarBear.d()); - this.goalSelector.a(1, new EntityPolarBear.e()); - this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.25D)); - this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D)); - this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); - this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, new EntityPolarBear.c()); - this.targetSelector.a(2, new EntityPolarBear.a()); - } - - protected void initAttributes() { - super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(30.0D); - this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(20.0D); - this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); - this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE); - this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(6.0D); - } - - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - int i = MathHelper.floor(this.locX); - int j = MathHelper.floor(this.getBoundingBox().minY); - int k = MathHelper.floor(this.locZ); - BlockPosition blockposition = new BlockPosition(i, j, k); - BiomeBase biomebase = generatoraccess.getBiome(blockposition); - - return biomebase != Biomes.FROZEN_OCEAN && biomebase != Biomes.DEEP_FROZEN_OCEAN ? super.a(generatoraccess, flag) : generatoraccess.getLightLevel(blockposition, 0) > 8 && generatoraccess.getType(blockposition.down()).getBlock() == Blocks.ICE; - } - - protected SoundEffect D() { - return this.isBaby() ? SoundEffects.ENTITY_POLAR_BEAR_AMBIENT_BABY : SoundEffects.ENTITY_POLAR_BEAR_AMBIENT; - } - - protected SoundEffect d(DamageSource damagesource) { - return SoundEffects.ENTITY_POLAR_BEAR_HURT; - } - - protected SoundEffect cs() { - return SoundEffects.ENTITY_POLAR_BEAR_DEATH; - } - - protected void a(BlockPosition blockposition, IBlockData iblockdata) { - this.a(SoundEffects.ENTITY_POLAR_BEAR_STEP, 0.15F, 1.0F); - } - - protected void dy() { - if (this.bG <= 0) { - this.a(SoundEffects.ENTITY_POLAR_BEAR_WARNING, 1.0F, 1.0F); - this.bG = 40; - } - - } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.M; - } - - protected void x_() { - super.x_(); - this.datawatcher.register(EntityPolarBear.bC, false); - } - - public void tick() { - super.tick(); - if (this.world.isClientSide) { - this.bD = this.bE; - if (this.dz()) { - this.bE = MathHelper.a(this.bE + 1.0F, 0.0F, 6.0F); - } else { - this.bE = MathHelper.a(this.bE - 1.0F, 0.0F, 6.0F); - } - } - - if (this.bG > 0) { - --this.bG; - } - - } - - public boolean B(Entity entity) { - boolean flag = entity.damageEntity(DamageSource.mobAttack(this), (float) ((int) this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).getValue())); - - if (flag) { - this.a((EntityLiving) this, entity); - } - - return flag; - } - - public boolean dz() { - return (Boolean) this.datawatcher.get(EntityPolarBear.bC); - } - - public void s(boolean flag) { - this.datawatcher.set(EntityPolarBear.bC, flag); - } - - protected float cJ() { - return 0.98F; - } - - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - if (groupdataentity instanceof EntityPolarBear.b) { - if (((EntityPolarBear.b) groupdataentity).a) { - this.setAgeRaw(-24000); - } - } else { - EntityPolarBear.b entitypolarbear_b = new EntityPolarBear.b(); - - entitypolarbear_b.a = true; - groupdataentity = entitypolarbear_b; - } - - return (GroupDataEntity) groupdataentity; - } - - class e extends PathfinderGoalPanic { - - public e() { - super(EntityPolarBear.this, 2.0D); - } - - public boolean a() { - return !EntityPolarBear.this.isBaby() && !EntityPolarBear.this.isBurning() ? false : super.a(); - } - } - - class d extends PathfinderGoalMeleeAttack { - - public d() { - super(EntityPolarBear.this, 1.25D, true); - } - - protected void a(EntityLiving entityliving, double d0) { - double d1 = this.a(entityliving); - - if (d0 <= d1 && this.b <= 0) { - this.b = 20; - this.a.B(entityliving); - EntityPolarBear.this.s(false); - } else if (d0 <= d1 * 2.0D) { - if (this.b <= 0) { - EntityPolarBear.this.s(false); - this.b = 20; - } - - if (this.b <= 10) { - EntityPolarBear.this.s(true); - EntityPolarBear.this.dy(); - } - } else { - this.b = 20; - EntityPolarBear.this.s(false); - } - - } - - public void d() { - EntityPolarBear.this.s(false); - super.d(); - } - - protected double a(EntityLiving entityliving) { - return (double) (4.0F + entityliving.width); - } - } - - class a extends PathfinderGoalNearestAttackableTarget { - - public a() { - super(EntityPolarBear.this, EntityHuman.class, 20, true, true, (Predicate) null); - } - - public boolean a() { - if (EntityPolarBear.this.isBaby()) { - return false; - } else { - if (super.a()) { - List list = EntityPolarBear.this.world.a(EntityPolarBear.class, EntityPolarBear.this.getBoundingBox().grow(8.0D, 4.0D, 8.0D)); - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - EntityPolarBear entitypolarbear = (EntityPolarBear) iterator.next(); - - if (entitypolarbear.isBaby()) { - return true; - } - } - } - - EntityPolarBear.this.setGoalTarget((EntityLiving) null); - return false; - } - } - - protected double i() { - return super.i() * 0.5D; - } - } - - class c extends PathfinderGoalHurtByTarget { - - public c() { - super(EntityPolarBear.this, false); - } - - public void c() { - super.c(); - if (EntityPolarBear.this.isBaby()) { - this.g(); - this.d(); - } - - } - - protected void a(EntityCreature entitycreature, EntityLiving entityliving) { - if (entitycreature instanceof EntityPolarBear && !entitycreature.isBaby()) { - super.a(entitycreature, entityliving); - } - - } - } - - static class b implements GroupDataEntity { - - public boolean a; - - private b() {} - } -} diff --git a/src/main/java/net/minecraft/server/EntityPotion.java b/src/main/java/net/minecraft/server/EntityPotion.java index eec8ed72c..998336557 100644 --- a/src/main/java/net/minecraft/server/EntityPotion.java +++ b/src/main/java/net/minecraft/server/EntityPotion.java @@ -3,6 +3,7 @@ package net.minecraft.server; import java.util.Iterator; import java.util.List; import java.util.function.Predicate; +import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; // CraftBukkit start @@ -15,27 +16,23 @@ import org.bukkit.entity.LivingEntity; public class EntityPotion extends EntityProjectile { private static final DataWatcherObject f = DataWatcher.a(EntityPotion.class, DataWatcherRegistry.g); - private static final Logger g = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public static final Predicate e = EntityPotion::a; - public EntityPotion(World world) { - super(EntityTypes.POTION, world); + public EntityPotion(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - public EntityPotion(World world, EntityLiving entityliving, ItemStack itemstack) { + public EntityPotion(World world, EntityLiving entityliving) { super(EntityTypes.POTION, entityliving, world); - this.setItem(itemstack); } - public EntityPotion(World world, double d0, double d1, double d2, ItemStack itemstack) { + public EntityPotion(World world, double d0, double d1, double d2) { super(EntityTypes.POTION, d0, d1, d2, world); - if (!itemstack.isEmpty()) { - this.setItem(itemstack); - } - } - protected void x_() { + @Override + protected void initDatawatcher() { this.getDataWatcher().register(EntityPotion.f, ItemStack.a); } @@ -44,7 +41,7 @@ public class EntityPotion extends EntityProjectile { if (itemstack.getItem() != Items.SPLASH_POTION && itemstack.getItem() != Items.LINGERING_POTION) { if (this.world != null) { - EntityPotion.g.error("ThrownPotion entity {} has no item?!", this.getId()); + EntityPotion.LOGGER.error("ThrownPotion entity {} has no item?!", this.getId()); } return new ItemStack(Items.SPLASH_POTION); @@ -54,51 +51,56 @@ public class EntityPotion extends EntityProjectile { } public void setItem(ItemStack itemstack) { - this.getDataWatcher().set(EntityPotion.f, itemstack); + this.getDataWatcher().set(EntityPotion.f, itemstack.cloneItemStack()); } - protected float f() { + @Override + protected float l() { return 0.05F; } + @Override protected void a(MovingObjectPosition movingobjectposition) { if (!this.world.isClientSide) { ItemStack itemstack = this.getItem(); PotionRegistry potionregistry = PotionUtil.d(itemstack); List list = PotionUtil.getEffects(itemstack); - boolean flag = potionregistry == Potions.b && list.isEmpty(); + boolean flag = potionregistry == Potions.WATER && list.isEmpty(); - if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK && flag) { - BlockPosition blockposition = movingobjectposition.getBlockPosition().shift(movingobjectposition.direction); + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK && flag) { + MovingObjectPositionBlock movingobjectpositionblock = (MovingObjectPositionBlock) movingobjectposition; + EnumDirection enumdirection = movingobjectpositionblock.getDirection(); + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition().shift(enumdirection); - this.a(blockposition, movingobjectposition.direction); + this.a(blockposition, enumdirection); + this.a(blockposition.shift(enumdirection.opposite()), enumdirection); Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); while (iterator.hasNext()) { - EnumDirection enumdirection = (EnumDirection) iterator.next(); + EnumDirection enumdirection1 = (EnumDirection) iterator.next(); - this.a(blockposition.shift(enumdirection), enumdirection); + this.a(blockposition.shift(enumdirection1), enumdirection1); } } if (flag) { - this.l(); + this.splash(); } else if (true || !list.isEmpty()) { // CraftBukkit - Call event even if no effects to apply if (this.isLingering()) { this.a(itemstack, potionregistry); } else { - this.a(movingobjectposition, list); + this.a(list, movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY ? ((MovingObjectPositionEntity) movingobjectposition).getEntity() : null); } } - int i = potionregistry.c() ? 2007 : 2002; + int i = potionregistry.b() ? 2007 : 2002; this.world.triggerEffect(i, new BlockPosition(this), PotionUtil.c(itemstack)); this.die(); } } - private void l() { + private void splash() { AxisAlignedBB axisalignedbb = this.getBoundingBox().grow(4.0D, 2.0D, 4.0D); List list = this.world.a(EntityLiving.class, axisalignedbb, EntityPotion.e); @@ -110,14 +112,14 @@ public class EntityPotion extends EntityProjectile { double d0 = this.h(entityliving); if (d0 < 16.0D && a(entityliving)) { - entityliving.damageEntity(DamageSource.DROWN, 1.0F); + entityliving.damageEntity(DamageSource.c(entityliving, this.getShooter()), 1.0F); } } } } - private void a(MovingObjectPosition movingobjectposition, List list) { + private void a(List list, @Nullable Entity entity) { AxisAlignedBB axisalignedbb = this.getBoundingBox().grow(4.0D, 2.0D, 4.0D); List list1 = this.world.a(EntityLiving.class, axisalignedbb); Map affected = new HashMap(); // CraftBukkit @@ -128,13 +130,13 @@ public class EntityPotion extends EntityProjectile { while (iterator.hasNext()) { EntityLiving entityliving = (EntityLiving) iterator.next(); - if (entityliving.de()) { + if (entityliving.dt()) { double d0 = this.h(entityliving); if (d0 < 16.0D) { double d1 = 1.0D - Math.sqrt(d0) / 4.0D; - if (entityliving == movingobjectposition.entity) { + if (entityliving == entity) { d1 = 1.0D; } @@ -200,7 +202,7 @@ public class EntityPotion extends EntityProjectile { while (iterator.hasNext()) { MobEffect mobeffect = (MobEffect) iterator.next(); - entityareaeffectcloud.a(new MobEffect(mobeffect)); + entityareaeffectcloud.addEffect(new MobEffect(mobeffect)); } NBTTagCompound nbttagcompound = itemstack.getTag(); @@ -224,12 +226,19 @@ public class EntityPotion extends EntityProjectile { } private void a(BlockPosition blockposition, EnumDirection enumdirection) { - if (this.world.getType(blockposition).getBlock() == Blocks.FIRE) { + IBlockData iblockdata = this.world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (block == Blocks.FIRE) { this.world.douseFire((EntityHuman) null, blockposition.shift(enumdirection), enumdirection.opposite()); + } else if (block == Blocks.CAMPFIRE && (Boolean) iblockdata.get(BlockCampfire.b)) { + this.world.a((EntityHuman) null, 1009, blockposition, 0); + this.world.setTypeUpdate(blockposition, (IBlockData) iblockdata.set(BlockCampfire.b, false)); } } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); ItemStack itemstack = ItemStack.a(nbttagcompound.getCompound("Potion")); @@ -242,6 +251,7 @@ public class EntityPotion extends EntityProjectile { } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); ItemStack itemstack = this.getItem(); diff --git a/src/main/java/net/minecraft/server/EntityProjectile.java b/src/main/java/net/minecraft/server/EntityProjectile.java index 1a5d946f5..bd4ca73f6 100644 --- a/src/main/java/net/minecraft/server/EntityProjectile.java +++ b/src/main/java/net/minecraft/server/EntityProjectile.java @@ -1,6 +1,6 @@ package net.minecraft.server; -import java.util.List; +import java.util.Iterator; import java.util.UUID; import javax.annotation.Nullable; @@ -13,72 +13,57 @@ public abstract class EntityProjectile extends Entity implements IProjectile { public int shake; public EntityLiving shooter; public UUID shooterId; - public Entity d; - private int aw; + private Entity as; + private int at; - protected EntityProjectile(EntityTypes entitytypes, World world) { + protected EntityProjectile(EntityTypes entitytypes, World world) { super(entitytypes, world); this.blockX = -1; this.blockY = -1; this.blockZ = -1; - this.setSize(0.25F, 0.25F); } - protected EntityProjectile(EntityTypes entitytypes, double d0, double d1, double d2, World world) { + protected EntityProjectile(EntityTypes entitytypes, double d0, double d1, double d2, World world) { this(entitytypes, world); this.setPosition(d0, d1, d2); } - protected EntityProjectile(EntityTypes entitytypes, EntityLiving entityliving, World world) { + protected EntityProjectile(EntityTypes entitytypes, EntityLiving entityliving, World world) { this(entitytypes, entityliving.locX, entityliving.locY + (double) entityliving.getHeadHeight() - 0.10000000149011612D, entityliving.locZ, world); this.shooter = entityliving; this.shooterId = entityliving.getUniqueID(); this.projectileSource = (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit } - protected void x_() {} - public void a(Entity entity, float f, float f1, float f2, float f3, float f4) { float f5 = -MathHelper.sin(f1 * 0.017453292F) * MathHelper.cos(f * 0.017453292F); float f6 = -MathHelper.sin((f + f2) * 0.017453292F); float f7 = MathHelper.cos(f1 * 0.017453292F) * MathHelper.cos(f * 0.017453292F); this.shoot((double) f5, (double) f6, (double) f7, f3, f4); - this.motX += entity.motX; - this.motZ += entity.motZ; - if (!entity.onGround) { - this.motY += entity.motY; - } + Vec3D vec3d = entity.getMot(); + if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(vec3d.x, entity.onGround ? 0.0D : vec3d.y, vec3d.z)); // Paper - allow disabling relative velocity } + @Override public void shoot(double d0, double d1, double d2, float f, float f1) { - float f2 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + Vec3D vec3d = (new Vec3D(d0, d1, d2)).d().add(this.random.nextGaussian() * 0.007499999832361937D * (double) f1, this.random.nextGaussian() * 0.007499999832361937D * (double) f1, this.random.nextGaussian() * 0.007499999832361937D * (double) f1).a((double) f); - d0 /= (double) f2; - d1 /= (double) f2; - d2 /= (double) f2; - d0 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; - d1 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; - d2 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; - d0 *= (double) f; - d1 *= (double) f; - d2 *= (double) f; - this.motX = d0; - this.motY = d1; - this.motZ = d2; - float f3 = MathHelper.sqrt(d0 * d0 + d2 * d2); + this.setMot(vec3d); + float f2 = MathHelper.sqrt(b(vec3d)); - this.yaw = (float) (MathHelper.c(d0, d2) * 57.2957763671875D); - this.pitch = (float) (MathHelper.c(d1, (double) f3) * 57.2957763671875D); + this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); + this.pitch = (float) (MathHelper.d(vec3d.y, (double) f2) * 57.2957763671875D); this.lastYaw = this.yaw; this.lastPitch = this.pitch; } + @Override public void tick() { - this.N = this.locX; - this.O = this.locY; - this.P = this.locZ; + this.H = this.locX; + this.I = this.locY; + this.J = this.locZ; super.tick(); if (this.shake > 0) { --this.shake; @@ -86,76 +71,49 @@ public abstract class EntityProjectile extends Entity implements IProjectile { if (this.inGround) { this.inGround = false; - this.motX *= (double) (this.random.nextFloat() * 0.2F); - this.motY *= (double) (this.random.nextFloat() * 0.2F); - this.motZ *= (double) (this.random.nextFloat() * 0.2F); + this.setMot(this.getMot().d((double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F), (double) (this.random.nextFloat() * 0.2F))); } - Vec3D vec3d = new Vec3D(this.locX, this.locY, this.locZ); - Vec3D vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); - MovingObjectPosition movingobjectposition = this.world.rayTrace(vec3d, vec3d1); + AxisAlignedBB axisalignedbb = this.getBoundingBox().a(this.getMot()).g(1.0D); + Iterator iterator = this.world.getEntities(this, axisalignedbb, (entity) -> { + return !entity.isSpectator() && entity.isInteractable(); + }).iterator(); - vec3d = new Vec3D(this.locX, this.locY, this.locZ); - vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); - if (movingobjectposition != null) { - vec3d1 = new Vec3D(movingobjectposition.pos.x, movingobjectposition.pos.y, movingobjectposition.pos.z); - } + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); - Entity entity = null; - List list = this.world.getEntities(this, this.getBoundingBox().b(this.motX, this.motY, this.motZ).g(1.0D)); - double d0 = 0.0D; - boolean flag = false; + if (entity == this.as) { + ++this.at; + break; + } - for (int i = 0; i < list.size(); ++i) { - Entity entity1 = (Entity) list.get(i); - - if (entity1.isInteractable()) { - if (entity1 == this.d) { - flag = true; - } else if (this.shooter != null && this.ticksLived < 2 && this.d == null && this.shooter == entity1) { // CraftBukkit - MC-88491 - this.d = entity1; - flag = true; - } else { - flag = false; - AxisAlignedBB axisalignedbb = entity1.getBoundingBox().g(0.30000001192092896D); - MovingObjectPosition movingobjectposition1 = axisalignedbb.b(vec3d, vec3d1); - - if (movingobjectposition1 != null) { - double d1 = vec3d.distanceSquared(movingobjectposition1.pos); - - if (d1 < d0 || d0 == 0.0D) { - entity = entity1; - d0 = d1; - } - } - } + if (this.shooter != null && this.ticksLived < 2 && this.as == null && this.shooter == entity) { // CraftBukkit - MC-88491 + this.as = entity; + this.at = 3; + break; } } - if (this.d != null) { - if (flag) { - this.aw = 2; - } else if (this.aw-- <= 0) { - this.d = null; - } - } + MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, axisalignedbb, (entity1) -> { + return !entity1.isSpectator() && entity1.isInteractable() && entity1 != this.as; + }, RayTrace.BlockCollisionOption.OUTLINE, true); - if (entity != null) { - movingobjectposition = new MovingObjectPosition(entity); + if (this.as != null && this.at-- <= 0) { + this.as = null; } // Paper start - Call ProjectileCollideEvent - if (movingobjectposition != null && movingobjectposition.entity != null) { - com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, movingobjectposition); + if (movingobjectposition instanceof MovingObjectPositionEntity) { + com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, (MovingObjectPositionEntity)movingobjectposition); if (event.isCancelled()) { movingobjectposition = null; } } // Paper end - if (movingobjectposition != null) { - if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK && this.world.getType(movingobjectposition.getBlockPosition()).getBlock() == Blocks.NETHER_PORTAL) { - this.e(movingobjectposition.getBlockPosition()); + if (movingobjectposition != null && movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { // Paper - add null check in case cancelled + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK && this.world.getType(((MovingObjectPositionBlock) movingobjectposition).getBlockPosition()).getBlock() == Blocks.NETHER_PORTAL) { + this.c(((MovingObjectPositionBlock) movingobjectposition).getBlockPosition()); } else { this.a(movingobjectposition); // CraftBukkit start @@ -166,14 +124,16 @@ public abstract class EntityProjectile extends Entity implements IProjectile { } } - this.locX += this.motX; - this.locY += this.motY; - this.locZ += this.motZ; - float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + Vec3D vec3d = this.getMot(); - this.yaw = (float) (MathHelper.c(this.motX, this.motZ) * 57.2957763671875D); + this.locX += vec3d.x; + this.locY += vec3d.y; + this.locZ += vec3d.z; + float f = MathHelper.sqrt(b(vec3d)); - for (this.pitch = (float) (MathHelper.c(this.motY, (double) f) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + this.yaw = (float) (MathHelper.d(vec3d.x, vec3d.z) * 57.2957763671875D); + + for (this.pitch = (float) (MathHelper.d(vec3d.y, (double) f) * 57.2957763671875D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { ; } @@ -189,41 +149,39 @@ public abstract class EntityProjectile extends Entity implements IProjectile { this.lastYaw += 360.0F; } - this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; - this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; - float f1 = 0.99F; - float f2 = this.f(); + this.pitch = MathHelper.g(0.2F, this.lastPitch, this.pitch); + this.yaw = MathHelper.g(0.2F, this.lastYaw, this.yaw); + float f1; if (this.isInWater()) { - // Akarin start - this handle by client - /* - for (int j = 0; j < 4; ++j) { - float f3 = 0.25F; + for (int i = 0; i < 4; ++i) { + float f2 = 0.25F; - this.world.addParticle(Particles.e, this.locX - this.motX * 0.25D, this.locY - this.motY * 0.25D, this.locZ - this.motZ * 0.25D, this.motX, this.motY, this.motZ); + this.world.addParticle(Particles.BUBBLE, this.locX - vec3d.x * 0.25D, this.locY - vec3d.y * 0.25D, this.locZ - vec3d.z * 0.25D, vec3d.x, vec3d.y, vec3d.z); } - */ - // Akarin end f1 = 0.8F; + } else { + f1 = 0.99F; } - this.motX *= (double) f1; - this.motY *= (double) f1; - this.motZ *= (double) f1; + this.setMot(vec3d.a((double) f1)); if (!this.isNoGravity()) { - this.motY -= (double) f2; + Vec3D vec3d1 = this.getMot(); + + this.setMot(vec3d1.x, vec3d1.y - (double) this.l(), vec3d1.z); } this.setPosition(this.locX, this.locY, this.locZ); } - protected float f() { + protected float l() { return 0.03F; } protected abstract void a(MovingObjectPosition movingobjectposition); + @Override public void b(NBTTagCompound nbttagcompound) { nbttagcompound.setInt("xTile", this.blockX); nbttagcompound.setInt("yTile", this.blockY); @@ -236,6 +194,7 @@ public abstract class EntityProjectile extends Entity implements IProjectile { } + @Override public void a(NBTTagCompound nbttagcompound) { this.blockX = nbttagcompound.getInt("xTile"); this.blockY = nbttagcompound.getInt("yTile"); @@ -274,4 +233,9 @@ public abstract class EntityProjectile extends Entity implements IProjectile { return this.shooter; } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); + } } diff --git a/src/main/java/net/minecraft/server/EntityPufferFish.java b/src/main/java/net/minecraft/server/EntityPufferFish.java index 5cc0e1f46..f5d384add 100644 --- a/src/main/java/net/minecraft/server/EntityPufferFish.java +++ b/src/main/java/net/minecraft/server/EntityPufferFish.java @@ -3,126 +3,100 @@ package net.minecraft.server; import java.util.Iterator; import java.util.List; import java.util.function.Predicate; -import javax.annotation.Nullable; public class EntityPufferFish extends EntityFish { - private static final DataWatcherObject a = DataWatcher.a(EntityPufferFish.class, DataWatcherRegistry.b); - private int b; + private static final DataWatcherObject b = DataWatcher.a(EntityPufferFish.class, DataWatcherRegistry.b); private int c; - private static final Predicate bC = (entityliving) -> { - return entityliving == null ? false : (entityliving instanceof EntityHuman && (((EntityHuman) entityliving).isSpectator() || ((EntityHuman) entityliving).u()) ? false : entityliving.getMonsterType() != EnumMonsterType.e); + private int d; + private static final Predicate bz = (entityliving) -> { + return entityliving == null ? false : (entityliving instanceof EntityHuman && (entityliving.isSpectator() || ((EntityHuman) entityliving).isCreative()) ? false : entityliving.getMonsterType() != EnumMonsterType.e); }; - private float bD = -1.0F; - private float bE; - public EntityPufferFish(World world) { - super(EntityTypes.PUFFERFISH, world); - this.setSize(0.7F, 0.7F); + public EntityPufferFish(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityPufferFish.a, 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityPufferFish.b, 0); } public int getPuffState() { - return (Integer) this.datawatcher.get(EntityPufferFish.a); + return (Integer) this.datawatcher.get(EntityPufferFish.b); } public void setPuffState(int i) { - this.datawatcher.set(EntityPufferFish.a, i); - this.d(i); - } - - private void d(int i) { - float f = 1.0F; - - if (i == 1) { - f = 0.7F; - } else if (i == 0) { - f = 0.5F; - } - - this.a(f); - } - - public final void setSize(float f, float f1) { - boolean flag = this.bD > 0.0F; - - this.bD = f; - this.bE = f1; - if (!flag) { - this.a(1.0F); - } - - } - - private void a(float f) { - super.setSize(this.bD * f, this.bE * f); + this.datawatcher.set(EntityPufferFish.b, i); } + @Override public void a(DataWatcherObject datawatcherobject) { - this.d(this.getPuffState()); + if (EntityPufferFish.b.equals(datawatcherobject)) { + this.updateSize(); + } + super.a(datawatcherobject); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setInt("PuffState", this.getPuffState()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setPuffState(nbttagcompound.getInt("PuffState")); } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aF; - } - + @Override protected ItemStack l() { return new ItemStack(Items.PUFFERFISH_BUCKET); } - protected void n() { - super.n(); + @Override + protected void initPathfinder() { + super.initPathfinder(); this.goalSelector.a(1, new EntityPufferFish.a(this)); } + @Override public void tick() { - if (this.isAlive() && !this.world.isClientSide) { - if (this.b > 0) { + if (!this.world.isClientSide && this.isAlive() && this.df()) { + if (this.c > 0) { if (this.getPuffState() == 0) { - this.a(SoundEffects.ENTITY_PUFFER_FISH_BLOW_UP, this.cD(), this.cE()); + this.a(SoundEffects.ENTITY_PUFFER_FISH_BLOW_UP, this.getSoundVolume(), this.cV()); this.setPuffState(1); - } else if (this.b > 40 && this.getPuffState() == 1) { - this.a(SoundEffects.ENTITY_PUFFER_FISH_BLOW_UP, this.cD(), this.cE()); + } else if (this.c > 40 && this.getPuffState() == 1) { + this.a(SoundEffects.ENTITY_PUFFER_FISH_BLOW_UP, this.getSoundVolume(), this.cV()); this.setPuffState(2); } - ++this.b; + ++this.c; } else if (this.getPuffState() != 0) { - if (this.c > 60 && this.getPuffState() == 2) { - this.a(SoundEffects.ENTITY_PUFFER_FISH_BLOW_OUT, this.cD(), this.cE()); + if (this.d > 60 && this.getPuffState() == 2) { + this.a(SoundEffects.ENTITY_PUFFER_FISH_BLOW_OUT, this.getSoundVolume(), this.cV()); this.setPuffState(1); - } else if (this.c > 100 && this.getPuffState() == 1) { - this.a(SoundEffects.ENTITY_PUFFER_FISH_BLOW_OUT, this.cD(), this.cE()); + } else if (this.d > 100 && this.getPuffState() == 1) { + this.a(SoundEffects.ENTITY_PUFFER_FISH_BLOW_OUT, this.getSoundVolume(), this.cV()); this.setPuffState(0); } - ++this.c; + ++this.d; } } super.tick(); } + @Override public void movementTick() { super.movementTick(); - if (this.getPuffState() > 0) { - List list = this.world.a(EntityInsentient.class, this.getBoundingBox().g(0.3D), EntityPufferFish.bC); + if (this.isAlive() && this.getPuffState() > 0) { + List list = this.world.a(EntityInsentient.class, this.getBoundingBox().g(0.3D), EntityPufferFish.bz); Iterator iterator = list.iterator(); while (iterator.hasNext()) { @@ -146,7 +120,8 @@ public class EntityPufferFish extends EntityFish { } - public void d(EntityHuman entityhuman) { + @Override + public void pickup(EntityHuman entityhuman) { int i = this.getPuffState(); if (entityhuman instanceof EntityPlayer && i > 0 && entityhuman.damageEntity(DamageSource.mobAttack(this), (float) (1 + i))) { @@ -156,22 +131,42 @@ public class EntityPufferFish extends EntityFish { } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_PUFFER_FISH_AMBIENT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_PUFFER_FISH_DEATH; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_PUFFER_FISH_HURT; } - protected SoundEffect dz() { + @Override + protected SoundEffect getSoundFlop() { return SoundEffects.ENTITY_PUFFER_FISH_FLOP; } + @Override + public EntitySize a(EntityPose entitypose) { + return super.a(entitypose).a(r(this.getPuffState())); + } + + private static float r(int i) { + switch (i) { + case 0: + return 0.5F; + case 1: + return 0.7F; + default: + return 1.0F; + } + } + static class a extends PathfinderGoal { private final EntityPufferFish a; @@ -180,23 +175,27 @@ public class EntityPufferFish extends EntityFish { this.a = entitypufferfish; } + @Override public boolean a() { - List list = this.a.world.a(EntityLiving.class, this.a.getBoundingBox().g(2.0D), EntityPufferFish.bC); + List list = this.a.world.a(EntityLiving.class, this.a.getBoundingBox().g(2.0D), EntityPufferFish.bz); return !list.isEmpty(); } + @Override public void c() { - this.a.b = 1; + this.a.c = 1; + this.a.d = 0; + } + + @Override + public void d() { this.a.c = 0; } - public void d() { - this.a.b = 0; - } - + @Override public boolean b() { - List list = this.a.world.a(EntityLiving.class, this.a.getBoundingBox().g(2.0D), EntityPufferFish.bC); + List list = this.a.world.a(EntityLiving.class, this.a.getBoundingBox().g(2.0D), EntityPufferFish.bz); return !list.isEmpty(); } diff --git a/src/main/java/net/minecraft/server/EntityRabbit.java b/src/main/java/net/minecraft/server/EntityRabbit.java index d6bac06a7..10fca4977 100644 --- a/src/main/java/net/minecraft/server/EntityRabbit.java +++ b/src/main/java/net/minecraft/server/EntityRabbit.java @@ -1,32 +1,33 @@ package net.minecraft.server; +import java.util.Random; import javax.annotation.Nullable; public class EntityRabbit extends EntityAnimal { - private static final DataWatcherObject bC = DataWatcher.a(EntityRabbit.class, DataWatcherRegistry.b); - private static final MinecraftKey bD = new MinecraftKey("killer_bunny"); + private static final DataWatcherObject bz = DataWatcher.a(EntityRabbit.class, DataWatcherRegistry.b); + private static final MinecraftKey bA = new MinecraftKey("killer_bunny"); + private int bB; + private int bC; + private boolean bD; private int bE; - private int bG; - private boolean bH; - private int bI; - private int bJ; + private int bF; - public EntityRabbit(World world) { - super(EntityTypes.RABBIT, world); - this.setSize(0.4F, 0.5F); - this.h = new EntityRabbit.ControllerJumpRabbit(this); + public EntityRabbit(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.bt = new EntityRabbit.ControllerJumpRabbit(this); this.moveController = new EntityRabbit.ControllerMoveRabbit(this); this.initializePathFinderGoals(); // CraftBukkit - moved code } // CraftBukkit start - code from constructor public void initializePathFinderGoals(){ - this.c(0.0D); + this.d(0.0D); } // CraftBukkit end - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); this.goalSelector.a(1, new EntityRabbit.PathfinderGoalRabbitPanic(this, 2.2D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 0.8D)); @@ -39,11 +40,12 @@ public class EntityRabbit extends EntityAnimal { this.goalSelector.a(11, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); } - protected float cG() { + @Override + protected float cX() { if (!this.positionChanged && (!this.moveController.b() || this.moveController.e() <= this.locY + 0.5D)) { - PathEntity pathentity = this.navigation.m(); + PathEntity pathentity = this.navigation.l(); - if (pathentity != null && pathentity.e() < pathentity.d()) { + if (pathentity != null && pathentity.f() < pathentity.e()) { Vec3D vec3d = pathentity.a((Entity) this); if (vec3d.y > this.locY + 0.5D) { @@ -57,15 +59,16 @@ public class EntityRabbit extends EntityAnimal { } } - protected void cH() { - super.cH(); + @Override + protected void jump() { + super.jump(); double d0 = this.moveController.c(); if (d0 > 0.0D) { - double d1 = this.motX * this.motX + this.motZ * this.motZ; + double d1 = b(this.getMot()); - if (d1 < 0.010000000000000002D) { - this.a(0.0F, 0.0F, 1.0F, 0.1F); + if (d1 < 0.01D) { + this.a(0.1F, new Vec3D(0.0D, 0.0D, 1.0D)); } } @@ -75,156 +78,168 @@ public class EntityRabbit extends EntityAnimal { } - public void c(double d0) { + public void d(double d0) { this.getNavigation().a(d0); this.moveController.a(this.moveController.d(), this.moveController.e(), this.moveController.f(), d0); } - public void o(boolean flag) { - super.o(flag); + @Override + public void setJumping(boolean flag) { + super.setJumping(flag); if (flag) { - this.a(this.dz(), this.cD(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) * 0.8F); + this.a(this.getSoundJump(), this.getSoundVolume(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) * 0.8F); } } - public void dy() { - this.o(true); - this.bG = 10; - this.bE = 0; + public void dV() { + this.setJumping(true); + this.bC = 10; + this.bB = 0; } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityRabbit.bC, 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityRabbit.bz, 0); } + @Override public void mobTick() { - if (this.bI > 0) { - --this.bI; + if (this.bE > 0) { + --this.bE; } - if (this.bJ > 0) { - this.bJ -= this.random.nextInt(3); - if (this.bJ < 0) { - this.bJ = 0; + if (this.bF > 0) { + this.bF -= this.random.nextInt(3); + if (this.bF < 0) { + this.bF = 0; } } if (this.onGround) { - if (!this.bH) { - this.o(false); - this.dI(); + if (!this.bD) { + this.setJumping(false); + this.ef(); } - if (this.getRabbitType() == 99 && this.bI == 0) { + if (this.getRabbitType() == 99 && this.bE == 0) { EntityLiving entityliving = this.getGoalTarget(); - if (entityliving != null && this.h(entityliving) < 16.0D) { + if (entityliving != null && this.h((Entity) entityliving) < 16.0D) { this.b(entityliving.locX, entityliving.locZ); this.moveController.a(entityliving.locX, entityliving.locY, entityliving.locZ, this.moveController.c()); - this.dy(); - this.bH = true; + this.dV(); + this.bD = true; } } - EntityRabbit.ControllerJumpRabbit entityrabbit_controllerjumprabbit = (EntityRabbit.ControllerJumpRabbit) this.h; + EntityRabbit.ControllerJumpRabbit entityrabbit_controllerjumprabbit = (EntityRabbit.ControllerJumpRabbit) this.bt; if (!entityrabbit_controllerjumprabbit.c()) { - if (this.moveController.b() && this.bI == 0) { - PathEntity pathentity = this.navigation.m(); + if (this.moveController.b() && this.bE == 0) { + PathEntity pathentity = this.navigation.l(); Vec3D vec3d = new Vec3D(this.moveController.d(), this.moveController.e(), this.moveController.f()); - if (pathentity != null && pathentity.e() < pathentity.d()) { + if (pathentity != null && pathentity.f() < pathentity.e()) { vec3d = pathentity.a((Entity) this); } this.b(vec3d.x, vec3d.z); - this.dy(); + this.dV(); } } else if (!entityrabbit_controllerjumprabbit.d()) { - this.dB(); + this.dY(); } } - this.bH = this.onGround; + this.bD = this.onGround; } - public void av() {} + @Override + public void aA() {} private void b(double d0, double d1) { - this.yaw = (float) (MathHelper.c(d1 - this.locZ, d0 - this.locX) * 57.2957763671875D) - 90.0F; + this.yaw = (float) (MathHelper.d(d1 - this.locZ, d0 - this.locX) * 57.2957763671875D) - 90.0F; } - private void dB() { - ((EntityRabbit.ControllerJumpRabbit) this.h).a(true); + private void dY() { + ((EntityRabbit.ControllerJumpRabbit) this.bt).a(true); } - private void dC() { - ((EntityRabbit.ControllerJumpRabbit) this.h).a(false); + private void dZ() { + ((EntityRabbit.ControllerJumpRabbit) this.bt).a(false); } - private void dH() { + private void ee() { if (this.moveController.c() < 2.2D) { - this.bI = 10; + this.bE = 10; } else { - this.bI = 1; + this.bE = 1; } } - private void dI() { - this.dH(); - this.dC(); + private void ef() { + this.ee(); + this.dZ(); } + @Override public void movementTick() { super.movementTick(); - if (this.bE != this.bG) { - ++this.bE; - } else if (this.bG != 0) { - this.bE = 0; - this.bG = 0; - this.o(false); + if (this.bB != this.bC) { + ++this.bB; + } else if (this.bC != 0) { + this.bB = 0; + this.bC = 0; + this.setJumping(false); } } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(3.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(3.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setInt("RabbitType", this.getRabbitType()); - nbttagcompound.setInt("MoreCarrotTicks", this.bJ); + nbttagcompound.setInt("MoreCarrotTicks", this.bF); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setRabbitType(nbttagcompound.getInt("RabbitType")); - this.bJ = nbttagcompound.getInt("MoreCarrotTicks"); + this.bF = nbttagcompound.getInt("MoreCarrotTicks"); } - protected SoundEffect dz() { + protected SoundEffect getSoundJump() { return SoundEffects.ENTITY_RABBIT_JUMP; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_RABBIT_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_RABBIT_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_RABBIT_DEATH; } - public boolean B(Entity entity) { + @Override + public boolean C(Entity entity) { if (this.getRabbitType() == 99) { this.a(SoundEffects.ENTITY_RABBIT_ATTACK, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); return entity.damageEntity(DamageSource.mobAttack(this), 8.0F); @@ -233,26 +248,24 @@ public class EntityRabbit extends EntityAnimal { } } - public SoundCategory bV() { + @Override + public SoundCategory getSoundCategory() { return this.getRabbitType() == 99 ? SoundCategory.HOSTILE : SoundCategory.NEUTRAL; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { return this.isInvulnerable(damagesource) ? false : super.damageEntity(damagesource, f); } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.I; - } - - private boolean a(Item item) { + private boolean b(Item item) { return item == Items.CARROT || item == Items.GOLDEN_CARROT || item == Blocks.DANDELION.getItem(); } + @Override public EntityRabbit createChild(EntityAgeable entityageable) { - EntityRabbit entityrabbit = EntityTypes.RABBIT.create(world); // Paper - int i = this.dJ(); + EntityRabbit entityrabbit = (EntityRabbit) EntityTypes.RABBIT.a(this.world); + int i = this.a((GeneratorAccess) this.world); if (this.random.nextInt(20) != 0) { if (entityageable instanceof EntityRabbit && this.random.nextBoolean()) { @@ -266,33 +279,35 @@ public class EntityRabbit extends EntityAnimal { return entityrabbit; } - public boolean f(ItemStack itemstack) { - return this.a(itemstack.getItem()); + @Override + public boolean i(ItemStack itemstack) { + return this.b(itemstack.getItem()); } public int getRabbitType() { - return (Integer) this.datawatcher.get(EntityRabbit.bC); + return (Integer) this.datawatcher.get(EntityRabbit.bz); } public void setRabbitType(int i) { if (i == 99) { - this.getAttributeInstance(GenericAttributes.h).setValue(8.0D); + this.getAttributeInstance(GenericAttributes.ARMOR).setValue(8.0D); this.goalSelector.a(4, new EntityRabbit.PathfinderGoalKillerRabbitMeleeAttack(this)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityWolf.class, true)); if (!this.hasCustomName()) { - this.setCustomName(new ChatMessage(SystemUtils.a("entity", EntityRabbit.bD), new Object[0])); + this.setCustomName(new ChatMessage(SystemUtils.a("entity", EntityRabbit.bA), new Object[0])); } } - this.datawatcher.set(EntityRabbit.bC, i); + this.datawatcher.set(EntityRabbit.bz, i); } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - Object object = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); - int i = this.dJ(); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + Object object = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + int i = this.a(generatoraccess); boolean flag = false; if (object instanceof EntityRabbit.GroupDataRabbit) { @@ -310,25 +325,21 @@ public class EntityRabbit extends EntityAnimal { return (GroupDataEntity) object; } - private int dJ() { - BiomeBase biomebase = this.world.getBiome(new BlockPosition(this)); + private int a(GeneratorAccess generatoraccess) { + BiomeBase biomebase = generatoraccess.getBiome(new BlockPosition(this)); int i = this.random.nextInt(100); - return biomebase.c() == BiomeBase.Precipitation.SNOW ? (i < 80 ? 1 : 3) : (biomebase.p() == BiomeBase.Geography.DESERT ? 4 : (i < 50 ? 0 : (i < 90 ? 5 : 2))); + return biomebase.b() == BiomeBase.Precipitation.SNOW ? (i < 80 ? 1 : 3) : (biomebase.o() == BiomeBase.Geography.DESERT ? 4 : (i < 50 ? 0 : (i < 90 ? 5 : 2))); } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - int i = MathHelper.floor(this.locX); - int j = MathHelper.floor(this.getBoundingBox().minY); - int k = MathHelper.floor(this.locZ); - BlockPosition blockposition = new BlockPosition(i, j, k); + public static boolean c(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { Block block = generatoraccess.getType(blockposition.down()).getBlock(); - return block != Blocks.GRASS && block != Blocks.SNOW && block != Blocks.SAND ? super.a(generatoraccess, flag) : true; + return (block == Blocks.GRASS_BLOCK || block == Blocks.SNOW || block == Blocks.SAND) && generatoraccess.getLightLevel(blockposition, 0) > 8; } - private boolean dK() { - return this.bJ == 0; + private boolean eg() { + return this.bF == 0; } static class PathfinderGoalKillerRabbitMeleeAttack extends PathfinderGoalMeleeAttack { @@ -337,8 +348,9 @@ public class EntityRabbit extends EntityAnimal { super(entityrabbit, 1.4D, true); } + @Override protected double a(EntityLiving entityliving) { - return (double) (4.0F + entityliving.width); + return (double) (4.0F + entityliving.getWidth()); } } @@ -351,51 +363,55 @@ public class EntityRabbit extends EntityAnimal { this.f = entityrabbit; } + @Override public void e() { super.e(); - this.f.c(this.b); + this.f.d(this.b); } } static class PathfinderGoalEatCarrots extends PathfinderGoalGotoTarget { private final EntityRabbit entity; - private boolean g; private boolean h; + private boolean i; public PathfinderGoalEatCarrots(EntityRabbit entityrabbit) { super(entityrabbit, 0.699999988079071D, 16); this.entity = entityrabbit; } + @Override public boolean a() { - if (this.b <= 0) { - if (!this.entity.world.getGameRules().getBoolean("mobGriefing")) { + if (this.c <= 0) { + if (!this.entity.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { return false; } - this.h = false; - this.g = this.entity.dK(); - this.g = true; + this.i = false; + this.h = this.entity.eg(); + this.h = true; } return super.a(); } + @Override public boolean b() { - return this.h && super.b(); + return this.i && super.b(); } + @Override public void e() { super.e(); - this.entity.getControllerLook().a((double) this.d.getX() + 0.5D, (double) (this.d.getY() + 1), (double) this.d.getZ() + 0.5D, 10.0F, (float) this.entity.K()); + this.entity.getControllerLook().a((double) this.e.getX() + 0.5D, (double) (this.e.getY() + 1), (double) this.e.getZ() + 0.5D, 10.0F, (float) this.entity.M()); if (this.k()) { World world = this.entity.world; - BlockPosition blockposition = this.d.up(); + BlockPosition blockposition = this.e.up(); IBlockData iblockdata = world.getType(blockposition); Block block = iblockdata.getBlock(); - if (this.h && block instanceof BlockCarrots) { + if (this.i && block instanceof BlockCarrots) { Integer integer = (Integer) iblockdata.get(BlockCarrots.AGE); if (integer == 0) { @@ -405,7 +421,7 @@ public class EntityRabbit extends EntityAnimal { } // CraftBukkit end world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 2); - world.setAir(blockposition, true); + world.b(blockposition, true); } else { // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent( @@ -420,25 +436,26 @@ public class EntityRabbit extends EntityAnimal { world.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); } - this.entity.bJ = 40; + this.entity.bF = 40; } - this.h = false; - this.b = 10; + this.i = false; + this.c = 10; } } + @Override protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) { Block block = iworldreader.getType(blockposition).getBlock(); - if (block == Blocks.FARMLAND && this.g && !this.h) { + if (block == Blocks.FARMLAND && this.h && !this.i) { blockposition = blockposition.up(); IBlockData iblockdata = iworldreader.getType(blockposition); block = iblockdata.getBlock(); - if (block instanceof BlockCarrots && ((BlockCarrots) block).w(iblockdata)) { - this.h = true; + if (block instanceof BlockCarrots && ((BlockCarrots) block).isRipe(iblockdata)) { + this.i = true; return true; } } @@ -447,17 +464,18 @@ public class EntityRabbit extends EntityAnimal { } } - static class PathfinderGoalRabbitAvoidTarget extends PathfinderGoalAvoidTarget { + static class PathfinderGoalRabbitAvoidTarget extends PathfinderGoalAvoidTarget { - private final EntityRabbit c; + private final EntityRabbit i; public PathfinderGoalRabbitAvoidTarget(EntityRabbit entityrabbit, Class oclass, float f, double d0, double d1) { super(entityrabbit, oclass, f, d0, d1); - this.c = entityrabbit; + this.i = entityrabbit; } + @Override public boolean a() { - return this.c.getRabbitType() != 99 && super.a(); + return this.i.getRabbitType() != 99 && super.a(); } } @@ -471,16 +489,18 @@ public class EntityRabbit extends EntityAnimal { this.i = entityrabbit; } + @Override public void a() { - if (this.i.onGround && !this.i.bg && !((EntityRabbit.ControllerJumpRabbit) this.i.h).c()) { - this.i.c(0.0D); + if (this.i.onGround && !this.i.jumping && !((EntityRabbit.ControllerJumpRabbit) this.i.bt).c()) { + this.i.d(0.0D); } else if (this.b()) { - this.i.c(this.j); + this.i.d(this.j); } super.a(); } + @Override public void a(double d0, double d1, double d2, double d3) { if (this.i.isInWater()) { d3 = 1.5D; @@ -516,9 +536,10 @@ public class EntityRabbit extends EntityAnimal { this.d = flag; } + @Override public void b() { if (this.a) { - this.c.dy(); + this.c.dV(); this.a = false; } @@ -527,7 +548,7 @@ public class EntityRabbit extends EntityAnimal { public static class GroupDataRabbit implements GroupDataEntity { - public int a; + public final int a; public GroupDataRabbit(int i) { this.a = i; diff --git a/src/main/java/net/minecraft/server/EntityRaider.java b/src/main/java/net/minecraft/server/EntityRaider.java new file mode 100644 index 000000000..6ffb35729 --- /dev/null +++ b/src/main/java/net/minecraft/server/EntityRaider.java @@ -0,0 +1,531 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; +import javax.annotation.Nullable; + +public abstract class EntityRaider extends EntityMonsterPatrolling { + + protected static final DataWatcherObject c = DataWatcher.a(EntityRaider.class, DataWatcherRegistry.i); + private static final Predicate b = (entityitem) -> { + return !entityitem.q() && entityitem.isAlive() && ItemStack.matches(entityitem.getItemStack(), Raid.s()); + }; + @Nullable + protected Raid d; + private int bz; + private boolean bA; + private int bB; + + protected EntityRaider(EntityTypes entitytypes, World world) { + super(entitytypes, world); + } + + @Override + protected void initPathfinder() { + super.initPathfinder(); + this.goalSelector.a(1, new EntityRaider.b<>(this)); + this.goalSelector.a(3, new PathfinderGoalRaid<>(this)); + this.goalSelector.a(4, new EntityRaider.d(this, 1.0499999523162842D, 1)); + this.goalSelector.a(5, new EntityRaider.c(this)); + } + + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityRaider.c, false); + } + + public abstract void a(int i, boolean flag); + + public boolean ei() { + return this.bA; + } + + public void t(boolean flag) { + this.bA = flag; + } + + @Override + public void movementTick() { + if (this.world instanceof WorldServer && this.isAlive()) { + Raid raid = this.ej(); + + if (this.ei()) { + if (raid == null) { + if (this.world.getTime() % 20L == 0L) { + Raid raid1 = ((WorldServer) this.world).c_(new BlockPosition(this)); + + if (raid1 != null && PersistentRaid.a(this, raid1)) { + raid1.a(raid1.k(), this, (BlockPosition) null, true); + } + } + } else { + EntityLiving entityliving = this.getGoalTarget(); + + if (entityliving != null && (entityliving.getEntityType() == EntityTypes.PLAYER || entityliving.getEntityType() == EntityTypes.IRON_GOLEM)) { + this.ticksFarFromPlayer = 0; + } + } + } + } + + super.movementTick(); + } + + @Override + protected void eb() { + this.ticksFarFromPlayer += 2; + } + + @Override + public void die(DamageSource damagesource) { + if (this.world instanceof WorldServer) { + Entity entity = damagesource.getEntity(); + Raid raid = this.ej(); + + if (raid != null) { + if (this.isPatrolLeader()) { + raid.c(this.el()); + } + + if (entity != null && entity.getEntityType() == EntityTypes.PLAYER) { + raid.a(entity); + } + + raid.a(this, false); + } + + if (this.isPatrolLeader() && raid == null && ((WorldServer) this.world).c_(new BlockPosition(this)) == null) { + ItemStack itemstack = this.getEquipment(EnumItemSlot.HEAD); + EntityHuman entityhuman = null; + + if (entity instanceof EntityHuman) { + entityhuman = (EntityHuman) entity; + } else if (entity instanceof EntityWolf) { + EntityWolf entitywolf = (EntityWolf) entity; + EntityLiving entityliving = entitywolf.getOwner(); + + if (entitywolf.isTamed() && entityliving instanceof EntityHuman) { + entityhuman = (EntityHuman) entityliving; + } + } + + if (!itemstack.isEmpty() && ItemStack.matches(itemstack, Raid.s()) && entityhuman != null) { + MobEffect mobeffect = entityhuman.getEffect(MobEffects.BAD_OMEN); + byte b0 = 1; + int i; + + if (mobeffect != null) { + i = b0 + mobeffect.getAmplifier(); + entityhuman.c(MobEffects.BAD_OMEN); + } else { + i = b0 - 1; + } + + i = MathHelper.clamp(i, 0, 5); + MobEffect mobeffect1 = new MobEffect(MobEffects.BAD_OMEN, 120000, i, false, false, true); + + if (!this.world.getGameRules().getBoolean(GameRules.x)) { + entityhuman.addEffect(mobeffect1); + } + } + } + } + + super.die(damagesource); + } + + @Override + public boolean ec() { + return !this.ek(); + } + + public void a(@Nullable Raid raid) { + this.d = raid; + } + + @Nullable + public Raid ej() { + return this.d; + } + + public boolean ek() { + return this.ej() != null && this.ej().v(); + } + + public void a(int i) { + this.bz = i; + } + + public int el() { + return this.bz; + } + + public void u(boolean flag) { + this.datawatcher.set(EntityRaider.c, flag); + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("Wave", this.bz); + nbttagcompound.setBoolean("CanJoinRaid", this.bA); + if (this.d != null) { + nbttagcompound.setInt("RaidId", this.d.u()); + } + + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.bz = nbttagcompound.getInt("Wave"); + this.bA = nbttagcompound.getBoolean("CanJoinRaid"); + if (nbttagcompound.hasKeyOfType("RaidId", 3)) { + if (this.world instanceof WorldServer) { + this.d = ((WorldServer) this.world).C().a(nbttagcompound.getInt("RaidId")); + } + + if (this.d != null) { + this.d.a(this.bz, this, false); + if (this.isPatrolLeader()) { + this.d.a(this.bz, this); + } + } + } + + } + + @Override + protected void a(EntityItem entityitem) { + ItemStack itemstack = entityitem.getItemStack(); + boolean flag = this.ek() && this.ej().b(this.el()) != null; + + if (this.ek() && !flag && ItemStack.matches(itemstack, Raid.s())) { + EnumItemSlot enumitemslot = EnumItemSlot.HEAD; + ItemStack itemstack1 = this.getEquipment(enumitemslot); + double d0 = (double) this.d(enumitemslot); + + if (!itemstack1.isEmpty() && (double) (this.random.nextFloat() - 0.1F) < d0) { + this.a(itemstack1); + } + + this.setSlot(enumitemslot, itemstack); + this.receive(entityitem, itemstack.getCount()); + entityitem.die(); + this.ej().a(this.el(), this); + this.setPatrolLeader(true); + } else { + super.a(entityitem); + } + + } + + @Override + public boolean isTypeNotPersistent(double d0) { + return this.ej() == null ? super.isTypeNotPersistent(d0) : false; + } + + @Override + public boolean I() { + return this.ej() != null; + } + + public int en() { + return this.bB; + } + + public void b(int i) { + this.bB = i; + } + + @Override + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.ek()) { + this.ej().p(); + } + + return super.damageEntity(damagesource, f); + } + + @Nullable + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.t(this.getEntityType() != EntityTypes.WITCH || enummobspawn != EnumMobSpawn.NATURAL); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + } + + public abstract SoundEffect dV(); + + static class d extends PathfinderGoal { + + private final EntityRaider a; + private final double b; + private BlockPosition c; + private final List d = Lists.newArrayList(); + private final int e; + private boolean f; + + public d(EntityRaider entityraider, double d0, int i) { + this.a = entityraider; + this.b = d0; + this.e = i; + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); + } + + @Override + public boolean a() { + this.j(); + return this.g() && this.h() && this.a.getGoalTarget() == null; + } + + private boolean g() { + return this.a.ek() && !this.a.ej().a(); + } + + private boolean h() { + WorldServer worldserver = (WorldServer) this.a.world; + BlockPosition blockposition = new BlockPosition(this.a); + Optional optional = worldserver.B().a((villageplacetype) -> { + return villageplacetype == VillagePlaceType.q; + }, this::a, VillagePlace.Occupancy.ANY, blockposition, 48, this.a.random); + + if (!optional.isPresent()) { + return false; + } else { + this.c = ((BlockPosition) optional.get()).immutableCopy(); + return true; + } + } + + @Override + public boolean b() { + return this.a.getNavigation().n() ? false : this.a.getGoalTarget() == null && !this.c.a((IPosition) this.a.getPositionVector(), (double) (this.a.getWidth() + (float) this.e)) && !this.f; + } + + @Override + public void d() { + if (this.c.a((IPosition) this.a.getPositionVector(), (double) this.e)) { + this.d.add(this.c); + } + + } + + @Override + public void c() { + super.c(); + this.a.n(0); + this.a.getNavigation().a((double) this.c.getX(), (double) this.c.getY(), (double) this.c.getZ(), this.b); + this.f = false; + } + + @Override + public void e() { + if (this.a.getNavigation().n()) { + int i = this.c.getX(); + int j = this.c.getY(); + int k = this.c.getZ(); + Vec3D vec3d = RandomPositionGenerator.a((EntityCreature) this.a, 16, 7, new Vec3D((double) i, (double) j, (double) k), 0.3141592741012573D); + + if (vec3d == null) { + vec3d = RandomPositionGenerator.a(this.a, 8, 7, new Vec3D((double) i, (double) j, (double) k)); + } + + if (vec3d == null) { + this.f = true; + return; + } + + this.a.getNavigation().a(vec3d.x, vec3d.y, vec3d.z, this.b); + } + + } + + private boolean a(BlockPosition blockposition) { + Iterator iterator = this.d.iterator(); + + BlockPosition blockposition1; + + do { + if (!iterator.hasNext()) { + return true; + } + + blockposition1 = (BlockPosition) iterator.next(); + } while (!Objects.equals(blockposition, blockposition1)); + + return false; + } + + private void j() { + if (this.d.size() > 2) { + this.d.remove(0); + } + + } + } + + public class a extends PathfinderGoal { + + private final EntityRaider c; + private final float d; + public final PathfinderTargetCondition a = (new PathfinderTargetCondition()).a(8.0D).d().a().b().c().e(); + + public a(EntityIllagerAbstract entityillagerabstract, float f) { + this.c = entityillagerabstract; + this.d = f * f; + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); + } + + @Override + public boolean a() { + EntityLiving entityliving = this.c.getLastDamager(); + + return this.c.ej() == null && this.c.isPatrolling() && this.c.getGoalTarget() != null && !this.c.dR() && (entityliving == null || entityliving.getEntityType() != EntityTypes.PLAYER); + } + + @Override + public void c() { + super.c(); + this.c.getNavigation().o(); + List list = this.c.world.a(EntityRaider.class, this.a, this.c, this.c.getBoundingBox().grow(8.0D, 8.0D, 8.0D)); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityRaider entityraider = (EntityRaider) iterator.next(); + + entityraider.setGoalTarget(this.c.getGoalTarget(), org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER, true); // CraftBukkit + } + + } + + @Override + public void d() { + super.d(); + EntityLiving entityliving = this.c.getGoalTarget(); + + if (entityliving != null) { + List list = this.c.world.a(EntityRaider.class, this.a, this.c, this.c.getBoundingBox().grow(8.0D, 8.0D, 8.0D)); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityRaider entityraider = (EntityRaider) iterator.next(); + + entityraider.setGoalTarget(this.c.getGoalTarget(), org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER, true); // CraftBukkit + entityraider.q(true); + } + + this.c.q(true); + } + + } + + @Override + public void e() { + EntityLiving entityliving = this.c.getGoalTarget(); + + if (entityliving != null) { + if (this.c.h((Entity) entityliving) > (double) this.d) { + this.c.getControllerLook().a(entityliving, 30.0F, 30.0F); + if (this.c.random.nextInt(50) == 0) { + this.c.B(); + } + } else { + this.c.q(true); + } + + super.e(); + } + } + } + + public class c extends PathfinderGoal { + + private final EntityRaider b; + + c(EntityRaider entityraider) { + this.b = entityraider; + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); + } + + @Override + public boolean a() { + Raid raid = this.b.ej(); + + return this.b.isAlive() && this.b.getGoalTarget() == null && raid != null && raid.f(); + } + + @Override + public void c() { + this.b.u(true); + super.c(); + } + + @Override + public void d() { + this.b.u(false); + super.d(); + } + + @Override + public void e() { + if (!this.b.isSilent() && this.b.random.nextInt(100) == 0) { + EntityRaider.this.a(EntityRaider.this.dV(), EntityRaider.this.getSoundVolume(), EntityRaider.this.cV()); + } + + if (!this.b.isPassenger() && this.b.random.nextInt(50) == 0) { + this.b.getControllerJump().jump(); + } + + super.e(); + } + } + + public class b extends PathfinderGoal { + + private final T b; + + public b(T entityraider) { // CraftBukkit - decompile error + this.b = entityraider; + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); + } + + @Override + public boolean a() { + Raid raid = this.b.ej(); + + if (this.b.ek() && !this.b.ej().a() && this.b.dX() && !ItemStack.matches(this.b.getEquipment(EnumItemSlot.HEAD), Raid.s())) { + EntityRaider entityraider = raid.b(this.b.el()); + + if (entityraider == null || !entityraider.isAlive()) { + List list = this.b.world.a(EntityItem.class, this.b.getBoundingBox().grow(16.0D, 8.0D, 16.0D), EntityRaider.b); + + if (!list.isEmpty()) { + return this.b.getNavigation().a((Entity) list.get(0), 1.149999976158142D); + } + } + + return false; + } else { + return false; + } + } + + @Override + public void e() { + if (this.b.getNavigation().h().a((IPosition) this.b.getPositionVector(), 1.414D)) { + List list = this.b.world.a(EntityItem.class, this.b.getBoundingBox().grow(4.0D, 4.0D, 4.0D), EntityRaider.b); + + if (!list.isEmpty()) { + this.b.a((EntityItem) list.get(0)); + } + } + + } + } +} diff --git a/src/main/java/net/minecraft/server/EntityRavager.java b/src/main/java/net/minecraft/server/EntityRavager.java new file mode 100644 index 000000000..971ea097b --- /dev/null +++ b/src/main/java/net/minecraft/server/EntityRavager.java @@ -0,0 +1,312 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; +import javax.annotation.Nullable; + +public class EntityRavager extends EntityRaider { + + private static final Predicate b = (entity) -> { + return entity.isAlive() && !(entity instanceof EntityRavager); + }; + private int bz; + private int bA; + private int bB; + + public EntityRavager(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.K = 1.0F; + this.f = 20; + } + + @Override + protected void initPathfinder() { + super.initPathfinder(); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(4, new EntityRavager.a()); + this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.4D)); + this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + this.targetSelector.a(2, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); + this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, true)); + this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); + } + + @Override + protected void F() { + boolean flag = !(this.getRidingPassenger() instanceof EntityInsentient) || this.getRidingPassenger().getEntityType().a(TagsEntity.RADIERS); + boolean flag1 = !(this.getVehicle() instanceof EntityBoat); + + this.goalSelector.a(PathfinderGoal.Type.MOVE, flag); + this.goalSelector.a(PathfinderGoal.Type.JUMP, flag && flag1); + this.goalSelector.a(PathfinderGoal.Type.LOOK, flag); + this.goalSelector.a(PathfinderGoal.Type.TARGET, flag); + } + + @Override + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(100.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.3D); + this.getAttributeInstance(GenericAttributes.KNOCKBACK_RESISTANCE).setValue(0.5D); + this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(12.0D); + this.getAttributeInstance(GenericAttributes.ATTACK_KNOCKBACK).setValue(1.5D); + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(32.0D); + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("AttackTick", this.bz); + nbttagcompound.setInt("StunTick", this.bA); + nbttagcompound.setInt("RoarTick", this.bB); + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.bz = nbttagcompound.getInt("AttackTick"); + this.bA = nbttagcompound.getInt("StunTick"); + this.bB = nbttagcompound.getInt("RoarTick"); + } + + @Override + public SoundEffect dV() { + return SoundEffects.ENTITY_RAVAGER_CELEBRATE; + } + + @Override + protected NavigationAbstract b(World world) { + return new EntityRavager.b(this, world); + } + + @Override + public int dA() { + return 45; + } + + @Override + public double aP() { + return 2.1D; + } + + @Override + public boolean dD() { + return !this.isNoAI() && this.getRidingPassenger() instanceof EntityLiving; + } + + @Nullable + @Override + public Entity getRidingPassenger() { + return this.getPassengers().isEmpty() ? null : (Entity) this.getPassengers().get(0); + } + + @Override + public void movementTick() { + super.movementTick(); + if (this.isAlive()) { + if (this.isFrozen()) { + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.0D); + } else { + double d0 = this.getGoalTarget() != null ? 0.35D : 0.3D; + double d1 = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getBaseValue(); + + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(MathHelper.d(0.1D, d1, d0)); + } + + if (this.positionChanged && this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { + boolean flag = false; + AxisAlignedBB axisalignedbb = this.getBoundingBox().g(0.2D); + Iterator iterator = BlockPosition.b(MathHelper.floor(axisalignedbb.minX), MathHelper.floor(axisalignedbb.minY), MathHelper.floor(axisalignedbb.minZ), MathHelper.floor(axisalignedbb.maxX), MathHelper.floor(axisalignedbb.maxY), MathHelper.floor(axisalignedbb.maxZ)).iterator(); + + while (iterator.hasNext()) { + BlockPosition blockposition = (BlockPosition) iterator.next(); + IBlockData iblockdata = this.world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (block instanceof BlockLeaves && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { // CraftBukkit + flag = this.world.b(blockposition, true) || flag; + } + } + + if (!flag && this.onGround) { + this.jump(); + } + } + + if (this.bB > 0) { + --this.bB; + if (this.bB == 10) { + this.eh(); + } + } + + if (this.bz > 0) { + --this.bz; + } + + if (this.bA > 0) { + --this.bA; + this.eg(); + if (this.bA == 0) { + this.a(SoundEffects.ENTITY_RAVAGER_ROAR, 1.0F, 1.0F); + this.bB = 20; + } + } + + } + } + + private void eg() { + if (this.random.nextInt(6) == 0) { + double d0 = this.locX - (double) this.getWidth() * Math.sin((double) (this.aK * 0.017453292F)) + (this.random.nextDouble() * 0.6D - 0.3D); + double d1 = this.locY + (double) this.getHeight() - 0.3D; + double d2 = this.locZ + (double) this.getWidth() * Math.cos((double) (this.aK * 0.017453292F)) + (this.random.nextDouble() * 0.6D - 0.3D); + + this.world.addParticle(Particles.ENTITY_EFFECT, d0, d1, d2, 0.4980392156862745D, 0.5137254901960784D, 0.5725490196078431D); + } + + } + + @Override + protected boolean isFrozen() { + return super.isFrozen() || this.bz > 0 || this.bA > 0 || this.bB > 0; + } + + @Override + public boolean hasLineOfSight(Entity entity) { + return this.bA <= 0 && this.bB <= 0 ? super.hasLineOfSight(entity) : false; + } + + @Override + protected void e(EntityLiving entityliving) { + if (this.bB == 0) { + if (this.random.nextDouble() < 0.5D) { + this.bA = 40; + this.a(SoundEffects.ENTITY_RAVAGER_STUNNED, 1.0F, 1.0F); + this.world.broadcastEntityEffect(this, (byte) 39); + entityliving.collide(this); + } else { + this.a((Entity) entityliving); + } + + entityliving.velocityChanged = true; + } + + } + + private void eh() { + if (this.isAlive()) { + List list = this.world.a(EntityLiving.class, this.getBoundingBox().g(4.0D), EntityRavager.b); + + Entity entity; + + for (Iterator iterator = list.iterator(); iterator.hasNext(); this.a(entity)) { + entity = (Entity) iterator.next(); + if (!(entity instanceof EntityIllagerAbstract)) { + entity.damageEntity(DamageSource.mobAttack(this), 6.0F); + } + } + + Vec3D vec3d = this.getBoundingBox().f(); + + for (int i = 0; i < 40; ++i) { + double d0 = this.random.nextGaussian() * 0.2D; + double d1 = this.random.nextGaussian() * 0.2D; + double d2 = this.random.nextGaussian() * 0.2D; + + this.world.addParticle(Particles.POOF, vec3d.x, vec3d.y, vec3d.z, d0, d1, d2); + } + } + + } + + private void a(Entity entity) { + double d0 = entity.locX - this.locX; + double d1 = entity.locZ - this.locZ; + double d2 = Math.max(d0 * d0 + d1 * d1, 0.001D); + + entity.f(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D); + } + + @Override + public boolean C(Entity entity) { + this.bz = 10; + this.world.broadcastEntityEffect(this, (byte) 4); + this.a(SoundEffects.ENTITY_RAVAGER_ATTACK, 1.0F, 1.0F); + return super.C(entity); + } + + @Nullable + @Override + protected SoundEffect getSoundAmbient() { + return SoundEffects.ENTITY_RAVAGER_AMBIENT; + } + + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return SoundEffects.ENTITY_RAVAGER_HURT; + } + + @Override + protected SoundEffect getSoundDeath() { + return SoundEffects.ENTITY_RAVAGER_DEATH; + } + + @Override + protected void a(BlockPosition blockposition, IBlockData iblockdata) { + this.a(SoundEffects.ENTITY_RAVAGER_STEP, 0.15F, 1.0F); + } + + @Override + public boolean a(IWorldReader iworldreader) { + return !iworldreader.containsLiquid(this.getBoundingBox()); + } + + @Override + public void a(int i, boolean flag) {} + + @Override + public boolean dX() { + return false; + } + + static class c extends PathfinderNormal { + + private c() {} + + @Override + protected PathType a(IBlockAccess iblockaccess, boolean flag, boolean flag1, BlockPosition blockposition, PathType pathtype) { + return pathtype == PathType.LEAVES ? PathType.OPEN : super.a(iblockaccess, flag, flag1, blockposition, pathtype); + } + } + + static class b extends Navigation { + + public b(EntityInsentient entityinsentient, World world) { + super(entityinsentient, world); + } + + @Override + protected Pathfinder a(int i) { + this.o = new EntityRavager.c(); + return new Pathfinder(this.o, i); + } + } + + class a extends PathfinderGoalMeleeAttack { + + public a() { + super(EntityRavager.this, 1.0D, true); + } + + @Override + protected double a(EntityLiving entityliving) { + float f = EntityRavager.this.getWidth() - 0.1F; + + return (double) (f * 2.0F * f * 2.0F + entityliving.getWidth()); + } + } +} diff --git a/src/main/java/net/minecraft/server/EntitySelector.java b/src/main/java/net/minecraft/server/EntitySelector.java index fb694104d..8ae668f67 100644 --- a/src/main/java/net/minecraft/server/EntitySelector.java +++ b/src/main/java/net/minecraft/server/EntitySelector.java @@ -27,10 +27,11 @@ public class EntitySelector { private final String j; @Nullable private final UUID k; - private final Class l; - private final boolean m; + @Nullable + private final EntityTypes l; + private final boolean checkPermissions; - public EntitySelector(int i, boolean flag, boolean flag1, Predicate predicate, CriterionConditionValue.FloatRange criterionconditionvalue_floatrange, Function function, @Nullable AxisAlignedBB axisalignedbb, BiConsumer> biconsumer, boolean flag2, @Nullable String s, @Nullable UUID uuid, Class oclass, boolean flag3) { + public EntitySelector(int i, boolean flag, boolean flag1, Predicate predicate, CriterionConditionValue.FloatRange criterionconditionvalue_floatrange, Function function, @Nullable AxisAlignedBB axisalignedbb, BiConsumer> biconsumer, boolean flag2, @Nullable String s, @Nullable UUID uuid, @Nullable EntityTypes entitytypes, boolean flag3) { this.a = i; this.b = flag; this.c = flag1; @@ -42,8 +43,8 @@ public class EntitySelector { this.i = flag2; this.j = s; this.k = uuid; - this.l = oclass; - this.m = flag3; + this.l = entitytypes; + this.checkPermissions = flag3; } public int a() { @@ -63,14 +64,14 @@ public class EntitySelector { } private void e(CommandListenerWrapper commandlistenerwrapper) throws CommandSyntaxException { - if (this.m && !commandlistenerwrapper.hasPermission(2, "minecraft.command.selector")) { // CraftBukkit + if (this.checkPermissions && !commandlistenerwrapper.hasPermission(2, "minecraft.command.selector")) { // CraftBukkit throw ArgumentEntity.f.create(); } } public Entity a(CommandListenerWrapper commandlistenerwrapper) throws CommandSyntaxException { this.e(commandlistenerwrapper); - List list = this.b(commandlistenerwrapper); + List list = this.getEntities(commandlistenerwrapper); if (list.isEmpty()) { throw ArgumentEntity.d.create(); @@ -81,14 +82,14 @@ public class EntitySelector { } } - public List b(CommandListenerWrapper commandlistenerwrapper) throws CommandSyntaxException { + public List getEntities(CommandListenerWrapper commandlistenerwrapper) throws CommandSyntaxException { this.e(commandlistenerwrapper); if (!this.b) { return this.d(commandlistenerwrapper); } else if (this.j != null) { EntityPlayer entityplayer = commandlistenerwrapper.getServer().getPlayerList().getPlayer(this.j); - return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new EntityPlayer[] { entityplayer})); + return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new EntityPlayer[]{entityplayer})); } else if (this.k != null) { Iterator iterator = commandlistenerwrapper.getServer().getWorlds().iterator(); @@ -104,13 +105,13 @@ public class EntitySelector { entity = worldserver.getEntity(this.k); } while (entity == null); - return Lists.newArrayList(new Entity[] { entity}); + return Lists.newArrayList(new Entity[]{entity}); } else { Vec3D vec3d = (Vec3D) this.f.apply(commandlistenerwrapper.getPosition()); Predicate predicate = this.a(vec3d); if (this.i) { - return (List) (commandlistenerwrapper.getEntity() != null && predicate.test(commandlistenerwrapper.getEntity()) ? Lists.newArrayList(new Entity[] { commandlistenerwrapper.getEntity()}) : Collections.emptyList()); + return (List) (commandlistenerwrapper.getEntity() != null && predicate.test(commandlistenerwrapper.getEntity()) ? Lists.newArrayList(new Entity[]{commandlistenerwrapper.getEntity()}) : Collections.emptyList()); } else { List list = Lists.newArrayList(); @@ -132,18 +133,10 @@ public class EntitySelector { } private void a(List list, WorldServer worldserver, Vec3D vec3d, Predicate predicate) { - Class oclass; - if (this.g != null) { - oclass = this.l; - AxisAlignedBB axisalignedbb = this.g.a(vec3d); - - predicate.getClass(); - list.addAll(worldserver.a(oclass, axisalignedbb, (java.util.function.Predicate) predicate::test)); // CraftBukkit - decompile error + list.addAll(worldserver.a(this.l, this.g.b(vec3d), predicate)); } else { - oclass = this.l; - predicate.getClass(); - list.addAll(worldserver.a(oclass, predicate::test)); + list.addAll(worldserver.a(this.l, predicate)); } } @@ -165,10 +158,10 @@ public class EntitySelector { if (this.j != null) { entityplayer = commandlistenerwrapper.getServer().getPlayerList().getPlayer(this.j); - return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new EntityPlayer[] { entityplayer})); + return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new EntityPlayer[]{entityplayer})); } else if (this.k != null) { entityplayer = commandlistenerwrapper.getServer().getPlayerList().a(this.k); - return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new EntityPlayer[] { entityplayer})); + return (List) (entityplayer == null ? Collections.emptyList() : Lists.newArrayList(new EntityPlayer[]{entityplayer})); } else { Vec3D vec3d = (Vec3D) this.f.apply(commandlistenerwrapper.getPosition()); Predicate predicate = this.a(vec3d); @@ -178,7 +171,7 @@ public class EntitySelector { EntityPlayer entityplayer1 = (EntityPlayer) commandlistenerwrapper.getEntity(); if (predicate.test(entityplayer1)) { - return Lists.newArrayList(new EntityPlayer[] { entityplayer1}); + return Lists.newArrayList(new EntityPlayer[]{entityplayer1}); } } @@ -190,10 +183,10 @@ public class EntitySelector { WorldServer worldserver = commandlistenerwrapper.getWorld(); predicate.getClass(); - object = worldserver.b(EntityPlayer.class, predicate::test); + object = worldserver.a(predicate::test); } else { object = Lists.newArrayList(); - Iterator iterator = commandlistenerwrapper.getServer().getPlayerList().v().iterator(); + Iterator iterator = commandlistenerwrapper.getServer().getPlayerList().getPlayers().iterator(); while (iterator.hasNext()) { EntityPlayer entityplayer2 = (EntityPlayer) iterator.next(); @@ -213,7 +206,7 @@ public class EntitySelector { Predicate predicate = this.d; if (this.g != null) { - AxisAlignedBB axisalignedbb = this.g.a(vec3d); + AxisAlignedBB axisalignedbb = this.g.b(vec3d); predicate = predicate.and((entity) -> { return axisalignedbb.c(entity.getBoundingBox()); @@ -222,7 +215,7 @@ public class EntitySelector { if (!this.e.c()) { predicate = predicate.and((entity) -> { - return this.e.a(entity.a(vec3d)); + return this.e.a(entity.c(vec3d)); }); } diff --git a/src/main/java/net/minecraft/server/EntitySheep.java b/src/main/java/net/minecraft/server/EntitySheep.java index c35d1eef4..ec13d4f37 100644 --- a/src/main/java/net/minecraft/server/EntitySheep.java +++ b/src/main/java/net/minecraft/server/EntitySheep.java @@ -4,6 +4,7 @@ import com.google.common.collect.Maps; import java.util.Arrays; import java.util.EnumMap; import java.util.Map; +import java.util.Optional; import java.util.Random; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -16,20 +17,8 @@ import org.bukkit.inventory.InventoryView; public class EntitySheep extends EntityAnimal { - private static final DataWatcherObject bC = DataWatcher.a(EntitySheep.class, DataWatcherRegistry.a); - private final InventoryCrafting container = new InventoryCrafting(new Container() { - public boolean canUse(EntityHuman entityhuman) { - return false; - } - - // CraftBukkit start - @Override - public InventoryView getBukkitView() { - return null; // TODO: O.O - } - // CraftBukkit end - }, 2, 1); - private static final Map bE = (Map) SystemUtils.a(Maps.newEnumMap(EnumColor.class), (enummap) -> { // CraftBukkit - decompile error + private static final DataWatcherObject bz = DataWatcher.a(EntitySheep.class, DataWatcherRegistry.a); + private static final Map bA = (Map) SystemUtils.a(Maps.newEnumMap(EnumColor.class), (enummap) -> { // CraftBukkit - decompile error enummap.put(EnumColor.WHITE, Blocks.WHITE_WOOL); enummap.put(EnumColor.ORANGE, Blocks.ORANGE_WOOL); enummap.put(EnumColor.MAGENTA, Blocks.MAGENTA_WOOL); @@ -47,194 +36,211 @@ public class EntitySheep extends EntityAnimal { enummap.put(EnumColor.RED, Blocks.RED_WOOL); enummap.put(EnumColor.BLACK, Blocks.BLACK_WOOL); }); - private static final Map bG = Maps.newEnumMap((Map) Arrays.stream(EnumColor.values()).collect(Collectors.toMap((enumcolor) -> { + private static final Map bB = Maps.newEnumMap((Map) Arrays.stream(EnumColor.values()).collect(Collectors.toMap((enumcolor) -> { return enumcolor; }, EntitySheep::c))); - private int bH; - private PathfinderGoalEatTile bI; + private int bC; + private PathfinderGoalEatTile bD; private static float[] c(EnumColor enumcolor) { if (enumcolor == EnumColor.WHITE) { - return new float[] { 0.9019608F, 0.9019608F, 0.9019608F}; + return new float[]{0.9019608F, 0.9019608F, 0.9019608F}; } else { float[] afloat = enumcolor.d(); float f = 0.75F; - return new float[] { afloat[0] * 0.75F, afloat[1] * 0.75F, afloat[2] * 0.75F}; + return new float[]{afloat[0] * 0.75F, afloat[1] * 0.75F, afloat[2] * 0.75F}; } } - public EntitySheep(World world) { - super(EntityTypes.SHEEP, world); - this.setSize(0.9F, 1.3F); + public EntitySheep(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - protected void n() { - this.bI = new PathfinderGoalEatTile(this); + @Override + protected void initPathfinder() { + this.bD = new PathfinderGoalEatTile(this); this.goalSelector.a(0, new PathfinderGoalFloat(this)); this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.1D, RecipeItemStack.a(Items.WHEAT), false)); this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.1D)); - this.goalSelector.a(5, this.bI); + this.goalSelector.a(5, this.bD); this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); } + @Override protected void mobTick() { - this.bH = this.bI.g(); + this.bC = this.bD.g(); super.mobTick(); } + @Override public void movementTick() { if (this.world.isClientSide) { - this.bH = Math.max(0, this.bH - 1); + this.bC = Math.max(0, this.bC - 1); } super.movementTick(); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(8.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(8.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.23000000417232513D); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntitySheep.bC, (byte) 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntitySheep.bz, (byte) 0); } - @Nullable - protected MinecraftKey getDefaultLootTable() { + @Override + public MinecraftKey getDefaultLootTable() { if (this.isSheared()) { - return LootTables.W; + return this.getEntityType().h(); } else { switch (this.getColor()) { - case WHITE: - default: - return LootTables.X; - case ORANGE: - return LootTables.Y; - case MAGENTA: - return LootTables.Z; - case LIGHT_BLUE: - return LootTables.aa; - case YELLOW: - return LootTables.ab; - case LIME: - return LootTables.ac; - case PINK: - return LootTables.ad; - case GRAY: - return LootTables.ae; - case LIGHT_GRAY: - return LootTables.af; - case CYAN: - return LootTables.ag; - case PURPLE: - return LootTables.ah; - case BLUE: - return LootTables.ai; - case BROWN: - return LootTables.aj; - case GREEN: - return LootTables.ak; - case RED: - return LootTables.al; - case BLACK: - return LootTables.am; + case WHITE: + default: + return LootTables.L; + case ORANGE: + return LootTables.M; + case MAGENTA: + return LootTables.N; + case LIGHT_BLUE: + return LootTables.O; + case YELLOW: + return LootTables.P; + case LIME: + return LootTables.Q; + case PINK: + return LootTables.R; + case GRAY: + return LootTables.S; + case LIGHT_GRAY: + return LootTables.T; + case CYAN: + return LootTables.U; + case PURPLE: + return LootTables.V; + case BLUE: + return LootTables.W; + case BROWN: + return LootTables.X; + case GREEN: + return LootTables.Y; + case RED: + return LootTables.Z; + case BLACK: + return LootTables.aa; } } } + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); if (itemstack.getItem() == Items.SHEARS && !this.isSheared() && !this.isBaby()) { - if (!this.world.isClientSide) { - // CraftBukkit start - PlayerShearEntityEvent event = new PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); - this.world.getServer().getPluginManager().callEvent(event); + // CraftBukkit start + PlayerShearEntityEvent event = new PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); + this.world.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return false; - } - // CraftBukkit end - - this.setSheared(true); - int i = 1 + this.random.nextInt(3); - - for (int j = 0; j < i; ++j) { - this.forceDrops = true; // CraftBukkit - EntityItem entityitem = this.a((IMaterial) EntitySheep.bE.get(this.getColor()), 1); - this.forceDrops = false; // CraftBukkit - - if (entityitem != null) { - entityitem.motY += (double) (this.random.nextFloat() * 0.05F); - entityitem.motX += (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F); - entityitem.motZ += (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F); - } - } + if (event.isCancelled()) { + return false; } + // CraftBukkit end - itemstack.damage(1, entityhuman); - this.a(SoundEffects.ENTITY_SHEEP_SHEAR, 1.0F, 1.0F); + this.shear(); + if (!this.world.isClientSide) { + itemstack.damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(enumhand); + }); + } } return super.a(entityhuman, enumhand); } + public void shear() { + if (!this.world.isClientSide) { + this.setSheared(true); + int i = 1 + this.random.nextInt(3); + + for (int j = 0; j < i; ++j) { + this.forceDrops = true; // CraftBukkit + EntityItem entityitem = this.a((IMaterial) EntitySheep.bA.get(this.getColor()), 1); + this.forceDrops = false; // CraftBukkit + + if (entityitem != null) { + entityitem.setMot(entityitem.getMot().add((double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F), (double) (this.random.nextFloat() * 0.05F), (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F))); + } + } + } + + this.a(SoundEffects.ENTITY_SHEEP_SHEAR, 1.0F, 1.0F); + } + + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setBoolean("Sheared", this.isSheared()); nbttagcompound.setByte("Color", (byte) this.getColor().getColorIndex()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setSheared(nbttagcompound.getBoolean("Sheared")); this.setColor(EnumColor.fromColorIndex(nbttagcompound.getByte("Color"))); } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_SHEEP_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_SHEEP_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_SHEEP_DEATH; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(SoundEffects.ENTITY_SHEEP_STEP, 0.15F, 1.0F); } public EnumColor getColor() { - return EnumColor.fromColorIndex((Byte) this.datawatcher.get(EntitySheep.bC) & 15); + return EnumColor.fromColorIndex((Byte) this.datawatcher.get(EntitySheep.bz) & 15); } public void setColor(EnumColor enumcolor) { - byte b0 = (Byte) this.datawatcher.get(EntitySheep.bC); + byte b0 = (Byte) this.datawatcher.get(EntitySheep.bz); - this.datawatcher.set(EntitySheep.bC, (byte) (b0 & 240 | enumcolor.getColorIndex() & 15)); + this.datawatcher.set(EntitySheep.bz, (byte) (b0 & 240 | enumcolor.getColorIndex() & 15)); } public boolean isSheared() { - return ((Byte) this.datawatcher.get(EntitySheep.bC) & 16) != 0; + return ((Byte) this.datawatcher.get(EntitySheep.bz) & 16) != 0; } public void setSheared(boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntitySheep.bC); + byte b0 = (Byte) this.datawatcher.get(EntitySheep.bz); if (flag) { - this.datawatcher.set(EntitySheep.bC, (byte) (b0 | 16)); + this.datawatcher.set(EntitySheep.bz, (byte) (b0 | 16)); } else { - this.datawatcher.set(EntitySheep.bC, (byte) (b0 & -17)); + this.datawatcher.set(EntitySheep.bz, (byte) (b0 & -17)); } } @@ -245,15 +251,17 @@ public class EntitySheep extends EntityAnimal { return i < 5 ? EnumColor.BLACK : (i < 10 ? EnumColor.GRAY : (i < 15 ? EnumColor.LIGHT_GRAY : (i < 18 ? EnumColor.BROWN : (random.nextInt(500) == 0 ? EnumColor.PINK : EnumColor.WHITE)))); } + @Override public EntitySheep createChild(EntityAgeable entityageable) { EntitySheep entitysheep = (EntitySheep) entityageable; - EntitySheep entitysheep1 = EntityTypes.SHEEP.create(world); // Paper + EntitySheep entitysheep1 = (EntitySheep) EntityTypes.SHEEP.a(this.world); entitysheep1.setColor(this.a((EntityAnimal) this, (EntityAnimal) entitysheep)); return entitysheep1; } - public void x() { + @Override + public void blockEaten() { // CraftBukkit start SheepRegrowWoolEvent event = new SheepRegrowWoolEvent((org.bukkit.entity.Sheep) this.getBukkitEntity()); this.world.getServer().getPluginManager().callEvent(event); @@ -268,33 +276,52 @@ public class EntitySheep extends EntityAnimal { } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - groupdataentity = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); - this.setColor(a(this.world.random)); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + groupdataentity = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + this.setColor(a(generatoraccess.getRandom())); return groupdataentity; } private EnumColor a(EntityAnimal entityanimal, EntityAnimal entityanimal1) { EnumColor enumcolor = ((EntitySheep) entityanimal).getColor(); EnumColor enumcolor1 = ((EntitySheep) entityanimal1).getColor(); + InventoryCrafting inventorycrafting = a(enumcolor, enumcolor1); + Optional optional = this.world.getCraftingManager().craft(Recipes.CRAFTING, inventorycrafting, this.world).map((recipecrafting) -> { // Eclipse fail + return recipecrafting.a(inventorycrafting); + }).map(ItemStack::getItem); - this.container.setItem(0, new ItemStack(ItemDye.a(enumcolor))); - this.container.setItem(1, new ItemStack(ItemDye.a(enumcolor1))); - this.container.resultInventory = new InventoryCraftResult(); // CraftBukkit - add result slot for event - ItemStack itemstack = entityanimal.world.getCraftingManager().craft(this.container, ((EntitySheep) entityanimal).world); - Item item = itemstack.getItem(); - EnumColor enumcolor2; - - if (item instanceof ItemDye) { - enumcolor2 = ((ItemDye) item).d(); - } else { - enumcolor2 = this.world.random.nextBoolean() ? enumcolor : enumcolor1; - } - - return enumcolor2; + ItemDye.class.getClass(); + optional = optional.filter(ItemDye.class::isInstance); + ItemDye.class.getClass(); + return (EnumColor) optional.map(ItemDye.class::cast).map(ItemDye::d).orElseGet(() -> { + return this.world.random.nextBoolean() ? enumcolor : enumcolor1; + }); } - public float getHeadHeight() { - return 0.95F * this.length; + private static InventoryCrafting a(EnumColor enumcolor, EnumColor enumcolor1) { + InventoryCrafting inventorycrafting = new InventoryCrafting(new Container((Containers) null, -1) { + @Override + public boolean canUse(EntityHuman entityhuman) { + return false; + } + + // CraftBukkit start + @Override + public InventoryView getBukkitView() { + return null; // TODO: O.O + } + // CraftBukkit end + }, 2, 1); + + inventorycrafting.setItem(0, new ItemStack(ItemDye.a(enumcolor))); + inventorycrafting.setItem(1, new ItemStack(ItemDye.a(enumcolor1))); + inventorycrafting.resultInventory = new InventoryCraftResult(); // CraftBukkit - add result slot for event + return inventorycrafting; + } + + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return 0.95F * entitysize.height; } } diff --git a/src/main/java/net/minecraft/server/EntityShulker.java b/src/main/java/net/minecraft/server/EntityShulker.java index 5ce91c8f6..aec2e2456 100644 --- a/src/main/java/net/minecraft/server/EntityShulker.java +++ b/src/main/java/net/minecraft/server/EntityShulker.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.Iterator; import java.util.List; import java.util.Optional; @@ -12,115 +13,126 @@ import org.bukkit.event.entity.EntityTeleportEvent; public class EntityShulker extends EntityGolem implements IMonster { - private static final UUID bD = UUID.fromString("7E0292F2-9434-48D5-A29F-9583AF7DF27F"); - private static final AttributeModifier bE = (new AttributeModifier(EntityShulker.bD, "Covered armor bonus", 20.0D, 0)).a(false); - protected static final DataWatcherObject a = DataWatcher.a(EntityShulker.class, DataWatcherRegistry.n); - protected static final DataWatcherObject> b = DataWatcher.a(EntityShulker.class, DataWatcherRegistry.m); - protected static final DataWatcherObject c = DataWatcher.a(EntityShulker.class, DataWatcherRegistry.a); + private static final UUID bA = UUID.fromString("7E0292F2-9434-48D5-A29F-9583AF7DF27F"); + private static final AttributeModifier bB = (new AttributeModifier(EntityShulker.bA, "Covered armor bonus", 20.0D, AttributeModifier.Operation.ADDITION)).a(false); + protected static final DataWatcherObject b = DataWatcher.a(EntityShulker.class, DataWatcherRegistry.n); + protected static final DataWatcherObject> c = DataWatcher.a(EntityShulker.class, DataWatcherRegistry.m); + protected static final DataWatcherObject d = DataWatcher.a(EntityShulker.class, DataWatcherRegistry.a); public static final DataWatcherObject COLOR = DataWatcher.a(EntityShulker.class, DataWatcherRegistry.a); - private float bF; - private float bG; - private BlockPosition bH; - private int bI; + private float bC; + private float bD; + private BlockPosition bE; + private int bF; - public EntityShulker(World world) { - super(EntityTypes.SHULKER, world); - this.setSize(1.0F, 1.0F); - this.aR = 180.0F; - this.aQ = 180.0F; - this.fireProof = true; - this.bH = null; - this.b_ = 5; + public EntityShulker(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.aL = 180.0F; + this.aK = 180.0F; + this.bE = null; + this.f = 5; } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - this.aQ = 180.0F; - this.aR = 180.0F; + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.aK = 180.0F; + this.aL = 180.0F; this.yaw = 180.0F; this.lastYaw = 180.0F; - this.aS = 180.0F; - this.aT = 180.0F; - return super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + this.aM = 180.0F; + this.aN = 180.0F; + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(4, new EntityShulker.a()); this.goalSelector.a(7, new EntityShulker.e()); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[0])); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(2, new EntityShulker.d(this)); this.targetSelector.a(3, new EntityShulker.c(this)); } + @Override protected boolean playStepSound() { return false; } - public SoundCategory bV() { + @Override + public SoundCategory getSoundCategory() { return SoundCategory.HOSTILE; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_SHULKER_AMBIENT; } - public void A() { - if (!this.dG()) { - super.A(); + @Override + public void B() { + if (!this.ed()) { + super.B(); } } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_SHULKER_DEATH; } - protected SoundEffect d(DamageSource damagesource) { - return this.dG() ? SoundEffects.ENTITY_SHULKER_HURT_CLOSED : SoundEffects.ENTITY_SHULKER_HURT; + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return this.ed() ? SoundEffects.ENTITY_SHULKER_HURT_CLOSED : SoundEffects.ENTITY_SHULKER_HURT; } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityShulker.a, EnumDirection.DOWN); - this.datawatcher.register(EntityShulker.b, Optional.empty()); - this.datawatcher.register(EntityShulker.c, (byte) 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityShulker.b, EnumDirection.DOWN); + this.datawatcher.register(EntityShulker.c, Optional.empty()); + this.datawatcher.register(EntityShulker.d, (byte) 0); this.datawatcher.register(EntityShulker.COLOR, (byte) 16); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(30.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(30.0D); } + @Override protected EntityAIBodyControl o() { return new EntityShulker.b(this); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.datawatcher.set(EntityShulker.a, EnumDirection.fromType1(nbttagcompound.getByte("AttachFace"))); - this.datawatcher.set(EntityShulker.c, nbttagcompound.getByte("Peek")); + this.datawatcher.set(EntityShulker.b, EnumDirection.fromType1(nbttagcompound.getByte("AttachFace"))); + this.datawatcher.set(EntityShulker.d, nbttagcompound.getByte("Peek")); this.datawatcher.set(EntityShulker.COLOR, nbttagcompound.getByte("Color")); if (nbttagcompound.hasKey("APX")) { int i = nbttagcompound.getInt("APX"); int j = nbttagcompound.getInt("APY"); int k = nbttagcompound.getInt("APZ"); - this.datawatcher.set(EntityShulker.b, Optional.of(new BlockPosition(i, j, k))); + this.datawatcher.set(EntityShulker.c, Optional.of(new BlockPosition(i, j, k))); } else { - this.datawatcher.set(EntityShulker.b, Optional.empty()); + this.datawatcher.set(EntityShulker.c, Optional.empty()); } } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setByte("AttachFace", (byte) ((EnumDirection) this.datawatcher.get(EntityShulker.a)).a()); - nbttagcompound.setByte("Peek", (Byte) this.datawatcher.get(EntityShulker.c)); + nbttagcompound.setByte("AttachFace", (byte) ((EnumDirection) this.datawatcher.get(EntityShulker.b)).a()); + nbttagcompound.setByte("Peek", (Byte) this.datawatcher.get(EntityShulker.d)); nbttagcompound.setByte("Color", (Byte) this.datawatcher.get(EntityShulker.COLOR)); - BlockPosition blockposition = this.dz(); + BlockPosition blockposition = this.dW(); if (blockposition != null) { nbttagcompound.setInt("APX", blockposition.getX()); @@ -130,13 +142,14 @@ public class EntityShulker extends EntityGolem implements IMonster { } + @Override public void tick() { super.tick(); - BlockPosition blockposition = (BlockPosition) ((Optional) this.datawatcher.get(EntityShulker.b)).orElse((Object) null); + BlockPosition blockposition = (BlockPosition) ((Optional) this.datawatcher.get(EntityShulker.c)).orElse((Object) null); if (blockposition == null && !this.world.isClientSide) { blockposition = new BlockPosition(this); - this.datawatcher.set(EntityShulker.b, Optional.of(blockposition)); + this.datawatcher.set(EntityShulker.c, Optional.of(blockposition)); } float f; @@ -145,9 +158,9 @@ public class EntityShulker extends EntityGolem implements IMonster { blockposition = null; f = this.getVehicle().yaw; this.yaw = f; - this.aQ = f; - this.aR = f; - this.bI = 0; + this.aK = f; + this.aL = f; + this.bF = 0; } else if (!this.world.isClientSide) { IBlockData iblockdata = this.world.getType(blockposition); @@ -158,7 +171,7 @@ public class EntityShulker extends EntityGolem implements IMonster { enumdirection = (EnumDirection) iblockdata.get(BlockPiston.FACING); if (this.world.isEmpty(blockposition.shift(enumdirection))) { blockposition = blockposition.shift(enumdirection); - this.datawatcher.set(EntityShulker.b, Optional.of(blockposition)); + this.datawatcher.set(EntityShulker.c, Optional.of(blockposition)); } else { this.l(); } @@ -166,7 +179,7 @@ public class EntityShulker extends EntityGolem implements IMonster { enumdirection = (EnumDirection) iblockdata.get(BlockPistonExtension.FACING); if (this.world.isEmpty(blockposition.shift(enumdirection))) { blockposition = blockposition.shift(enumdirection); - this.datawatcher.set(EntityShulker.b, Optional.of(blockposition)); + this.datawatcher.set(EntityShulker.c, Optional.of(blockposition)); } else { this.l(); } @@ -175,9 +188,9 @@ public class EntityShulker extends EntityGolem implements IMonster { } } - BlockPosition blockposition1 = blockposition.shift(this.dy()); + BlockPosition blockposition1 = blockposition.shift(this.dV()); - if (!this.world.q(blockposition1)) { + if (!this.world.a(blockposition1, (Entity) this)) { boolean flag = false; EnumDirection[] aenumdirection = EnumDirection.values(); int i = aenumdirection.length; @@ -186,8 +199,8 @@ public class EntityShulker extends EntityGolem implements IMonster { EnumDirection enumdirection1 = aenumdirection[j]; blockposition1 = blockposition.shift(enumdirection1); - if (this.world.q(blockposition1)) { - this.datawatcher.set(EntityShulker.a, enumdirection1); + if (this.world.a(blockposition1, (Entity) this)) { + this.datawatcher.set(EntityShulker.b, enumdirection1); flag = true; break; } @@ -198,27 +211,27 @@ public class EntityShulker extends EntityGolem implements IMonster { } } - BlockPosition blockposition2 = blockposition.shift(this.dy().opposite()); + BlockPosition blockposition2 = blockposition.shift(this.dV().opposite()); - if (this.world.q(blockposition2)) { + if (this.world.a(blockposition2, (Entity) this)) { this.l(); } } - f = (float) this.dA() * 0.01F; - this.bF = this.bG; - if (this.bG > f) { - this.bG = MathHelper.a(this.bG - 0.05F, f, 1.0F); - } else if (this.bG < f) { - this.bG = MathHelper.a(this.bG + 0.05F, 0.0F, f); + f = (float) this.dX() * 0.01F; + this.bC = this.bD; + if (this.bD > f) { + this.bD = MathHelper.a(this.bD - 0.05F, f, 1.0F); + } else if (this.bD < f) { + this.bD = MathHelper.a(this.bD + 0.05F, 0.0F, f); } if (blockposition != null) { if (this.world.isClientSide) { - if (this.bI > 0 && this.bH != null) { - --this.bI; + if (this.bF > 0 && this.bE != null) { + --this.bF; } else { - this.bH = blockposition; + this.bE = blockposition; } } @@ -228,42 +241,15 @@ public class EntityShulker extends EntityGolem implements IMonster { this.lastX = this.locX; this.lastY = this.locY; this.lastZ = this.locZ; - this.N = this.locX; - this.O = this.locY; - this.P = this.locZ; - double d0 = 0.5D - (double) MathHelper.sin((0.5F + this.bG) * 3.1415927F) * 0.5D; - double d1 = 0.5D - (double) MathHelper.sin((0.5F + this.bF) * 3.1415927F) * 0.5D; - double d2 = d0 - d1; - double d3 = 0.0D; - double d4 = 0.0D; - double d5 = 0.0D; - EnumDirection enumdirection2 = this.dy(); + this.H = this.locX; + this.I = this.locY; + this.J = this.locZ; + double d0 = 0.5D - (double) MathHelper.sin((0.5F + this.bD) * 3.1415927F) * 0.5D; + double d1 = 0.5D - (double) MathHelper.sin((0.5F + this.bC) * 3.1415927F) * 0.5D; + EnumDirection enumdirection2 = this.dV().opposite(); - switch (enumdirection2) { - case DOWN: - this.a(new AxisAlignedBB(this.locX - 0.5D, this.locY, this.locZ - 0.5D, this.locX + 0.5D, this.locY + 1.0D + d0, this.locZ + 0.5D)); - d4 = d2; - break; - case UP: - this.a(new AxisAlignedBB(this.locX - 0.5D, this.locY - d0, this.locZ - 0.5D, this.locX + 0.5D, this.locY + 1.0D, this.locZ + 0.5D)); - d4 = -d2; - break; - case NORTH: - this.a(new AxisAlignedBB(this.locX - 0.5D, this.locY, this.locZ - 0.5D, this.locX + 0.5D, this.locY + 1.0D, this.locZ + 0.5D + d0)); - d5 = d2; - break; - case SOUTH: - this.a(new AxisAlignedBB(this.locX - 0.5D, this.locY, this.locZ - 0.5D - d0, this.locX + 0.5D, this.locY + 1.0D, this.locZ + 0.5D)); - d5 = -d2; - break; - case WEST: - this.a(new AxisAlignedBB(this.locX - 0.5D, this.locY, this.locZ - 0.5D, this.locX + 0.5D + d0, this.locY + 1.0D, this.locZ + 0.5D)); - d3 = d2; - break; - case EAST: - this.a(new AxisAlignedBB(this.locX - 0.5D - d0, this.locY, this.locZ - 0.5D, this.locX + 0.5D, this.locY + 1.0D, this.locZ + 0.5D)); - d3 = -d2; - } + this.a((new AxisAlignedBB(this.locX - 0.5D, this.locY, this.locZ - 0.5D, this.locX + 0.5D, this.locY + 1.0D, this.locZ + 0.5D)).b((double) enumdirection2.getAdjacentX() * d0, (double) enumdirection2.getAdjacentY() * d0, (double) enumdirection2.getAdjacentZ() * d0)); + double d2 = d0 - d1; if (d2 > 0.0D) { List list = this.world.getEntities(this, this.getBoundingBox()); @@ -275,7 +261,7 @@ public class EntityShulker extends EntityGolem implements IMonster { Entity entity = (Entity) iterator.next(); if (!(entity instanceof EntityShulker) && !entity.noclip) { - entity.move(EnumMoveType.SHULKER, d3, d4, d5); + entity.move(EnumMoveType.SHULKER, new Vec3D(d2 * (double) enumdirection2.getAdjacentX(), d2 * (double) enumdirection2.getAdjacentY(), d2 * (double) enumdirection2.getAdjacentZ())); } } } @@ -284,24 +270,26 @@ public class EntityShulker extends EntityGolem implements IMonster { } - public void move(EnumMoveType enummovetype, double d0, double d1, double d2) { + @Override + public void move(EnumMoveType enummovetype, Vec3D vec3d) { if (enummovetype == EnumMoveType.SHULKER_BOX) { this.l(); } else { - super.move(enummovetype, d0, d1, d2); + super.move(enummovetype, vec3d); } } + @Override public void setPosition(double d0, double d1, double d2) { super.setPosition(d0, d1, d2); if (this.datawatcher != null && this.ticksLived != 0) { - Optional optional = (Optional) this.datawatcher.get(EntityShulker.b); + Optional optional = (Optional) this.datawatcher.get(EntityShulker.c); Optional optional1 = Optional.of(new BlockPosition(d0, d1, d2)); if (!optional1.equals(optional)) { - this.datawatcher.set(EntityShulker.b, optional1); - this.datawatcher.set(EntityShulker.c, (byte) 0); + this.datawatcher.set(EntityShulker.c, optional1); + this.datawatcher.set(EntityShulker.d, (byte) 0); this.impulse = true; } @@ -313,9 +301,9 @@ public class EntityShulker extends EntityGolem implements IMonster { BlockPosition blockposition = new BlockPosition(this); for (int i = 0; i < 5; ++i) { - BlockPosition blockposition1 = blockposition.a(8 - this.random.nextInt(17), 8 - this.random.nextInt(17), 8 - this.random.nextInt(17)); + BlockPosition blockposition1 = blockposition.b(8 - this.random.nextInt(17), 8 - this.random.nextInt(17), 8 - this.random.nextInt(17)); - if (blockposition1.getY() > 0 && this.world.isEmpty(blockposition1) && this.world.i((Entity) this) && this.world.getCubes(this, new AxisAlignedBB(blockposition1))) { + if (blockposition1.getY() > 0 && this.world.isEmpty(blockposition1) && this.world.getWorldBorder().a(blockposition1) && this.world.getCubes(this, new AxisAlignedBB(blockposition1))) { boolean flag = false; EnumDirection[] aenumdirection = EnumDirection.values(); int j = aenumdirection.length; @@ -323,7 +311,7 @@ public class EntityShulker extends EntityGolem implements IMonster { for (int k = 0; k < j; ++k) { EnumDirection enumdirection = aenumdirection[k]; - if (this.world.q(blockposition1.shift(enumdirection))) { + if (this.world.a(blockposition1.shift(enumdirection), (Entity) this)) { // CraftBukkit start EntityTeleportEvent teleport = new EntityTeleportEvent(this.getBukkitEntity(), this.getBukkitEntity().getLocation(), new Location(this.world.getWorld(), blockposition1.getX(), blockposition1.getY(), blockposition1.getZ())); this.world.getServer().getPluginManager().callEvent(teleport); @@ -331,7 +319,7 @@ public class EntityShulker extends EntityGolem implements IMonster { Location to = teleport.getTo(); blockposition1 = new BlockPosition(to.getX(), to.getY(), to.getZ()); - this.datawatcher.set(EntityShulker.a, enumdirection); + this.datawatcher.set(EntityShulker.b, enumdirection); flag = true; } // CraftBukkit end @@ -341,8 +329,8 @@ public class EntityShulker extends EntityGolem implements IMonster { if (flag) { this.a(SoundEffects.ENTITY_SHULKER_TELEPORT, 1.0F, 1.0F); - this.datawatcher.set(EntityShulker.b, Optional.of(blockposition1)); - this.datawatcher.set(EntityShulker.c, (byte) 0); + this.datawatcher.set(EntityShulker.c, Optional.of(blockposition1)); + this.datawatcher.set(EntityShulker.d, (byte) 0); this.setGoalTarget((EntityLiving) null); return true; } @@ -355,45 +343,46 @@ public class EntityShulker extends EntityGolem implements IMonster { } } + @Override public void movementTick() { super.movementTick(); - this.motX = 0.0D; - this.motY = 0.0D; - this.motZ = 0.0D; - this.aR = 180.0F; - this.aQ = 180.0F; + this.setMot(Vec3D.a); + this.aL = 180.0F; + this.aK = 180.0F; this.yaw = 180.0F; } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntityShulker.b.equals(datawatcherobject) && this.world.isClientSide && !this.isPassenger()) { - BlockPosition blockposition = this.dz(); + if (EntityShulker.c.equals(datawatcherobject) && this.world.isClientSide && !this.isPassenger()) { + BlockPosition blockposition = this.dW(); if (blockposition != null) { - if (this.bH == null) { - this.bH = blockposition; + if (this.bE == null) { + this.bE = blockposition; } else { - this.bI = 6; + this.bF = 6; } this.locX = (double) blockposition.getX() + 0.5D; this.locY = (double) blockposition.getY(); this.locZ = (double) blockposition.getZ() + 0.5D; - if (valid) world.entityJoinedWorld(this, false); // CraftBukkit + if (valid) ((WorldServer) world).chunkCheck(this); // CraftBukkit this.lastX = this.locX; this.lastY = this.locY; this.lastZ = this.locZ; - this.N = this.locX; - this.O = this.locY; - this.P = this.locZ; + this.H = this.locX; + this.I = this.locY; + this.J = this.locZ; } } super.a(datawatcherobject); } + @Override public boolean damageEntity(DamageSource damagesource, float f) { - if (this.dG()) { + if (this.ed()) { Entity entity = damagesource.j(); if (entity instanceof EntityArrow) { @@ -412,69 +401,70 @@ public class EntityShulker extends EntityGolem implements IMonster { } } - private boolean dG() { - return this.dA() == 0; + private boolean ed() { + return this.dX() == 0; } @Nullable - public AxisAlignedBB al() { + @Override + public AxisAlignedBB aq() { return this.isAlive() ? this.getBoundingBox() : null; } - public EnumDirection dy() { - return (EnumDirection) this.datawatcher.get(EntityShulker.a); + public EnumDirection dV() { + return (EnumDirection) this.datawatcher.get(EntityShulker.b); } @Nullable - public BlockPosition dz() { - return (BlockPosition) ((Optional) this.datawatcher.get(EntityShulker.b)).orElse((Object) null); + public BlockPosition dW() { + return (BlockPosition) ((Optional) this.datawatcher.get(EntityShulker.c)).orElse((Object) null); } public void g(@Nullable BlockPosition blockposition) { - this.datawatcher.set(EntityShulker.b, Optional.ofNullable(blockposition)); + this.datawatcher.set(EntityShulker.c, Optional.ofNullable(blockposition)); } - public int dA() { - return (Byte) this.datawatcher.get(EntityShulker.c); + public int dX() { + return (Byte) this.datawatcher.get(EntityShulker.d); } public void a(int i) { if (!this.world.isClientSide) { - this.getAttributeInstance(GenericAttributes.h).c(EntityShulker.bE); + this.getAttributeInstance(GenericAttributes.ARMOR).removeModifier(EntityShulker.bB); if (i == 0) { - this.getAttributeInstance(GenericAttributes.h).b(EntityShulker.bE); + this.getAttributeInstance(GenericAttributes.ARMOR).addModifier(EntityShulker.bB); this.a(SoundEffects.ENTITY_SHULKER_CLOSE, 1.0F, 1.0F); } else { this.a(SoundEffects.ENTITY_SHULKER_OPEN, 1.0F, 1.0F); } } - this.datawatcher.set(EntityShulker.c, (byte) i); + this.datawatcher.set(EntityShulker.d, (byte) i); } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 0.5F; } - public int K() { + @Override + public int M() { return 180; } - public int L() { + @Override + public int dA() { return 180; } + @Override public void collide(Entity entity) {} - public float aM() { + @Override + public float aS() { return 0.0F; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.F; - } - static class c extends PathfinderGoalNearestAttackableTarget { public c(EntityShulker entityshulker) { @@ -483,12 +473,14 @@ public class EntityShulker extends EntityGolem implements IMonster { }); } + @Override public boolean a() { return this.e.getScoreboardTeam() == null ? false : super.a(); } + @Override protected AxisAlignedBB a(double d0) { - EnumDirection enumdirection = ((EntityShulker) this.e).dy(); + EnumDirection enumdirection = ((EntityShulker) this.e).dV(); return enumdirection.k() == EnumDirection.EnumAxis.X ? this.e.getBoundingBox().grow(4.0D, d0, d0) : (enumdirection.k() == EnumDirection.EnumAxis.Z ? this.e.getBoundingBox().grow(d0, d0, 4.0D) : this.e.getBoundingBox().grow(d0, 4.0D, d0)); } @@ -500,12 +492,14 @@ public class EntityShulker extends EntityGolem implements IMonster { super(entityshulker, EntityHuman.class, true); } + @Override public boolean a() { return EntityShulker.this.world.getDifficulty() == EnumDifficulty.PEACEFUL ? false : super.a(); } + @Override protected AxisAlignedBB a(double d0) { - EnumDirection enumdirection = ((EntityShulker) this.e).dy(); + EnumDirection enumdirection = ((EntityShulker) this.e).dV(); return enumdirection.k() == EnumDirection.EnumAxis.X ? this.e.getBoundingBox().grow(4.0D, d0, d0) : (enumdirection.k() == EnumDirection.EnumAxis.Z ? this.e.getBoundingBox().grow(d0, d0, 4.0D) : this.e.getBoundingBox().grow(d0, 4.0D, d0)); } @@ -516,38 +510,40 @@ public class EntityShulker extends EntityGolem implements IMonster { private int b; public a() { - this.a(3); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); } + @Override public boolean a() { EntityLiving entityliving = EntityShulker.this.getGoalTarget(); return entityliving != null && entityliving.isAlive() ? EntityShulker.this.world.getDifficulty() != EnumDifficulty.PEACEFUL : false; } + @Override public void c() { this.b = 20; EntityShulker.this.a(100); } + @Override public void d() { EntityShulker.this.a(0); } + @Override public void e() { if (EntityShulker.this.world.getDifficulty() != EnumDifficulty.PEACEFUL) { --this.b; EntityLiving entityliving = EntityShulker.this.getGoalTarget(); EntityShulker.this.getControllerLook().a(entityliving, 180.0F, 180.0F); - double d0 = EntityShulker.this.h(entityliving); + double d0 = EntityShulker.this.h((Entity) entityliving); if (d0 < 400.0D) { if (this.b <= 0) { this.b = 20 + EntityShulker.this.random.nextInt(10) * 20 / 2; - EntityShulkerBullet entityshulkerbullet = new EntityShulkerBullet(EntityShulker.this.world, EntityShulker.this, entityliving, EntityShulker.this.dy().k()); - - EntityShulker.this.world.addEntity(entityshulkerbullet); + EntityShulker.this.world.addEntity(new EntityShulkerBullet(EntityShulker.this.world, EntityShulker.this, entityliving, EntityShulker.this.dV().k())); EntityShulker.this.a(SoundEffects.ENTITY_SHULKER_SHOOT, 2.0F, (EntityShulker.this.random.nextFloat() - EntityShulker.this.random.nextFloat()) * 0.2F + 1.0F); } } else { @@ -565,19 +561,23 @@ public class EntityShulker extends EntityGolem implements IMonster { private e() {} + @Override public boolean a() { return EntityShulker.this.getGoalTarget() == null && EntityShulker.this.random.nextInt(40) == 0; } + @Override public boolean b() { return EntityShulker.this.getGoalTarget() == null && this.b > 0; } + @Override public void c() { this.b = 20 * (1 + EntityShulker.this.random.nextInt(3)); EntityShulker.this.a(30); } + @Override public void d() { if (EntityShulker.this.getGoalTarget() == null) { EntityShulker.this.a(0); @@ -585,6 +585,7 @@ public class EntityShulker extends EntityGolem implements IMonster { } + @Override public void e() { --this.b; } @@ -592,10 +593,11 @@ public class EntityShulker extends EntityGolem implements IMonster { class b extends EntityAIBodyControl { - public b(EntityLiving entityliving) { - super(entityliving); + public b(EntityInsentient entityinsentient) { + super(entityinsentient); } + @Override public void a() {} } } diff --git a/src/main/java/net/minecraft/server/EntityShulkerBullet.java b/src/main/java/net/minecraft/server/EntityShulkerBullet.java index 4b95a3a67..5fe06d80d 100644 --- a/src/main/java/net/minecraft/server/EntityShulkerBullet.java +++ b/src/main/java/net/minecraft/server/EntityShulkerBullet.java @@ -11,26 +11,25 @@ public class EntityShulkerBullet extends Entity { private EntityLiving shooter; private Entity target; @Nullable - private EnumDirection c; - private int d; - private double e; + private EnumDirection dir; + private int e; private double f; private double g; + private double ar; @Nullable - private UUID h; - private BlockPosition aw; + private UUID as; + private BlockPosition at; @Nullable - private UUID ax; - private BlockPosition ay; + private UUID au; + private BlockPosition av; - public EntityShulkerBullet(World world) { - super(EntityTypes.SHULKER_BULLET, world); - this.setSize(0.3125F, 0.3125F); + public EntityShulkerBullet(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.noclip = true; } public EntityShulkerBullet(World world, EntityLiving entityliving, Entity entity, EnumDirection.EnumAxis enumdirection_enumaxis) { - this(world); + this(EntityTypes.SHULKER_BULLET, world); this.shooter = entityliving; BlockPosition blockposition = new BlockPosition(entityliving); double d0 = (double) blockposition.getX() + 0.5D; @@ -39,7 +38,7 @@ public class EntityShulkerBullet extends Entity { this.setPositionRotation(d0, d1, d2, this.yaw, this.pitch); this.target = entity; - this.c = EnumDirection.UP; + this.dir = EnumDirection.UP; this.a(enumdirection_enumaxis); projectileSource = (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit } @@ -59,15 +58,17 @@ public class EntityShulkerBullet extends Entity { public void setTarget(Entity e) { this.target = e; - this.c = EnumDirection.UP; + this.dir = EnumDirection.UP; this.a(EnumDirection.EnumAxis.X); } // CraftBukkit end - public SoundCategory bV() { + @Override + public SoundCategory getSoundCategory() { return SoundCategory.HOSTILE; } + @Override protected void b(NBTTagCompound nbttagcompound) { BlockPosition blockposition; NBTTagCompound nbttagcompound1; @@ -90,45 +91,47 @@ public class EntityShulkerBullet extends Entity { nbttagcompound.set("Target", nbttagcompound1); } - if (this.c != null) { - nbttagcompound.setInt("Dir", this.c.a()); + if (this.dir != null) { + nbttagcompound.setInt("Dir", this.dir.a()); } - nbttagcompound.setInt("Steps", this.d); - nbttagcompound.setDouble("TXD", this.e); - nbttagcompound.setDouble("TYD", this.f); - nbttagcompound.setDouble("TZD", this.g); + nbttagcompound.setInt("Steps", this.e); + nbttagcompound.setDouble("TXD", this.f); + nbttagcompound.setDouble("TYD", this.g); + nbttagcompound.setDouble("TZD", this.ar); } + @Override protected void a(NBTTagCompound nbttagcompound) { - this.d = nbttagcompound.getInt("Steps"); - this.e = nbttagcompound.getDouble("TXD"); - this.f = nbttagcompound.getDouble("TYD"); - this.g = nbttagcompound.getDouble("TZD"); + this.e = nbttagcompound.getInt("Steps"); + this.f = nbttagcompound.getDouble("TXD"); + this.g = nbttagcompound.getDouble("TYD"); + this.ar = nbttagcompound.getDouble("TZD"); if (nbttagcompound.hasKeyOfType("Dir", 99)) { - this.c = EnumDirection.fromType1(nbttagcompound.getInt("Dir")); + this.dir = EnumDirection.fromType1(nbttagcompound.getInt("Dir")); } NBTTagCompound nbttagcompound1; if (nbttagcompound.hasKeyOfType("Owner", 10)) { nbttagcompound1 = nbttagcompound.getCompound("Owner"); - this.h = GameProfileSerializer.b(nbttagcompound1); - this.aw = new BlockPosition(nbttagcompound1.getInt("X"), nbttagcompound1.getInt("Y"), nbttagcompound1.getInt("Z")); + this.as = GameProfileSerializer.b(nbttagcompound1); + this.at = new BlockPosition(nbttagcompound1.getInt("X"), nbttagcompound1.getInt("Y"), nbttagcompound1.getInt("Z")); } if (nbttagcompound.hasKeyOfType("Target", 10)) { nbttagcompound1 = nbttagcompound.getCompound("Target"); - this.ax = GameProfileSerializer.b(nbttagcompound1); - this.ay = new BlockPosition(nbttagcompound1.getInt("X"), nbttagcompound1.getInt("Y"), nbttagcompound1.getInt("Z")); + this.au = GameProfileSerializer.b(nbttagcompound1); + this.av = new BlockPosition(nbttagcompound1.getInt("X"), nbttagcompound1.getInt("Y"), nbttagcompound1.getInt("Z")); } } - protected void x_() {} + @Override + protected void initDatawatcher() {} private void a(@Nullable EnumDirection enumdirection) { - this.c = enumdirection; + this.dir = enumdirection; } private void a(@Nullable EnumDirection.EnumAxis enumdirection_enumaxis) { @@ -138,7 +141,7 @@ public class EntityShulkerBullet extends Entity { if (this.target == null) { blockposition = (new BlockPosition(this)).down(); } else { - d0 = (double) this.target.length * 0.5D; + d0 = (double) this.target.getHeight() * 0.5D; blockposition = new BlockPosition(this.target.locX, this.target.locY + d0, this.target.locZ); } @@ -147,7 +150,7 @@ public class EntityShulkerBullet extends Entity { double d3 = (double) blockposition.getZ() + 0.5D; EnumDirection enumdirection = null; - if (blockposition.g(this.locX, this.locY, this.locZ) >= 4.0D) { + if (!blockposition.a((IPosition) this.getPositionVector(), 2.0D)) { BlockPosition blockposition1 = new BlockPosition(this); List list = Lists.newArrayList(); @@ -196,94 +199,97 @@ public class EntityShulkerBullet extends Entity { double d7 = (double) MathHelper.sqrt(d4 * d4 + d5 * d5 + d6 * d6); if (d7 == 0.0D) { - this.e = 0.0D; this.f = 0.0D; this.g = 0.0D; + this.ar = 0.0D; } else { - this.e = d4 / d7 * 0.15D; - this.f = d5 / d7 * 0.15D; - this.g = d6 / d7 * 0.15D; + this.f = d4 / d7 * 0.15D; + this.g = d5 / d7 * 0.15D; + this.ar = d6 / d7 * 0.15D; } this.impulse = true; - this.d = 10 + this.random.nextInt(5) * 10; + this.e = 10 + this.random.nextInt(5) * 10; } + @Override public void tick() { if (!this.world.isClientSide && this.world.getDifficulty() == EnumDifficulty.PEACEFUL) { this.die(); } else { super.tick(); + Vec3D vec3d; + if (!this.world.isClientSide) { List list; Iterator iterator; EntityLiving entityliving; - if (this.target == null && this.ax != null) { - list = this.world.a(EntityLiving.class, new AxisAlignedBB(this.ay.a(-2, -2, -2), this.ay.a(2, 2, 2))); + if (this.target == null && this.au != null) { + list = this.world.a(EntityLiving.class, new AxisAlignedBB(this.av.b(-2, -2, -2), this.av.b(2, 2, 2))); iterator = list.iterator(); while (iterator.hasNext()) { entityliving = (EntityLiving) iterator.next(); - if (entityliving.getUniqueID().equals(this.ax)) { + if (entityliving.getUniqueID().equals(this.au)) { this.target = entityliving; break; } } - this.ax = null; + this.au = null; } - if (this.shooter == null && this.h != null) { - list = this.world.a(EntityLiving.class, new AxisAlignedBB(this.aw.a(-2, -2, -2), this.aw.a(2, 2, 2))); + if (this.shooter == null && this.as != null) { + list = this.world.a(EntityLiving.class, new AxisAlignedBB(this.at.b(-2, -2, -2), this.at.b(2, 2, 2))); iterator = list.iterator(); while (iterator.hasNext()) { entityliving = (EntityLiving) iterator.next(); - if (entityliving.getUniqueID().equals(this.h)) { + if (entityliving.getUniqueID().equals(this.as)) { this.shooter = entityliving; break; } } - this.h = null; + this.as = null; } if (this.target != null && this.target.isAlive() && (!(this.target instanceof EntityHuman) || !((EntityHuman) this.target).isSpectator())) { - this.e = MathHelper.a(this.e * 1.025D, -1.0D, 1.0D); this.f = MathHelper.a(this.f * 1.025D, -1.0D, 1.0D); this.g = MathHelper.a(this.g * 1.025D, -1.0D, 1.0D); - this.motX += (this.e - this.motX) * 0.2D; - this.motY += (this.f - this.motY) * 0.2D; - this.motZ += (this.g - this.motZ) * 0.2D; + this.ar = MathHelper.a(this.ar * 1.025D, -1.0D, 1.0D); + vec3d = this.getMot(); + this.setMot(vec3d.add((this.f - vec3d.x) * 0.2D, (this.g - vec3d.y) * 0.2D, (this.ar - vec3d.z) * 0.2D)); } else if (!this.isNoGravity()) { - this.motY -= 0.04D; + this.setMot(this.getMot().add(0.0D, -0.04D, 0.0D)); } - MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, true, false, this.shooter); + MovingObjectPosition movingobjectposition = ProjectileHelper.a(this, true, false, this.shooter, RayTrace.BlockCollisionOption.COLLIDER); - if (movingobjectposition != null) { + if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { this.a(movingobjectposition); } } - this.setPosition(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + vec3d = this.getMot(); + this.setPosition(this.locX + vec3d.x, this.locY + vec3d.y, this.locZ + vec3d.z); ProjectileHelper.a(this, 0.5F); if (this.world.isClientSide) { - this.world.addParticle(Particles.r, this.locX - this.motX, this.locY - this.motY + 0.15D, this.locZ - this.motZ, 0.0D, 0.0D, 0.0D); + this.world.addParticle(Particles.END_ROD, this.locX - vec3d.x, this.locY - vec3d.y + 0.15D, this.locZ - vec3d.z, 0.0D, 0.0D, 0.0D); } else if (this.target != null && !this.target.dead) { - if (this.d > 0) { - --this.d; - if (this.d == 0) { - this.a(this.c == null ? null : this.c.k()); + if (this.e > 0) { + --this.e; + if (this.e == 0) { + this.a(this.dir == null ? null : this.dir.k()); } } - if (this.c != null) { + if (this.dir != null) { BlockPosition blockposition = new BlockPosition(this); - EnumDirection.EnumAxis enumdirection_enumaxis = this.c.k(); + EnumDirection.EnumAxis enumdirection_enumaxis = this.dir.k(); - if (this.world.q(blockposition.shift(this.c))) { + if (this.world.a(blockposition.shift(this.dir), (Entity) this)) { this.a(enumdirection_enumaxis); } else { BlockPosition blockposition1 = new BlockPosition(this.target); @@ -298,44 +304,54 @@ public class EntityShulkerBullet extends Entity { } } + @Override public boolean isBurning() { return false; } - public float az() { + @Override + public float aF() { return 1.0F; } protected void a(MovingObjectPosition movingobjectposition) { org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition); // Craftbukkit - Call event - if (movingobjectposition.entity == null) { - ((WorldServer) this.world).a(Particles.u, this.locX, this.locY, this.locZ, 2, 0.2D, 0.2D, 0.2D, 0.0D); - this.a(SoundEffects.ENTITY_SHULKER_BULLET_HIT, 1.0F, 1.0F); - } else { - boolean flag = movingobjectposition.entity.damageEntity(DamageSource.a(this, this.shooter).c(), 4.0F); + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + Entity entity = ((MovingObjectPositionEntity) movingobjectposition).getEntity(); + boolean flag = entity.damageEntity(DamageSource.a(this, this.shooter).c(), 4.0F); if (flag) { - this.a(this.shooter, movingobjectposition.entity); - if (movingobjectposition.entity instanceof EntityLiving) { - ((EntityLiving) movingobjectposition.entity).addEffect(new MobEffect(MobEffects.LEVITATION, 200), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit + this.a(this.shooter, entity); + if (entity instanceof EntityLiving) { + ((EntityLiving) entity).addEffect(new MobEffect(MobEffects.LEVITATION, 200), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit } } + } else { + ((WorldServer) this.world).a(Particles.EXPLOSION, this.locX, this.locY, this.locZ, 2, 0.2D, 0.2D, 0.2D, 0.0D); + this.a(SoundEffects.ENTITY_SHULKER_BULLET_HIT, 1.0F, 1.0F); } this.die(); } + @Override public boolean isInteractable() { return true; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (!this.world.isClientSide) { this.a(SoundEffects.ENTITY_SHULKER_BULLET_HURT, 1.0F, 1.0F); - ((WorldServer) this.world).a(Particles.h, this.locX, this.locY, this.locZ, 15, 0.2D, 0.2D, 0.2D, 0.0D); + ((WorldServer) this.world).a(Particles.CRIT, this.locX, this.locY, this.locZ, 15, 0.2D, 0.2D, 0.2D, 0.0D); this.die(); } return true; } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); + } } diff --git a/src/main/java/net/minecraft/server/EntitySilverfish.java b/src/main/java/net/minecraft/server/EntitySilverfish.java index ba40e03fc..eb3c56fef 100644 --- a/src/main/java/net/minecraft/server/EntitySilverfish.java +++ b/src/main/java/net/minecraft/server/EntitySilverfish.java @@ -1,100 +1,103 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.Random; -import javax.annotation.Nullable; public class EntitySilverfish extends EntityMonster { - private EntitySilverfish.PathfinderGoalSilverfishWakeOthers a; + private EntitySilverfish.PathfinderGoalSilverfishWakeOthers b; - public EntitySilverfish(World world) { - super(EntityTypes.SILVERFISH, world); - this.setSize(0.4F, 0.3F); + public EntitySilverfish(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - protected void n() { - this.a = new EntitySilverfish.PathfinderGoalSilverfishWakeOthers(this); + @Override + protected void initPathfinder() { + this.b = new EntitySilverfish.PathfinderGoalSilverfishWakeOthers(this); this.goalSelector.a(1, new PathfinderGoalFloat(this)); - this.goalSelector.a(3, this.a); + this.goalSelector.a(3, this.b); this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false)); this.goalSelector.a(5, new EntitySilverfish.PathfinderGoalSilverfishHideInBlock(this)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[0])); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); } - public double aI() { + @Override + public double aO() { return 0.1D; } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 0.1F; } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(8.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(8.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(1.0D); } + @Override protected boolean playStepSound() { return false; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_SILVERFISH_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_SILVERFISH_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_SILVERFISH_DEATH; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(SoundEffects.ENTITY_SILVERFISH_STEP, 0.15F, 1.0F); } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; } else { - if ((damagesource instanceof EntityDamageSource || damagesource == DamageSource.MAGIC) && this.a != null) { - this.a.g(); + if ((damagesource instanceof EntityDamageSource || damagesource == DamageSource.MAGIC) && this.b != null) { + this.b.g(); } return super.damageEntity(damagesource, f); } } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.B; - } - + @Override public void tick() { - this.aQ = this.yaw; + this.aK = this.yaw; super.tick(); } - public void k(float f) { + @Override + public void l(float f) { this.yaw = f; - super.k(f); + super.l(f); } + @Override public float a(BlockPosition blockposition, IWorldReader iworldreader) { - return BlockMonsterEggs.k(iworldreader.getType(blockposition.down())) ? 10.0F : super.a(blockposition, iworldreader); + return BlockMonsterEggs.j(iworldreader.getType(blockposition.down())) ? 10.0F : super.a(blockposition, iworldreader); } - protected boolean K_() { - return true; - } - - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - if (super.a(generatoraccess, flag)) { - EntityHuman entityhuman = generatoraccess.b(this, 5.0D); + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + if (d(entitytypes, generatoraccess, enummobspawn, blockposition, random)) { + EntityHuman entityhuman = generatoraccess.a((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, 5.0D, true); return !(entityhuman != null && !entityhuman.affectsSpawning) && entityhuman == null; // Paper - Affects Spawning API } else { @@ -102,6 +105,7 @@ public class EntitySilverfish extends EntityMonster { } } + @Override public EnumMonsterType getMonsterType() { return EnumMonsterType.ARTHROPOD; } @@ -113,23 +117,24 @@ public class EntitySilverfish extends EntityMonster { public PathfinderGoalSilverfishHideInBlock(EntitySilverfish entitysilverfish) { super(entitysilverfish, 1.0D, 10); - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); } + @Override public boolean a() { if (this.a.getGoalTarget() != null) { return false; - } else if (!this.a.getNavigation().p()) { + } else if (!this.a.getNavigation().n()) { return false; } else { Random random = this.a.getRandom(); - if (this.a.world.getGameRules().getBoolean("mobGriefing") && random.nextInt(10) == 0) { + if (this.a.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) && random.nextInt(10) == 0) { this.h = EnumDirection.a(random); BlockPosition blockposition = (new BlockPosition(this.a.locX, this.a.locY + 0.5D, this.a.locZ)).shift(this.h); IBlockData iblockdata = this.a.world.getType(blockposition); - if (BlockMonsterEggs.k(iblockdata)) { + if (BlockMonsterEggs.j(iblockdata)) { this.i = true; return true; } @@ -140,10 +145,12 @@ public class EntitySilverfish extends EntityMonster { } } + @Override public boolean b() { return this.i ? false : super.b(); } + @Override public void c() { if (!this.i) { super.c(); @@ -152,13 +159,13 @@ public class EntitySilverfish extends EntityMonster { BlockPosition blockposition = (new BlockPosition(this.a.locX, this.a.locY + 0.5D, this.a.locZ)).shift(this.h); IBlockData iblockdata = world.getType(blockposition); - if (BlockMonsterEggs.k(iblockdata)) { + if (BlockMonsterEggs.j(iblockdata)) { // CraftBukkit start - if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.a, blockposition, BlockMonsterEggs.f(iblockdata.getBlock())).isCancelled()) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.a, blockposition, BlockMonsterEggs.e(iblockdata.getBlock())).isCancelled()) { return; } // CraftBukkit end - world.setTypeAndData(blockposition, BlockMonsterEggs.f(iblockdata.getBlock()), 3); + world.setTypeAndData(blockposition, BlockMonsterEggs.e(iblockdata.getBlock()), 3); this.a.doSpawnEffect(); this.a.die(); } @@ -183,10 +190,12 @@ public class EntitySilverfish extends EntityMonster { } + @Override public boolean a() { return this.b > 0; } + @Override public void e() { --this.b; if (this.b <= 0) { @@ -197,7 +206,7 @@ public class EntitySilverfish extends EntityMonster { for (int i = 0; i <= 5 && i >= -5; i = (i <= 0 ? 1 : 0) - i) { for (int j = 0; j <= 10 && j >= -10; j = (j <= 0 ? 1 : 0) - j) { for (int k = 0; k <= 10 && k >= -10; k = (k <= 0 ? 1 : 0) - k) { - BlockPosition blockposition1 = blockposition.a(j, i, k); + BlockPosition blockposition1 = blockposition.b(j, i, k); IBlockData iblockdata = world.getType(blockposition1); Block block = iblockdata.getBlock(); @@ -207,8 +216,8 @@ public class EntitySilverfish extends EntityMonster { continue; } // CraftBukkit end - if (world.getGameRules().getBoolean("mobGriefing")) { - world.setAir(blockposition1, true); + if (world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { + world.b(blockposition1, true); } else { world.setTypeAndData(blockposition1, ((BlockMonsterEggs) block).d().getBlockData(), 3); } diff --git a/src/main/java/net/minecraft/server/EntitySkeleton.java b/src/main/java/net/minecraft/server/EntitySkeleton.java deleted file mode 100644 index 592fadd50..000000000 --- a/src/main/java/net/minecraft/server/EntitySkeleton.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.minecraft.server; - -import javax.annotation.Nullable; - -public class EntitySkeleton extends EntitySkeletonAbstract { - - public EntitySkeleton(World world) { - super(EntityTypes.SKELETON, world); - } - - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.av; - } - - protected SoundEffect D() { - return SoundEffects.ENTITY_SKELETON_AMBIENT; - } - - protected SoundEffect d(DamageSource damagesource) { - return SoundEffects.ENTITY_SKELETON_HURT; - } - - protected SoundEffect cs() { - return SoundEffects.ENTITY_SKELETON_DEATH; - } - - SoundEffect l() { - return SoundEffects.ENTITY_SKELETON_STEP; - } - - public void die(DamageSource damagesource) { - // super.die(damagesource); // CraftBukkit - if (damagesource.getEntity() instanceof EntityCreeper) { - EntityCreeper entitycreeper = (EntityCreeper) damagesource.getEntity(); - - if (entitycreeper.isPowered() && entitycreeper.canCauseHeadDrop()) { - entitycreeper.setCausedHeadDrop(); - this.a((IMaterial) Items.SKELETON_SKULL); - } - } - super.die(damagesource); // CraftBukkit - moved from above - - } - - protected EntityArrow a(float f) { - ItemStack itemstack = this.getEquipment(EnumItemSlot.OFFHAND); - - if (itemstack.getItem() == Items.SPECTRAL_ARROW) { - EntitySpectralArrow entityspectralarrow = new EntitySpectralArrow(this.world, this); - - entityspectralarrow.a((EntityLiving) this, f); - return entityspectralarrow; - } else { - EntityArrow entityarrow = super.a(f); - - if (itemstack.getItem() == Items.TIPPED_ARROW && entityarrow instanceof EntityTippedArrow) { - ((EntityTippedArrow) entityarrow).b(itemstack); - } - - return entityarrow; - } - } -} diff --git a/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java b/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java index 6e2ee04c7..8f1b5a550 100644 --- a/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java +++ b/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java @@ -6,61 +6,61 @@ import javax.annotation.Nullable; public abstract class EntitySkeletonAbstract extends EntityMonster implements IRangedEntity { - private static final DataWatcherObject a = DataWatcher.a(EntitySkeletonAbstract.class, DataWatcherRegistry.i); private final PathfinderGoalBowShoot b = new PathfinderGoalBowShoot<>(this, 1.0D, 20, 15.0F); private final PathfinderGoalMeleeAttack c = new PathfinderGoalMeleeAttack(this, 1.2D, false) { + @Override public void d() { super.d(); - EntitySkeletonAbstract.this.s(false); + EntitySkeletonAbstract.this.q(false); } + @Override public void c() { super.c(); - EntitySkeletonAbstract.this.s(true); + EntitySkeletonAbstract.this.q(true); } }; - protected EntitySkeletonAbstract(EntityTypes entitytypes, World world) { + protected EntitySkeletonAbstract(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.setSize(0.6F, 1.99F); - this.dz(); + this.dV(); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(2, new PathfinderGoalRestrictSun(this)); this.goalSelector.a(3, new PathfinderGoalFleeSun(this, 1.0D)); this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityWolf.class, 6.0F, 1.0D, 1.2D)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0])); this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, true, false, EntityTurtle.bC)); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, true, false, EntityTurtle.bz)); } + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntitySkeletonAbstract.a, false); - } - + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(this.l(), 0.15F, 1.0F); } abstract SoundEffect l(); + @Override public EnumMonsterType getMonsterType() { return EnumMonsterType.UNDEAD; } + @Override public void movementTick() { - boolean flag = this.dq(); + boolean flag = this.dS(); if (flag) { ItemStack itemstack = this.getEquipment(EnumItemSlot.HEAD); @@ -69,7 +69,7 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR if (itemstack.e()) { itemstack.setDamage(itemstack.getDamage() + this.random.nextInt(2)); if (itemstack.getDamage() >= itemstack.h()) { - this.c(itemstack); + this.c(EnumItemSlot.HEAD); this.setSlot(EnumItemSlot.HEAD, ItemStack.a); } } @@ -85,28 +85,31 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR super.movementTick(); } - public void aH() { - super.aH(); + @Override + public void passengerTick() { + super.passengerTick(); if (this.getVehicle() instanceof EntityCreature) { EntityCreature entitycreature = (EntityCreature) this.getVehicle(); - this.aQ = entitycreature.aQ; + this.aK = entitycreature.aK; } } + @Override protected void a(DifficultyDamageScaler difficultydamagescaler) { super.a(difficultydamagescaler); this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.BOW)); } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - groupdataentity = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + groupdataentity = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); this.a(difficultydamagescaler); this.b(difficultydamagescaler); - this.dz(); - this.p(this.random.nextFloat() < 0.55F * difficultydamagescaler.d()); + this.dV(); + this.setCanPickupLoot(this.random.nextFloat() < 0.55F * difficultydamagescaler.d()); if (this.getEquipment(EnumItemSlot.HEAD).isEmpty()) { LocalDate localdate = LocalDate.now(); int i = localdate.get(ChronoField.DAY_OF_MONTH); @@ -121,11 +124,11 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR return groupdataentity; } - public void dz() { + public void dV() { if (this.world != null && !this.world.isClientSide) { this.goalSelector.a((PathfinderGoal) this.c); this.goalSelector.a((PathfinderGoal) this.b); - ItemStack itemstack = this.getItemInMainHand(); + ItemStack itemstack = this.b(ProjectileHelper.a(this, Items.BOW)); if (itemstack.getItem() == Items.BOW) { byte b0 = 20; @@ -134,7 +137,7 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR b0 = 40; } - this.b.b(b0); + this.b.a(b0); this.goalSelector.a(4, this.b); } else { this.goalSelector.a(4, this.c); @@ -143,10 +146,12 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR } } + @Override public void a(EntityLiving entityliving, float f) { - EntityArrow entityarrow = this.a(f); + ItemStack itemstack = this.f(this.b(ProjectileHelper.a(this, Items.BOW))); + EntityArrow entityarrow = this.b(itemstack, f); double d0 = entityliving.locX - this.locX; - double d1 = entityliving.getBoundingBox().minY + (double) (entityliving.length / 3.0F) - entityarrow.locY; + double d1 = entityliving.getBoundingBox().minY + (double) (entityliving.getHeight() / 3.0F) - entityarrow.locY; double d2 = entityliving.locZ - this.locZ; double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2); @@ -166,35 +171,32 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR // this.world.addEntity(entityarrow); // CraftBukkit - moved up } - protected EntityArrow a(float f) { - EntityTippedArrow entitytippedarrow = new EntityTippedArrow(this.world, this); - - entitytippedarrow.a((EntityLiving) this, f); - return entitytippedarrow; + protected EntityArrow b(ItemStack itemstack, float f) { + return ProjectileHelper.a(this, itemstack, f); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.dz(); + this.dV(); } + @Override public void setSlot(EnumItemSlot enumitemslot, ItemStack itemstack) { super.setSlot(enumitemslot, itemstack); - if (!this.world.isClientSide && enumitemslot == EnumItemSlot.MAINHAND) { - this.dz(); + if (!this.world.isClientSide) { + this.dV(); } } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 1.74F; } - public double aI() { + @Override + public double aO() { return -0.6D; } - - public void s(boolean flag) { - this.datawatcher.set(EntitySkeletonAbstract.a, flag); - } } diff --git a/src/main/java/net/minecraft/server/EntitySkeletonWither.java b/src/main/java/net/minecraft/server/EntitySkeletonWither.java index 88d323525..872f79cc6 100644 --- a/src/main/java/net/minecraft/server/EntitySkeletonWither.java +++ b/src/main/java/net/minecraft/server/EntitySkeletonWither.java @@ -4,68 +4,73 @@ import javax.annotation.Nullable; public class EntitySkeletonWither extends EntitySkeletonAbstract { - public EntitySkeletonWither(World world) { - super(EntityTypes.WITHER_SKELETON, world); - this.setSize(0.7F, 2.4F); - this.fireProof = true; + public EntitySkeletonWither(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.a(PathType.LAVA, 8.0F); } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aw; - } - - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_WITHER_SKELETON_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_WITHER_SKELETON_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_WITHER_SKELETON_DEATH; } + @Override SoundEffect l() { return SoundEffects.ENTITY_WITHER_SKELETON_STEP; } - public void die(DamageSource damagesource) { - // super.die(damagesource); // CraftBukkit - if (damagesource.getEntity() instanceof EntityCreeper) { - EntityCreeper entitycreeper = (EntityCreeper) damagesource.getEntity(); + @Override + protected void dropDeathLoot(DamageSource damagesource, int i, boolean flag) { + super.dropDeathLoot(damagesource, i, flag); + Entity entity = damagesource.getEntity(); - if (entitycreeper.isPowered() && entitycreeper.canCauseHeadDrop()) { + if (entity instanceof EntityCreeper) { + EntityCreeper entitycreeper = (EntityCreeper) entity; + + if (entitycreeper.canCauseHeadDrop()) { entitycreeper.setCausedHeadDrop(); this.a((IMaterial) Items.WITHER_SKELETON_SKULL); } } - super.die(damagesource); // CraftBukkit - moved from above } + @Override protected void a(DifficultyDamageScaler difficultydamagescaler) { this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.STONE_SWORD)); } + @Override protected void b(DifficultyDamageScaler difficultydamagescaler) {} @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - GroupDataEntity groupdataentity1 = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + GroupDataEntity groupdataentity1 = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(4.0D); - this.dz(); + this.dV(); return groupdataentity1; } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 2.1F; } - public boolean B(Entity entity) { - if (!super.B(entity)) { + @Override + public boolean C(Entity entity) { + if (!super.C(entity)) { return false; } else { if (entity instanceof EntityLiving) { @@ -76,10 +81,16 @@ public class EntitySkeletonWither extends EntitySkeletonAbstract { } } - protected EntityArrow a(float f) { - EntityArrow entityarrow = super.a(f); + @Override + protected EntityArrow b(ItemStack itemstack, float f) { + EntityArrow entityarrow = super.b(itemstack, f); entityarrow.setOnFire(100); return entityarrow; } + + @Override + public boolean d(MobEffect mobeffect) { + return mobeffect.getMobEffect() == MobEffects.WITHER ? false : super.d(mobeffect); + } } diff --git a/src/main/java/net/minecraft/server/EntitySlice.java b/src/main/java/net/minecraft/server/EntitySlice.java deleted file mode 100644 index e2b75a09b..000000000 --- a/src/main/java/net/minecraft/server/EntitySlice.java +++ /dev/null @@ -1,133 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import java.util.AbstractSet; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class EntitySlice extends AbstractSet { - - private static final Set> a = Sets.newConcurrentHashSet(); // CraftBukkit - private final Map, List> b = Maps.newHashMap(); - private final Set> c = Sets.newIdentityHashSet(); - private final Class d; - private final List e = Lists.newArrayList(); - - public EntitySlice(Class oclass) { - this.d = oclass; - this.c.add(oclass); - this.b.put(oclass, this.e); - Iterator iterator = Lists.newArrayList(EntitySlice.a).iterator(); - - while (iterator.hasNext()) { - Class oclass1 = (Class) iterator.next(); - - this.a(oclass1); - } - - } - - protected void a(Class oclass) { - EntitySlice.a.add(oclass); - Iterator iterator = this.e.iterator(); // CraftBukkit - decompile error - - while (iterator.hasNext()) { - T t0 = iterator.next(); - - if (oclass.isAssignableFrom(t0.getClass())) { - this.a(t0, oclass); - } - } - - this.c.add(oclass); - } - - protected Class b(Class oclass) { - if (this.d.isAssignableFrom(oclass)) { - if (!this.c.contains(oclass)) { - this.a(oclass); - } - - return oclass; - } else { - throw new IllegalArgumentException("Don't know how to search for " + oclass); - } - } - - public boolean add(T t0) { - Iterator iterator = this.c.iterator(); - - while (iterator.hasNext()) { - Class oclass = (Class) iterator.next(); - - if (oclass.isAssignableFrom(t0.getClass())) { - this.a(t0, oclass); - } - } - - return true; - } - - private void a(T t0, Class oclass) { - List list = (List) this.b.get(oclass); - - if (list == null) { - this.b.put(oclass, Lists.newArrayList(t0)); - } else { - list.add(t0); - } - - } - - public boolean remove(Object object) { - T t0 = (T) object; // CraftBukkit - decompile error - boolean flag = false; - Iterator iterator = this.c.iterator(); - - while (iterator.hasNext()) { - Class oclass = (Class) iterator.next(); - - if (oclass.isAssignableFrom(t0.getClass())) { - List list = (List) this.b.get(oclass); - - if (list != null && list.remove(t0)) { - flag = true; - } - } - } - - return flag; - } - - public boolean contains(Object object) { - return Iterators.contains(this.c(object.getClass()).iterator(), object); - } - - public Iterable c(Class oclass) { - return () -> { - List list = (List) this.b.get(this.b(oclass)); - - if (list == null) { - return Collections.emptyIterator(); - } else { - Iterator iterator = list.iterator(); - - return Iterators.filter(iterator, oclass); - } - }; - } - - public Iterator iterator() { - return (Iterator) (this.e.isEmpty() ? Collections.emptyIterator() : Iterators.unmodifiableIterator(this.e.iterator())); - } - - public int size() { - return this.e.size(); - } -} diff --git a/src/main/java/net/minecraft/server/EntitySlime.java b/src/main/java/net/minecraft/server/EntitySlime.java index afbdc00c2..253ff9594 100644 --- a/src/main/java/net/minecraft/server/EntitySlime.java +++ b/src/main/java/net/minecraft/server/EntitySlime.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import java.util.EnumSet; +import java.util.Random; import javax.annotation.Nullable; // Paper start import com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent; @@ -19,59 +21,61 @@ import org.bukkit.event.entity.SlimeSplitEvent; public class EntitySlime extends EntityInsentient implements IMonster { - private static final DataWatcherObject bC = DataWatcher.a(EntitySlime.class, DataWatcherRegistry.b); - public float a; + private static final DataWatcherObject bz = DataWatcher.a(EntitySlime.class, DataWatcherRegistry.b); public float b; public float c; - private boolean bD; + public float d; + private boolean bA; - protected EntitySlime(EntityTypes entitytypes, World world) { + public EntitySlime(EntityTypes entitytypes, World world) { super(entitytypes, world); this.moveController = new EntitySlime.ControllerMoveSlime(this); } - public EntitySlime(World world) { - this(EntityTypes.SLIME, world); - } - - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(1, new EntitySlime.PathfinderGoalSlimeRandomJump(this)); this.goalSelector.a(2, new EntitySlime.PathfinderGoalSlimeNearestPlayer(this)); this.goalSelector.a(3, new EntitySlime.PathfinderGoalSlimeRandomDirection(this)); this.goalSelector.a(5, new EntitySlime.PathfinderGoalSlimeIdle(this)); - this.targetSelector.a(1, new PathfinderGoalTargetNearestPlayer(this)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTargetInsentient(this, EntityIronGolem.class)); + this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, (entityliving) -> { + return Math.abs(entityliving.locY - this.locY) <= 4.0D; + })); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntitySlime.bC, 1); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntitySlime.bz, 1); } public void setSize(int i, boolean flag) { - this.datawatcher.set(EntitySlime.bC, i); - this.setSize(0.51000005F * (float) i, 0.51000005F * (float) i); + this.datawatcher.set(EntitySlime.bz, i); this.setPosition(this.locX, this.locY, this.locZ); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue((double) (i * i)); + this.updateSize(); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue((double) (i * i)); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue((double) (0.2F + 0.1F * (float) i)); if (flag) { this.setHealth(this.getMaxHealth()); } - this.b_ = i; + this.f = i; } public int getSize() { - return (Integer) this.datawatcher.get(EntitySlime.bC); + return (Integer) this.datawatcher.get(EntitySlime.bz); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setInt("Size", this.getSize() - 1); - nbttagcompound.setBoolean("wasOnGround", this.bD); + nbttagcompound.setBoolean("wasOnGround", this.bA); nbttagcompound.setBoolean("Paper.canWander", this.canWander); // Paper } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); int i = nbttagcompound.getInt("Size"); @@ -81,7 +85,7 @@ public class EntitySlime extends EntityInsentient implements IMonster { } this.setSize(i + 1, false); - this.bD = nbttagcompound.getBoolean("wasOnGround"); + this.bA = nbttagcompound.getBoolean("wasOnGround"); // Paper start - check exists before loading or this will be loaded as false if (nbttagcompound.hasKey("Paper.canWander")) { this.canWander = nbttagcompound.getBoolean("Paper.canWander"); @@ -89,25 +93,24 @@ public class EntitySlime extends EntityInsentient implements IMonster { // Paper end } - public boolean dy() { + public boolean ea() { return this.getSize() <= 1; } protected ParticleParam l() { - return Particles.D; + return Particles.ITEM_SLIME; } + @Override public void tick() { if (!this.world.isClientSide && this.world.getDifficulty() == EnumDifficulty.PEACEFUL && this.getSize() > 0) { this.dead = true; } - this.b += (this.a - this.b) * 0.5F; - this.c = this.b; + this.c += (this.b - this.c) * 0.5F; + this.d = this.c; super.tick(); - if (this.onGround && !this.bD) { - // Akarin start - this handle by client - /* + if (this.onGround && !this.bA) { int i = this.getSize(); for (int j = 0; j < i * 8; ++j) { @@ -122,46 +125,45 @@ public class EntitySlime extends EntityInsentient implements IMonster { world.addParticle(particleparam, d0, this.getBoundingBox().minY, d1, 0.0D, 0.0D, 0.0D); } - */ - // Akarin end - this.a(this.dv(), this.cD(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) / 0.8F); - this.a = -0.5F; - } else if (!this.onGround && this.bD) { - this.a = 1.0F; + this.a(this.getSoundSquish(), this.getSoundVolume(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) / 0.8F); + this.b = -0.5F; + } else if (!this.onGround && this.bA) { + this.b = 1.0F; } - this.bD = this.onGround; - this.ds(); + this.bA = this.onGround; + this.dU(); } - protected void ds() { - this.a *= 0.6F; + protected void dU() { + this.b *= 0.6F; } - protected int dr() { + protected int dT() { return this.random.nextInt(20) + 10; } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntitySlime.bC.equals(datawatcherobject)) { - int i = this.getSize(); - - this.setSize(0.51000005F * (float) i, 0.51000005F * (float) i); - this.yaw = this.aS; - this.aQ = this.aS; + if (EntitySlime.bz.equals(datawatcherobject)) { + this.updateSize(); + this.yaw = this.aM; + this.aK = this.aM; if (this.isInWater() && this.random.nextInt(20) == 0) { - this.au(); + this.az(); } } super.a(datawatcherobject); } - public EntityTypes P() { - return (EntityTypes) super.P(); // CraftBukkit - decompile error + @Override + public EntityTypes getEntityType() { + return (EntityTypes) super.getEntityType(); // CraftBukkit - decompile error } + @Override public void die() { int i = this.getSize(); @@ -184,14 +186,14 @@ public class EntitySlime extends EntityInsentient implements IMonster { for (int k = 0; k < j; ++k) { float f = ((float) (k % 2) - 0.5F) * (float) i / 4.0F; float f1 = ((float) (k / 2) - 0.5F) * (float) i / 4.0F; - EntitySlime entityslime = (EntitySlime) this.P().a(this.world); + EntitySlime entityslime = (EntitySlime) this.getEntityType().a(this.world); if (this.hasCustomName()) { entityslime.setCustomName(this.getCustomName()); } if (this.isPersistent()) { - entityslime.di(); + entityslime.setPersistent(); } entityslime.setSize(i / 2, true); @@ -213,82 +215,83 @@ public class EntitySlime extends EntityInsentient implements IMonster { super.die(); } + @Override public void collide(Entity entity) { super.collide(entity); - if (entity instanceof EntityIronGolem && this.dt()) { - this.f((EntityLiving) entity); + if (entity instanceof EntityIronGolem && this.dV()) { + this.h((EntityLiving) entity); } } - public void d(EntityHuman entityhuman) { - if (this.dt()) { - this.f((EntityLiving) entityhuman); + @Override + public void pickup(EntityHuman entityhuman) { + if (this.dV()) { + this.h((EntityLiving) entityhuman); } } - protected void f(EntityLiving entityliving) { - int i = this.getSize(); + protected void h(EntityLiving entityliving) { + if (this.isAlive()) { + int i = this.getSize(); - if (this.hasLineOfSight(entityliving) && this.h(entityliving) < 0.6D * (double) i * 0.6D * (double) i && entityliving.damageEntity(DamageSource.mobAttack(this), (float) this.du())) { - this.a(SoundEffects.ENTITY_SLIME_ATTACK, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); - this.a((EntityLiving) this, (Entity) entityliving); + if (this.h((Entity) entityliving) < 0.6D * (double) i * 0.6D * (double) i && this.hasLineOfSight(entityliving) && entityliving.damageEntity(DamageSource.mobAttack(this), (float) this.dW())) { + this.a(SoundEffects.ENTITY_SLIME_ATTACK, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + this.a((EntityLiving) this, (Entity) entityliving); + } } } - public float getHeadHeight() { - return 0.625F * this.length; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return 0.625F * entitysize.height; } - protected boolean dt() { - return !this.dy() && this.cP(); + protected boolean dV() { + return !this.ea() && this.df(); } - protected int du() { + protected int dW() { return this.getSize(); } - protected SoundEffect d(DamageSource damagesource) { - return this.dy() ? SoundEffects.ENTITY_SLIME_HURT_SMALL : SoundEffects.ENTITY_SLIME_HURT; + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return this.ea() ? SoundEffects.ENTITY_SLIME_HURT_SMALL : SoundEffects.ENTITY_SLIME_HURT; } - protected SoundEffect cs() { - return this.dy() ? SoundEffects.ENTITY_SLIME_DEATH_SMALL : SoundEffects.ENTITY_SLIME_DEATH; + @Override + protected SoundEffect getSoundDeath() { + return this.ea() ? SoundEffects.ENTITY_SLIME_DEATH_SMALL : SoundEffects.ENTITY_SLIME_DEATH; } - protected SoundEffect dv() { - return this.dy() ? SoundEffects.ENTITY_SLIME_SQUISH_SMALL : SoundEffects.ENTITY_SLIME_SQUISH; + protected SoundEffect getSoundSquish() { + return this.ea() ? SoundEffects.ENTITY_SLIME_SQUISH_SMALL : SoundEffects.ENTITY_SLIME_SQUISH; } - protected Item getLoot() { - return this.getSize() == 1 ? Items.SLIME_BALL : null; - } - - @Nullable + @Override protected MinecraftKey getDefaultLootTable() { - return this.getSize() == 1 ? LootTables.ao : LootTables.a; + return this.getSize() == 1 ? this.getEntityType().h() : LootTables.a; } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - BlockPosition blockposition = new BlockPosition(MathHelper.floor(this.locX), 0, MathHelper.floor(this.locZ)); - - if (generatoraccess.getWorldData().getType() == WorldType.FLAT && this.random.nextInt(4) != 1) { + public static boolean c(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + if (generatoraccess.getWorldData().getType() == WorldType.FLAT && random.nextInt(4) != 1) { return false; } else { if (generatoraccess.getDifficulty() != EnumDifficulty.PEACEFUL) { BiomeBase biomebase = generatoraccess.getBiome(blockposition); - if (biomebase == Biomes.SWAMP && this.locY > 50.0D && this.locY < 70.0D && this.random.nextFloat() < 0.5F && this.random.nextFloat() < generatoraccess.ah() && generatoraccess.getLightLevel(new BlockPosition(this)) <= this.random.nextInt(8)) { - return super.a(generatoraccess, flag); + if (biomebase == Biomes.SWAMP && blockposition.getY() > 50 && blockposition.getY() < 70 && random.nextFloat() < 0.5F && random.nextFloat() < generatoraccess.aa() && generatoraccess.getLightLevel(blockposition) <= random.nextInt(8)) { + return a(entitytypes, generatoraccess, enummobspawn, blockposition, random); } ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(blockposition); - boolean flag1 = world.paperConfig.allChunksAreSlimeChunks || SeededRandom.a(chunkcoordintpair.x, chunkcoordintpair.z, generatoraccess.getSeed(), world.spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper - add allChunksAreSlime + boolean flag = generatoraccess.getMinecraftWorld().paperConfig.allChunksAreSlimeChunks || SeededRandom.a(chunkcoordintpair.x, chunkcoordintpair.z, generatoraccess.getSeed(), generatoraccess.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper - if (this.random.nextInt(10) == 0 && flag1 && this.locY < 40.0D) { - return super.a(generatoraccess, flag); + if (random.nextInt(10) == 0 && flag && blockposition.getY() < 40) { + return a(entitytypes, generatoraccess, enummobspawn, blockposition, random); } } @@ -296,25 +299,31 @@ public class EntitySlime extends EntityInsentient implements IMonster { } } - protected float cD() { + @Override + protected float getSoundVolume() { return 0.4F * (float) this.getSize(); } - public int K() { + @Override + public int M() { return 0; } - protected boolean dz() { + protected boolean eb() { return this.getSize() > 0; } - protected void cH() { - this.motY = 0.41999998688697815D; + @Override + protected void jump() { + Vec3D vec3d = this.getMot(); + + this.setMot(vec3d.x, 0.41999998688697815D, vec3d.z); this.impulse = true; } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { int i = this.random.nextInt(3); if (i < 2 && this.random.nextFloat() < 0.5F * difficultydamagescaler.d()) { @@ -324,11 +333,16 @@ public class EntitySlime extends EntityInsentient implements IMonster { int j = 1 << i; this.setSize(j, true); - return super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } - protected SoundEffect dw() { - return this.dy() ? SoundEffects.ENTITY_SLIME_JUMP_SMALL : SoundEffects.ENTITY_SLIME_JUMP; + protected SoundEffect getSoundJump() { + return this.ea() ? SoundEffects.ENTITY_SLIME_JUMP_SMALL : SoundEffects.ENTITY_SLIME_JUMP; + } + + @Override + public EntitySize a(EntityPose entitypose) { + return super.a(entitypose).a(0.255F * (float) this.getSize()); } static class PathfinderGoalSlimeIdle extends PathfinderGoal { @@ -337,13 +351,15 @@ public class EntitySlime extends EntityInsentient implements IMonster { public PathfinderGoalSlimeIdle(EntitySlime entityslime) { this.a = entityslime; - this.a(5); + this.a(EnumSet.of(PathfinderGoal.Type.JUMP, PathfinderGoal.Type.MOVE)); } + @Override public boolean a() { - return this.a.canWander && new SlimeWanderEvent((Slime) this.a.getBukkitEntity()).callEvent(); // Paper + return !this.a.isPassenger() && this.a.canWander && new SlimeWanderEvent((Slime) this.a.getBukkitEntity()).callEvent(); // Paper } + @Override public void e() { ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(1.0D); } @@ -355,17 +371,19 @@ public class EntitySlime extends EntityInsentient implements IMonster { public PathfinderGoalSlimeRandomJump(EntitySlime entityslime) { this.a = entityslime; - this.a(5); - ((Navigation) entityslime.getNavigation()).d(true); + this.a(EnumSet.of(PathfinderGoal.Type.JUMP, PathfinderGoal.Type.MOVE)); + entityslime.getNavigation().d(true); } + @Override public boolean a() { - return (this.a.isInWater() || this.a.ax()) && this.a.canWander && new SlimeSwimEvent((Slime) this.a.getBukkitEntity()).callEvent(); // Paper + return (this.a.isInWater() || this.a.aD()) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime && this.a.canWander && new SlimeSwimEvent((Slime) this.a.getBukkitEntity()).callEvent(); // Paper } + @Override public void e() { if (this.a.getRandom().nextFloat() < 0.8F) { - this.a.getControllerJump().a(); + this.a.getControllerJump().jump(); } ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(1.2D); @@ -380,13 +398,15 @@ public class EntitySlime extends EntityInsentient implements IMonster { public PathfinderGoalSlimeRandomDirection(EntitySlime entityslime) { this.a = entityslime; - this.a(2); + this.a(EnumSet.of(PathfinderGoal.Type.LOOK)); } + @Override public boolean a() { - return this.a.canWander && this.a.getGoalTarget() == null && (this.a.onGround || this.a.isInWater() || this.a.ax() || this.a.hasEffect(MobEffects.LEVITATION)); // Paper + return this.a.canWander && this.a.getGoalTarget() == null && (this.a.onGround || this.a.isInWater() || this.a.aD() || this.a.hasEffect(MobEffects.LEVITATION)) && this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime; } + @Override public void e() { if (--this.c <= 0) { this.c = 40 + this.a.getRandom().nextInt(60); @@ -408,9 +428,10 @@ public class EntitySlime extends EntityInsentient implements IMonster { public PathfinderGoalSlimeNearestPlayer(EntitySlime entityslime) { this.a = entityslime; - this.a(2); + this.a(EnumSet.of(PathfinderGoal.Type.LOOK)); } + @Override public boolean a() { EntityLiving entityliving = this.a.getGoalTarget(); @@ -421,15 +442,17 @@ public class EntitySlime extends EntityInsentient implements IMonster { if (entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.isInvulnerable) { return false; } - return this.a.canWander && new SlimeTargetLivingEntityEvent((Slime) this.a.getBukkitEntity(), (LivingEntity) entityliving.getBukkitEntity()).callEvent(); + return this.a.getControllerMove() instanceof EntitySlime.ControllerMoveSlime && this.a.canWander && new SlimeTargetLivingEntityEvent((Slime) this.a.getBukkitEntity(), (LivingEntity) entityliving.getBukkitEntity()).callEvent(); // Paper end } + @Override public void c() { this.b = 300; super.c(); } + @Override public boolean b() { EntityLiving entityliving = this.a.getGoalTarget(); @@ -444,9 +467,10 @@ public class EntitySlime extends EntityInsentient implements IMonster { // Paper end } + @Override public void e() { this.a.a((Entity) this.a.getGoalTarget(), 10.0F, 10.0F); - ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(this.a.yaw, this.a.dt()); + ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(this.a.yaw, this.a.dV()); } // Paper start - clear timer and target when goal resets @@ -480,10 +504,11 @@ public class EntitySlime extends EntityInsentient implements IMonster { this.h = ControllerMove.Operation.MOVE_TO; } + @Override public void a() { this.a.yaw = this.a(this.a.yaw, this.i, 90.0F); - this.a.aS = this.a.yaw; - this.a.aQ = this.a.yaw; + this.a.aM = this.a.yaw; + this.a.aK = this.a.yaw; if (this.h != ControllerMove.Operation.MOVE_TO) { this.a.r(0.0F); } else { @@ -491,18 +516,18 @@ public class EntitySlime extends EntityInsentient implements IMonster { if (this.a.onGround) { this.a.o((float) (this.e * this.a.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue())); if (this.j-- <= 0) { - this.j = this.k.dr(); + this.j = this.k.dT(); if (this.l) { this.j /= 3; } - this.k.getControllerJump().a(); - if (this.k.dz()) { - this.k.a(this.k.dw(), this.k.cD(), ((this.k.getRandom().nextFloat() - this.k.getRandom().nextFloat()) * 0.2F + 1.0F) * 0.8F); + this.k.getControllerJump().jump(); + if (this.k.eb()) { + this.k.a(this.k.getSoundJump(), this.k.getSoundVolume(), ((this.k.getRandom().nextFloat() - this.k.getRandom().nextFloat()) * 0.2F + 1.0F) * 0.8F); } } else { - this.k.bh = 0.0F; - this.k.bj = 0.0F; + this.k.bb = 0.0F; + this.k.bd = 0.0F; this.a.o(0.0F); } } else { diff --git a/src/main/java/net/minecraft/server/EntitySmallFireball.java b/src/main/java/net/minecraft/server/EntitySmallFireball.java index 121921e35..c0071eb1f 100644 --- a/src/main/java/net/minecraft/server/EntitySmallFireball.java +++ b/src/main/java/net/minecraft/server/EntitySmallFireball.java @@ -2,62 +2,58 @@ package net.minecraft.server; import org.bukkit.event.entity.EntityCombustByEntityEvent; // CraftBukkit -public class EntitySmallFireball extends EntityFireball { +public class EntitySmallFireball extends EntityFireballFireball { - public EntitySmallFireball(World world) { - super(EntityTypes.SMALL_FIREBALL, world, 0.3125F, 0.3125F); + public EntitySmallFireball(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntitySmallFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) { - super(EntityTypes.SMALL_FIREBALL, entityliving, d0, d1, d2, world, 0.3125F, 0.3125F); + super(EntityTypes.SMALL_FIREBALL, entityliving, d0, d1, d2, world); // CraftBukkit start if (this.shooter != null && this.shooter instanceof EntityInsentient) { - isIncendiary = this.world.getGameRules().getBoolean("mobGriefing"); + isIncendiary = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING); } // CraftBukkit end } public EntitySmallFireball(World world, double d0, double d1, double d2, double d3, double d4, double d5) { - super(EntityTypes.SMALL_FIREBALL, d0, d1, d2, d3, d4, d5, world, 0.3125F, 0.3125F); + super(EntityTypes.SMALL_FIREBALL, d0, d1, d2, d3, d4, d5, world); } + @Override protected void a(MovingObjectPosition movingobjectposition) { if (!this.world.isClientSide) { - boolean flag; + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + Entity entity = ((MovingObjectPositionEntity) movingobjectposition).getEntity(); + + if (!entity.isFireProof()) { + int i = entity.ad(); - if (movingobjectposition.entity != null) { - if (!movingobjectposition.entity.isFireProof()) { // CraftBukkit start - Entity damage by entity event + combust event if (isIncendiary) { - EntityCombustByEntityEvent event = new EntityCombustByEntityEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), movingobjectposition.entity.getBukkitEntity(), 5); - movingobjectposition.entity.world.getServer().getPluginManager().callEvent(event); + EntityCombustByEntityEvent event = new EntityCombustByEntityEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), entity.getBukkitEntity(), 5); + entity.world.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { - movingobjectposition.entity.setOnFire(event.getDuration(), false); + entity.setOnFire(event.getDuration(), false); } } // CraftBukkit end - flag = movingobjectposition.entity.damageEntity(DamageSource.fireball(this, this.shooter), 5.0F); + boolean flag = entity.damageEntity(DamageSource.fireball(this, this.shooter), 5.0F); + if (flag) { - this.a(this.shooter, movingobjectposition.entity); + this.a(this.shooter, entity); + } else { + entity.g(i); } } - } else { - flag = true; - if (this.shooter != null && this.shooter instanceof EntityInsentient) { - flag = this.world.getGameRules().getBoolean("mobGriefing"); - } + } else if (isIncendiary) { // CraftBukkit + MovingObjectPositionBlock movingobjectpositionblock = (MovingObjectPositionBlock) movingobjectposition; + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition().shift(movingobjectpositionblock.getDirection()); - // CraftBukkit start - if (isIncendiary) { - BlockPosition blockposition = movingobjectposition.getBlockPosition().shift(movingobjectposition.direction); - - if (this.world.isEmpty(blockposition)) { - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, this).isCancelled()) { - this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); - } - // CraftBukkit end - } + if (this.world.isEmpty(blockposition) && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, this).isCancelled()) { // CraftBukkit + this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); } } @@ -66,10 +62,12 @@ public class EntitySmallFireball extends EntityFireball { } + @Override public boolean isInteractable() { return false; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { return false; } diff --git a/src/main/java/net/minecraft/server/EntitySnowman.java b/src/main/java/net/minecraft/server/EntitySnowman.java index 6fdd8cc3a..fe1381cc1 100644 --- a/src/main/java/net/minecraft/server/EntitySnowman.java +++ b/src/main/java/net/minecraft/server/EntitySnowman.java @@ -8,37 +8,43 @@ import org.bukkit.event.player.PlayerShearEntityEvent; public class EntitySnowman extends EntityGolem implements IRangedEntity { - private static final DataWatcherObject a = DataWatcher.a(EntitySnowman.class, DataWatcherRegistry.a); + private static final DataWatcherObject b = DataWatcher.a(EntitySnowman.class, DataWatcherRegistry.a); - public EntitySnowman(World world) { - super(EntityTypes.SNOW_GOLEM, world); - this.setSize(0.7F, 1.9F); + public EntitySnowman(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalArrowAttack(this, 1.25D, 20, 10.0F)); this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D, 1.0000001E-5F)); this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 10, true, false, IMonster.d)); + this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 10, true, false, (entityliving) -> { + return entityliving instanceof IMonster; + })); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(4.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(4.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.20000000298023224D); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntitySnowman.a, (byte) 16); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntitySnowman.b, (byte) 16); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setBoolean("Pumpkin", this.hasPumpkin()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKey("Pumpkin")) { @@ -47,6 +53,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { } + @Override public void movementTick() { super.movementTick(); if (!this.world.isClientSide) { @@ -54,7 +61,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { int j = MathHelper.floor(this.locY); int k = MathHelper.floor(this.locZ); - if (this.ap()) { + if (this.au()) { this.damageEntity(DamageSource.DROWN, 1.0F); } @@ -62,7 +69,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { this.damageEntity(CraftEventFactory.MELTING, 1.0F); // CraftBukkit - DamageSource.BURN -> CraftEventFactory.MELTING } - if (!this.world.getGameRules().getBoolean("mobGriefing")) { + if (!this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { return; } @@ -82,11 +89,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.H; - } - + @Override public void a(EntityLiving entityliving, float f) { EntitySnowball entitysnowball = new EntitySnowball(this.world, this); double d0 = entityliving.locY + (double) entityliving.getHeadHeight() - 1.100000023841858D; @@ -100,10 +103,12 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { this.world.addEntity(entitysnowball); } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 1.7F; } + @Override protected boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -118,41 +123,44 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { // CraftBukkit end this.setHasPumpkin(false); - itemstack.damage(1, entityhuman); + itemstack.damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(enumhand); + }); } return super.a(entityhuman, enumhand); } public boolean hasPumpkin() { - return ((Byte) this.datawatcher.get(EntitySnowman.a) & 16) != 0; + return ((Byte) this.datawatcher.get(EntitySnowman.b) & 16) != 0; } public void setHasPumpkin(boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntitySnowman.a); + byte b0 = (Byte) this.datawatcher.get(EntitySnowman.b); if (flag) { - this.datawatcher.set(EntitySnowman.a, (byte) (b0 | 16)); + this.datawatcher.set(EntitySnowman.b, (byte) (b0 | 16)); } else { - this.datawatcher.set(EntitySnowman.a, (byte) (b0 & -17)); + this.datawatcher.set(EntitySnowman.b, (byte) (b0 & -17)); } } @Nullable - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_SNOW_GOLEM_AMBIENT; } @Nullable - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_SNOW_GOLEM_HURT; } @Nullable - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_SNOW_GOLEM_DEATH; } - - public void s(boolean flag) {} } diff --git a/src/main/java/net/minecraft/server/EntitySpectralArrow.java b/src/main/java/net/minecraft/server/EntitySpectralArrow.java index 13027fa3c..fad23ed2b 100644 --- a/src/main/java/net/minecraft/server/EntitySpectralArrow.java +++ b/src/main/java/net/minecraft/server/EntitySpectralArrow.java @@ -4,8 +4,8 @@ public class EntitySpectralArrow extends EntityArrow { public int duration = 200; - public EntitySpectralArrow(World world) { - super(EntityTypes.SPECTRAL_ARROW, world); + public EntitySpectralArrow(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntitySpectralArrow(World world, EntityLiving entityliving) { @@ -16,18 +16,21 @@ public class EntitySpectralArrow extends EntityArrow { super(EntityTypes.SPECTRAL_ARROW, d0, d1, d2, world); } + @Override public void tick() { super.tick(); if (this.world.isClientSide && !this.inGround) { - this.world.addParticle(Particles.B, this.locX, this.locY, this.locZ, 0.0D, 0.0D, 0.0D); + this.world.addParticle(Particles.INSTANT_EFFECT, this.locX, this.locY, this.locZ, 0.0D, 0.0D, 0.0D); } } + @Override protected ItemStack getItemStack() { return new ItemStack(Items.SPECTRAL_ARROW); } + @Override protected void a(EntityLiving entityliving) { super.a(entityliving); MobEffect mobeffect = new MobEffect(MobEffects.GLOWING, this.duration, 0); @@ -35,6 +38,7 @@ public class EntitySpectralArrow extends EntityArrow { entityliving.addEffect(mobeffect, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ARROW); // CraftBukkit } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKey("Duration")) { @@ -43,6 +47,7 @@ public class EntitySpectralArrow extends EntityArrow { } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setInt("Duration", this.duration); diff --git a/src/main/java/net/minecraft/server/EntitySpider.java b/src/main/java/net/minecraft/server/EntitySpider.java index 9ef1c9baf..3929c86f8 100644 --- a/src/main/java/net/minecraft/server/EntitySpider.java +++ b/src/main/java/net/minecraft/server/EntitySpider.java @@ -5,97 +5,106 @@ import javax.annotation.Nullable; public class EntitySpider extends EntityMonster { - private static final DataWatcherObject a = DataWatcher.a(EntitySpider.class, DataWatcherRegistry.a); + private static final DataWatcherObject b = DataWatcher.a(EntitySpider.class, DataWatcherRegistry.a); - protected EntitySpider(EntityTypes entitytypes, World world) { + public EntitySpider(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.setSize(1.4F, 0.9F); } - public EntitySpider(World world) { - this(EntityTypes.SPIDER, world); - } - - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); this.goalSelector.a(3, new PathfinderGoalLeapAtTarget(this, 0.4F)); this.goalSelector.a(4, new EntitySpider.PathfinderGoalSpiderMeleeAttack(this)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.8D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0])); this.targetSelector.a(2, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget<>(this, EntityHuman.class)); this.targetSelector.a(3, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget<>(this, EntityIronGolem.class)); } - public double aJ() { - return (double) (this.length * 0.5F); + @Override + public double aP() { + return (double) (this.getHeight() * 0.5F); } + @Override protected NavigationAbstract b(World world) { return new NavigationSpider(this, world); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntitySpider.a, (byte) 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntitySpider.b, (byte) 0); } + @Override public void tick() { super.tick(); if (!this.world.isClientSide) { - this.a(this.positionChanged); + this.r(this.positionChanged); } } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(16.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(16.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_SPIDER_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_SPIDER_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_SPIDER_DEATH; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(SoundEffects.ENTITY_SPIDER_STEP, 0.15F, 1.0F); } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.y; - } - - public boolean z_() { + @Override + public boolean isClimbing() { return this.l(); } - public void bh() {} + @Override + public void a(IBlockData iblockdata, Vec3D vec3d) { + if (iblockdata.getBlock() != Blocks.COBWEB) { + super.a(iblockdata, vec3d); + } + } + + @Override public EnumMonsterType getMonsterType() { return EnumMonsterType.ARTHROPOD; } + @Override public boolean d(MobEffect mobeffect) { return mobeffect.getMobEffect() == MobEffects.POISON ? false : super.d(mobeffect); } public boolean l() { - return ((Byte) this.datawatcher.get(EntitySpider.a) & 1) != 0; + return ((Byte) this.datawatcher.get(EntitySpider.b) & 1) != 0; } - public void a(boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntitySpider.a); + public void r(boolean flag) { + byte b0 = (Byte) this.datawatcher.get(EntitySpider.b); if (flag) { b0 = (byte) (b0 | 1); @@ -103,26 +112,27 @@ public class EntitySpider extends EntityMonster { b0 &= -2; } - this.datawatcher.set(EntitySpider.a, b0); + this.datawatcher.set(EntitySpider.b, b0); } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - Object object = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + Object object = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); - if (this.world.random.nextInt(100) == 0) { - EntitySkeleton entityskeleton = EntityTypes.SKELETON.create(world); // Paper + if (generatoraccess.getRandom().nextInt(100) == 0) { + EntitySkeleton entityskeleton = (EntitySkeleton) EntityTypes.SKELETON.a(this.world); entityskeleton.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); - entityskeleton.prepare(difficultydamagescaler, (GroupDataEntity) null, (NBTTagCompound) null); - this.world.addEntity(entityskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.JOCKEY); // CraftBukkit - add SpawnReason + entityskeleton.prepare(generatoraccess, difficultydamagescaler, enummobspawn, (GroupDataEntity) null, (NBTTagCompound) null); + generatoraccess.addEntity(entityskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.JOCKEY); // CraftBukkit - add SpawnReason entityskeleton.startRiding(this); } if (object == null) { object = new EntitySpider.GroupDataSpider(); - if (this.world.getDifficulty() == EnumDifficulty.HARD && this.world.random.nextFloat() < 0.1F * difficultydamagescaler.d()) { - ((EntitySpider.GroupDataSpider) object).a(this.world.random); + if (generatoraccess.getDifficulty() == EnumDifficulty.HARD && generatoraccess.getRandom().nextFloat() < 0.1F * difficultydamagescaler.d()) { + ((EntitySpider.GroupDataSpider) object).a(generatoraccess.getRandom()); } } @@ -137,7 +147,8 @@ public class EntitySpider extends EntityMonster { return (GroupDataEntity) object; } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 0.65F; } @@ -147,8 +158,9 @@ public class EntitySpider extends EntityMonster { super(entityspider, oclass, true); } + @Override public boolean a() { - float f = this.e.az(); + float f = this.e.aF(); return f >= 0.5F ? false : super.a(); } @@ -160,8 +172,14 @@ public class EntitySpider extends EntityMonster { super(entityspider, 1.0D, true); } + @Override + public boolean a() { + return super.a() && !this.a.isVehicle(); + } + + @Override public boolean b() { - float f = this.a.az(); + float f = this.a.aF(); if (f >= 0.5F && this.a.getRandom().nextInt(100) == 0) { this.a.setGoalTarget((EntityLiving) null); @@ -171,8 +189,9 @@ public class EntitySpider extends EntityMonster { } } + @Override protected double a(EntityLiving entityliving) { - return (double) (4.0F + entityliving.width); + return (double) (4.0F + entityliving.getWidth()); } } diff --git a/src/main/java/net/minecraft/server/EntitySquid.java b/src/main/java/net/minecraft/server/EntitySquid.java index a23b1d337..a4d2ff64d 100644 --- a/src/main/java/net/minecraft/server/EntitySquid.java +++ b/src/main/java/net/minecraft/server/EntitySquid.java @@ -1,186 +1,188 @@ package net.minecraft.server; -import javax.annotation.Nullable; +import java.util.Random; public class EntitySquid extends EntityWaterAnimal { - public float a; public float b; public float c; + public float d; + public float bz; + public float bA; + public float bB; public float bC; public float bD; - public float bE; - public float bF; - public float bG; + private float bE; + private float bF; + private float bG; private float bH; private float bI; private float bJ; - private float bK; - private float bL; - private float bM; - public EntitySquid(World world) { - super(EntityTypes.SQUID, world); - this.setSize(0.8F, 0.8F); - //this.random.setSeed((long) (1 + this.getId())); // Paper - this.bI = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; + public EntitySquid(EntityTypes entitytypes, World world) { + super(entitytypes, world); + //this.random.setSeed((long) this.getId()); // Paper + this.bF = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(0, new EntitySquid.PathfinderGoalSquid(this)); this.goalSelector.a(1, new EntitySquid.a()); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D); } - public float getHeadHeight() { - return this.length * 0.5F; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height * 0.5F; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_SQUID_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_SQUID_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_SQUID_DEATH; } - protected float cD() { + @Override + protected float getSoundVolume() { return 0.4F; } + @Override protected boolean playStepSound() { return false; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.ar; - } - + @Override public void movementTick() { super.movementTick(); - this.b = this.a; - this.bC = this.c; - this.bE = this.bD; - this.bG = this.bF; - this.bD += this.bI; - if ((double) this.bD > 6.283185307179586D) { + this.c = this.b; + this.bz = this.d; + this.bB = this.bA; + this.bD = this.bC; + this.bA += this.bF; + if ((double) this.bA > 6.283185307179586D) { if (this.world.isClientSide) { - this.bD = 6.2831855F; + this.bA = 6.2831855F; } else { - this.bD = (float) ((double) this.bD - 6.283185307179586D); + this.bA = (float) ((double) this.bA - 6.283185307179586D); if (this.random.nextInt(10) == 0) { - this.bI = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; + this.bF = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; } this.world.broadcastEntityEffect(this, (byte) 19); } } - if (this.aq()) { - float f; + if (this.av()) { + if (this.bA < 3.1415927F) { + float f = this.bA / 3.1415927F; - if (this.bD < 3.1415927F) { - f = this.bD / 3.1415927F; - this.bF = MathHelper.sin(f * f * 3.1415927F) * 3.1415927F * 0.25F; + this.bC = MathHelper.sin(f * f * 3.1415927F) * 3.1415927F * 0.25F; if ((double) f > 0.75D) { - this.bH = 1.0F; - this.bJ = 1.0F; + this.bE = 1.0F; + this.bG = 1.0F; } else { - this.bJ *= 0.8F; + this.bG *= 0.8F; } } else { - this.bF = 0.0F; - this.bH *= 0.9F; - this.bJ *= 0.99F; + this.bC = 0.0F; + this.bE *= 0.9F; + this.bG *= 0.99F; } if (!this.world.isClientSide) { - this.motX = (double) (this.bK * this.bH); - this.motY = (double) (this.bL * this.bH); - this.motZ = (double) (this.bM * this.bH); + this.setMot((double) (this.bH * this.bE), (double) (this.bI * this.bE), (double) (this.bJ * this.bE)); } - f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); - this.aQ += (-((float) MathHelper.c(this.motX, this.motZ)) * 57.295776F - this.aQ) * 0.1F; - this.yaw = this.aQ; - this.c = (float) ((double) this.c + 3.141592653589793D * (double) this.bJ * 1.5D); - this.a += (-((float) MathHelper.c((double) f, this.motY)) * 57.295776F - this.a) * 0.1F; + Vec3D vec3d = this.getMot(); + float f1 = MathHelper.sqrt(b(vec3d)); + + this.aK += (-((float) MathHelper.d(vec3d.x, vec3d.z)) * 57.295776F - this.aK) * 0.1F; + this.yaw = this.aK; + this.d = (float) ((double) this.d + 3.141592653589793D * (double) this.bG * 1.5D); + this.b += (-((float) MathHelper.d((double) f1, vec3d.y)) * 57.295776F - this.b) * 0.1F; } else { - this.bF = MathHelper.e(MathHelper.sin(this.bD)) * 3.1415927F * 0.25F; + this.bC = MathHelper.e(MathHelper.sin(this.bA)) * 3.1415927F * 0.25F; if (!this.world.isClientSide) { - this.motX = 0.0D; - this.motZ = 0.0D; + double d0 = this.getMot().y; + if (this.hasEffect(MobEffects.LEVITATION)) { - this.motY += 0.05D * (double) (this.getEffect(MobEffects.LEVITATION).getAmplifier() + 1) - this.motY; + d0 = 0.05D * (double) (this.getEffect(MobEffects.LEVITATION).getAmplifier() + 1); } else if (!this.isNoGravity()) { - this.motY -= 0.08D; + d0 -= 0.08D; } - this.motY *= 0.9800000190734863D; + this.setMot(0.0D, d0 * 0.9800000190734863D, 0.0D); } - this.a = (float) ((double) this.a + (double) (-90.0F - this.a) * 0.02D); + this.b = (float) ((double) this.b + (double) (-90.0F - this.b) * 0.02D); } } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (super.damageEntity(damagesource, f) && this.getLastDamager() != null) { - this.dy(); + this.dV(); return true; } else { return false; } } - private Vec3D b(Vec3D vec3d) { - Vec3D vec3d1 = vec3d.a(this.b * 0.017453292F); + private Vec3D f(Vec3D vec3d) { + Vec3D vec3d1 = vec3d.a(this.c * 0.017453292F); - vec3d1 = vec3d1.b(-this.aR * 0.017453292F); + vec3d1 = vec3d1.b(-this.aL * 0.017453292F); return vec3d1; } - private void dy() { - this.a(SoundEffects.ENTITY_SQUID_SQUIRT, this.cD(), this.cE()); - Vec3D vec3d = this.b(new Vec3D(0.0D, -1.0D, 0.0D)).add(this.locX, this.locY, this.locZ); + private void dV() { + this.a(SoundEffects.ENTITY_SQUID_SQUIRT, this.getSoundVolume(), this.cV()); + Vec3D vec3d = this.f(new Vec3D(0.0D, -1.0D, 0.0D)).add(this.locX, this.locY, this.locZ); for (int i = 0; i < 30; ++i) { - Vec3D vec3d1 = this.b(new Vec3D((double) this.random.nextFloat() * 0.6D - 0.3D, -1.0D, (double) this.random.nextFloat() * 0.6D - 0.3D)); + Vec3D vec3d1 = this.f(new Vec3D((double) this.random.nextFloat() * 0.6D - 0.3D, -1.0D, (double) this.random.nextFloat() * 0.6D - 0.3D)); Vec3D vec3d2 = vec3d1.a(0.3D + (double) (this.random.nextFloat() * 2.0F)); - ((WorldServer) this.world).a(Particles.V, vec3d.x, vec3d.y + 0.5D, vec3d.z, 0, vec3d2.x, vec3d2.y, vec3d2.z, 0.10000000149011612D); + ((WorldServer) this.world).a(Particles.SQUID_INK, vec3d.x, vec3d.y + 0.5D, vec3d.z, 0, vec3d2.x, vec3d2.y, vec3d2.z, 0.10000000149011612D); } } + @Override + public void e(Vec3D vec3d) { + this.move(EnumMoveType.SELF, this.getMot()); + } + + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + final double maxHeight = generatoraccess.getMinecraftWorld().paperConfig.squidMaxSpawnHeight > 0 ? generatoraccess.getMinecraftWorld().paperConfig.squidMaxSpawnHeight : generatoraccess.getSeaLevel(); // Paper + return blockposition.getY() > generatoraccess.getMinecraftWorld().spigotConfig.squidSpawnRangeMin && blockposition.getY() < maxHeight; // Spigot // Paper + } + public void a(float f, float f1, float f2) { - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - } - - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - // Paper - Make max spawn height configurable - final double maxHeight = world.paperConfig.squidMaxSpawnHeight > 0 ? world.paperConfig.squidMaxSpawnHeight : world.getSeaLevel(); - return this.locY > this.world.spigotConfig.squidSpawnRangeMin && this.locY < maxHeight; // Spigot - // Paper end - } - - public void c(float f, float f1, float f2) { - this.bK = f; - this.bL = f1; - this.bM = f2; + this.bH = f; + this.bI = f1; + this.bJ = f2; } public boolean l() { - return this.bK != 0.0F || this.bL != 0.0F || this.bM != 0.0F; + return this.bH != 0.0F || this.bI != 0.0F || this.bJ != 0.0F; } class a extends PathfinderGoal { @@ -189,16 +191,19 @@ public class EntitySquid extends EntityWaterAnimal { private a() {} + @Override public boolean a() { EntityLiving entityliving = EntitySquid.this.getLastDamager(); - return EntitySquid.this.isInWater() && entityliving != null ? EntitySquid.this.h(entityliving) < 100.0D : false; + return EntitySquid.this.isInWater() && entityliving != null ? EntitySquid.this.h((Entity) entityliving) < 100.0D : false; } + @Override public void c() { this.b = 0; } + @Override public void e() { ++this.b; EntityLiving entityliving = EntitySquid.this.getLastDamager(); @@ -209,10 +214,10 @@ public class EntitySquid extends EntityWaterAnimal { Fluid fluid = EntitySquid.this.world.getFluid(new BlockPosition(EntitySquid.this.locX + vec3d.x, EntitySquid.this.locY + vec3d.y, EntitySquid.this.locZ + vec3d.z)); if (fluid.a(TagsFluid.WATER) || iblockdata.isAir()) { - double d0 = vec3d.b(); + double d0 = vec3d.f(); if (d0 > 0.0D) { - vec3d.a(); + vec3d.d(); float f = 3.0F; if (d0 > 5.0D) { @@ -228,15 +233,12 @@ public class EntitySquid extends EntityWaterAnimal { vec3d = vec3d.a(0.0D, vec3d.y, 0.0D); } - EntitySquid.this.c((float) vec3d.x / 20.0F, (float) vec3d.y / 20.0F, (float) vec3d.z / 20.0F); + EntitySquid.this.a((float) vec3d.x / 20.0F, (float) vec3d.y / 20.0F, (float) vec3d.z / 20.0F); } - // Akarin start - this handle by client - /* if (this.b % 10 == 5) { - EntitySquid.this.world.addParticle(Particles.e, EntitySquid.this.locX, EntitySquid.this.locY, EntitySquid.this.locZ, 0.0D, 0.0D, 0.0D); + EntitySquid.this.world.addParticle(Particles.BUBBLE, EntitySquid.this.locX, EntitySquid.this.locY, EntitySquid.this.locZ, 0.0D, 0.0D, 0.0D); } - */ } } @@ -250,22 +252,24 @@ public class EntitySquid extends EntityWaterAnimal { this.b = entitysquid; } + @Override public boolean a() { return true; } + @Override public void e() { - int i = this.b.cj(); + int i = this.b.cw(); if (i > 100) { - this.b.c(0.0F, 0.0F, 0.0F); + this.b.a(0.0F, 0.0F, 0.0F); } else if (this.b.getRandom().nextInt(50) == 0 || !this.b.inWater || !this.b.l()) { float f = this.b.getRandom().nextFloat() * 6.2831855F; float f1 = MathHelper.cos(f) * 0.2F; float f2 = -0.1F + this.b.getRandom().nextFloat() * 0.2F; float f3 = MathHelper.sin(f) * 0.2F; - this.b.c(f1, f2, f3); + this.b.a(f1, f2, f3); } } diff --git a/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/src/main/java/net/minecraft/server/EntityTNTPrimed.java index 55efec83e..dc0d944ea 100644 --- a/src/main/java/net/minecraft/server/EntityTNTPrimed.java +++ b/src/main/java/net/minecraft/server/EntityTNTPrimed.java @@ -8,26 +8,22 @@ public class EntityTNTPrimed extends Entity { private static final DataWatcherObject FUSE_TICKS = DataWatcher.a(EntityTNTPrimed.class, DataWatcherRegistry.b); @Nullable private EntityLiving source; - private int c; + private int fuseTicks; public float yield = 4; // CraftBukkit - add field public boolean isIncendiary = false; // CraftBukkit - add field - public EntityTNTPrimed(World world) { - super(EntityTypes.TNT, world); - this.c = 80; - this.j = true; - this.fireProof = true; - this.setSize(0.98F, 0.98F); + public EntityTNTPrimed(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.fuseTicks = 80; + this.i = true; } public EntityTNTPrimed(World world, double d0, double d1, double d2, @Nullable EntityLiving entityliving) { - this(world); + this(EntityTypes.TNT, world); this.setPosition(d0, d1, d2); - float f = (float) (Math.random() * 6.2831854820251465D); + double d3 = world.random.nextDouble() * 6.2831854820251465D; - this.motX = (double) (-((float) Math.sin((double) f)) * 0.02F); - this.motY = 0.20000000298023224D; - this.motZ = (double) (-((float) Math.cos((double) f)) * 0.02F); + this.setMot(-Math.sin(d3) * 0.02D, 0.20000000298023224D, -Math.cos(d3) * 0.02D); this.setFuseTicks(80); this.lastX = d0; this.lastY = d1; @@ -35,46 +31,44 @@ public class EntityTNTPrimed extends Entity { this.source = entityliving; } - protected void x_() { + @Override + protected void initDatawatcher() { this.datawatcher.register(EntityTNTPrimed.FUSE_TICKS, 80); } + @Override protected boolean playStepSound() { return false; } + @Override public boolean isInteractable() { return !this.dead; } + @Override public void tick() { if (world.spigotConfig.currentPrimedTnt++ > world.spigotConfig.maxTntTicksPerTick) { return; } // Spigot this.lastX = this.locX; this.lastY = this.locY; this.lastZ = this.locZ; if (!this.isNoGravity()) { - this.motY -= 0.03999999910593033D; + this.setMot(this.getMot().add(0.0D, -0.04D, 0.0D)); } - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - + this.move(EnumMoveType.SELF, this.getMot()); // Paper start - Configurable TNT entity height nerf if (this.world.paperConfig.entityTNTHeightNerf != 0 && this.locY > this.world.paperConfig.entityTNTHeightNerf) { this.die(); } // Paper end - - this.motX *= 0.9800000190734863D; - this.motY *= 0.9800000190734863D; - this.motZ *= 0.9800000190734863D; + this.setMot(this.getMot().a(0.98D)); if (this.onGround) { - this.motX *= 0.699999988079071D; - this.motZ *= 0.699999988079071D; - this.motY *= -0.5D; + this.setMot(this.getMot().d(0.7D, -0.5D, 0.7D)); } - --this.c; - if (this.c <= 0) { + --this.fuseTicks; + if (this.fuseTicks <= 0) { // CraftBukkit start - Need to reverse the order of the explosion and the entity death so we have a location for the event // this.die(); if (!this.world.isClientSide) { @@ -83,10 +77,30 @@ public class EntityTNTPrimed extends Entity { this.die(); // CraftBukkit end } else { - this.at(); - //this.world.addParticle(Particles.M, this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D); // Akarin start - this handle by client + this.ay(); + this.world.addParticle(Particles.SMOKE, this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D); } + // Paper start - Optional prevent TNT from moving in water + if (!this.dead && this.inWater && this.world.paperConfig.preventTntFromMovingInWater) { + /* + * Author: Jedediah Smith + */ + // Send position and velocity updates to nearby players on every tick while the TNT is in water. + // This does pretty well at keeping their clients in sync with the server. + PlayerChunkMap.EntityTracker ete = this.tracker; + if (ete != null) { + PacketPlayOutEntityVelocity velocityPacket = new PacketPlayOutEntityVelocity(this); + PacketPlayOutEntityTeleport positionPacket = new PacketPlayOutEntityTeleport(this); + ete.trackedPlayers.stream() + .filter(viewer -> (viewer.locX - this.locX) * (viewer.locY - this.locY) * (viewer.locZ - this.locZ) < 16 * 16) + .forEach(viewer -> { + viewer.playerConnection.sendPacket(velocityPacket); + viewer.playerConnection.sendPacket(positionPacket); + }); + } + } + // Paper end } private void explode() { @@ -97,15 +111,17 @@ public class EntityTNTPrimed extends Entity { this.world.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { - this.world.createExplosion(this, this.locX, this.locY + (double) (this.length / 16.0F), this.locZ, event.getRadius(), event.getFire(), true); + this.world.createExplosion(this, this.locX, this.locY + (double) (this.getHeight() / 16.0F), this.locZ, event.getRadius(), event.getFire(), Explosion.Effect.BREAK); } // CraftBukkit end } + @Override protected void b(NBTTagCompound nbttagcompound) { nbttagcompound.setShort("Fuse", (short) this.getFuseTicks()); } + @Override protected void a(NBTTagCompound nbttagcompound) { this.setFuseTicks(nbttagcompound.getShort("Fuse")); // Paper start - Try and load origin location from the old NBT tags for backwards compatibility @@ -123,18 +139,20 @@ public class EntityTNTPrimed extends Entity { return this.source; } - public float getHeadHeight() { + @Override + protected float getHeadHeight(EntityPose entitypose, EntitySize entitysize) { return 0.0F; } public void setFuseTicks(int i) { this.datawatcher.set(EntityTNTPrimed.FUSE_TICKS, i); - this.c = i; + this.fuseTicks = i; } + @Override public void a(DataWatcherObject datawatcherobject) { if (EntityTNTPrimed.FUSE_TICKS.equals(datawatcherobject)) { - this.c = this.i(); + this.fuseTicks = this.i(); } } @@ -144,7 +162,12 @@ public class EntityTNTPrimed extends Entity { } public int getFuseTicks() { - return this.c; + return this.fuseTicks; + } + + @Override + public Packet N() { + return new PacketPlayOutSpawnEntity(this); } // Paper start - Optional prevent TNT from moving in water @@ -152,43 +175,5 @@ public class EntityTNTPrimed extends Entity { public boolean pushedByWater() { return !world.paperConfig.preventTntFromMovingInWater && super.pushedByWater(); } - - /** - * Author: Jedediah Smith - */ - @Override - public boolean doWaterMovement() { - if (!world.paperConfig.preventTntFromMovingInWater) return super.doWaterMovement(); - - // Preserve velocity while calling the super method - double oldMotX = this.motX; - double oldMotY = this.motY; - double oldMotZ = this.motZ; - - super.doWaterMovement(); - - this.motX = oldMotX; - this.motY = oldMotY; - this.motZ = oldMotZ; - - if (this.inWater) { - // Send position and velocity updates to nearby players on every tick while the TNT is in water. - // This does pretty well at keeping their clients in sync with the server. - EntityTrackerEntry ete = ((WorldServer) this.getWorld()).getTracker().trackedEntities.get(this.getId()); - if (ete != null) { - PacketPlayOutEntityVelocity velocityPacket = new PacketPlayOutEntityVelocity(this); - PacketPlayOutEntityTeleport positionPacket = new PacketPlayOutEntityTeleport(this); - - ete.trackedPlayers.stream() - .filter(viewer -> (viewer.locX - this.locX) * (viewer.locY - this.locY) * (viewer.locZ - this.locZ) < 16 * 16) - .forEach(viewer -> { - viewer.playerConnection.sendPacket(velocityPacket); - viewer.playerConnection.sendPacket(positionPacket); - }); - } - } - - return this.inWater; - } // Paper end } diff --git a/src/main/java/net/minecraft/server/EntityThrownExpBottle.java b/src/main/java/net/minecraft/server/EntityThrownExpBottle.java index e73dba09a..05970c564 100644 --- a/src/main/java/net/minecraft/server/EntityThrownExpBottle.java +++ b/src/main/java/net/minecraft/server/EntityThrownExpBottle.java @@ -1,9 +1,9 @@ package net.minecraft.server; -public class EntityThrownExpBottle extends EntityProjectile { +public class EntityThrownExpBottle extends EntityProjectileThrowable { - public EntityThrownExpBottle(World world) { - super(EntityTypes.EXPERIENCE_BOTTLE, world); + public EntityThrownExpBottle(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntityThrownExpBottle(World world, EntityLiving entityliving) { @@ -14,21 +14,28 @@ public class EntityThrownExpBottle extends EntityProjectile { super(EntityTypes.EXPERIENCE_BOTTLE, d0, d1, d2, world); } - protected float f() { + @Override + protected Item i() { + return Items.EXPERIENCE_BOTTLE; + } + + @Override + protected float l() { return 0.07F; } + @Override protected void a(MovingObjectPosition movingobjectposition) { if (!this.world.isClientSide) { // CraftBukkit - moved to after event - // this.world.triggerEffect(2002, new BlockPosition(this), PotionUtil.a(Potions.b)); + // this.world.triggerEffect(2002, new BlockPosition(this), PotionUtil.a(Potions.WATER)); int i = 3 + this.world.random.nextInt(5) + this.world.random.nextInt(5); // CraftBukkit start org.bukkit.event.entity.ExpBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExpBottleEvent(this, i); i = event.getExperience(); if (event.getShowEffect()) { - this.world.triggerEffect(2002, new BlockPosition(this), PotionUtil.a(Potions.b)); + this.world.triggerEffect(2002, new BlockPosition(this), PotionUtil.a(Potions.WATER)); } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/EntityThrownTrident.java b/src/main/java/net/minecraft/server/EntityThrownTrident.java index d9107f24b..392cadf31 100644 --- a/src/main/java/net/minecraft/server/EntityThrownTrident.java +++ b/src/main/java/net/minecraft/server/EntityThrownTrident.java @@ -4,13 +4,13 @@ import javax.annotation.Nullable; public class EntityThrownTrident extends EntityArrow { - private static final DataWatcherObject h = DataWatcher.a(EntityThrownTrident.class, DataWatcherRegistry.a); + private static final DataWatcherObject as = DataWatcher.a(EntityThrownTrident.class, DataWatcherRegistry.a); public ItemStack trident; - private boolean ax; - public int g; + private boolean au; + public int ar; - public EntityThrownTrident(World world) { - super(EntityTypes.TRIDENT, world); + public EntityThrownTrident(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.trident = new ItemStack(Items.TRIDENT); } @@ -18,73 +18,75 @@ public class EntityThrownTrident extends EntityArrow { super(EntityTypes.TRIDENT, entityliving, world); this.trident = new ItemStack(Items.TRIDENT); this.trident = itemstack.cloneItemStack(); - this.datawatcher.set(EntityThrownTrident.h, (byte) EnchantmentManager.f(itemstack)); + this.datawatcher.set(EntityThrownTrident.as, (byte) EnchantmentManager.f(itemstack)); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityThrownTrident.h, (byte) 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityThrownTrident.as, (byte) 0); } + @Override public void tick() { - if (this.c > 4) { - this.ax = true; + if (this.d > 4) { + this.au = true; } Entity entity = this.getShooter(); - if ((this.ax || this.q()) && entity != null) { - byte b0 = (Byte) this.datawatcher.get(EntityThrownTrident.h); + if ((this.au || this.v()) && entity != null) { + byte b0 = (Byte) this.datawatcher.get(EntityThrownTrident.as); - if (b0 > 0 && !this.r()) { + if (b0 > 0 && !this.w()) { if (!this.world.isClientSide && this.fromPlayer == EntityArrow.PickupStatus.ALLOWED) { this.a(this.getItemStack(), 0.1F); } this.die(); } else if (b0 > 0) { - this.o(true); + this.n(true); Vec3D vec3d = new Vec3D(entity.locX - this.locX, entity.locY + (double) entity.getHeadHeight() - this.locY, entity.locZ - this.locZ); this.locY += vec3d.y * 0.015D * (double) b0; if (this.world.isClientSide) { - this.O = this.locY; + this.I = this.locY; } - vec3d = vec3d.a(); double d0 = 0.05D * (double) b0; - this.motX += vec3d.x * d0 - this.motX * 0.05D; - this.motY += vec3d.y * d0 - this.motY * 0.05D; - this.motZ += vec3d.z * d0 - this.motZ * 0.05D; - if (this.g == 0) { + this.setMot(this.getMot().a(0.95D).e(vec3d.d().a(d0))); + if (this.ar == 0) { this.a(SoundEffects.ITEM_TRIDENT_RETURN, 10.0F, 1.0F); } - ++this.g; + ++this.ar; } } super.tick(); } - private boolean r() { + private boolean w() { Entity entity = this.getShooter(); - return entity != null && entity.isAlive() ? !(entity instanceof EntityPlayer) || !((EntityPlayer) entity).isSpectator() : false; + return entity != null && entity.isAlive() ? !(entity instanceof EntityPlayer) || !entity.isSpectator() : false; } + @Override protected ItemStack getItemStack() { return this.trident.cloneItemStack(); } @Nullable - protected Entity a(Vec3D vec3d, Vec3D vec3d1) { - return this.ax ? null : super.a(vec3d, vec3d1); + @Override + protected MovingObjectPositionEntity a(Vec3D vec3d, Vec3D vec3d1) { + return this.au ? null : super.a(vec3d, vec3d1); } - protected void b(MovingObjectPosition movingobjectposition) { - Entity entity = movingobjectposition.entity; + @Override + protected void a(MovingObjectPositionEntity movingobjectpositionentity) { + Entity entity = movingobjectpositionentity.getEntity(); float f = 8.0F; if (entity instanceof EntityLiving) { @@ -96,7 +98,7 @@ public class EntityThrownTrident extends EntityArrow { Entity entity1 = this.getShooter(); DamageSource damagesource = DamageSource.a(this, (Entity) (entity1 == null ? this : entity1)); - this.ax = true; + this.au = true; SoundEffect soundeffect = SoundEffects.ITEM_TRIDENT_HIT; if (entity.damageEntity(damagesource, f) && entity instanceof EntityLiving) { @@ -110,15 +112,13 @@ public class EntityThrownTrident extends EntityArrow { this.a(entityliving1); } - this.motX *= -0.009999999776482582D; - this.motY *= -0.10000000149011612D; - this.motZ *= -0.009999999776482582D; + this.setMot(this.getMot().d(-0.01D, -0.1D, -0.01D)); float f1 = 1.0F; - if (this.world.Y() && EnchantmentManager.h(this.trident)) { + if (this.world instanceof WorldServer && this.world.U() && EnchantmentManager.h(this.trident)) { BlockPosition blockposition = entity.getChunkCoordinates(); - if (this.world.e(blockposition)) { + if (this.world.f(blockposition)) { EntityLightning entitylightning = new EntityLightning(this.world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, false); entitylightning.d(entity1 instanceof EntityPlayer ? (EntityPlayer) entity1 : null); @@ -131,44 +131,50 @@ public class EntityThrownTrident extends EntityArrow { this.a(soundeffect, f1, 1.0F); } - protected SoundEffect i() { + @Override + protected SoundEffect k() { return SoundEffects.ITEM_TRIDENT_HIT_GROUND; } - public void d(EntityHuman entityhuman) { + @Override + public void pickup(EntityHuman entityhuman) { Entity entity = this.getShooter(); if (entity == null || entity.getUniqueID() == entityhuman.getUniqueID()) { - super.d(entityhuman); + super.pickup(entityhuman); } } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKeyOfType("Trident", 10)) { this.trident = ItemStack.a(nbttagcompound.getCompound("Trident")); } - this.ax = nbttagcompound.getBoolean("DealtDamage"); - this.datawatcher.set(EntityThrownTrident.h, (byte) EnchantmentManager.f(this.trident)); + this.au = nbttagcompound.getBoolean("DealtDamage"); + this.datawatcher.set(EntityThrownTrident.as, (byte) EnchantmentManager.f(this.trident)); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.set("Trident", this.trident.save(new NBTTagCompound())); - nbttagcompound.setBoolean("DealtDamage", this.ax); + nbttagcompound.setBoolean("DealtDamage", this.au); } - protected void f() { - byte b0 = (Byte) this.datawatcher.get(EntityThrownTrident.h); + @Override + protected void i() { + byte b0 = (Byte) this.datawatcher.get(EntityThrownTrident.as); if (this.fromPlayer != EntityArrow.PickupStatus.ALLOWED || b0 <= 0) { - super.f(); + super.i(); } } - protected float p() { + @Override + protected float u() { return 0.99F; } } diff --git a/src/main/java/net/minecraft/server/EntityTippedArrow.java b/src/main/java/net/minecraft/server/EntityTippedArrow.java index 12d1fa121..ddf420ea2 100644 --- a/src/main/java/net/minecraft/server/EntityTippedArrow.java +++ b/src/main/java/net/minecraft/server/EntityTippedArrow.java @@ -7,13 +7,13 @@ import java.util.Set; public class EntityTippedArrow extends EntityArrow { - private static final DataWatcherObject g = DataWatcher.a(EntityTippedArrow.class, DataWatcherRegistry.b); + private static final DataWatcherObject COLOR = DataWatcher.a(EntityTippedArrow.class, DataWatcherRegistry.b); private PotionRegistry potionRegistry; public final Set effects; private boolean hasColor; - public EntityTippedArrow(World world) { - super(EntityTypes.ARROW, world); + public EntityTippedArrow(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.potionRegistry = Potions.EMPTY; this.effects = Sets.newHashSet(); } @@ -48,14 +48,14 @@ public class EntityTippedArrow extends EntityArrow { int i = c(itemstack); if (i == -1) { - this.s(); + this.z(); } else { this.setColor(i); } } else if (itemstack.getItem() == Items.ARROW) { this.potionRegistry = Potions.EMPTY; this.effects.clear(); - this.datawatcher.set(EntityTippedArrow.g, -1); + this.datawatcher.set(EntityTippedArrow.COLOR, -1); } } @@ -66,36 +66,38 @@ public class EntityTippedArrow extends EntityArrow { return nbttagcompound != null && nbttagcompound.hasKeyOfType("CustomPotionColor", 99) ? nbttagcompound.getInt("CustomPotionColor") : -1; } - private void s() { + private void z() { this.hasColor = false; - this.datawatcher.set(EntityTippedArrow.g, PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects))); + this.datawatcher.set(EntityTippedArrow.COLOR, PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects))); } - public void a(MobEffect mobeffect) { + public void addEffect(MobEffect mobeffect) { this.effects.add(mobeffect); - this.getDataWatcher().set(EntityTippedArrow.g, PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects))); + this.getDataWatcher().set(EntityTippedArrow.COLOR, PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects))); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityTippedArrow.g, -1); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityTippedArrow.COLOR, -1); } + @Override public void tick() { super.tick(); if (this.world.isClientSide) { if (this.inGround) { - if (this.c % 5 == 0) { + if (this.d % 5 == 0) { this.b(1); } } else { this.b(2); } - } else if (this.inGround && this.c != 0 && !this.effects.isEmpty() && this.c >= 600) { + } else if (this.inGround && this.d != 0 && !this.effects.isEmpty() && this.d >= 600) { this.world.broadcastEntityEffect(this, (byte) 0); this.potionRegistry = Potions.EMPTY; this.effects.clear(); - this.datawatcher.set(EntityTippedArrow.g, -1); + this.datawatcher.set(EntityTippedArrow.COLOR, -1); } } @@ -109,7 +111,7 @@ public class EntityTippedArrow extends EntityArrow { double d2 = (double) (j >> 0 & 255) / 255.0D; for (int k = 0; k < i; ++k) { - this.world.addParticle(Particles.s, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, d0, d1, d2); + this.world.addParticle(Particles.ENTITY_EFFECT, this.locX + (this.random.nextDouble() - 0.5D) * (double) this.getWidth(), this.locY + this.random.nextDouble() * (double) this.getHeight(), this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.getWidth(), d0, d1, d2); } } @@ -117,7 +119,7 @@ public class EntityTippedArrow extends EntityArrow { // CraftBukkit start accessor methods public void refreshEffects() { - this.getDataWatcher().set(EntityTippedArrow.g, Integer.valueOf(PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects)))); + this.getDataWatcher().set(EntityTippedArrow.COLOR, PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects))); } public String getType() { @@ -126,7 +128,7 @@ public class EntityTippedArrow extends EntityArrow { public void setType(String string) { this.potionRegistry = IRegistry.POTION.get(new MinecraftKey(string)); - this.datawatcher.set(EntityTippedArrow.g, Integer.valueOf(PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects)))); + this.getDataWatcher().set(EntityTippedArrow.COLOR, PotionUtil.a((Collection) PotionUtil.a(this.potionRegistry, (Collection) this.effects))); } public boolean isTipped() { @@ -135,14 +137,15 @@ public class EntityTippedArrow extends EntityArrow { // CraftBukkit end public int getColor() { - return (Integer) this.datawatcher.get(EntityTippedArrow.g); + return (Integer) this.datawatcher.get(EntityTippedArrow.COLOR); } public void setColor(int i) { this.hasColor = true; - this.datawatcher.set(EntityTippedArrow.g, i); + this.datawatcher.set(EntityTippedArrow.COLOR, i); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); if (this.potionRegistry != Potions.EMPTY && this.potionRegistry != null) { @@ -160,7 +163,7 @@ public class EntityTippedArrow extends EntityArrow { while (iterator.hasNext()) { MobEffect mobeffect = (MobEffect) iterator.next(); - nbttaglist.add((NBTBase) mobeffect.a(new NBTTagCompound())); + nbttaglist.add(mobeffect.a(new NBTTagCompound())); } nbttagcompound.set("CustomPotionEffects", nbttaglist); @@ -168,6 +171,7 @@ public class EntityTippedArrow extends EntityArrow { } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKeyOfType("Potion", 8)) { @@ -179,17 +183,18 @@ public class EntityTippedArrow extends EntityArrow { while (iterator.hasNext()) { MobEffect mobeffect = (MobEffect) iterator.next(); - this.a(mobeffect); + this.addEffect(mobeffect); } if (nbttagcompound.hasKeyOfType("Color", 99)) { this.setColor(nbttagcompound.getInt("Color")); } else { - this.s(); + this.z(); } } + @Override protected void a(EntityLiving entityliving) { super.a(entityliving); Iterator iterator = this.potionRegistry.a().iterator(); @@ -212,6 +217,7 @@ public class EntityTippedArrow extends EntityArrow { } + @Override protected ItemStack getItemStack() { if (this.effects.isEmpty() && this.potionRegistry == Potions.EMPTY) { return new ItemStack(Items.ARROW); diff --git a/src/main/java/net/minecraft/server/EntityTracker.java b/src/main/java/net/minecraft/server/EntityTracker.java deleted file mode 100644 index 8b9e4831e..000000000 --- a/src/main/java/net/minecraft/server/EntityTracker.java +++ /dev/null @@ -1,302 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class EntityTracker { - - private static final Logger a = LogManager.getLogger(); - private final WorldServer world; - private final Set c = Sets.newHashSet(); - public final IntHashMap trackedEntities = new IntHashMap<>(); - private int trackingDistance; - - public EntityTracker(WorldServer worldserver) { - this.world = worldserver; - this.trackingDistance = PlayerChunkMap.getFurthestViewableBlock(worldserver.spigotConfig.viewDistance); // Spigot - } - - public static long a(double d0) { - return MathHelper.d(d0 * 4096.0D); - } - - public void track(Entity entity) { - if (entity instanceof EntityPlayer) { - this.addEntity(entity, 512, 2); - EntityPlayer entityplayer = (EntityPlayer) entity; - Iterator iterator = this.c.iterator(); - - while (iterator.hasNext()) { - EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); - - if (entitytrackerentry.b() != entityplayer) { - entitytrackerentry.updatePlayer(entityplayer); - } - } - } else if (entity instanceof EntityFishingHook) { - this.addEntity(entity, 64, 5, true); - } else if (entity instanceof EntityArrow) { - this.addEntity(entity, 64, 20, false); - } else if (entity instanceof EntitySmallFireball) { - this.addEntity(entity, 64, 10, false); - } else if (entity instanceof EntityFireball) { - this.addEntity(entity, 64, 10, true); - } else if (entity instanceof EntitySnowball) { - this.addEntity(entity, 64, 10, true); - } else if (entity instanceof EntityLlamaSpit) { - this.addEntity(entity, 64, 10, false); - } else if (entity instanceof EntityEnderPearl) { - this.addEntity(entity, 64, 10, true); - } else if (entity instanceof EntityEnderSignal) { - this.addEntity(entity, 64, 4, true); - } else if (entity instanceof EntityEgg) { - this.addEntity(entity, 64, 10, true); - } else if (entity instanceof EntityPotion) { - this.addEntity(entity, 64, 10, true); - } else if (entity instanceof EntityThrownExpBottle) { - this.addEntity(entity, 64, 10, true); - } else if (entity instanceof EntityFireworks) { - this.addEntity(entity, 64, 10, true); - } else if (entity instanceof EntityItem) { - this.addEntity(entity, 64, 20, true); - } else if (entity instanceof EntityMinecartAbstract) { - this.addEntity(entity, 80, 3, true); - } else if (entity instanceof EntityBoat) { - this.addEntity(entity, 80, 3, true); - } else if (entity instanceof EntitySquid) { - this.addEntity(entity, 64, 3, true); - } else if (entity instanceof EntityWither) { - this.addEntity(entity, 80, 3, false); - } else if (entity instanceof EntityShulkerBullet) { - this.addEntity(entity, 80, 3, true); - } else if (entity instanceof EntityBat) { - this.addEntity(entity, 80, 3, false); - } else if (entity instanceof EntityEnderDragon) { - this.addEntity(entity, 160, 3, true); - } else if (entity instanceof IAnimal) { - this.addEntity(entity, 80, 3, true); - } else if (entity instanceof EntityTNTPrimed) { - this.addEntity(entity, 160, 10, true); - } else if (entity instanceof EntityFallingBlock) { - this.addEntity(entity, 160, 20, true); - } else if (entity instanceof EntityHanging) { - this.addEntity(entity, 160, Integer.MAX_VALUE, false); - } else if (entity instanceof EntityArmorStand) { - this.addEntity(entity, 160, 3, true); - } else if (entity instanceof EntityExperienceOrb) { - this.addEntity(entity, 160, 20, true); - } else if (entity instanceof EntityAreaEffectCloud) { - this.addEntity(entity, 160, 10, true); // CraftBukkit - } else if (entity instanceof EntityEnderCrystal) { - this.addEntity(entity, 256, Integer.MAX_VALUE, false); - } else if (entity instanceof EntityEvokerFangs) { - this.addEntity(entity, 160, 2, false); - } - - } - - public void addEntity(Entity entity, int i, int j) { - this.addEntity(entity, i, j, false); - } - - public void addEntity(Entity entity, int originalRange, int j, boolean flag) { // Spigot - //org.spigotmc.AsyncCatcher.catchOp( "entity track"); // Spigot // Akarin - int i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, originalRange); // Spigot - try { - if (this.trackedEntities.b(entity.getId())) { - throw new IllegalStateException("Entity is already tracked!"); - } - - EntityTrackerEntry entitytrackerentry = new EntityTrackerEntry(entity, i, this.trackingDistance, j, flag); - - this.c.add(entitytrackerentry); - this.trackedEntities.a(entity.getId(), entitytrackerentry); - entitytrackerentry.scanPlayers(this.world.players); - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Adding entity to track"); - CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity To Track"); - - crashreportsystemdetails.a("Tracking range", (Object) (i + " blocks")); - crashreportsystemdetails.a("Update interval", () -> { - String s = "Once per " + j + " ticks"; - - if (j == Integer.MAX_VALUE) { - s = "Maximum (" + s + ")"; - } - - return s; - }); - entity.appendEntityCrashDetails(crashreportsystemdetails); - ((EntityTrackerEntry) this.trackedEntities.get(entity.getId())).b().appendEntityCrashDetails(crashreport.a("Entity That Is Already Tracked")); - - try { - throw new ReportedException(crashreport); - } catch (ReportedException reportedexception) { - EntityTracker.a.error("\"Silently\" catching entity tracking error.", reportedexception); - } - } - - } - - public void untrackEntity(Entity entity) { - //org.spigotmc.AsyncCatcher.catchOp( "entity untrack"); // Spigot // Akarin - if (entity instanceof EntityPlayer) { - EntityPlayer entityplayer = (EntityPlayer) entity; - Iterator iterator = this.c.iterator(); - - while (iterator.hasNext()) { - EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); - - entitytrackerentry.a(entityplayer); - } - } - - EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry) this.trackedEntities.d(entity.getId()); - - if (entitytrackerentry1 != null) { - this.c.remove(entitytrackerentry1); - entitytrackerentry1.a(); - } - - } - - public void updatePlayers() { - List list = Lists.newArrayList(); - Iterator iterator = this.c.iterator(); - world.timings.tracker1.startTimingUnsafe(); // Paper - while (iterator.hasNext()) { - EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); - - entitytrackerentry.track(this.world.players); - if (entitytrackerentry.b) { - Entity entity = entitytrackerentry.b(); - - if (entity instanceof EntityPlayer) { - list.add((EntityPlayer) entity); - } - } - } - world.timings.tracker1.stopTimingUnsafe(); // Paper - - world.timings.tracker2.startTimingUnsafe(); // Paper - for (int i = 0; i < list.size(); ++i) { - EntityPlayer entityplayer = (EntityPlayer) list.get(i); - Iterator iterator1 = this.c.iterator(); - - while (iterator1.hasNext()) { - EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry) iterator1.next(); - - if (entitytrackerentry1.b() != entityplayer) { - entitytrackerentry1.updatePlayer(entityplayer); - } - } - } - world.timings.tracker2.stopTimingUnsafe(); // Paper - - } - - public void updatePlayer(EntityPlayer entityplayer) { a(entityplayer); } // Paper - OBFHELPER - public void a(EntityPlayer entityplayer) { - Iterator iterator = this.c.iterator(); - - while (iterator.hasNext()) { - EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); - - if (entitytrackerentry.b() == entityplayer) { - entitytrackerentry.scanPlayers(this.world.players); - } else { - entitytrackerentry.updatePlayer(entityplayer); - } - } - - } - - public void a(Entity entity, Packet packet) { - EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) this.trackedEntities.get(entity.getId()); - - if (entitytrackerentry != null) { - entitytrackerentry.broadcast(packet); - } - - } - - public void sendPacketToEntity(Entity entity, Packet packet) { - EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) this.trackedEntities.get(entity.getId()); - - if (entitytrackerentry != null) { - entitytrackerentry.broadcastIncludingSelf(packet); - } - - } - - public void untrackPlayer(EntityPlayer entityplayer) { - Iterator iterator = this.c.iterator(); - - while (iterator.hasNext()) { - EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); - - entitytrackerentry.clear(entityplayer); - } - - } - - public void a(EntityPlayer entityplayer, Chunk chunk) { - List list = Lists.newArrayList(); - List list1 = Lists.newArrayList(); - Iterator iterator = this.c.iterator(); - - while (iterator.hasNext()) { - EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); - Entity entity = entitytrackerentry.b(); - - if (entity != entityplayer && entity.chunkX == chunk.locX && entity.chunkZ == chunk.locZ) { - entitytrackerentry.updatePlayer(entityplayer); - if (entity instanceof EntityInsentient && ((EntityInsentient) entity).getLeashHolder() != null) { - list.add(entity); - } - - if (!entity.bP().isEmpty()) { - list1.add(entity); - } - } - } - - Entity entity1; - - if (!list.isEmpty()) { - iterator = list.iterator(); - - while (iterator.hasNext()) { - entity1 = (Entity) iterator.next(); - entityplayer.playerConnection.sendPacket(new PacketPlayOutAttachEntity(entity1, ((EntityInsentient) entity1).getLeashHolder())); - } - } - - if (!list1.isEmpty()) { - iterator = list1.iterator(); - - while (iterator.hasNext()) { - entity1 = (Entity) iterator.next(); - entityplayer.playerConnection.sendPacket(new PacketPlayOutMount(entity1)); - } - } - - } - - public void a(int i) { - this.trackingDistance = (i - 1) * 16; - Iterator iterator = this.c.iterator(); - - while (iterator.hasNext()) { - EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); - - entitytrackerentry.a(this.trackingDistance); - } - - } -} diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java index 7fd51f7dc..460c687d3 100644 --- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java @@ -1,11 +1,12 @@ package net.minecraft.server; -import com.google.common.collect.Sets; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.function.Consumer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -16,36 +17,28 @@ import org.bukkit.event.player.PlayerVelocityEvent; public class EntityTrackerEntry { - private static final Logger c = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); + private final WorldServer b; private final Entity tracker; - private final int e; - private int f; - private final int g; + private final int d; + private final boolean e; + private final Consumer> f; private Consumer> getPacketConsumer() { return f; } // Paper - OBFHELPER private long xLoc; private long yLoc; private long zLoc; private int yRot; private int xRot; private int headYaw; - private double n; - private double o; - private double p; - public int a; - private double q; - private double r; - private double s; - private boolean isMoving; - private final boolean u; - private int v; - private List w = Collections.emptyList(); - private boolean x; - private boolean y; - public boolean b; + private Vec3D m; + private int n; + private int o; + private List p; + private boolean q; + private boolean r; + // CraftBukkit start + final Set trackedPlayers; // Paper - private -> package // Paper start - // Replace trackedPlayers Set with a Map. The value is true until the player receives - // their first update (which is forced to have absolute coordinates), false afterward. - public java.util.Map trackedPlayerMap = new java.util.HashMap(); - public Set trackedPlayers = trackedPlayerMap.keySet(); + private java.util.Map trackedPlayerMap = null; /** * Requested in https://github.com/PaperMC/Paper/issues/1537 to allow intercepting packets @@ -53,65 +46,52 @@ public class EntityTrackerEntry { public void sendPlayerPacket(EntityPlayer player, Packet packet) { player.playerConnection.sendPacket(packet); } - // Paper end - public EntityTrackerEntry(Entity entity, int i, int j, int k, boolean flag) { - entity.tracker = this; // Paper + public EntityTrackerEntry(WorldServer worldserver, Entity entity, int i, boolean flag, Consumer> consumer, java.util.Map trackedPlayers) { + this(worldserver, entity, i, flag, consumer, trackedPlayers.keySet()); + trackedPlayerMap = trackedPlayers; + } + + public EntityTrackerEntry(WorldServer worldserver, Entity entity, int i, boolean flag, Consumer> consumer, Set trackedPlayers) { + // Paper end + this.trackedPlayers = trackedPlayers; + // CraftBukkit end + this.m = Vec3D.a; + this.p = Collections.emptyList(); + this.b = worldserver; + this.f = consumer; this.tracker = entity; - this.e = i; - this.f = j; - this.g = k; - this.u = flag; - this.xLoc = EntityTracker.a(entity.locX); - this.yLoc = EntityTracker.a(entity.locY); - this.zLoc = EntityTracker.a(entity.locZ); + this.d = i; + this.e = flag; + this.d(); this.yRot = MathHelper.d(entity.yaw * 256.0F / 360.0F); this.xRot = MathHelper.d(entity.pitch * 256.0F / 360.0F); this.headYaw = MathHelper.d(entity.getHeadRotation() * 256.0F / 360.0F); - this.y = entity.onGround; + this.r = entity.onGround; } - public boolean equals(Object object) { - return object instanceof EntityTrackerEntry ? ((EntityTrackerEntry) object).tracker.getId() == this.tracker.getId() : false; - } + public void a() { + List list = this.tracker.getPassengers(); - public int hashCode() { - return this.tracker.getId(); - } - - public void track(List list) { - this.b = false; - if (!this.isMoving || this.tracker.d(this.q, this.r, this.s) > 16.0D) { - this.q = this.tracker.locX; - this.r = this.tracker.locY; - this.s = this.tracker.locZ; - this.isMoving = true; - this.b = true; - this.scanPlayers(list); - } - - List list1 = this.tracker.bP(); - - if (!list1.equals(this.w)) { - this.w = list1; + if (!list.equals(this.p)) { + this.p = list; this.broadcastIncludingSelf(new PacketPlayOutMount(this.tracker)); // CraftBukkit } // PAIL : rename - if (this.tracker instanceof EntityItemFrame /*&& this.a % 10 == 0*/) { // CraftBukkit - Moved below, should always enter this block + if (this.tracker instanceof EntityItemFrame /*&& this.n % 10 == 0*/) { // CraftBukkit - Moved below, should always enter this block EntityItemFrame entityitemframe = (EntityItemFrame) this.tracker; ItemStack itemstack = entityitemframe.getItem(); - if (this.a % 10 == 0 && itemstack.getItem() instanceof ItemWorldMap) { // CraftBukkit - Moved this.a % 10 logic here so item frames do not enter the other blocks - WorldMap worldmap = ItemWorldMap.getSavedMap(itemstack, this.tracker.world); + if (this.n % 10 == 0 && itemstack.getItem() instanceof ItemWorldMap) { // CraftBukkit - Moved this.n % 10 logic here so item frames do not enter the other blocks + WorldMap worldmap = ItemWorldMap.getSavedMap(itemstack, this.b); Iterator iterator = this.trackedPlayers.iterator(); // CraftBukkit while (iterator.hasNext()) { - EntityHuman entityhuman = (EntityHuman) iterator.next(); - EntityPlayer entityplayer = (EntityPlayer) entityhuman; + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); worldmap.a((EntityHuman) entityplayer, itemstack); - Packet packet = ((ItemWorldMap) itemstack.getItem()).a(itemstack, this.tracker.world, (EntityHuman) entityplayer); + Packet packet = ((ItemWorldMap) itemstack.getItem()).a(itemstack, (World) this.b, (EntityHuman) entityplayer); if (packet != null) { entityplayer.playerConnection.sendPacket(packet); @@ -119,105 +99,85 @@ public class EntityTrackerEntry { } } - this.d(); + this.c(); } - if (this.a % this.g == 0 || this.tracker.impulse || this.tracker.getDataWatcher().a()) { + if (this.n % this.d == 0 || this.tracker.impulse || this.tracker.getDataWatcher().a()) { int i; + int j; if (this.tracker.isPassenger()) { i = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F); - int j = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F); + j = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F); boolean flag = Math.abs(i - this.yRot) >= 1 || Math.abs(j - this.xRot) >= 1; if (flag) { - this.broadcast(new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) i, (byte) j, this.tracker.onGround)); + this.f.accept(new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) i, (byte) j, this.tracker.onGround)); this.yRot = i; this.xRot = j; } - this.xLoc = EntityTracker.a(this.tracker.locX); - this.yLoc = EntityTracker.a(this.tracker.locY); - this.zLoc = EntityTracker.a(this.tracker.locZ); this.d(); - this.x = true; + this.c(); + this.q = true; } else { - ++this.v; - long k = EntityTracker.a(this.tracker.locX); - long l = EntityTracker.a(this.tracker.locY); - long i1 = EntityTracker.a(this.tracker.locZ); - int j1 = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F); - int k1 = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F); - long l1 = k - this.xLoc; - long i2 = l - this.yLoc; - long j2 = i1 - this.zLoc; + ++this.o; + i = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F); + j = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F); + Vec3D vec3d = (new Vec3D(this.tracker.locX, this.tracker.locY, this.tracker.locZ)).d(PacketPlayOutEntity.a(this.xLoc, this.yLoc, this.zLoc)); + boolean flag1 = vec3d.g() >= 7.62939453125E-6D; Packet packet1 = null; - boolean flag1 = l1 * l1 + i2 * i2 + j2 * j2 >= 128L || this.a % 60 == 0; - boolean flag2 = Math.abs(j1 - this.yRot) >= 1 || Math.abs(k1 - this.xRot) >= 1; + boolean flag2 = flag1 || this.n % 60 == 0; + boolean flag3 = Math.abs(i - this.yRot) >= 1 || Math.abs(j - this.xRot) >= 1; - if (this.a > 0 || this.tracker instanceof EntityArrow) { // Paper - Moved up // CraftBukkit start - Code moved from below - if (flag1) { - this.xLoc = k; - this.yLoc = l; - this.zLoc = i1; + if (flag2) { + this.d(); } - if (flag2) { - this.yRot = j1; - this.xRot = k1; + if (flag3) { + this.yRot = i; + this.xRot = j; } // CraftBukkit end - if (l1 >= -32768L && l1 < 32768L && i2 >= -32768L && i2 < 32768L && j2 >= -32768L && j2 < 32768L && this.v <= 400 && !this.x && this.y == this.tracker.onGround) { - if ((!flag1 || !flag2) && !(this.tracker instanceof EntityArrow)) { - if (flag1) { - packet1 = new PacketPlayOutEntity.PacketPlayOutRelEntityMove(this.tracker.getId(), l1, i2, j2, this.tracker.onGround); - } else if (flag2) { - packet1 = new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) j1, (byte) k1, this.tracker.onGround); + if (this.n > 0 || this.tracker instanceof EntityArrow) { + long k = PacketPlayOutEntity.a(vec3d.x); + long l = PacketPlayOutEntity.a(vec3d.y); + long i1 = PacketPlayOutEntity.a(vec3d.z); + boolean flag4 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L; + + if (!flag4 && this.o <= 400 && !this.q && this.r == this.tracker.onGround) { + if ((!flag2 || !flag3) && !(this.tracker instanceof EntityArrow)) { + if (flag2) { + packet1 = new PacketPlayOutEntity.PacketPlayOutRelEntityMove(this.tracker.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), this.tracker.onGround); + } else if (flag3) { + packet1 = new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) i, (byte) j, this.tracker.onGround); } } else { - packet1 = new PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook(this.tracker.getId(), l1, i2, j2, (byte) j1, (byte) k1, this.tracker.onGround); + packet1 = new PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook(this.tracker.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), (byte) i, (byte) j, this.tracker.onGround); } } else { - this.y = this.tracker.onGround; - this.v = 0; - // CraftBukkit start - Refresh list of who can see a player before sending teleport packet - if (this.tracker instanceof EntityPlayer) { - this.scanPlayers(new java.util.ArrayList(this.trackedPlayers)); - } - // CraftBukkit end - this.c(); + this.r = this.tracker.onGround; + this.o = 0; packet1 = new PacketPlayOutEntityTeleport(this.tracker); } } - boolean flag3 = this.u || this.tracker.impulse; + if ((this.e || this.tracker.impulse || this.tracker instanceof EntityLiving && ((EntityLiving) this.tracker).isGliding()) && this.n > 0) { + Vec3D vec3d1 = this.tracker.getMot(); + double d0 = vec3d1.distanceSquared(this.m); - if (this.tracker instanceof EntityLiving && ((EntityLiving) this.tracker).dc()) { - flag3 = true; - } - - if (flag3 && this.a > 0) { - double d0 = this.tracker.motX - this.n; - double d1 = this.tracker.motY - this.o; - double d2 = this.tracker.motZ - this.p; - double d3 = 0.02D; - double d4 = d0 * d0 + d1 * d1 + d2 * d2; - - if (d4 > 4.0E-4D || d4 > 0.0D && this.tracker.motX == 0.0D && this.tracker.motY == 0.0D && this.tracker.motZ == 0.0D) { - this.n = this.tracker.motX; - this.o = this.tracker.motY; - this.p = this.tracker.motZ; - this.broadcast(new PacketPlayOutEntityVelocity(this.tracker.getId(), this.n, this.o, this.p)); + if (d0 > 1.0E-7D || d0 > 0.0D && vec3d1.g() == 0.0D) { + this.m = vec3d1; + this.f.accept(new PacketPlayOutEntityVelocity(this.tracker.getId(), this.m)); } } if (packet1 != null) { - // Paper start - ensure fresh viewers get an absolute position on their first update, - // since we can't be certain what position they received in the spawn packet. - if (packet1 instanceof PacketPlayOutEntityTeleport) { - this.broadcast((Packet) packet1); + // paper start + if (trackedPlayerMap == null || packet1 instanceof PacketPlayOutEntityTeleport) { + this.f.accept((packet1)); } else { PacketPlayOutEntityTeleport teleportPacket = null; @@ -229,40 +189,38 @@ public class EntityTrackerEntry { } sendPlayerPacket(viewer.getKey(), teleportPacket); } else { - sendPlayerPacket(viewer.getKey(), (Packet) packet1); + sendPlayerPacket(viewer.getKey(), packet1); } } } // Paper end } - this.d(); + this.c(); /* CraftBukkit start - Code moved up - if (flag1) { - this.xLoc = k; - this.yLoc = l; - this.zLoc = i1; + if (flag2) { + this.d(); } - if (flag2) { - this.yRot = j1; - this.xRot = k1; + if (flag3) { + this.yRot = i; + this.xRot = j; } // CraftBukkit end */ - this.x = false; + this.q = false; } i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F); if (Math.abs(i - this.headYaw) >= 1) { - this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i)); + this.f.accept(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i)); this.headYaw = i; } this.tracker.impulse = false; } - ++this.a; + ++this.n; if (this.tracker.velocityChanged) { // CraftBukkit start - Create PlayerVelocity event boolean cancelled = false; @@ -290,7 +248,103 @@ public class EntityTrackerEntry { } - private void d() { + public void a(EntityPlayer entityplayer) { + this.tracker.c(entityplayer); + entityplayer.c(this.tracker); + } + + public void b(EntityPlayer entityplayer) { + PlayerConnection playerconnection = entityplayer.playerConnection; + + entityplayer.playerConnection.getClass(); + this.a(playerconnection::sendPacket, entityplayer); // CraftBukkit - add player + this.tracker.b(entityplayer); + entityplayer.d(this.tracker); + } + + public void a(Consumer> consumer, EntityPlayer entityplayer) { // CraftBukkit - add player + if (this.tracker.dead) { + // CraftBukkit start - Remove useless error spam, just return + // EntityTrackerEntry.LOGGER.warn("Fetching packet for removed entity " + this.tracker); + return; + // CraftBukkit end + } + + Packet packet = this.tracker.N(); + + this.headYaw = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F); + consumer.accept(packet); + if (!this.tracker.getDataWatcher().d()) { + consumer.accept(new PacketPlayOutEntityMetadata(this.tracker.getId(), this.tracker.getDataWatcher(), true)); + } + + boolean flag = this.e; + + if (this.tracker instanceof EntityLiving) { + AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap(); + Collection collection = attributemapserver.c(); + + // CraftBukkit start - If sending own attributes send scaled health instead of current maximum health + if (this.tracker.getId() == entityplayer.getId()) { + ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(collection, false); + } + // CraftBukkit end + + if (!collection.isEmpty()) { + consumer.accept(new PacketPlayOutUpdateAttributes(this.tracker.getId(), collection)); + } + + if (((EntityLiving) this.tracker).isGliding()) { + flag = true; + } + } + + this.m = this.tracker.getMot(); + if (flag && !(packet instanceof PacketPlayOutSpawnEntityLiving)) { + consumer.accept(new PacketPlayOutEntityVelocity(this.tracker.getId(), this.m)); + } + + if (this.tracker instanceof EntityLiving) { + EnumItemSlot[] aenumitemslot = EnumItemSlot.values(); + int i = aenumitemslot.length; + + for (int j = 0; j < i; ++j) { + EnumItemSlot enumitemslot = aenumitemslot[j]; + ItemStack itemstack = ((EntityLiving) this.tracker).getEquipment(enumitemslot); + + if (!itemstack.isEmpty()) { + consumer.accept(new PacketPlayOutEntityEquipment(this.tracker.getId(), enumitemslot, itemstack)); + } + } + } + + // CraftBukkit start - Fix for nonsensical head yaw + this.headYaw = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F); + consumer.accept(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) headYaw)); + // CraftBukkit end + + if (this.tracker instanceof EntityLiving) { + EntityLiving entityliving = (EntityLiving) this.tracker; + Iterator iterator = entityliving.getEffects().iterator(); + + while (iterator.hasNext()) { + MobEffect mobeffect = (MobEffect) iterator.next(); + + consumer.accept(new PacketPlayOutEntityEffect(this.tracker.getId(), mobeffect)); + } + } + + if (!this.tracker.getPassengers().isEmpty()) { + consumer.accept(new PacketPlayOutMount(this.tracker)); + } + + if (this.tracker.isPassenger()) { + consumer.accept(new PacketPlayOutMount(this.tracker.getVehicle())); + } + + } + + private void c() { DataWatcher datawatcher = this.tracker.getDataWatcher(); if (datawatcher.a()) { @@ -315,352 +369,27 @@ public class EntityTrackerEntry { } - public void broadcast(Packet packet) { - Iterator iterator = this.trackedPlayers.iterator(); - - while (iterator.hasNext()) { - EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - - entityplayer.playerConnection.sendPacket(packet); - } - + private void d() { + this.xLoc = PacketPlayOutEntity.a(this.tracker.locX); + this.yLoc = PacketPlayOutEntity.a(this.tracker.locY); + this.zLoc = PacketPlayOutEntity.a(this.tracker.locZ); } - public void broadcastIncludingSelf(Packet packet) { - this.broadcast(packet); + public Vec3D b() { + return PacketPlayOutEntity.a(this.xLoc, this.yLoc, this.zLoc); + } + + // Paper start - Add broadcast method + void broadcast(Packet packet) { + this.getPacketConsumer().accept(packet); + } + // Paper end + + private void broadcastIncludingSelf(Packet packet) { + this.f.accept(packet); if (this.tracker instanceof EntityPlayer) { ((EntityPlayer) this.tracker).playerConnection.sendPacket(packet); } } - - public void a() { - Iterator iterator = this.trackedPlayers.iterator(); - - while (iterator.hasNext()) { - EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - - this.tracker.c(entityplayer); - entityplayer.c(this.tracker); - } - - } - - public void a(EntityPlayer entityplayer) { - if (this.trackedPlayers.contains(entityplayer)) { - this.tracker.c(entityplayer); - entityplayer.c(this.tracker); - this.trackedPlayers.remove(entityplayer); - } - - } - - public void updatePlayer(EntityPlayer entityplayer) { - //org.spigotmc.AsyncCatcher.catchOp( "player tracker update"); // Spigot // Akarin - if (entityplayer != this.tracker) { - if (this.c(entityplayer)) { - if (!this.trackedPlayers.contains(entityplayer) && (this.e(entityplayer) || this.tracker.attachedToPlayer)) { - // CraftBukkit start - respect vanish API - if (this.tracker instanceof EntityPlayer) { - Player player = ((EntityPlayer) this.tracker).getBukkitEntity(); - if (!entityplayer.getBukkitEntity().canSee(player)) { - return; - } - } - - entityplayer.removeQueue.remove(Integer.valueOf(this.tracker.getId())); - // CraftBukkit end - this.trackedPlayerMap.put(entityplayer, true); // Paper - Packet packet = this.e(); - - entityplayer.playerConnection.sendPacket(packet); - if (!this.tracker.getDataWatcher().d()) { - entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityMetadata(this.tracker.getId(), this.tracker.getDataWatcher(), true)); - } - - boolean flag = this.u; - - if (this.tracker instanceof EntityLiving) { - AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap(); - Collection collection = attributemapserver.c(); - - // CraftBukkit start - If sending own attributes send scaled health instead of current maximum health - if (this.tracker.getId() == entityplayer.getId()) { - ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(collection, false); - } - // CraftBukkit end - - if (!collection.isEmpty()) { - entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(this.tracker.getId(), collection)); - } - - if (((EntityLiving) this.tracker).dc()) { - flag = true; - } - } - - this.n = this.tracker.motX; - this.o = this.tracker.motY; - this.p = this.tracker.motZ; - if (flag && !(packet instanceof PacketPlayOutSpawnEntityLiving)) { - entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityVelocity(this.tracker.getId(), this.tracker.motX, this.tracker.motY, this.tracker.motZ)); - } - - if (this.tracker instanceof EntityLiving) { - EnumItemSlot[] aenumitemslot = EnumItemSlot.values(); - int i = aenumitemslot.length; - - for (int j = 0; j < i; ++j) { - EnumItemSlot enumitemslot = aenumitemslot[j]; - ItemStack itemstack = ((EntityLiving) this.tracker).getEquipment(enumitemslot); - - if (!itemstack.isEmpty()) { - entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEquipment(this.tracker.getId(), enumitemslot, itemstack)); - } - } - } - - if (this.tracker instanceof EntityHuman) { - EntityHuman entityhuman = (EntityHuman) this.tracker; - - if (entityhuman.isSleeping()) { - entityplayer.playerConnection.sendPacket(new PacketPlayOutBed(entityhuman, new BlockPosition(this.tracker))); - } - } - - // CraftBukkit start - Fix for nonsensical head yaw - this.headYaw = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F); - this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) headYaw)); - // CraftBukkit end - - if (this.tracker instanceof EntityLiving) { - EntityLiving entityliving = (EntityLiving) this.tracker; - Iterator iterator = entityliving.getEffects().iterator(); - - while (iterator.hasNext()) { - MobEffect mobeffect = (MobEffect) iterator.next(); - - entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.tracker.getId(), mobeffect)); - } - } - - if (!this.tracker.bP().isEmpty()) { - entityplayer.playerConnection.sendPacket(new PacketPlayOutMount(this.tracker)); - } - - if (this.tracker.isPassenger()) { - entityplayer.playerConnection.sendPacket(new PacketPlayOutMount(this.tracker.getVehicle())); - } - - this.tracker.b(entityplayer); - entityplayer.d(this.tracker); - updatePassengers(entityplayer); // Paper - } - } else if (this.trackedPlayers.contains(entityplayer)) { - this.trackedPlayers.remove(entityplayer); - this.tracker.c(entityplayer); - entityplayer.c(this.tracker); - updatePassengers(entityplayer); // Paper - } - - } - } - - public boolean c(EntityPlayer entityplayer) { - // Paper start - if (tracker.isPassenger()) { - return isTrackedBy(tracker.getVehicle(), entityplayer); - } else if (hasPassengerInRange(tracker, entityplayer)) { - return true; - } - - return isInRangeOfPlayer(entityplayer); - } - private static boolean hasPassengerInRange(Entity entity, EntityPlayer entityplayer) { - if (!entity.isVehicle()) { - return false; - } - for (Entity passenger : entity.passengers) { - if (passenger.tracker != null && passenger.tracker.isInRangeOfPlayer(entityplayer)) { - return true; - } - if (passenger.isVehicle()) { - if (hasPassengerInRange(passenger, entityplayer)) { - return true; - } - } - } - return false; - } - private static boolean isTrackedBy(Entity entity, EntityPlayer entityplayer) { - return entity == entityplayer || entity.tracker != null && entity.tracker.trackedPlayers.contains(entityplayer); - } - private void updatePassengers(EntityPlayer player) { - if (tracker.isVehicle()) { - tracker.passengers.forEach((e) -> { - if (e.tracker != null) { - e.tracker.updatePlayer(player); - } - }); - player.playerConnection.sendPacket(new PacketPlayOutMount(this.tracker)); - } - } - private boolean isInRangeOfPlayer(EntityPlayer entityplayer) { - // Paper end - double d0 = entityplayer.locX - (double) this.xLoc / 4096.0D; - double d1 = entityplayer.locZ - (double) this.zLoc / 4096.0D; - int i = Math.min(this.e, (entityplayer.getViewDistance() - 1) * 16); // Paper - Use player view distance API - - return d0 >= (double) (-i) && d0 <= (double) i && d1 >= (double) (-i) && d1 <= (double) i && this.tracker.a(entityplayer); - } - - private boolean e(EntityPlayer entityplayer) { - return entityplayer.getWorldServer().getPlayerChunkMap().a(entityplayer, this.tracker.chunkX, this.tracker.chunkZ); - } - - public void scanPlayers(List list) { - for (int i = 0; i < list.size(); ++i) { - this.updatePlayer((EntityPlayer) list.get(i)); - } - - } - - private Packet e() { - if (this.tracker.dead) { - // CraftBukkit start - Remove useless error spam, just return - // EntityTrackerEntry.d.warn("Fetching addPacket for removed entity"); - return null; - // CraftBukkit end - } - - if (this.tracker instanceof EntityPlayer) { - return new PacketPlayOutNamedEntitySpawn((EntityHuman) this.tracker); - } else if (this.tracker instanceof IAnimal) { - this.headYaw = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F); - return new PacketPlayOutSpawnEntityLiving((EntityLiving) this.tracker); - } else if (this.tracker instanceof EntityPainting) { - return new PacketPlayOutSpawnEntityPainting((EntityPainting) this.tracker); - } else if (this.tracker instanceof EntityItem) { - return new PacketPlayOutSpawnEntity(this.tracker, 2, 1); - } else if (this.tracker instanceof EntityMinecartAbstract) { - EntityMinecartAbstract entityminecartabstract = (EntityMinecartAbstract) this.tracker; - - return new PacketPlayOutSpawnEntity(this.tracker, 10, entityminecartabstract.v().a()); - } else if (this.tracker instanceof EntityBoat) { - return new PacketPlayOutSpawnEntity(this.tracker, 1); - } else if (this.tracker instanceof EntityExperienceOrb) { - return new PacketPlayOutSpawnEntityExperienceOrb((EntityExperienceOrb) this.tracker); - } else if (this.tracker instanceof EntityFishingHook) { - EntityHuman entityhuman = ((EntityFishingHook) this.tracker).i(); - - return new PacketPlayOutSpawnEntity(this.tracker, 90, entityhuman == null ? this.tracker.getId() : entityhuman.getId()); - } else { - Entity entity; - - if (this.tracker instanceof EntitySpectralArrow) { - entity = ((EntitySpectralArrow) this.tracker).getShooter(); - return new PacketPlayOutSpawnEntity(this.tracker, 91, 1 + (entity == null ? this.tracker.getId() : entity.getId())); - } else if (this.tracker instanceof EntityTippedArrow) { - entity = ((EntityArrow) this.tracker).getShooter(); - return new PacketPlayOutSpawnEntity(this.tracker, 60, 1 + (entity == null ? this.tracker.getId() : entity.getId())); - } else if (this.tracker instanceof EntitySnowball) { - return new PacketPlayOutSpawnEntity(this.tracker, 61); - } else if (this.tracker instanceof EntityThrownTrident) { - entity = ((EntityArrow) this.tracker).getShooter(); - return new PacketPlayOutSpawnEntity(this.tracker, 94, 1 + (entity == null ? this.tracker.getId() : entity.getId())); - } else if (this.tracker instanceof EntityLlamaSpit) { - return new PacketPlayOutSpawnEntity(this.tracker, 68); - } else if (this.tracker instanceof EntityPotion) { - return new PacketPlayOutSpawnEntity(this.tracker, 73); - } else if (this.tracker instanceof EntityThrownExpBottle) { - return new PacketPlayOutSpawnEntity(this.tracker, 75); - } else if (this.tracker instanceof EntityEnderPearl) { - return new PacketPlayOutSpawnEntity(this.tracker, 65); - } else if (this.tracker instanceof EntityEnderSignal) { - return new PacketPlayOutSpawnEntity(this.tracker, 72); - } else if (this.tracker instanceof EntityFireworks) { - return new PacketPlayOutSpawnEntity(this.tracker, 76); - } else if (this.tracker instanceof EntityFireball) { - EntityFireball entityfireball = (EntityFireball) this.tracker; - byte b0 = 63; - - if (this.tracker instanceof EntitySmallFireball) { - b0 = 64; - } else if (this.tracker instanceof EntityDragonFireball) { - b0 = 93; - } else if (this.tracker instanceof EntityWitherSkull) { - b0 = 66; - } - - PacketPlayOutSpawnEntity packetplayoutspawnentity; - - if (entityfireball.shooter == null) { - packetplayoutspawnentity = new PacketPlayOutSpawnEntity(this.tracker, b0, 0); - } else { - packetplayoutspawnentity = new PacketPlayOutSpawnEntity(this.tracker, b0, ((EntityFireball) this.tracker).shooter.getId()); - } - - packetplayoutspawnentity.a((int) (entityfireball.dirX * 8000.0D)); - packetplayoutspawnentity.b((int) (entityfireball.dirY * 8000.0D)); - packetplayoutspawnentity.c((int) (entityfireball.dirZ * 8000.0D)); - return packetplayoutspawnentity; - } else if (this.tracker instanceof EntityShulkerBullet) { - PacketPlayOutSpawnEntity packetplayoutspawnentity1 = new PacketPlayOutSpawnEntity(this.tracker, 67, 0); - - packetplayoutspawnentity1.a((int) (this.tracker.motX * 8000.0D)); - packetplayoutspawnentity1.b((int) (this.tracker.motY * 8000.0D)); - packetplayoutspawnentity1.c((int) (this.tracker.motZ * 8000.0D)); - return packetplayoutspawnentity1; - } else if (this.tracker instanceof EntityEgg) { - return new PacketPlayOutSpawnEntity(this.tracker, 62); - } else if (this.tracker instanceof EntityEvokerFangs) { - return new PacketPlayOutSpawnEntity(this.tracker, 79); - } else if (this.tracker instanceof EntityTNTPrimed) { - return new PacketPlayOutSpawnEntity(this.tracker, 50); - } else if (this.tracker instanceof EntityEnderCrystal) { - return new PacketPlayOutSpawnEntity(this.tracker, 51); - } else if (this.tracker instanceof EntityFallingBlock) { - EntityFallingBlock entityfallingblock = (EntityFallingBlock) this.tracker; - - return new PacketPlayOutSpawnEntity(this.tracker, 70, Block.getCombinedId(entityfallingblock.getBlock())); - } else if (this.tracker instanceof EntityArmorStand) { - return new PacketPlayOutSpawnEntity(this.tracker, 78); - } else if (this.tracker instanceof EntityItemFrame) { - EntityItemFrame entityitemframe = (EntityItemFrame) this.tracker; - - return new PacketPlayOutSpawnEntity(this.tracker, 71, entityitemframe.direction.a(), entityitemframe.getBlockPosition()); - } else if (this.tracker instanceof EntityLeash) { - EntityLeash entityleash = (EntityLeash) this.tracker; - - return new PacketPlayOutSpawnEntity(this.tracker, 77, 0, entityleash.getBlockPosition()); - } else if (this.tracker instanceof EntityAreaEffectCloud) { - return new PacketPlayOutSpawnEntity(this.tracker, 3); - } else { - throw new IllegalArgumentException("Don't know how to add " + this.tracker.getClass() + "!"); - } - } - } - - public void clear(EntityPlayer entityplayer) { - //org.spigotmc.AsyncCatcher.catchOp( "player tracker clear"); // Spigot // Akarin - if (this.trackedPlayers.contains(entityplayer)) { - this.trackedPlayers.remove(entityplayer); - this.tracker.c(entityplayer); - entityplayer.c(this.tracker); - updatePassengers(entityplayer); // Paper - } - - } - - public Entity b() { - return this.tracker; - } - - public void a(int i) { - this.f = i; - } - - public void c() { - this.isMoving = false; - } } diff --git a/src/main/java/net/minecraft/server/EntityTurtle.java b/src/main/java/net/minecraft/server/EntityTurtle.java index 270b95082..0bd80e562 100644 --- a/src/main/java/net/minecraft/server/EntityTurtle.java +++ b/src/main/java/net/minecraft/server/EntityTurtle.java @@ -1,6 +1,7 @@ package net.minecraft.server; import com.google.common.collect.Sets; +import java.util.EnumSet; import java.util.Random; import java.util.Set; import java.util.function.Predicate; @@ -8,107 +9,108 @@ import javax.annotation.Nullable; public class EntityTurtle extends EntityAnimal { + private static final DataWatcherObject bA = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.l); + private static final DataWatcherObject bB = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.i); + private static final DataWatcherObject bC = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.i); private static final DataWatcherObject bD = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.l); private static final DataWatcherObject bE = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.i); - private static final DataWatcherObject bG = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.i); - private static final DataWatcherObject bH = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.l); - private static final DataWatcherObject bI = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.i); - private static final DataWatcherObject bJ = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.i); - private int bK; - public static final Predicate bC = (entity) -> { - return !(entity instanceof EntityLiving) ? false : ((EntityLiving) entity).isBaby() && !entity.isInWater(); + private static final DataWatcherObject bF = DataWatcher.a(EntityTurtle.class, DataWatcherRegistry.i); + private int bG; + public static final Predicate bz = (entityliving) -> { + return entityliving.isBaby() && !entityliving.isInWater(); }; - public EntityTurtle(World world) { - super(EntityTypes.TURTLE, world); - this.setSize(1.2F, 0.4F); + public EntityTurtle(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.moveController = new EntityTurtle.e(this); - this.bF = Blocks.SAND; - this.Q = 1.0F; + this.K = 1.0F; } - public void setHome(BlockPosition pos) { g(pos); } // Paper - OBFHELPER + public final void setHome(BlockPosition pos) { g(pos); } // Paper - OBFHELPER public void g(BlockPosition blockposition) { + this.datawatcher.set(EntityTurtle.bA, blockposition); + } + + public final BlockPosition getHome() { return this.dX(); } // Paper - OBFHELPER + private BlockPosition dX() { + return (BlockPosition) this.datawatcher.get(EntityTurtle.bA); + } + + public final void setTravelPos(BlockPosition pos) { this.h(pos); } // Paper - OBFHELPER + private void h(BlockPosition blockposition) { this.datawatcher.set(EntityTurtle.bD, blockposition); } - public BlockPosition getHome() { return dA(); } // Paper - OBFHELPER - private BlockPosition dA() { + public final BlockPosition getTravelPos() { return this.dY(); } // Paper - OBFHELPER + private BlockPosition dY() { return (BlockPosition) this.datawatcher.get(EntityTurtle.bD); } - public void setTravelPos(BlockPosition pos) { h(pos); } // Paper - OBFHELPER - private void h(BlockPosition blockposition) { - this.datawatcher.set(EntityTurtle.bH, blockposition); + public final boolean hasEgg() { return this.dV(); } // Paper - OBFHELPER + public boolean dV() { + return (Boolean) this.datawatcher.get(EntityTurtle.bB); } - public BlockPosition getTravelPos() { return dB(); } // Paper - OBFHELPER - private BlockPosition dB() { - return (BlockPosition) this.datawatcher.get(EntityTurtle.bH); + public final void setHasEgg(boolean hasEgg) { this.r(hasEgg); } // Paper - OBFHELPER + private void r(boolean flag) { + this.datawatcher.set(EntityTurtle.bB, flag); } - public boolean hasEgg() { return dy(); } // Paper - OBFHELPER - public boolean dy() { + public final boolean isDigging() { return this.dW(); } // Paper - OBFHELPER + public boolean dW() { + return (Boolean) this.datawatcher.get(EntityTurtle.bC); + } + + public final void setDigging(boolean digging) { this.s(digging); } // Paper - OBFHELPER + private void s(boolean flag) { + this.bG = flag ? 1 : 0; + this.datawatcher.set(EntityTurtle.bC, flag); + } + + public final boolean isGoingHome() { return this.dZ(); } // Paper - OBFHELPER + private boolean dZ() { return (Boolean) this.datawatcher.get(EntityTurtle.bE); } - public void setHasEgg(boolean hasEgg) { s(hasEgg); } // Paper - OBFHELPER - private void s(boolean flag) { + public final void setGoingHome(boolean goingHome) { this.t(goingHome); } // Paper - OBFHELPER + private void t(boolean flag) { this.datawatcher.set(EntityTurtle.bE, flag); } - public boolean isDigging() { return dz(); } // Paper - OBFHELPER - public boolean dz() { - return (Boolean) this.datawatcher.get(EntityTurtle.bG); + public final boolean isTravelling() { return this.ee(); } // Paper - OBFHELPER + private boolean ee() { + return (Boolean) this.datawatcher.get(EntityTurtle.bF); } - public void setDigging(boolean digging) { t(digging); } // Paper - OBFHELPER - private void t(boolean flag) { - this.bK = flag ? 1 : 0; - this.datawatcher.set(EntityTurtle.bG, flag); - } - - public boolean isGoingHome() { return dC(); } // Paper - OBFHELPER - private boolean dC() { - return (Boolean) this.datawatcher.get(EntityTurtle.bI); - } - - public void setGoingHome(boolean goingHome) { u(goingHome); } // Paper - OBFHELPER + public final void setTravelling(boolean travelling) { this.u(travelling); } // Paper - OBFHELPER private void u(boolean flag) { - this.datawatcher.set(EntityTurtle.bI, flag); + this.datawatcher.set(EntityTurtle.bF, flag); } - public boolean isTravelling() { return dH(); } // Paper - OBFHELPER - private boolean dH() { - return (Boolean) this.datawatcher.get(EntityTurtle.bJ); - } - - public void setTravelling(boolean travelling) { v(travelling); } // Paper - OBFHELPER - private void v(boolean flag) { - this.datawatcher.set(EntityTurtle.bJ, flag); - } - - protected void x_() { - super.x_(); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityTurtle.bA, BlockPosition.ZERO); + this.datawatcher.register(EntityTurtle.bB, false); this.datawatcher.register(EntityTurtle.bD, BlockPosition.ZERO); this.datawatcher.register(EntityTurtle.bE, false); - this.datawatcher.register(EntityTurtle.bH, BlockPosition.ZERO); - this.datawatcher.register(EntityTurtle.bI, false); - this.datawatcher.register(EntityTurtle.bJ, false); - this.datawatcher.register(EntityTurtle.bG, false); + this.datawatcher.register(EntityTurtle.bF, false); + this.datawatcher.register(EntityTurtle.bC, false); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setInt("HomePosX", this.dA().getX()); - nbttagcompound.setInt("HomePosY", this.dA().getY()); - nbttagcompound.setInt("HomePosZ", this.dA().getZ()); - nbttagcompound.setBoolean("HasEgg", this.dy()); - nbttagcompound.setInt("TravelPosX", this.dB().getX()); - nbttagcompound.setInt("TravelPosY", this.dB().getY()); - nbttagcompound.setInt("TravelPosZ", this.dB().getZ()); + nbttagcompound.setInt("HomePosX", this.dX().getX()); + nbttagcompound.setInt("HomePosY", this.dX().getY()); + nbttagcompound.setInt("HomePosZ", this.dX().getZ()); + nbttagcompound.setBoolean("HasEgg", this.dV()); + nbttagcompound.setInt("TravelPosX", this.dY().getX()); + nbttagcompound.setInt("TravelPosY", this.dY().getY()); + nbttagcompound.setInt("TravelPosZ", this.dY().getZ()); } + @Override public void a(NBTTagCompound nbttagcompound) { int i = nbttagcompound.getInt("HomePosX"); int j = nbttagcompound.getInt("HomePosY"); @@ -116,7 +118,7 @@ public class EntityTurtle extends EntityAnimal { this.g(new BlockPosition(i, j, k)); super.a(nbttagcompound); - this.s(nbttagcompound.getBoolean("HasEgg")); + this.r(nbttagcompound.getBoolean("HasEgg")); int l = nbttagcompound.getInt("TravelPosX"); int i1 = nbttagcompound.getInt("TravelPosY"); int j1 = nbttagcompound.getInt("TravelPosZ"); @@ -125,19 +127,19 @@ public class EntityTurtle extends EntityAnimal { } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - this.g(new BlockPosition(this.locX, this.locY, this.locZ)); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.g(new BlockPosition(this)); this.h(BlockPosition.ZERO); - return super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - BlockPosition blockposition = new BlockPosition(this.locX, this.getBoundingBox().minY, this.locZ); - - return blockposition.getY() < generatoraccess.getSeaLevel() + 4 && super.a(generatoraccess, flag); + public static boolean c(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return blockposition.getY() < generatoraccess.getSeaLevel() + 4 && generatoraccess.getType(blockposition.down()).getBlock() == Blocks.SAND && generatoraccess.getLightLevel(blockposition, 0) > 8; } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(0, new EntityTurtle.f(this, 1.2D)); this.goalSelector.a(1, new EntityTurtle.a(this, 1.0D)); this.goalSelector.a(1, new EntityTurtle.d(this, 1.0D)); @@ -149,89 +151,108 @@ public class EntityTurtle extends EntityAnimal { this.goalSelector.a(9, new EntityTurtle.h(this, 1.0D, 100)); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(30.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(30.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); } - public boolean bw() { + @Override + public boolean bE() { return false; } - public boolean ca() { + @Override + public boolean cm() { return true; } + @Override public EnumMonsterType getMonsterType() { return EnumMonsterType.e; } - public int z() { + @Override + public int A() { return 200; } @Nullable - protected SoundEffect D() { - return !this.isInWater() && this.onGround && !this.isBaby() ? SoundEffects.ENTITY_TURTLE_AMBIENT_LAND : super.D(); + @Override + protected SoundEffect getSoundAmbient() { + return !this.isInWater() && this.onGround && !this.isBaby() ? SoundEffects.ENTITY_TURTLE_AMBIENT_LAND : super.getSoundAmbient(); } + @Override protected void d(float f) { super.d(f * 1.5F); } - protected SoundEffect ad() { + @Override + protected SoundEffect getSoundSwim() { return SoundEffects.ENTITY_TURTLE_SWIM; } @Nullable - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return this.isBaby() ? SoundEffects.ENTITY_TURTLE_HURT_BABY : SoundEffects.ENTITY_TURTLE_HURT; } @Nullable - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return this.isBaby() ? SoundEffects.ENTITY_TURTLE_DEATH_BABY : SoundEffects.ENTITY_TURTLE_DEATH; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { SoundEffect soundeffect = this.isBaby() ? SoundEffects.ENTITY_TURTLE_SHAMBLE_BABY : SoundEffects.ENTITY_TURTLE_SHAMBLE; this.a(soundeffect, 0.15F, 1.0F); } - public boolean dD() { - return super.dD() && !this.dy(); + @Override + public boolean ea() { + return super.ea() && !this.dV(); } - protected float ab() { - return this.L + 0.15F; + @Override + protected float ag() { + return this.F + 0.15F; } - public void a(boolean flag) { - this.a(flag ? 0.3F : 1.0F); + @Override + public float cn() { + return this.isBaby() ? 0.3F : 1.0F; } + @Override protected NavigationAbstract b(World world) { return new EntityTurtle.g(this, world); } @Nullable + @Override public EntityAgeable createChild(EntityAgeable entityageable) { - return EntityTypes.TURTLE.create(world); // Paper + return (EntityAgeable) EntityTypes.TURTLE.a(this.world); } - public boolean f(ItemStack itemstack) { + @Override + public boolean i(ItemStack itemstack) { return itemstack.getItem() == Blocks.SEAGRASS.getItem(); } + @Override public float a(BlockPosition blockposition, IWorldReader iworldreader) { - return !this.dC() && iworldreader.getFluid(blockposition).a(TagsFluid.WATER) ? 10.0F : super.a(blockposition, iworldreader); + return !this.dZ() && iworldreader.getFluid(blockposition).a(TagsFluid.WATER) ? 10.0F : (iworldreader.getType(blockposition.down()).getBlock() == Blocks.SAND ? 10.0F : iworldreader.v(blockposition) - 0.5F); } + @Override public void movementTick() { super.movementTick(); - if (this.dz() && this.bK >= 1 && this.bK % 5 == 0) { + if (this.isAlive() && this.dW() && this.bG >= 1 && this.bG % 5 == 0) { BlockPosition blockposition = new BlockPosition(this); if (this.world.getType(blockposition.down()).getBlock() == Blocks.SAND) { @@ -241,9 +262,10 @@ public class EntityTurtle extends EntityAnimal { } + @Override protected void l() { super.l(); - if (this.world.getGameRules().getBoolean("doMobLoot")) { + if (!this.isBaby() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { this.forceDrops = true; // CraftBukkit this.a((IMaterial) Items.SCUTE, 1); this.forceDrops = false; // CraftBukkit @@ -251,64 +273,55 @@ public class EntityTurtle extends EntityAnimal { } - public void a(float f, float f1, float f2) { - if (this.cP() && this.isInWater()) { - this.a(f, f1, f2, 0.1F); - this.move(EnumMoveType.SELF, this.motX, this.motY, this.motZ); - this.motX *= 0.8999999761581421D; - this.motY *= 0.8999999761581421D; - this.motZ *= 0.8999999761581421D; - if (this.getGoalTarget() == null && (!this.dC() || this.c(this.dA()) >= 400.0D)) { - this.motY -= 0.005D; + @Override + public void e(Vec3D vec3d) { + if (this.df() && this.isInWater()) { + this.a(0.1F, vec3d); + this.move(EnumMoveType.SELF, this.getMot()); + this.setMot(this.getMot().a(0.9D)); + if (this.getGoalTarget() == null && (!this.dZ() || !this.dX().a((IPosition) this.getPositionVector(), 20.0D))) { + this.setMot(this.getMot().add(0.0D, -0.005D, 0.0D)); } } else { - super.a(f, f1, f2); + super.e(vec3d); } } + @Override public boolean a(EntityHuman entityhuman) { return false; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aI; - } - + @Override public void onLightningStrike(EntityLightning entitylightning) { org.bukkit.craftbukkit.event.CraftEventFactory.entityDamage = entitylightning; // CraftBukkit this.damageEntity(DamageSource.LIGHTNING, Float.MAX_VALUE); org.bukkit.craftbukkit.event.CraftEventFactory.entityDamage = null; // CraftBukkit } - public void die(DamageSource damagesource) { - super.die(damagesource); - if (damagesource == DamageSource.LIGHTNING) { - this.a(new ItemStack(Items.BOWL, 1), 0.0F); - } - - } - static class g extends NavigationGuardian { g(EntityTurtle entityturtle, World world) { super(entityturtle, world); } - protected boolean b() { + @Override + protected boolean a() { return true; } - protected Pathfinder a() { - return new Pathfinder(new PathfinderTurtle()); + @Override + protected Pathfinder a(int i) { + return new Pathfinder(new PathfinderTurtle(), i); } + @Override public boolean a(BlockPosition blockposition) { if (this.a instanceof EntityTurtle) { EntityTurtle entityturtle = (EntityTurtle) this.a; - if (entityturtle.dH()) { + if (entityturtle.ee()) { return this.b.getType(blockposition).getBlock() == Blocks.WATER; } } @@ -328,37 +341,38 @@ public class EntityTurtle extends EntityAnimal { private void g() { if (this.i.isInWater()) { - this.i.motY += 0.005D; - if (this.i.c(this.i.dA()) > 256.0D) { - this.i.o(Math.max(this.i.cK() / 2.0F, 0.08F)); + this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); + if (!this.i.dX().a((IPosition) this.i.getPositionVector(), 16.0D)) { + this.i.o(Math.max(this.i.db() / 2.0F, 0.08F)); } if (this.i.isBaby()) { - this.i.o(Math.max(this.i.cK() / 3.0F, 0.06F)); + this.i.o(Math.max(this.i.db() / 3.0F, 0.06F)); } } else if (this.i.onGround) { - this.i.o(Math.max(this.i.cK() / 2.0F, 0.06F)); + this.i.o(Math.max(this.i.db() / 2.0F, 0.06F)); } } + @Override public void a() { this.g(); - if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().p()) { + if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().n()) { double d0 = this.b - this.i.locX; double d1 = this.c - this.i.locY; double d2 = this.d - this.i.locZ; double d3 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); d1 /= d3; - float f = (float) (MathHelper.c(d2, d0) * 57.2957763671875D) - 90.0F; + float f = (float) (MathHelper.d(d2, d0) * 57.2957763671875D) - 90.0F; this.i.yaw = this.a(this.i.yaw, f, 90.0F); - this.i.aQ = this.i.yaw; + this.i.aK = this.i.yaw; float f1 = (float) (this.e * this.i.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); - this.i.o(this.i.cK() + (f1 - this.i.cK()) * 0.125F); - this.i.motY += (double) this.i.cK() * d1 * 0.1D; + this.i.o(MathHelper.g(0.125F, this.i.db(), f1)); + this.i.setMot(this.i.getMot().add(0.0D, (double) this.i.db() * d1 * 0.1D, 0.0D)); } else { this.i.o(0.0F); } @@ -367,30 +381,30 @@ public class EntityTurtle extends EntityAnimal { static class c extends PathfinderGoalGotoTarget { - private final EntityTurtle f; + private final EntityTurtle g; private c(EntityTurtle entityturtle, double d0) { super(entityturtle, entityturtle.isBaby() ? 2.0D : d0, 24); - this.f = entityturtle; - this.e = -1; + this.g = entityturtle; + this.f = -1; } + @Override public boolean b() { - return !this.f.isInWater() && this.c <= 1200 && this.a(this.f.world, this.d); + return !this.g.isInWater() && this.d <= 1200 && this.a(this.g.world, this.e); } + @Override public boolean a() { - return this.f.isBaby() && !this.f.isInWater() ? super.a() : (!this.f.dC() && !this.f.isInWater() && !this.f.dy() ? super.a() : false); + return this.g.isBaby() && !this.g.isInWater() ? super.a() : (!this.g.dZ() && !this.g.isInWater() && !this.g.dV() ? super.a() : false); } - public int j() { - return 1; - } - - public boolean i() { - return this.c % 160 == 0; + @Override + public boolean j() { + return this.d % 160 == 0; } + @Override protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) { Block block = iworldreader.getType(blockposition).getBlock(); @@ -407,59 +421,64 @@ public class EntityTurtle extends EntityAnimal { this.h = entityturtle; } + @Override public boolean a() { - return !this.a.isInWater() && !this.h.dC() && !this.h.dy() ? super.a() : false; + return !this.a.isInWater() && !this.h.dZ() && !this.h.dV() ? super.a() : false; } } static class d extends PathfinderGoalGotoTarget { - private final EntityTurtle f; + private final EntityTurtle g; d(EntityTurtle entityturtle, double d0) { super(entityturtle, d0, 16); - this.f = entityturtle; + this.g = entityturtle; } + @Override public boolean a() { - return this.f.dy() && this.f.c(this.f.dA()) < 81.0D ? super.a() : false; + return this.g.dV() && this.g.dX().a((IPosition) this.g.getPositionVector(), 9.0D) ? super.a() : false; } + @Override public boolean b() { - return super.b() && this.f.dy() && this.f.c(this.f.dA()) < 81.0D; + return super.b() && this.g.dV() && this.g.dX().a((IPosition) this.g.getPositionVector(), 9.0D); } + @Override public void e() { super.e(); - BlockPosition blockposition = new BlockPosition(this.f); + BlockPosition blockposition = new BlockPosition(this.g); - if (!this.f.isInWater() && this.k()) { - if (this.f.bK < 1) { - this.f.setDigging(new com.destroystokyo.paper.event.entity.TurtleStartDiggingEvent((org.bukkit.entity.Turtle) this.f.getBukkitEntity(), MCUtil.toLocation(this.f.world, this.d)).callEvent()); // Paper - } else if (this.f.bK > 200) { - World world = this.f.world; + if (!this.g.isInWater() && this.k()) { + if (this.g.bG < 1) { + this.g.setDigging(new com.destroystokyo.paper.event.entity.TurtleStartDiggingEvent((org.bukkit.entity.Turtle) this.g.getBukkitEntity(), MCUtil.toLocation(this.g.world, this.e)).callEvent()); // Paper + } else if (this.g.bG > 200) { + World world = this.g.world; // CraftBukkit start // Paper start - int eggCount = this.f.random.nextInt(4) + 1; - com.destroystokyo.paper.event.entity.TurtleLayEggEvent layEggEvent = new com.destroystokyo.paper.event.entity.TurtleLayEggEvent((org.bukkit.entity.Turtle) this.f.getBukkitEntity(), MCUtil.toLocation(this.f.world, this.d.up()), eggCount); - if (layEggEvent.callEvent() && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.f, this.d.up(), Blocks.TURTLE_EGG.getBlockData().set(BlockTurtleEgg.b, layEggEvent.getEggCount())).isCancelled()) { - world.a((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_LAY_EGG, SoundCategory.BLOCKS, 0.3F, 0.9F + world.random.nextFloat() * 0.2F); - world.setTypeAndData(this.d.up(), (IBlockData) Blocks.TURTLE_EGG.getBlockData().set(BlockTurtleEgg.b, layEggEvent.getEggCount()), 3); + int eggCount = this.g.random.nextInt(4) + 1; + com.destroystokyo.paper.event.entity.TurtleLayEggEvent layEggEvent = new com.destroystokyo.paper.event.entity.TurtleLayEggEvent((org.bukkit.entity.Turtle) this.g.getBukkitEntity(), MCUtil.toLocation(this.g.world, this.e.up()), eggCount); + if (layEggEvent.callEvent() && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.g, this.e.up(), Blocks.TURTLE_EGG.getBlockData().set(BlockTurtleEgg.b, layEggEvent.getEggCount())).isCancelled()) { + world.playSound((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_LAY_EGG, SoundCategory.BLOCKS, 0.3F, 0.9F + world.random.nextFloat() * 0.2F); + world.setTypeAndData(this.e.up(), (IBlockData) Blocks.TURTLE_EGG.getBlockData().set(BlockTurtleEgg.b, layEggEvent.getEggCount()), 3); } // CraftBukkit end - this.f.s(false); - this.f.t(false); - this.f.d(600); + this.g.r(false); + this.g.s(false); + this.g.setLoveTicks(600); } - if (this.f.dz()) { - this.f.bK++; + if (this.g.dW()) { + this.g.bG++; } } } + @Override protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) { if (!iworldreader.isEmpty(blockposition.up())) { return false; @@ -480,10 +499,12 @@ public class EntityTurtle extends EntityAnimal { this.d = entityturtle; } + @Override public boolean a() { - return super.a() && !this.d.dy(); + return super.a() && !this.d.dV(); } + @Override protected void g() { EntityPlayer entityplayer = this.animal.getBreedCause(); @@ -496,13 +517,13 @@ public class EntityTurtle extends EntityAnimal { CriterionTriggers.o.a(entityplayer, this.animal, this.partner, (EntityAgeable) null); } - this.d.s(true); + this.d.r(true); this.animal.resetLove(); this.partner.resetLove(); Random random = this.animal.getRandom(); - if (this.b.getGameRules().getBoolean("doMobLoot")) { - this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX, this.animal.locY, this.animal.locZ, random.nextInt(7) + 1)); + if (this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { + this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX, this.animal.locY, this.animal.locZ, random.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper; } } @@ -510,49 +531,54 @@ public class EntityTurtle extends EntityAnimal { static class i extends PathfinderGoal { - private final EntityTurtle a; - private final double b; - private EntityHuman c; - private int d; - private final Set e; + private static final PathfinderTargetCondition a = (new PathfinderTargetCondition()).a(10.0D).b().a(); + private final EntityTurtle b; + private final double c; + private EntityHuman d; + private int e; + private final Set f; i(EntityTurtle entityturtle, double d0, Item item) { - this.a = entityturtle; - this.b = d0; - this.e = Sets.newHashSet(new Item[] { item}); - this.a(3); + this.b = entityturtle; + this.c = d0; + this.f = Sets.newHashSet(new Item[]{item}); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); } + @Override public boolean a() { - if (this.d > 0) { - --this.d; + if (this.e > 0) { + --this.e; return false; } else { - this.c = this.a.world.findNearbyPlayer(this.a, 10.0D); - return this.c == null ? false : this.a(this.c.getItemInMainHand()) || this.a(this.c.getItemInOffHand()); + this.d = this.b.world.a(this.a, (EntityLiving) this.b); // CraftBukkit - decompile error + return this.d == null ? false : this.a(this.d.getItemInMainHand()) || this.a(this.d.getItemInOffHand()); } } private boolean a(ItemStack itemstack) { - return this.e.contains(itemstack.getItem()); + return this.f.contains(itemstack.getItem()); } + @Override public boolean b() { return this.a(); } + @Override public void d() { - this.c = null; - this.a.getNavigation().q(); - this.d = 100; + this.d = null; + this.b.getNavigation().o(); + this.e = 100; } + @Override public void e() { - this.a.getControllerLook().a(this.c, (float) (this.a.L() + 20), (float) this.a.K()); - if (this.a.h((Entity) this.c) < 6.25D) { - this.a.getNavigation().q(); + this.b.getControllerLook().a(this.d, (float) (this.b.dA() + 20), (float) this.b.M()); + if (this.b.h((Entity) this.d) < 6.25D) { + this.b.getNavigation().o(); } else { - this.a.getNavigation().a((Entity) this.c, this.b); + this.b.getNavigation().a((Entity) this.d, this.c); } } @@ -570,33 +596,38 @@ public class EntityTurtle extends EntityAnimal { this.b = d0; } + @Override public boolean a() { - return this.a.isBaby() ? false : (this.a.dy() ? true : (this.a.getRandom().nextInt(700) != 0 ? false : this.a.c(this.a.dA()) >= 4096.0D)) && new com.destroystokyo.paper.event.entity.TurtleGoHomeEvent((org.bukkit.entity.Turtle) this.a.getBukkitEntity()).callEvent(); // Paper; + return this.a.isBaby() ? false : (this.a.dW() ? true : (this.a.getRandom().nextInt(700) != 0 ? false : !this.a.dY().a((IPosition) this.a.getPositionVector(), 64.0D))) && new com.destroystokyo.paper.event.entity.TurtleGoHomeEvent((org.bukkit.entity.Turtle) this.a.getBukkitEntity()).callEvent(); // Paper } + @Override public void c() { - this.a.u(true); + this.a.t(true); this.c = false; this.d = 0; } + @Override public void d() { - this.a.u(false); + this.a.t(false); } + @Override public boolean b() { - return this.a.c(this.a.dA()) >= 49.0D && !this.c && this.d <= 600; + return !this.a.dX().a((IPosition) this.a.getPositionVector(), 7.0D) && !this.c && this.d <= 600; } + @Override public void e() { - BlockPosition blockposition = this.a.dA(); - boolean flag = this.a.c(blockposition) <= 256.0D; + BlockPosition blockposition = this.a.dX(); + boolean flag = blockposition.a((IPosition) this.a.getPositionVector(), 16.0D); if (flag) { ++this.d; } - if (this.a.getNavigation().p()) { + if (this.a.getNavigation().n()) { Vec3D vec3d = RandomPositionGenerator.a((EntityCreature) this.a, 16, 3, new Vec3D((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), 0.3141592741012573D); if (vec3d == null) { @@ -629,10 +660,12 @@ public class EntityTurtle extends EntityAnimal { this.b = d0; } + @Override public boolean a() { - return !this.a.dC() && !this.a.dy() && this.a.isInWater(); + return !this.a.dZ() && !this.a.dV() && this.a.isInWater(); } + @Override public void c() { boolean flag = true; boolean flag1 = true; @@ -648,13 +681,14 @@ public class EntityTurtle extends EntityAnimal { BlockPosition blockposition = new BlockPosition((double) i + this.a.locX, (double) j + this.a.locY, (double) k + this.a.locZ); this.a.h(blockposition); - this.a.v(true); + this.a.u(true); this.c = false; } + @Override public void e() { - if (this.a.getNavigation().p()) { - BlockPosition blockposition = this.a.dB(); + if (this.a.getNavigation().n()) { + BlockPosition blockposition = this.a.dY(); Vec3D vec3d = RandomPositionGenerator.a((EntityCreature) this.a, 16, 3, new Vec3D((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), 0.3141592741012573D); if (vec3d == null) { @@ -665,9 +699,8 @@ public class EntityTurtle extends EntityAnimal { int i = MathHelper.floor(vec3d.x); int j = MathHelper.floor(vec3d.z); boolean flag = true; - StructureBoundingBox structureboundingbox = new StructureBoundingBox(i - 34, 0, j - 34, i + 34, 0, j + 34); - if (!this.a.world.a(structureboundingbox)) { + if (!this.a.world.isAreaLoaded(i - 34, 0, j - 34, i + 34, 0, j + 34)) { vec3d = null; } } @@ -682,12 +715,14 @@ public class EntityTurtle extends EntityAnimal { } + @Override public boolean b() { - return !this.a.getNavigation().p() && !this.c && !this.a.dC() && !this.a.isInLove() && !this.a.dy(); + return !this.a.getNavigation().n() && !this.c && !this.a.dZ() && !this.a.isInLove() && !this.a.dV(); } + @Override public void d() { - this.a.v(false); + this.a.u(false); super.d(); } } @@ -698,6 +733,7 @@ public class EntityTurtle extends EntityAnimal { super(entityturtle, d0); } + @Override public boolean a() { if (this.a.getLastDamager() == null && !this.a.isBurning()) { return false; diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java index 55d6adca1..612b9b7e3 100644 --- a/src/main/java/net/minecraft/server/EntityTypes.java +++ b/src/main/java/net/minecraft/server/EntityTypes.java @@ -1,11 +1,10 @@ package net.minecraft.server; -import com.koloboke.collect.map.hash.HashObjObjMaps; import com.mojang.datafixers.DataFixUtils; -import com.mojang.datafixers.types.Type; - -import java.util.Map; -import java.util.Set; +import java.util.Collections; +import java.util.Optional; +import java.util.Set; // Paper +import java.util.Map; // Paper import java.util.UUID; import java.util.function.Function; import java.util.stream.Stream; @@ -15,170 +14,166 @@ import org.apache.logging.log4j.Logger; public class EntityTypes { - private static final Logger aR = LogManager.getLogger(); - public static final EntityTypes AREA_EFFECT_CLOUD = a("area_effect_cloud", EntityTypes.a.a(EntityAreaEffectCloud.class, EntityAreaEffectCloud::new)); - public static final EntityTypes ARMOR_STAND = a("armor_stand", EntityTypes.a.a(EntityArmorStand.class, EntityArmorStand::new)); - public static final EntityTypes ARROW = a("arrow", EntityTypes.a.a(EntityTippedArrow.class, EntityTippedArrow::new)); - public static final EntityTypes BAT = a("bat", EntityTypes.a.a(EntityBat.class, EntityBat::new)); - public static final EntityTypes BLAZE = a("blaze", EntityTypes.a.a(EntityBlaze.class, EntityBlaze::new)); - public static final EntityTypes BOAT = a("boat", EntityTypes.a.a(EntityBoat.class, EntityBoat::new)); - public static final EntityTypes CAVE_SPIDER = a("cave_spider", EntityTypes.a.a(EntityCaveSpider.class, EntityCaveSpider::new)); - public static final EntityTypes CHICKEN = a("chicken", EntityTypes.a.a(EntityChicken.class, EntityChicken::new)); - public static final EntityTypes COD = a("cod", EntityTypes.a.a(EntityCod.class, EntityCod::new)); - public static final EntityTypes COW = a("cow", EntityTypes.a.a(EntityCow.class, EntityCow::new)); - public static final EntityTypes CREEPER = a("creeper", EntityTypes.a.a(EntityCreeper.class, EntityCreeper::new)); - public static final EntityTypes DONKEY = a("donkey", EntityTypes.a.a(EntityHorseDonkey.class, EntityHorseDonkey::new)); - public static final EntityTypes DOLPHIN = a("dolphin", EntityTypes.a.a(EntityDolphin.class, EntityDolphin::new)); - public static final EntityTypes DRAGON_FIREBALL = a("dragon_fireball", EntityTypes.a.a(EntityDragonFireball.class, EntityDragonFireball::new)); - public static final EntityTypes DROWNED = a("drowned", EntityTypes.a.a(EntityDrowned.class, EntityDrowned::new)); - public static final EntityTypes ELDER_GUARDIAN = a("elder_guardian", EntityTypes.a.a(EntityGuardianElder.class, EntityGuardianElder::new)); - public static final EntityTypes END_CRYSTAL = a("end_crystal", EntityTypes.a.a(EntityEnderCrystal.class, EntityEnderCrystal::new)); - public static final EntityTypes ENDER_DRAGON = a("ender_dragon", EntityTypes.a.a(EntityEnderDragon.class, EntityEnderDragon::new)); - public static final EntityTypes ENDERMAN = a("enderman", EntityTypes.a.a(EntityEnderman.class, EntityEnderman::new)); - public static final EntityTypes ENDERMITE = a("endermite", EntityTypes.a.a(EntityEndermite.class, EntityEndermite::new)); - public static final EntityTypes EVOKER_FANGS = a("evoker_fangs", EntityTypes.a.a(EntityEvokerFangs.class, EntityEvokerFangs::new)); - public static final EntityTypes EVOKER = a("evoker", EntityTypes.a.a(EntityEvoker.class, EntityEvoker::new)); - public static final EntityTypes EXPERIENCE_ORB = a("experience_orb", EntityTypes.a.a(EntityExperienceOrb.class, EntityExperienceOrb::new)); - public static final EntityTypes EYE_OF_ENDER = a("eye_of_ender", EntityTypes.a.a(EntityEnderSignal.class, EntityEnderSignal::new)); - public static final EntityTypes FALLING_BLOCK = a("falling_block", EntityTypes.a.a(EntityFallingBlock.class, EntityFallingBlock::new)); - public static final EntityTypes FIREWORK_ROCKET = a("firework_rocket", EntityTypes.a.a(EntityFireworks.class, EntityFireworks::new)); - public static final EntityTypes GHAST = a("ghast", EntityTypes.a.a(EntityGhast.class, EntityGhast::new)); - public static final EntityTypes GIANT = a("giant", EntityTypes.a.a(EntityGiantZombie.class, EntityGiantZombie::new)); - public static final EntityTypes GUARDIAN = a("guardian", EntityTypes.a.a(EntityGuardian.class, EntityGuardian::new)); - public static final EntityTypes HORSE = a("horse", EntityTypes.a.a(EntityHorse.class, EntityHorse::new)); - public static final EntityTypes HUSK = a("husk", EntityTypes.a.a(EntityZombieHusk.class, EntityZombieHusk::new)); - public static final EntityTypes ILLUSIONER = a("illusioner", EntityTypes.a.a(EntityIllagerIllusioner.class, EntityIllagerIllusioner::new)); - public static final EntityTypes ITEM = a("item", EntityTypes.a.a(EntityItem.class, EntityItem::new)); - public static final EntityTypes ITEM_FRAME = a("item_frame", EntityTypes.a.a(EntityItemFrame.class, EntityItemFrame::new)); - public static final EntityTypes FIREBALL = a("fireball", EntityTypes.a.a(EntityLargeFireball.class, EntityLargeFireball::new)); - public static final EntityTypes LEASH_KNOT = a("leash_knot", EntityTypes.a.a(EntityLeash.class, EntityLeash::new).b()); - public static final EntityTypes LLAMA = a("llama", EntityTypes.a.a(EntityLlama.class, EntityLlama::new)); - public static final EntityTypes LLAMA_SPIT = a("llama_spit", EntityTypes.a.a(EntityLlamaSpit.class, EntityLlamaSpit::new)); - public static final EntityTypes MAGMA_CUBE = a("magma_cube", EntityTypes.a.a(EntityMagmaCube.class, EntityMagmaCube::new)); - public static final EntityTypes MINECART = a("minecart", EntityTypes.a.a(EntityMinecartRideable.class, EntityMinecartRideable::new)); - public static final EntityTypes CHEST_MINECART = a("chest_minecart", EntityTypes.a.a(EntityMinecartChest.class, EntityMinecartChest::new)); - public static final EntityTypes COMMAND_BLOCK_MINECART = a("command_block_minecart", EntityTypes.a.a(EntityMinecartCommandBlock.class, EntityMinecartCommandBlock::new)); - public static final EntityTypes FURNACE_MINECART = a("furnace_minecart", EntityTypes.a.a(EntityMinecartFurnace.class, EntityMinecartFurnace::new)); - public static final EntityTypes HOPPER_MINECART = a("hopper_minecart", EntityTypes.a.a(EntityMinecartHopper.class, EntityMinecartHopper::new)); - public static final EntityTypes SPAWNER_MINECART = a("spawner_minecart", EntityTypes.a.a(EntityMinecartMobSpawner.class, EntityMinecartMobSpawner::new)); - public static final EntityTypes TNT_MINECART = a("tnt_minecart", EntityTypes.a.a(EntityMinecartTNT.class, EntityMinecartTNT::new)); - public static final EntityTypes MULE = a("mule", EntityTypes.a.a(EntityHorseMule.class, EntityHorseMule::new)); - public static final EntityTypes MOOSHROOM = a("mooshroom", EntityTypes.a.a(EntityMushroomCow.class, EntityMushroomCow::new)); - public static final EntityTypes OCELOT = a("ocelot", EntityTypes.a.a(EntityOcelot.class, EntityOcelot::new)); - public static final EntityTypes PAINTING = a("painting", EntityTypes.a.a(EntityPainting.class, EntityPainting::new)); - public static final EntityTypes PARROT = a("parrot", EntityTypes.a.a(EntityParrot.class, EntityParrot::new)); - public static final EntityTypes PIG = a("pig", EntityTypes.a.a(EntityPig.class, EntityPig::new)); - public static final EntityTypes PUFFERFISH = a("pufferfish", EntityTypes.a.a(EntityPufferFish.class, EntityPufferFish::new)); - public static final EntityTypes ZOMBIE_PIGMAN = a("zombie_pigman", EntityTypes.a.a(EntityPigZombie.class, EntityPigZombie::new)); - public static final EntityTypes POLAR_BEAR = a("polar_bear", EntityTypes.a.a(EntityPolarBear.class, EntityPolarBear::new)); - public static final EntityTypes TNT = a("tnt", EntityTypes.a.a(EntityTNTPrimed.class, EntityTNTPrimed::new)); - public static final EntityTypes RABBIT = a("rabbit", EntityTypes.a.a(EntityRabbit.class, EntityRabbit::new)); - public static final EntityTypes SALMON = a("salmon", EntityTypes.a.a(EntitySalmon.class, EntitySalmon::new)); - public static final EntityTypes SHEEP = a("sheep", EntityTypes.a.a(EntitySheep.class, EntitySheep::new)); - public static final EntityTypes SHULKER = a("shulker", EntityTypes.a.a(EntityShulker.class, EntityShulker::new)); - public static final EntityTypes SHULKER_BULLET = a("shulker_bullet", EntityTypes.a.a(EntityShulkerBullet.class, EntityShulkerBullet::new)); - public static final EntityTypes SILVERFISH = a("silverfish", EntityTypes.a.a(EntitySilverfish.class, EntitySilverfish::new)); - public static final EntityTypes SKELETON = a("skeleton", EntityTypes.a.a(EntitySkeleton.class, EntitySkeleton::new)); - public static final EntityTypes SKELETON_HORSE = a("skeleton_horse", EntityTypes.a.a(EntityHorseSkeleton.class, EntityHorseSkeleton::new)); - public static final EntityTypes SLIME = a("slime", EntityTypes.a.a(EntitySlime.class, EntitySlime::new)); - public static final EntityTypes SMALL_FIREBALL = a("small_fireball", EntityTypes.a.a(EntitySmallFireball.class, EntitySmallFireball::new)); - public static final EntityTypes SNOW_GOLEM = a("snow_golem", EntityTypes.a.a(EntitySnowman.class, EntitySnowman::new)); - public static final EntityTypes SNOWBALL = a("snowball", EntityTypes.a.a(EntitySnowball.class, EntitySnowball::new)); - public static final EntityTypes SPECTRAL_ARROW = a("spectral_arrow", EntityTypes.a.a(EntitySpectralArrow.class, EntitySpectralArrow::new)); - public static final EntityTypes SPIDER = a("spider", EntityTypes.a.a(EntitySpider.class, EntitySpider::new)); - public static final EntityTypes SQUID = a("squid", EntityTypes.a.a(EntitySquid.class, EntitySquid::new)); - public static final EntityTypes STRAY = a("stray", EntityTypes.a.a(EntitySkeletonStray.class, EntitySkeletonStray::new)); - public static final EntityTypes TROPICAL_FISH = a("tropical_fish", EntityTypes.a.a(EntityTropicalFish.class, EntityTropicalFish::new)); - public static final EntityTypes TURTLE = a("turtle", EntityTypes.a.a(EntityTurtle.class, EntityTurtle::new)); - public static final EntityTypes EGG = a("egg", EntityTypes.a.a(EntityEgg.class, EntityEgg::new)); - public static final EntityTypes ENDER_PEARL = a("ender_pearl", EntityTypes.a.a(EntityEnderPearl.class, EntityEnderPearl::new)); - public static final EntityTypes EXPERIENCE_BOTTLE = a("experience_bottle", EntityTypes.a.a(EntityThrownExpBottle.class, EntityThrownExpBottle::new)); - public static final EntityTypes POTION = a("potion", EntityTypes.a.a(EntityPotion.class, EntityPotion::new)); - public static final EntityTypes VEX = a("vex", EntityTypes.a.a(EntityVex.class, EntityVex::new)); - public static final EntityTypes VILLAGER = a("villager", EntityTypes.a.a(EntityVillager.class, EntityVillager::new)); - public static final EntityTypes IRON_GOLEM = a("iron_golem", EntityTypes.a.a(EntityIronGolem.class, EntityIronGolem::new)); - public static final EntityTypes VINDICATOR = a("vindicator", EntityTypes.a.a(EntityVindicator.class, EntityVindicator::new)); - public static final EntityTypes WITCH = a("witch", EntityTypes.a.a(EntityWitch.class, EntityWitch::new)); - public static final EntityTypes WITHER = a("wither", EntityTypes.a.a(EntityWither.class, EntityWither::new)); - public static final EntityTypes WITHER_SKELETON = a("wither_skeleton", EntityTypes.a.a(EntitySkeletonWither.class, EntitySkeletonWither::new)); - public static final EntityTypes WITHER_SKULL = a("wither_skull", EntityTypes.a.a(EntityWitherSkull.class, EntityWitherSkull::new)); - public static final EntityTypes WOLF = a("wolf", EntityTypes.a.a(EntityWolf.class, EntityWolf::new)); - public static final EntityTypes ZOMBIE = a("zombie", EntityTypes.a.a(EntityZombie.class, EntityZombie::new)); - public static final EntityTypes ZOMBIE_HORSE = a("zombie_horse", EntityTypes.a.a(EntityHorseZombie.class, EntityHorseZombie::new)); - public static final EntityTypes ZOMBIE_VILLAGER = a("zombie_villager", EntityTypes.a.a(EntityZombieVillager.class, EntityZombieVillager::new)); - public static final EntityTypes PHANTOM = a("phantom", EntityTypes.a.a(EntityPhantom.class, EntityPhantom::new)); - public static final EntityTypes LIGHTNING_BOLT = a("lightning_bolt", EntityTypes.a.a(EntityLightning.class).b()); - public static final EntityTypes PLAYER = a("player", EntityTypes.a.a(EntityHuman.class).b().a()); - public static final EntityTypes FISHING_BOBBER = a("fishing_bobber", EntityTypes.a.a(EntityFishingHook.class).b().a()); - public static final EntityTypes TRIDENT = a("trident", EntityTypes.a.a(EntityThrownTrident.class, EntityThrownTrident::new)); - private final Class aS; - private final Function aT; - private final boolean aU; - private final boolean aV; + private static final Logger LOGGER = LogManager.getLogger(); + public static final EntityTypes AREA_EFFECT_CLOUD = a("area_effect_cloud", EntityTypes.a.a(EntityAreaEffectCloud::new, EnumCreatureType.MISC).c().a(6.0F, 0.5F)); + public static final EntityTypes ARMOR_STAND = a("armor_stand", EntityTypes.a.a(EntityArmorStand::new, EnumCreatureType.MISC).a(0.5F, 1.975F)); + public static final EntityTypes ARROW = a("arrow", EntityTypes.a.a(EntityTippedArrow::new, EnumCreatureType.MISC).a(0.5F, 0.5F)); + public static final EntityTypes BAT = a("bat", EntityTypes.a.a(EntityBat::new, EnumCreatureType.AMBIENT).a(0.5F, 0.9F)); + public static final EntityTypes BLAZE = a("blaze", EntityTypes.a.a(EntityBlaze::new, EnumCreatureType.MONSTER).c().a(0.6F, 1.8F)); + public static final EntityTypes BOAT = a("boat", EntityTypes.a.a(EntityBoat::new, EnumCreatureType.MISC).a(1.375F, 0.5625F)); + public static final EntityTypes CAT = a("cat", EntityTypes.a.a(EntityCat::new, EnumCreatureType.CREATURE).a(0.6F, 0.7F)); + public static final EntityTypes CAVE_SPIDER = a("cave_spider", EntityTypes.a.a(EntityCaveSpider::new, EnumCreatureType.MONSTER).a(0.7F, 0.5F)); + public static final EntityTypes CHICKEN = a("chicken", EntityTypes.a.a(EntityChicken::new, EnumCreatureType.CREATURE).a(0.4F, 0.7F)); + public static final EntityTypes COD = a("cod", EntityTypes.a.a(EntityCod::new, EnumCreatureType.WATER_CREATURE).a(0.5F, 0.3F)); + public static final EntityTypes COW = a("cow", EntityTypes.a.a(EntityCow::new, EnumCreatureType.CREATURE).a(0.9F, 1.4F)); + public static final EntityTypes CREEPER = a("creeper", EntityTypes.a.a(EntityCreeper::new, EnumCreatureType.MONSTER).a(0.6F, 1.7F)); + public static final EntityTypes DONKEY = a("donkey", EntityTypes.a.a(EntityHorseDonkey::new, EnumCreatureType.CREATURE).a(1.3964844F, 1.5F)); + public static final EntityTypes DOLPHIN = a("dolphin", EntityTypes.a.a(EntityDolphin::new, EnumCreatureType.WATER_CREATURE).a(0.9F, 0.6F)); + public static final EntityTypes DRAGON_FIREBALL = a("dragon_fireball", EntityTypes.a.a(EntityDragonFireball::new, EnumCreatureType.MISC).a(1.0F, 1.0F)); + public static final EntityTypes DROWNED = a("drowned", EntityTypes.a.a(EntityDrowned::new, EnumCreatureType.MONSTER).a(0.6F, 1.95F)); + public static final EntityTypes ELDER_GUARDIAN = a("elder_guardian", EntityTypes.a.a(EntityGuardianElder::new, EnumCreatureType.MONSTER).a(1.9975F, 1.9975F)); + public static final EntityTypes END_CRYSTAL = a("end_crystal", EntityTypes.a.a(EntityEnderCrystal::new, EnumCreatureType.MISC).a(2.0F, 2.0F)); + public static final EntityTypes ENDER_DRAGON = a("ender_dragon", EntityTypes.a.a(EntityEnderDragon::new, EnumCreatureType.MONSTER).c().a(16.0F, 8.0F)); + public static final EntityTypes ENDERMAN = a("enderman", EntityTypes.a.a(EntityEnderman::new, EnumCreatureType.MONSTER).a(0.6F, 2.9F)); + public static final EntityTypes ENDERMITE = a("endermite", EntityTypes.a.a(EntityEndermite::new, EnumCreatureType.MONSTER).a(0.4F, 0.3F)); + public static final EntityTypes EVOKER_FANGS = a("evoker_fangs", EntityTypes.a.a(EntityEvokerFangs::new, EnumCreatureType.MISC).a(0.5F, 0.8F)); + public static final EntityTypes EVOKER = a("evoker", EntityTypes.a.a(EntityEvoker::new, EnumCreatureType.MONSTER).a(0.6F, 1.95F)); + public static final EntityTypes EXPERIENCE_ORB = a("experience_orb", EntityTypes.a.a(EntityExperienceOrb::new, EnumCreatureType.MISC).a(0.5F, 0.5F)); + public static final EntityTypes EYE_OF_ENDER = a("eye_of_ender", EntityTypes.a.a(EntityEnderSignal::new, EnumCreatureType.MISC).a(0.25F, 0.25F)); + public static final EntityTypes FALLING_BLOCK = a("falling_block", EntityTypes.a.a(EntityFallingBlock::new, EnumCreatureType.MISC).a(0.98F, 0.98F)); + public static final EntityTypes FIREWORK_ROCKET = a("firework_rocket", EntityTypes.a.a(EntityFireworks::new, EnumCreatureType.MISC).a(0.25F, 0.25F)); + public static final EntityTypes FOX = a("fox", EntityTypes.a.a(EntityFox::new, EnumCreatureType.CREATURE).a(0.6F, 0.7F)); + public static final EntityTypes GHAST = a("ghast", EntityTypes.a.a(EntityGhast::new, EnumCreatureType.MONSTER).c().a(4.0F, 4.0F)); + public static final EntityTypes GIANT = a("giant", EntityTypes.a.a(EntityGiantZombie::new, EnumCreatureType.MONSTER).a(3.6F, 12.0F)); + public static final EntityTypes GUARDIAN = a("guardian", EntityTypes.a.a(EntityGuardian::new, EnumCreatureType.MONSTER).a(0.85F, 0.85F)); + public static final EntityTypes HORSE = a("horse", EntityTypes.a.a(EntityHorse::new, EnumCreatureType.CREATURE).a(1.3964844F, 1.6F)); + public static final EntityTypes HUSK = a("husk", EntityTypes.a.a(EntityZombieHusk::new, EnumCreatureType.MONSTER).a(0.6F, 1.95F)); + public static final EntityTypes ILLUSIONER = a("illusioner", EntityTypes.a.a(EntityIllagerIllusioner::new, EnumCreatureType.MONSTER).a(0.6F, 1.95F)); + public static final EntityTypes ITEM = a("item", EntityTypes.a.a(EntityItem::new, EnumCreatureType.MISC).a(0.25F, 0.25F)); + public static final EntityTypes ITEM_FRAME = a("item_frame", EntityTypes.a.a(EntityItemFrame::new, EnumCreatureType.MISC).a(0.5F, 0.5F)); + public static final EntityTypes FIREBALL = a("fireball", EntityTypes.a.a(EntityLargeFireball::new, EnumCreatureType.MISC).a(1.0F, 1.0F)); + public static final EntityTypes LEASH_KNOT = a("leash_knot", EntityTypes.a.a(EntityLeash::new, EnumCreatureType.MISC).b().a(0.5F, 0.5F)); + public static final EntityTypes LLAMA = a("llama", EntityTypes.a.a(EntityLlama::new, EnumCreatureType.CREATURE).a(0.9F, 1.87F)); + public static final EntityTypes LLAMA_SPIT = a("llama_spit", EntityTypes.a.a(EntityLlamaSpit::new, EnumCreatureType.MISC).a(0.25F, 0.25F)); + public static final EntityTypes MAGMA_CUBE = a("magma_cube", EntityTypes.a.a(EntityMagmaCube::new, EnumCreatureType.MONSTER).c().a(2.04F, 2.04F)); + public static final EntityTypes MINECART = a("minecart", EntityTypes.a.a(EntityMinecartRideable::new, EnumCreatureType.MISC).a(0.98F, 0.7F)); + public static final EntityTypes CHEST_MINECART = a("chest_minecart", EntityTypes.a.a(EntityMinecartChest::new, EnumCreatureType.MISC).a(0.98F, 0.7F)); + public static final EntityTypes COMMAND_BLOCK_MINECART = a("command_block_minecart", EntityTypes.a.a(EntityMinecartCommandBlock::new, EnumCreatureType.MISC).a(0.98F, 0.7F)); + public static final EntityTypes FURNACE_MINECART = a("furnace_minecart", EntityTypes.a.a(EntityMinecartFurnace::new, EnumCreatureType.MISC).a(0.98F, 0.7F)); + public static final EntityTypes HOPPER_MINECART = a("hopper_minecart", EntityTypes.a.a(EntityMinecartHopper::new, EnumCreatureType.MISC).a(0.98F, 0.7F)); + public static final EntityTypes SPAWNER_MINECART = a("spawner_minecart", EntityTypes.a.a(EntityMinecartMobSpawner::new, EnumCreatureType.MISC).a(0.98F, 0.7F)); + public static final EntityTypes TNT_MINECART = a("tnt_minecart", EntityTypes.a.a(EntityMinecartTNT::new, EnumCreatureType.MISC).a(0.98F, 0.7F)); + public static final EntityTypes MULE = a("mule", EntityTypes.a.a(EntityHorseMule::new, EnumCreatureType.CREATURE).a(1.3964844F, 1.6F)); + public static final EntityTypes MOOSHROOM = a("mooshroom", EntityTypes.a.a(EntityMushroomCow::new, EnumCreatureType.CREATURE).a(0.9F, 1.4F)); + public static final EntityTypes OCELOT = a("ocelot", EntityTypes.a.a(EntityOcelot::new, EnumCreatureType.CREATURE).a(0.6F, 0.7F)); + public static final EntityTypes PAINTING = a("painting", EntityTypes.a.a(EntityPainting::new, EnumCreatureType.MISC).a(0.5F, 0.5F)); + public static final EntityTypes PANDA = a("panda", EntityTypes.a.a(EntityPanda::new, EnumCreatureType.CREATURE).a(1.3F, 1.25F)); + public static final EntityTypes PARROT = a("parrot", EntityTypes.a.a(EntityParrot::new, EnumCreatureType.CREATURE).a(0.5F, 0.9F)); + public static final EntityTypes PIG = a("pig", EntityTypes.a.a(EntityPig::new, EnumCreatureType.CREATURE).a(0.9F, 0.9F)); + public static final EntityTypes PUFFERFISH = a("pufferfish", EntityTypes.a.a(EntityPufferFish::new, EnumCreatureType.WATER_CREATURE).a(0.7F, 0.7F)); + public static final EntityTypes ZOMBIE_PIGMAN = a("zombie_pigman", EntityTypes.a.a(EntityPigZombie::new, EnumCreatureType.MONSTER).c().a(0.6F, 1.95F)); + public static final EntityTypes POLAR_BEAR = a("polar_bear", EntityTypes.a.a(EntityPolarBear::new, EnumCreatureType.CREATURE).a(1.4F, 1.4F)); + public static final EntityTypes TNT = a("tnt", EntityTypes.a.a(EntityTNTPrimed::new, EnumCreatureType.MISC).c().a(0.98F, 0.98F)); + public static final EntityTypes RABBIT = a("rabbit", EntityTypes.a.a(EntityRabbit::new, EnumCreatureType.CREATURE).a(0.4F, 0.5F)); + public static final EntityTypes SALMON = a("salmon", EntityTypes.a.a(EntitySalmon::new, EnumCreatureType.WATER_CREATURE).a(0.7F, 0.4F)); + public static final EntityTypes SHEEP = a("sheep", EntityTypes.a.a(EntitySheep::new, EnumCreatureType.CREATURE).a(0.9F, 1.3F)); + public static final EntityTypes SHULKER = a("shulker", EntityTypes.a.a(EntityShulker::new, EnumCreatureType.MONSTER).c().d().a(1.0F, 1.0F)); + public static final EntityTypes SHULKER_BULLET = a("shulker_bullet", EntityTypes.a.a(EntityShulkerBullet::new, EnumCreatureType.MISC).a(0.3125F, 0.3125F)); + public static final EntityTypes SILVERFISH = a("silverfish", EntityTypes.a.a(EntitySilverfish::new, EnumCreatureType.MONSTER).a(0.4F, 0.3F)); + public static final EntityTypes SKELETON = a("skeleton", EntityTypes.a.a(EntitySkeleton::new, EnumCreatureType.MONSTER).a(0.6F, 1.99F)); + public static final EntityTypes SKELETON_HORSE = a("skeleton_horse", EntityTypes.a.a(EntityHorseSkeleton::new, EnumCreatureType.CREATURE).a(1.3964844F, 1.6F)); + public static final EntityTypes SLIME = a("slime", EntityTypes.a.a(EntitySlime::new, EnumCreatureType.MONSTER).a(2.04F, 2.04F)); + public static final EntityTypes SMALL_FIREBALL = a("small_fireball", EntityTypes.a.a(EntitySmallFireball::new, EnumCreatureType.MISC).a(0.3125F, 0.3125F)); + public static final EntityTypes SNOW_GOLEM = a("snow_golem", EntityTypes.a.a(EntitySnowman::new, EnumCreatureType.MISC).a(0.7F, 1.9F)); + public static final EntityTypes SNOWBALL = a("snowball", EntityTypes.a.a(EntitySnowball::new, EnumCreatureType.MISC).a(0.25F, 0.25F)); + public static final EntityTypes SPECTRAL_ARROW = a("spectral_arrow", EntityTypes.a.a(EntitySpectralArrow::new, EnumCreatureType.MISC).a(0.5F, 0.5F)); + public static final EntityTypes SPIDER = a("spider", EntityTypes.a.a(EntitySpider::new, EnumCreatureType.MONSTER).a(1.4F, 0.9F)); + public static final EntityTypes SQUID = a("squid", EntityTypes.a.a(EntitySquid::new, EnumCreatureType.WATER_CREATURE).a(0.8F, 0.8F)); + public static final EntityTypes STRAY = a("stray", EntityTypes.a.a(EntitySkeletonStray::new, EnumCreatureType.MONSTER).a(0.6F, 1.99F)); + public static final EntityTypes TRADER_LLAMA = a("trader_llama", EntityTypes.a.a(EntityLlamaTrader::new, EnumCreatureType.CREATURE).a(0.9F, 1.87F)); + public static final EntityTypes TROPICAL_FISH = a("tropical_fish", EntityTypes.a.a(EntityTropicalFish::new, EnumCreatureType.WATER_CREATURE).a(0.5F, 0.4F)); + public static final EntityTypes TURTLE = a("turtle", EntityTypes.a.a(EntityTurtle::new, EnumCreatureType.CREATURE).a(1.2F, 0.4F)); + public static final EntityTypes EGG = a("egg", EntityTypes.a.a(EntityEgg::new, EnumCreatureType.MISC).a(0.25F, 0.25F)); + public static final EntityTypes ENDER_PEARL = a("ender_pearl", EntityTypes.a.a(EntityEnderPearl::new, EnumCreatureType.MISC).a(0.25F, 0.25F)); + public static final EntityTypes EXPERIENCE_BOTTLE = a("experience_bottle", EntityTypes.a.a(EntityThrownExpBottle::new, EnumCreatureType.MISC).a(0.25F, 0.25F)); + public static final EntityTypes POTION = a("potion", EntityTypes.a.a(EntityPotion::new, EnumCreatureType.MISC).a(0.25F, 0.25F)); + public static final EntityTypes TRIDENT = a("trident", EntityTypes.a.a(EntityThrownTrident::new, EnumCreatureType.MISC).a(0.5F, 0.5F)); + public static final EntityTypes VEX = a("vex", EntityTypes.a.a(EntityVex::new, EnumCreatureType.MONSTER).c().a(0.4F, 0.8F)); + public static final EntityTypes VILLAGER = a("villager", EntityTypes.a.a(EntityVillager::new, EnumCreatureType.MISC).a(0.6F, 1.95F)); + public static final EntityTypes IRON_GOLEM = a("iron_golem", EntityTypes.a.a(EntityIronGolem::new, EnumCreatureType.MISC).a(1.4F, 2.7F)); + public static final EntityTypes VINDICATOR = a("vindicator", EntityTypes.a.a(EntityVindicator::new, EnumCreatureType.MONSTER).a(0.6F, 1.95F)); + public static final EntityTypes PILLAGER = a("pillager", EntityTypes.a.a(EntityPillager::new, EnumCreatureType.MONSTER).d().a(0.6F, 1.95F)); + public static final EntityTypes WANDERING_TRADER = a("wandering_trader", EntityTypes.a.a(EntityVillagerTrader::new, EnumCreatureType.CREATURE).a(0.6F, 1.95F)); + public static final EntityTypes WITCH = a("witch", EntityTypes.a.a(EntityWitch::new, EnumCreatureType.MONSTER).a(0.6F, 1.95F)); + public static final EntityTypes WITHER = a("wither", EntityTypes.a.a(EntityWither::new, EnumCreatureType.MONSTER).c().a(0.9F, 3.5F)); + public static final EntityTypes WITHER_SKELETON = a("wither_skeleton", EntityTypes.a.a(EntitySkeletonWither::new, EnumCreatureType.MONSTER).c().a(0.7F, 2.4F)); + public static final EntityTypes WITHER_SKULL = a("wither_skull", EntityTypes.a.a(EntityWitherSkull::new, EnumCreatureType.MISC).a(0.3125F, 0.3125F)); + public static final EntityTypes WOLF = a("wolf", EntityTypes.a.a(EntityWolf::new, EnumCreatureType.CREATURE).a(0.6F, 0.85F)); + public static final EntityTypes ZOMBIE = a("zombie", EntityTypes.a.a(EntityZombie::new, EnumCreatureType.MONSTER).a(0.6F, 1.95F)); + public static final EntityTypes ZOMBIE_HORSE = a("zombie_horse", EntityTypes.a.a(EntityHorseZombie::new, EnumCreatureType.CREATURE).a(1.3964844F, 1.6F)); + public static final EntityTypes ZOMBIE_VILLAGER = a("zombie_villager", EntityTypes.a.a(EntityZombieVillager::new, EnumCreatureType.MONSTER).a(0.6F, 1.95F)); + public static final EntityTypes PHANTOM = a("phantom", EntityTypes.a.a(EntityPhantom::new, EnumCreatureType.MONSTER).a(0.9F, 0.5F)); + public static final EntityTypes RAVAGER = a("ravager", EntityTypes.a.a(EntityRavager::new, EnumCreatureType.MONSTER).a(1.95F, 2.2F)); + public static final EntityTypes LIGHTNING_BOLT = a("lightning_bolt", EntityTypes.a.a(EnumCreatureType.MISC).b().a(0.0F, 0.0F)); + public static final EntityTypes PLAYER = a("player", EntityTypes.a.a(EnumCreatureType.MISC).b().a().a(0.6F, 1.8F)); + public static final EntityTypes FISHING_BOBBER = a("fishing_bobber", EntityTypes.a.a(EnumCreatureType.MISC).b().a().a(0.25F, 0.25F)); + private final EntityTypes.b aZ; + private final EnumCreatureType ba; + private final boolean bb; + private final boolean bc; + private final boolean bd; + private final boolean be; @Nullable - private String aW; + private String bf; @Nullable - private IChatBaseComponent aX; + private IChatBaseComponent bg; @Nullable - private final Type aY; + private MinecraftKey bh; + private final EntitySize bi; - public static EntityTypes a(String s, EntityTypes.a entitytypes_a) { - EntityTypes entitytypes = entitytypes_a.a(s); - - // Paper start - if (clsToKeyMap == null ) clsToKeyMap = HashObjObjMaps.newUpdatableMap(); // Akarin - if (clsToTypeMap == null ) clsToTypeMap = HashObjObjMaps.newUpdatableMap(); // Akarin - - MinecraftKey key = new MinecraftKey(s); - Class entityClass = entitytypes_a.getEntityClass(); - IRegistry.ENTITY_TYPE.a(new MinecraftKey(s), entitytypes); // CraftBukkit - decompile error - clsToKeyMap.put(entityClass, key); - clsToTypeMap.put(entityClass, org.bukkit.entity.EntityType.fromName(s)); - return entitytypes; + private static EntityTypes a(String s, EntityTypes.a entitytypes_a) { // CraftBukkit - decompile error + return (EntityTypes) IRegistry.a((IRegistry) IRegistry.ENTITY_TYPE, s, (Object) entitytypes_a.a(s)); } - public static Map, MinecraftKey> clsToKeyMap; - public static Map, org.bukkit.entity.EntityType> clsToTypeMap; - // Paper end - @Nullable public static MinecraftKey getName(EntityTypes entitytypes) { return IRegistry.ENTITY_TYPE.getKey(entitytypes); } - @Nullable - public static EntityTypes a(String s) { - return (EntityTypes) IRegistry.ENTITY_TYPE.get(MinecraftKey.a(s)); + public static Optional> a(String s) { + return IRegistry.ENTITY_TYPE.getOptional(MinecraftKey.a(s)); } - public EntityTypes(Class oclass, Function function, boolean flag, boolean flag1, @Nullable Type type) { - this.aS = oclass; - this.aT = function; - this.aU = flag; - this.aV = flag1; - this.aY = type; + public EntityTypes(EntityTypes.b entitytypes_b, EnumCreatureType enumcreaturetype, boolean flag, boolean flag1, boolean flag2, boolean flag3, EntitySize entitysize) { + this.aZ = entitytypes_b; + this.ba = enumcreaturetype; + this.be = flag3; + this.bb = flag; + this.bc = flag1; + this.bd = flag2; + this.bi = entitysize; } @Nullable - public Entity a(World world, @Nullable ItemStack itemstack, @Nullable EntityHuman entityhuman, BlockPosition blockposition, boolean flag, boolean flag1) { - return this.a(world, itemstack == null ? null : itemstack.getTag(), itemstack != null && itemstack.hasName() ? itemstack.getName() : null, entityhuman, blockposition, flag, flag1); + public Entity spawnCreature(World world, @Nullable ItemStack itemstack, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumMobSpawn enummobspawn, boolean flag, boolean flag1) { + return this.spawnCreature(world, itemstack == null ? null : itemstack.getTag(), itemstack != null && itemstack.hasName() ? itemstack.getName() : null, entityhuman, blockposition, enummobspawn, flag, flag1); } @Nullable - public T a(World world, @Nullable NBTTagCompound nbttagcompound, @Nullable IChatBaseComponent ichatbasecomponent, @Nullable EntityHuman entityhuman, BlockPosition blockposition, boolean flag, boolean flag1) { + public T spawnCreature(World world, @Nullable NBTTagCompound nbttagcompound, @Nullable IChatBaseComponent ichatbasecomponent, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumMobSpawn enummobspawn, boolean flag, boolean flag1) { // CraftBukkit start - return spawnCreature(world, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, flag, flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); + return this.spawnCreature(world, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, enummobspawn, flag, flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); } @Nullable - public T spawnCreature(World world, @Nullable NBTTagCompound nbttagcompound, @Nullable IChatBaseComponent ichatbasecomponent, @Nullable EntityHuman entityhuman, BlockPosition blockposition, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { - T t0 = this.b(world, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, flag, flag1); + public T spawnCreature(World world, @Nullable NBTTagCompound nbttagcompound, @Nullable IChatBaseComponent ichatbasecomponent, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumMobSpawn enummobspawn, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { + T t0 = this.b(world, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, enummobspawn, flag, flag1); return world.addEntity(t0, spawnReason) ? t0 : null; // Don't return an entity when CreatureSpawnEvent is canceled // CraftBukkit end } @Nullable - public T b(World world, @Nullable NBTTagCompound nbttagcompound, @Nullable IChatBaseComponent ichatbasecomponent, @Nullable EntityHuman entityhuman, BlockPosition blockposition, boolean flag, boolean flag1) { + public T b(World world, @Nullable NBTTagCompound nbttagcompound, @Nullable IChatBaseComponent ichatbasecomponent, @Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumMobSpawn enummobspawn, boolean flag, boolean flag1) { T t0 = this.a(world); if (t0 == null) { @@ -197,10 +192,10 @@ public class EntityTypes { if (t0 instanceof EntityInsentient) { EntityInsentient entityinsentient = (EntityInsentient) t0; - entityinsentient.aS = entityinsentient.yaw; - entityinsentient.aQ = entityinsentient.yaw; - entityinsentient.prepare(world.getDamageScaler(new BlockPosition(entityinsentient)), (GroupDataEntity) null, nbttagcompound); - entityinsentient.A(); + entityinsentient.aM = entityinsentient.yaw; + entityinsentient.aK = entityinsentient.yaw; + entityinsentient.prepare(world, world.getDamageScaler(new BlockPosition(entityinsentient)), enummobspawn, (GroupDataEntity) null, nbttagcompound); + entityinsentient.B(); } if (ichatbasecomponent != null && t0 instanceof EntityLiving) { @@ -219,7 +214,7 @@ public class EntityTypes { axisalignedbb1 = axisalignedbb1.b(0.0D, -1.0D, 0.0D); } - Stream stream = iworldreader.b((Entity) null, axisalignedbb1); + Stream stream = iworldreader.c((Entity) null, axisalignedbb1, Collections.emptySet()); return 1.0D + VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb, stream, flag ? -2.0D : -1.0D); } @@ -229,7 +224,7 @@ public class EntityTypes { MinecraftServer minecraftserver = world.getMinecraftServer(); if (minecraftserver != null && entity != null) { - if (world.isClientSide || !entity.bM() || entityhuman != null && minecraftserver.getPlayerList().isOp(entityhuman.getProfile())) { + if (world.isClientSide || !entity.bT() || entityhuman != null && minecraftserver.getPlayerList().isOp(entityhuman.getProfile())) { NBTTagCompound nbttagcompound1 = entity.save(new NBTTagCompound()); UUID uuid = entity.getUniqueID(); @@ -243,84 +238,168 @@ public class EntityTypes { public boolean isPersistable() { return a(); } // Paper - OBFHELPER public boolean a() { - return this.aU; + return this.bb; } public boolean b() { - return this.aV; + return this.bc; } - public Class entityClass() { return this.c(); } // Akarin - public Class c() { - return this.aS; + public boolean c() { + return this.bd; } - public String d() { - if (this.aW == null) { - this.aW = SystemUtils.a("entity", IRegistry.ENTITY_TYPE.getKey(this)); + public boolean d() { + return this.be; + } + + public EnumCreatureType getEnumCreatureType() { return this.e(); } // Paper - OBFHELPER + public EnumCreatureType e() { + return this.ba; + } + + public String f() { + if (this.bf == null) { + this.bf = SystemUtils.a("entity", IRegistry.ENTITY_TYPE.getKey(this)); } - return this.aW; + return this.bf; } - public IChatBaseComponent e() { - if (this.aX == null) { - this.aX = new ChatMessage(this.d(), new Object[0]); + public IChatBaseComponent g() { + if (this.bg == null) { + this.bg = new ChatMessage(this.f(), new Object[0]); } - return this.aX; + return this.bg; } - @Nullable public T create(World world) { return a(world); } // Paper - OBFHELPER - @Nullable - public T a(World world) { - return this.aT.apply(world); // CraftBukkit - decompile error + public MinecraftKey h() { + if (this.bh == null) { + MinecraftKey minecraftkey = IRegistry.ENTITY_TYPE.getKey(this); + + this.bh = new MinecraftKey(minecraftkey.getNamespace(), "entities/" + minecraftkey.getKey()); + } + + return this.bh; } - @Nullable - public static Entity a(World world, MinecraftKey minecraftkey) { - return a(world, (EntityTypes) IRegistry.ENTITY_TYPE.get(minecraftkey)); + public float i() { + return this.bi.width; } - @Nullable - public static Entity a(NBTTagCompound nbttagcompound, World world) { - MinecraftKey minecraftkey = new MinecraftKey(nbttagcompound.getString("id")); - Entity entity = a(world, minecraftkey); + public float j() { + return this.bi.height; + } - if (entity == null) { - EntityTypes.aR.warn("Skipping Entity with id {}", minecraftkey); - } else { + public T create(World world) { return this.a(world); } // Paper - OBFHELPER + @Nullable public T a(World world) { // Paper - OBFHELPER + return this.aZ.create(this, world); + } + + public static Optional a(NBTTagCompound nbttagcompound, World world) { + return SystemUtils.a(a(nbttagcompound).map((entitytypes) -> { + return entitytypes.a(world); + }), (entity) -> { entity.f(nbttagcompound); - } + }, () -> { + EntityTypes.LOGGER.warn("Skipping Entity with id {}", nbttagcompound.getString("id")); + }); + } - return entity; + public AxisAlignedBB a(double d0, double d1, double d2) { + float f = this.i() / 2.0F; + + return new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) this.j(), d2 + (double) f); + } + + public EntitySize k() { + return this.bi; + } + + public static Optional> a(NBTTagCompound nbttagcompound) { + return IRegistry.ENTITY_TYPE.getOptional(new MinecraftKey(nbttagcompound.getString("id"))); } @Nullable - private static Entity a(World world, @Nullable EntityTypes entitytypes) { - return entitytypes == null ? null : entitytypes.a(world); + public static Entity a(NBTTagCompound nbttagcompound, World world, Function function) { + return (Entity) b(nbttagcompound, world).map(function).map((entity) -> { + if (nbttagcompound.hasKeyOfType("Passengers", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("Passengers", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + Entity entity1 = a(nbttaglist.getCompound(i), world, function); + + if (entity1 != null) { + entity1.a(entity, true); + } + } + } + + return entity; + }).orElse(null); // CraftBukkit - decompile error + } + + private static Optional b(NBTTagCompound nbttagcompound, World world) { + try { + return a(nbttagcompound, world); + } catch (RuntimeException runtimeexception) { + EntityTypes.LOGGER.warn("Exception loading entity: ", runtimeexception); + return Optional.empty(); + } + } + + public int getChunkRange() { + return this == EntityTypes.PLAYER ? 32 : (this == EntityTypes.END_CRYSTAL ? 16 : (this != EntityTypes.ENDER_DRAGON && this != EntityTypes.TNT && this != EntityTypes.FALLING_BLOCK && this != EntityTypes.ITEM_FRAME && this != EntityTypes.LEASH_KNOT && this != EntityTypes.PAINTING && this != EntityTypes.ARMOR_STAND && this != EntityTypes.EXPERIENCE_ORB && this != EntityTypes.AREA_EFFECT_CLOUD && this != EntityTypes.EVOKER_FANGS ? (this != EntityTypes.FISHING_BOBBER && this != EntityTypes.ARROW && this != EntityTypes.SPECTRAL_ARROW && this != EntityTypes.TRIDENT && this != EntityTypes.SMALL_FIREBALL && this != EntityTypes.DRAGON_FIREBALL && this != EntityTypes.FIREBALL && this != EntityTypes.WITHER_SKULL && this != EntityTypes.SNOWBALL && this != EntityTypes.LLAMA_SPIT && this != EntityTypes.ENDER_PEARL && this != EntityTypes.EYE_OF_ENDER && this != EntityTypes.EGG && this != EntityTypes.POTION && this != EntityTypes.EXPERIENCE_BOTTLE && this != EntityTypes.FIREWORK_ROCKET && this != EntityTypes.ITEM ? 5 : 4) : 10)); + } + + public int getUpdateInterval() { + // CraftBukkit - SPIGOT-3729: track area effect clouds + return this != EntityTypes.PLAYER && this != EntityTypes.EVOKER_FANGS ? (this == EntityTypes.EYE_OF_ENDER ? 4 : (this == EntityTypes.FISHING_BOBBER ? 5 : (this != EntityTypes.SMALL_FIREBALL && this != EntityTypes.DRAGON_FIREBALL && this != EntityTypes.FIREBALL && this != EntityTypes.WITHER_SKULL && this != EntityTypes.SNOWBALL && this != EntityTypes.LLAMA_SPIT && this != EntityTypes.ENDER_PEARL && this != EntityTypes.EGG && this != EntityTypes.POTION && this != EntityTypes.EXPERIENCE_BOTTLE && this != EntityTypes.FIREWORK_ROCKET && this != EntityTypes.TNT ? (this != EntityTypes.ARROW && this != EntityTypes.SPECTRAL_ARROW && this != EntityTypes.TRIDENT && this != EntityTypes.ITEM && this != EntityTypes.FALLING_BLOCK && this != EntityTypes.EXPERIENCE_ORB ? (this != EntityTypes.ITEM_FRAME && this != EntityTypes.LEASH_KNOT && this != EntityTypes.PAINTING && this != EntityTypes.END_CRYSTAL ? 3 : Integer.MAX_VALUE) : 20) : 10))) : 2; + } + + public boolean isDeltaTracking() { + return this != EntityTypes.PLAYER && this != EntityTypes.LLAMA_SPIT && this != EntityTypes.WITHER && this != EntityTypes.BAT && this != EntityTypes.ITEM_FRAME && this != EntityTypes.LEASH_KNOT && this != EntityTypes.PAINTING && this != EntityTypes.END_CRYSTAL && this != EntityTypes.EVOKER_FANGS; + } + + public boolean a(Tag> tag) { + return tag.isTagged(this); + } + + public interface b { + + T create(EntityTypes entitytypes, World world); } public static class a { - private final Class a; public Class getEntityClass() { return a; } // Paper - OBFHELPER - private final Function b; + private final EntityTypes.b a; + private final EnumCreatureType b; private boolean c = true; private boolean d = true; + private boolean e; + private boolean f; + private EntitySize g = EntitySize.b(0.6F, 1.8F); - private a(Class oclass, Function function) { - this.a = oclass; - this.b = function; + private a(EntityTypes.b entitytypes_b, EnumCreatureType enumcreaturetype) { + this.a = entitytypes_b; + this.b = enumcreaturetype; + this.f = enumcreaturetype == EnumCreatureType.CREATURE || enumcreaturetype == EnumCreatureType.MISC; } - public static EntityTypes.a a(Class oclass, Function function) { - return new EntityTypes.a<>(oclass, function); + public static EntityTypes.a a(EntityTypes.b entitytypes_b, EnumCreatureType enumcreaturetype) { // CraftBukkit - decompile error + return new EntityTypes.a<>(entitytypes_b, enumcreaturetype); } - public static EntityTypes.a a(Class oclass) { - return new EntityTypes.a<>(oclass, (world) -> { + public static EntityTypes.a a(EnumCreatureType enumcreaturetype) { + return new EntityTypes.a<>((entitytypes, world) -> { return null; - }); + }, enumcreaturetype); + } + + public EntityTypes.a a(float f, float f1) { + this.g = EntitySize.b(f, f1); + return this; } public EntityTypes.a a() { @@ -333,22 +412,30 @@ public class EntityTypes { return this; } - public EntityTypes a(String s) { - Type type = null; + public EntityTypes.a c() { + this.e = true; + return this; + } + public EntityTypes.a d() { + this.f = true; + return this; + } + + public EntityTypes a(String s) { if (this.c) { try { - type = DataConverterRegistry.a().getSchema(DataFixUtils.makeKey(1631)).getChoiceType(DataConverterTypes.n, s); + DataConverterRegistry.a().getSchema(DataFixUtils.makeKey(SharedConstants.a().getWorldVersion())).getChoiceType(DataConverterTypes.o, s); } catch (IllegalStateException illegalstateexception) { if (SharedConstants.b) { throw illegalstateexception; } - EntityTypes.aR.warn("No data fixer registered for entity {}", s); + EntityTypes.LOGGER.warn("No data fixer registered for entity {}", s); } } - return new EntityTypes<>(this.a, this.b, this.c, this.d, type); + return new EntityTypes<>(this.a, this.b, this.c, this.d, this.e, this.f, this.g); } } diff --git a/src/main/java/net/minecraft/server/EntityVex.java b/src/main/java/net/minecraft/server/EntityVex.java index 589b13f4e..51c05376d 100644 --- a/src/main/java/net/minecraft/server/EntityVex.java +++ b/src/main/java/net/minecraft/server/EntityVex.java @@ -1,69 +1,74 @@ package net.minecraft.server; +import java.util.EnumSet; import javax.annotation.Nullable; import org.bukkit.event.entity.EntityTargetEvent; public class EntityVex extends EntityMonster { - protected static final DataWatcherObject a = DataWatcher.a(EntityVex.class, DataWatcherRegistry.a); - private EntityInsentient b; + protected static final DataWatcherObject b = DataWatcher.a(EntityVex.class, DataWatcherRegistry.a); + private EntityInsentient c; @Nullable - private BlockPosition c; - private boolean bC; - private int bD; + private BlockPosition d; + private boolean bz; + private int bA; - public EntityVex(World world) { - super(EntityTypes.VEX, world); - this.fireProof = true; + public EntityVex(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.moveController = new EntityVex.c(this); - this.setSize(0.4F, 0.8F); - this.b_ = 3; + this.f = 3; } - public void move(EnumMoveType enummovetype, double d0, double d1, double d2) { - super.move(enummovetype, d0, d1, d2); + @Override + public void move(EnumMoveType enummovetype, Vec3D vec3d) { + super.move(enummovetype, vec3d); this.checkBlockCollisions(); } + @Override public void tick() { this.noclip = true; super.tick(); this.noclip = false; this.setNoGravity(true); - if (this.bC && --this.bD <= 0) { - this.bD = 20; + if (this.bz && --this.bA <= 0) { + this.bA = 20; this.damageEntity(DamageSource.STARVE, 1.0F); } } - protected void n() { - super.n(); + @Override + protected void initPathfinder() { + super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); this.goalSelector.a(4, new EntityVex.a()); this.goalSelector.a(8, new EntityVex.d()); this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[] { EntityVex.class})); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(2, new EntityVex.b(this)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(14.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(14.0D); this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(4.0D); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityVex.a, (byte) 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityVex.b, (byte) 0); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKey("BoundX")) { - this.c = new BlockPosition(nbttagcompound.getInt("BoundX"), nbttagcompound.getInt("BoundY"), nbttagcompound.getInt("BoundZ")); + this.d = new BlockPosition(nbttagcompound.getInt("BoundX"), nbttagcompound.getInt("BoundY"), nbttagcompound.getInt("BoundZ")); } if (nbttagcompound.hasKey("LifeTicks")) { @@ -72,42 +77,43 @@ public class EntityVex extends EntityMonster { } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - if (this.c != null) { - nbttagcompound.setInt("BoundX", this.c.getX()); - nbttagcompound.setInt("BoundY", this.c.getY()); - nbttagcompound.setInt("BoundZ", this.c.getZ()); + if (this.d != null) { + nbttagcompound.setInt("BoundX", this.d.getX()); + nbttagcompound.setInt("BoundY", this.d.getY()); + nbttagcompound.setInt("BoundZ", this.d.getZ()); } - if (this.bC) { - nbttagcompound.setInt("LifeTicks", this.bD); + if (this.bz) { + nbttagcompound.setInt("LifeTicks", this.bA); } } public EntityInsentient getOwner() { return l(); } // Paper - OBFHELPER public EntityInsentient l() { - return this.b; - } - - @Nullable - public BlockPosition dz() { return this.c; } + @Nullable + public BlockPosition dV() { + return this.d; + } + public void g(@Nullable BlockPosition blockposition) { - this.c = blockposition; + this.d = blockposition; } private boolean b(int i) { - byte b0 = (Byte) this.datawatcher.get(EntityVex.a); + byte b0 = (Byte) this.datawatcher.get(EntityVex.b); return (b0 & i) != 0; } private void a(int i, boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntityVex.a); + byte b0 = (Byte) this.datawatcher.get(EntityVex.b); int j; if (flag) { @@ -116,55 +122,56 @@ public class EntityVex extends EntityMonster { j = b0 & ~i; } - this.datawatcher.set(EntityVex.a, (byte) (j & 255)); + this.datawatcher.set(EntityVex.b, (byte) (j & 255)); } - public boolean dA() { + public boolean isCharging() { return this.b(1); } - public void a(boolean flag) { + public void setCharging(boolean flag) { this.a(1, flag); } public void setOwner(EntityInsentient entityinsentient) { a(entityinsentient); } // Paper - OBFHELPER public void a(EntityInsentient entityinsentient) { - this.b = entityinsentient; + this.c = entityinsentient; } public void a(int i) { - this.bC = true; - this.bD = i; + this.bz = true; + this.bA = i; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_VEX_AMBIENT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_VEX_DEATH; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_VEX_HURT; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aG; - } - - public float az() { + @Override + public float aF() { return 1.0F; } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { this.a(difficultydamagescaler); this.b(difficultydamagescaler); - return super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } + @Override protected void a(DifficultyDamageScaler difficultydamagescaler) { this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.IRON_SWORD)); this.a(EnumItemSlot.MAINHAND, 0.0F); @@ -172,16 +179,20 @@ public class EntityVex extends EntityMonster { class b extends PathfinderGoalTarget { + private final PathfinderTargetCondition b = (new PathfinderTargetCondition()).c().e(); + public b(EntityCreature entitycreature) { super(entitycreature, false); } + @Override public boolean a() { - return EntityVex.this.b != null && EntityVex.this.b.getGoalTarget() != null && this.a(EntityVex.this.b.getGoalTarget(), false); + return EntityVex.this.c != null && EntityVex.this.c.getGoalTarget() != null && this.a(EntityVex.this.c.getGoalTarget(), this.b); } + @Override public void c() { - EntityVex.this.setGoalTarget(EntityVex.this.b.getGoalTarget(), EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET, true); // CraftBukkit + EntityVex.this.setGoalTarget(EntityVex.this.c.getGoalTarget(), EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET, true); // CraftBukkit super.c(); } } @@ -189,26 +200,29 @@ public class EntityVex extends EntityMonster { class d extends PathfinderGoal { public d() { - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); } + @Override public boolean a() { return !EntityVex.this.getControllerMove().b() && EntityVex.this.random.nextInt(7) == 0; } + @Override public boolean b() { return false; } + @Override public void e() { - BlockPosition blockposition = EntityVex.this.dz(); + BlockPosition blockposition = EntityVex.this.dV(); if (blockposition == null) { blockposition = new BlockPosition(EntityVex.this); } for (int i = 0; i < 3; ++i) { - BlockPosition blockposition1 = blockposition.a(EntityVex.this.random.nextInt(15) - 7, EntityVex.this.random.nextInt(11) - 5, EntityVex.this.random.nextInt(15) - 7); + BlockPosition blockposition1 = blockposition.b(EntityVex.this.random.nextInt(15) - 7, EntityVex.this.random.nextInt(11) - 5, EntityVex.this.random.nextInt(15) - 7); if (EntityVex.this.world.isEmpty(blockposition1)) { EntityVex.this.moveController.a((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.5D, (double) blockposition1.getZ() + 0.5D, 0.25D); @@ -225,41 +239,46 @@ public class EntityVex extends EntityMonster { class a extends PathfinderGoal { public a() { - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); } + @Override public boolean a() { return EntityVex.this.getGoalTarget() != null && !EntityVex.this.getControllerMove().b() && EntityVex.this.random.nextInt(7) == 0 ? EntityVex.this.h((Entity) EntityVex.this.getGoalTarget()) > 4.0D : false; } + @Override public boolean b() { - return EntityVex.this.getControllerMove().b() && EntityVex.this.dA() && EntityVex.this.getGoalTarget() != null && EntityVex.this.getGoalTarget().isAlive(); + return EntityVex.this.getControllerMove().b() && EntityVex.this.isCharging() && EntityVex.this.getGoalTarget() != null && EntityVex.this.getGoalTarget().isAlive(); } + @Override public void c() { EntityLiving entityliving = EntityVex.this.getGoalTarget(); - Vec3D vec3d = entityliving.i(1.0F); + Vec3D vec3d = entityliving.j(1.0F); EntityVex.this.moveController.a(vec3d.x, vec3d.y, vec3d.z, 1.0D); - EntityVex.this.a(true); + EntityVex.this.setCharging(true); EntityVex.this.a(SoundEffects.ENTITY_VEX_CHARGE, 1.0F, 1.0F); } + @Override public void d() { - EntityVex.this.a(false); + EntityVex.this.setCharging(false); } + @Override public void e() { EntityLiving entityliving = EntityVex.this.getGoalTarget(); if (EntityVex.this.getBoundingBox().c(entityliving.getBoundingBox())) { - EntityVex.this.B(entityliving); - EntityVex.this.a(false); + EntityVex.this.C(entityliving); + EntityVex.this.setCharging(false); } else { double d0 = EntityVex.this.h((Entity) entityliving); if (d0 < 9.0D) { - Vec3D vec3d = entityliving.i(1.0F); + Vec3D vec3d = entityliving.j(1.0F); EntityVex.this.moveController.a(vec3d.x, vec3d.y, vec3d.z, 1.0D); } @@ -274,32 +293,28 @@ public class EntityVex extends EntityMonster { super(entityvex); } + @Override public void a() { if (this.h == ControllerMove.Operation.MOVE_TO) { - double d0 = this.b - EntityVex.this.locX; - double d1 = this.c - EntityVex.this.locY; - double d2 = this.d - EntityVex.this.locZ; - double d3 = d0 * d0 + d1 * d1 + d2 * d2; + Vec3D vec3d = new Vec3D(this.b - EntityVex.this.locX, this.c - EntityVex.this.locY, this.d - EntityVex.this.locZ); + double d0 = vec3d.f(); - d3 = (double) MathHelper.sqrt(d3); - if (d3 < EntityVex.this.getBoundingBox().a()) { + if (d0 < EntityVex.this.getBoundingBox().a()) { this.h = ControllerMove.Operation.WAIT; - EntityVex.this.motX *= 0.5D; - EntityVex.this.motY *= 0.5D; - EntityVex.this.motZ *= 0.5D; + EntityVex.this.setMot(EntityVex.this.getMot().a(0.5D)); } else { - EntityVex.this.motX += d0 / d3 * 0.05D * this.e; - EntityVex.this.motY += d1 / d3 * 0.05D * this.e; - EntityVex.this.motZ += d2 / d3 * 0.05D * this.e; + EntityVex.this.setMot(EntityVex.this.getMot().e(vec3d.a(this.e * 0.05D / d0))); if (EntityVex.this.getGoalTarget() == null) { - EntityVex.this.yaw = -((float) MathHelper.c(EntityVex.this.motX, EntityVex.this.motZ)) * 57.295776F; - EntityVex.this.aQ = EntityVex.this.yaw; - } else { - double d4 = EntityVex.this.getGoalTarget().locX - EntityVex.this.locX; - double d5 = EntityVex.this.getGoalTarget().locZ - EntityVex.this.locZ; + Vec3D vec3d1 = EntityVex.this.getMot(); - EntityVex.this.yaw = -((float) MathHelper.c(d4, d5)) * 57.295776F; - EntityVex.this.aQ = EntityVex.this.yaw; + EntityVex.this.yaw = -((float) MathHelper.d(vec3d1.x, vec3d1.z)) * 57.295776F; + EntityVex.this.aK = EntityVex.this.yaw; + } else { + double d1 = EntityVex.this.getGoalTarget().locX - EntityVex.this.locX; + double d2 = EntityVex.this.getGoalTarget().locZ - EntityVex.this.locZ; + + EntityVex.this.yaw = -((float) MathHelper.d(d1, d2)) * 57.295776F; + EntityVex.this.aK = EntityVex.this.yaw; } } diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java index 40b3ffd8c..7f747fac9 100644 --- a/src/main/java/net/minecraft/server/EntityVillager.java +++ b/src/main/java/net/minecraft/server/EntityVillager.java @@ -1,11 +1,21 @@ package net.minecraft.server; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.DynamicOps; +import com.mojang.datafixers.util.Pair; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import java.util.Iterator; -import java.util.Locale; -import java.util.Random; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.Map.Entry; +import java.util.function.BiPredicate; +import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; // CraftBukkit start import org.bukkit.Bukkit; import org.bukkit.craftbukkit.entity.CraftVillager; @@ -17,160 +27,170 @@ import org.bukkit.event.entity.VillagerAcquireTradeEvent; import org.bukkit.event.entity.VillagerReplenishTradeEvent; // CraftBukkit end -public class EntityVillager extends EntityAgeable implements NPC, IMerchant { +public class EntityVillager extends EntityVillagerAbstract implements ReputationHandler, VillagerDataHolder { - private static final Logger bC = LogManager.getLogger(); - private static final DataWatcherObject bD = DataWatcher.a(EntityVillager.class, DataWatcherRegistry.b); - private int profession; + private static final DataWatcherObject bC = DataWatcher.a(EntityVillager.class, DataWatcherRegistry.q); + public static final Map bA = ImmutableMap.of(Items.BREAD, 4, Items.POTATO, 1, Items.CARROT, 1, Items.BEETROOT, 1); + private static final Set bD = ImmutableSet.of(Items.BREAD, Items.POTATO, Items.CARROT, Items.WHEAT, Items.WHEAT_SEEDS, Items.BEETROOT, new Item[]{Items.BEETROOT_SEEDS}); + private int bE; private boolean bF; - private boolean bG; - private Village village; @Nullable - private EntityHuman tradingPlayer; - @Nullable - public MerchantRecipeList trades; - private int bK; - private boolean bL; - private boolean bM; - public int riches; - private String bO; - public int careerId; - public int careerLevel; - private boolean bR; - private boolean bS; - public final InventorySubcontainer inventory; - private static final EntityVillager.IMerchantRecipeOption[][][][] bU = new EntityVillager.IMerchantRecipeOption[][][][] { { { { new EntityVillager.MerchantRecipeOptionBuy(Items.WHEAT, new EntityVillager.MerchantOptionRandomRange(18, 22)), new EntityVillager.MerchantRecipeOptionBuy(Items.POTATO, new EntityVillager.MerchantOptionRandomRange(15, 19)), new EntityVillager.MerchantRecipeOptionBuy(Items.CARROT, new EntityVillager.MerchantOptionRandomRange(15, 19)), new EntityVillager.MerchantRecipeOptionSell(Items.BREAD, new EntityVillager.MerchantOptionRandomRange(-4, -2))}, { new EntityVillager.MerchantRecipeOptionBuy(Blocks.PUMPKIN, new EntityVillager.MerchantOptionRandomRange(8, 13)), new EntityVillager.MerchantRecipeOptionSell(Items.PUMPKIN_PIE, new EntityVillager.MerchantOptionRandomRange(-3, -2))}, { new EntityVillager.MerchantRecipeOptionBuy(Blocks.MELON, new EntityVillager.MerchantOptionRandomRange(7, 12)), new EntityVillager.MerchantRecipeOptionSell(Items.APPLE, new EntityVillager.MerchantOptionRandomRange(-7, -5))}, { new EntityVillager.MerchantRecipeOptionSell(Items.COOKIE, new EntityVillager.MerchantOptionRandomRange(-10, -6)), new EntityVillager.MerchantRecipeOptionSell(Blocks.CAKE, new EntityVillager.MerchantOptionRandomRange(1, 1))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.STRING, new EntityVillager.MerchantOptionRandomRange(15, 20)), new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionProcess(Items.COD, new EntityVillager.MerchantOptionRandomRange(6, 6), Items.COOKED_COD, new EntityVillager.MerchantOptionRandomRange(6, 6)), new EntityVillager.MerchantRecipeOptionProcess(Items.SALMON, new EntityVillager.MerchantOptionRandomRange(6, 6), Items.COOKED_SALMON, new EntityVillager.MerchantOptionRandomRange(6, 6))}, { new EntityVillager.MerchantRecipeOptionEnchant(Items.FISHING_ROD, new EntityVillager.MerchantOptionRandomRange(7, 8))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Blocks.WHITE_WOOL, new EntityVillager.MerchantOptionRandomRange(16, 22)), new EntityVillager.MerchantRecipeOptionSell(Items.SHEARS, new EntityVillager.MerchantOptionRandomRange(3, 4))}, { new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.WHITE_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.ORANGE_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.MAGENTA_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.LIGHT_BLUE_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.YELLOW_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.LIME_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.PINK_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.GRAY_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.LIGHT_GRAY_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.CYAN_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.PURPLE_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.BLUE_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.BROWN_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.GREEN_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.RED_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Blocks.BLACK_WOOL), new EntityVillager.MerchantOptionRandomRange(1, 2))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.STRING, new EntityVillager.MerchantOptionRandomRange(15, 20)), new EntityVillager.MerchantRecipeOptionSell(Items.ARROW, new EntityVillager.MerchantOptionRandomRange(-12, -8))}, { new EntityVillager.MerchantRecipeOptionSell(Items.BOW, new EntityVillager.MerchantOptionRandomRange(2, 3)), new EntityVillager.MerchantRecipeOptionProcess(Blocks.GRAVEL, new EntityVillager.MerchantOptionRandomRange(10, 10), Items.FLINT, new EntityVillager.MerchantOptionRandomRange(6, 10))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.PAPER, new EntityVillager.MerchantOptionRandomRange(24, 36)), new EntityVillager.MerchantRecipeOptionBook()}, { new EntityVillager.MerchantRecipeOptionBuy(Items.BOOK, new EntityVillager.MerchantOptionRandomRange(8, 10)), new EntityVillager.MerchantRecipeOptionSell(Items.COMPASS, new EntityVillager.MerchantOptionRandomRange(10, 12)), new EntityVillager.MerchantRecipeOptionSell(Blocks.BOOKSHELF, new EntityVillager.MerchantOptionRandomRange(3, 4))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.WRITTEN_BOOK, new EntityVillager.MerchantOptionRandomRange(2, 2)), new EntityVillager.MerchantRecipeOptionSell(Items.CLOCK, new EntityVillager.MerchantOptionRandomRange(10, 12)), new EntityVillager.MerchantRecipeOptionSell(Blocks.GLASS, new EntityVillager.MerchantOptionRandomRange(-5, -3))}, { new EntityVillager.MerchantRecipeOptionBook()}, { new EntityVillager.MerchantRecipeOptionBook()}, { new EntityVillager.MerchantRecipeOptionSell(Items.NAME_TAG, new EntityVillager.MerchantOptionRandomRange(20, 22))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.PAPER, new EntityVillager.MerchantOptionRandomRange(24, 36))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.COMPASS, new EntityVillager.MerchantOptionRandomRange(1, 1))}, { new EntityVillager.MerchantRecipeOptionSell(Items.MAP, new EntityVillager.MerchantOptionRandomRange(7, 11))}, { new EntityVillager.h(new EntityVillager.MerchantOptionRandomRange(12, 20), "Monument", MapIcon.Type.MONUMENT), new EntityVillager.h(new EntityVillager.MerchantOptionRandomRange(16, 28), "Mansion", MapIcon.Type.MANSION)}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.ROTTEN_FLESH, new EntityVillager.MerchantOptionRandomRange(36, 40)), new EntityVillager.MerchantRecipeOptionBuy(Items.GOLD_INGOT, new EntityVillager.MerchantOptionRandomRange(8, 10))}, { new EntityVillager.MerchantRecipeOptionSell(Items.REDSTONE, new EntityVillager.MerchantOptionRandomRange(-4, -1)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Items.LAPIS_LAZULI), new EntityVillager.MerchantOptionRandomRange(-2, -1))}, { new EntityVillager.MerchantRecipeOptionSell(Items.ENDER_PEARL, new EntityVillager.MerchantOptionRandomRange(4, 7)), new EntityVillager.MerchantRecipeOptionSell(Blocks.GLOWSTONE, new EntityVillager.MerchantOptionRandomRange(-3, -1))}, { new EntityVillager.MerchantRecipeOptionSell(Items.EXPERIENCE_BOTTLE, new EntityVillager.MerchantOptionRandomRange(3, 11))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionSell(Items.IRON_HELMET, new EntityVillager.MerchantOptionRandomRange(4, 6))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.IRON_INGOT, new EntityVillager.MerchantOptionRandomRange(7, 9)), new EntityVillager.MerchantRecipeOptionSell(Items.IRON_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(10, 14))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.DIAMOND, new EntityVillager.MerchantOptionRandomRange(3, 4)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(16, 19))}, { new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_BOOTS, new EntityVillager.MerchantOptionRandomRange(5, 7)), new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_LEGGINGS, new EntityVillager.MerchantOptionRandomRange(9, 11)), new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_HELMET, new EntityVillager.MerchantOptionRandomRange(5, 7)), new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(11, 15))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionSell(Items.IRON_AXE, new EntityVillager.MerchantOptionRandomRange(6, 8))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.IRON_INGOT, new EntityVillager.MerchantOptionRandomRange(7, 9)), new EntityVillager.MerchantRecipeOptionEnchant(Items.IRON_SWORD, new EntityVillager.MerchantOptionRandomRange(9, 10))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.DIAMOND, new EntityVillager.MerchantOptionRandomRange(3, 4)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_SWORD, new EntityVillager.MerchantOptionRandomRange(12, 15)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_AXE, new EntityVillager.MerchantOptionRandomRange(9, 12))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionEnchant(Items.IRON_SHOVEL, new EntityVillager.MerchantOptionRandomRange(5, 7))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.IRON_INGOT, new EntityVillager.MerchantOptionRandomRange(7, 9)), new EntityVillager.MerchantRecipeOptionEnchant(Items.IRON_PICKAXE, new EntityVillager.MerchantOptionRandomRange(9, 11))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.DIAMOND, new EntityVillager.MerchantOptionRandomRange(3, 4)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_PICKAXE, new EntityVillager.MerchantOptionRandomRange(12, 15))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.PORKCHOP, new EntityVillager.MerchantOptionRandomRange(14, 18)), new EntityVillager.MerchantRecipeOptionBuy(Items.CHICKEN, new EntityVillager.MerchantOptionRandomRange(14, 18))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionSell(Items.COOKED_PORKCHOP, new EntityVillager.MerchantOptionRandomRange(-7, -5)), new EntityVillager.MerchantRecipeOptionSell(Items.COOKED_CHICKEN, new EntityVillager.MerchantOptionRandomRange(-8, -6))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.LEATHER, new EntityVillager.MerchantOptionRandomRange(9, 12)), new EntityVillager.MerchantRecipeOptionSell(Items.LEATHER_LEGGINGS, new EntityVillager.MerchantOptionRandomRange(2, 4))}, { new EntityVillager.MerchantRecipeOptionEnchant(Items.LEATHER_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(7, 12))}, { new EntityVillager.MerchantRecipeOptionSell(Items.SADDLE, new EntityVillager.MerchantOptionRandomRange(8, 10))}}}, { new EntityVillager.IMerchantRecipeOption[0][]}}; + private EntityHuman bG; + private byte bI; + private final Reputation bJ; + private long bK; + private long bL; + private int bM; + private long bN; + private int bO; + private long bP; + private static final ImmutableList> bQ = ImmutableList.of(MemoryModuleType.HOME, MemoryModuleType.JOB_SITE, MemoryModuleType.MEETING_POINT, MemoryModuleType.MOBS, MemoryModuleType.VISIBLE_MOBS, MemoryModuleType.VISIBLE_VILLAGER_BABIES, MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.WALK_TARGET, MemoryModuleType.LOOK_TARGET, MemoryModuleType.INTERACTION_TARGET, MemoryModuleType.BREED_TARGET, new MemoryModuleType[]{MemoryModuleType.PATH, MemoryModuleType.INTERACTABLE_DOORS, MemoryModuleType.OPENED_DOORS, MemoryModuleType.NEAREST_BED, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.NEAREST_HOSTILE, MemoryModuleType.SECONDARY_JOB_SITE, MemoryModuleType.HIDING_PLACE, MemoryModuleType.HEARD_BELL_TIME, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.LAST_SLEPT, MemoryModuleType.LAST_WORKED_AT_POI, MemoryModuleType.GOLEM_LAST_SEEN_TIME}); + private static final ImmutableList>> bR = ImmutableList.of(SensorType.b, SensorType.c, SensorType.d, SensorType.e, SensorType.f, SensorType.g, SensorType.h, SensorType.i, SensorType.j); + public static final Map, BiPredicate> bB = ImmutableMap.of(MemoryModuleType.HOME, (entityvillager, villageplacetype) -> { + return villageplacetype == VillagePlaceType.q; + }, MemoryModuleType.JOB_SITE, (entityvillager, villageplacetype) -> { + return entityvillager.getVillagerData().getProfession().b() == villageplacetype; + }, MemoryModuleType.MEETING_POINT, (entityvillager, villageplacetype) -> { + return villageplacetype == VillagePlaceType.r; + }); - public EntityVillager(World world) { - this(world, 0); + public EntityVillager(EntityTypes entitytypes, World world) { + this(entitytypes, world, VillagerType.PLAINS); } - public EntityVillager(World world, int i) { - super(EntityTypes.VILLAGER, world); - this.inventory = new InventorySubcontainer(new ChatComponentText("Items"), 8, (CraftVillager) this.getBukkitEntity()); // CraftBukkit add argument - this.setProfession(i); - this.setSize(0.6F, 1.95F); + public EntityVillager(EntityTypes entitytypes, World world, VillagerType villagertype) { + super(entitytypes, world); + this.bJ = new Reputation(); ((Navigation) this.getNavigation()).a(true); - this.p(true); + this.getNavigation().d(true); + this.setCanPickupLoot(true); + this.setVillagerData(this.getVillagerData().withType(villagertype).withProfession(VillagerProfession.NONE)); + this.br = this.a(new Dynamic(DynamicOpsNBT.a, new NBTTagCompound())); } - protected void n() { - this.goalSelector.a(0, new PathfinderGoalFloat(this)); - this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityZombie.class, 8.0F, 0.6D, 0.6D)); - this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityEvoker.class, 12.0F, 0.8D, 0.8D)); - this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityVindicator.class, 8.0F, 0.8D, 0.8D)); - this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityVex.class, 8.0F, 0.6D, 0.6D)); - this.goalSelector.a(1, new PathfinderGoalTradeWithPlayer(this)); - this.goalSelector.a(1, new PathfinderGoalLookAtTradingPlayer(this)); - this.goalSelector.a(2, new PathfinderGoalMoveIndoors(this)); - this.goalSelector.a(3, new PathfinderGoalRestrictOpenDoor(this)); - this.goalSelector.a(4, new PathfinderGoalOpenDoor(this, true)); - this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 0.6D)); - this.goalSelector.a(6, new PathfinderGoalMakeLove(this)); - this.goalSelector.a(7, new PathfinderGoalTakeFlower(this)); - this.goalSelector.a(9, new PathfinderGoalInteract(this, EntityHuman.class, 3.0F, 1.0F)); - this.goalSelector.a(9, new PathfinderGoalInteractVillagers(this)); - this.goalSelector.a(9, new PathfinderGoalRandomStrollLand(this, 0.6D)); - this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + @Override + public BehaviorController getBehaviorController() { + return (BehaviorController) super.getBehaviorController(); // CraftBukkit - decompile error } - private void dJ() { - if (!this.bS) { - this.bS = true; - if (this.isBaby()) { - this.goalSelector.a(8, new PathfinderGoalPlay(this, 0.32D)); - } else if (this.getProfession() == 0) { - this.goalSelector.a(6, new PathfinderGoalVillagerFarm(this, 0.6D)); - } + @Override + protected BehaviorController a(Dynamic dynamic) { + BehaviorController behaviorcontroller = new BehaviorController<>(EntityVillager.bQ, EntityVillager.bR, dynamic); + this.a(behaviorcontroller); + return behaviorcontroller; + } + + public void a(WorldServer worldserver) { + BehaviorController behaviorcontroller = this.getBehaviorController(); + + behaviorcontroller.b(worldserver, this); + this.br = behaviorcontroller.f(); + this.a(this.getBehaviorController()); + } + + private void a(BehaviorController behaviorcontroller) { + VillagerProfession villagerprofession = this.getVillagerData().getProfession(); + float f = (float) this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue(); + + if (this.isBaby()) { + behaviorcontroller.setSchedule(Schedule.VILLAGER_BABY); + behaviorcontroller.a(Activity.PLAY, Behaviors.a(f)); + } else { + behaviorcontroller.setSchedule(Schedule.VILLAGER_DEFAULT); + behaviorcontroller.a(Activity.WORK, Behaviors.b(villagerprofession, f), (Set) ImmutableSet.of(Pair.of(MemoryModuleType.JOB_SITE, MemoryStatus.VALUE_PRESENT))); } + + behaviorcontroller.a(Activity.CORE, Behaviors.a(villagerprofession, f)); + behaviorcontroller.a(Activity.MEET, Behaviors.d(villagerprofession, f), (Set) ImmutableSet.of(Pair.of(MemoryModuleType.MEETING_POINT, MemoryStatus.VALUE_PRESENT))); + behaviorcontroller.a(Activity.REST, Behaviors.c(villagerprofession, f)); + behaviorcontroller.a(Activity.IDLE, Behaviors.e(villagerprofession, f)); + behaviorcontroller.a(Activity.PANIC, Behaviors.f(villagerprofession, f)); + behaviorcontroller.a(Activity.PRE_RAID, Behaviors.g(villagerprofession, f)); + behaviorcontroller.a(Activity.RAID, Behaviors.h(villagerprofession, f)); + behaviorcontroller.a(Activity.HIDE, Behaviors.i(villagerprofession, f)); + behaviorcontroller.a((Set) ImmutableSet.of(Activity.CORE)); + behaviorcontroller.b(Activity.IDLE); + behaviorcontroller.a(Activity.IDLE); + behaviorcontroller.a(this.world.getDayTime(), this.world.getTime()); } + @Override protected void l() { - if (this.getProfession() == 0) { - this.goalSelector.a(8, new PathfinderGoalVillagerFarm(this, 0.6D)); + super.l(); + if (this.world instanceof WorldServer) { + this.a((WorldServer) this.world); } - super.l(); } + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.5D); + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(48.0D); } // Spigot Start @Override public void inactiveTick() { - // SPIGOT-3874 - if (world.spigotConfig.tickInactiveVillagers) { - // SPIGOT-3894 - Chunk startingChunk = this.world.getChunkIfLoaded(MathHelper.floor(this.locX) >> 4, MathHelper.floor(this.locZ) >> 4); - if (!(startingChunk != null && startingChunk.areNeighborsLoaded(1))) { - return; - } - this.mobTick(); // SPIGOT-3846 + // SPIGOT-3874, SPIGOT-3894, SPIGOT-3846, SPIGOT-5286 :( + if (world.spigotConfig.tickInactiveVillagers && this.df()) { + this.mobTick(); } super.inactiveTick(); } // Spigot End + @Override protected void mobTick() { - if (--this.profession <= 0) { - BlockPosition blockposition = new BlockPosition(this); - - this.world.af().a(blockposition); - this.profession = 70 + this.random.nextInt(50); - this.village = this.world.af().getClosestVillage(blockposition, 32); - if (this.village == null) { - this.dv(); - } else { - BlockPosition blockposition1 = this.village.a(); - - this.a(blockposition1, this.village.b()); - if (this.bR) { - this.bR = false; - this.village.b(5); - } - } - } - - if (!this.dB() && this.bK > 0) { - --this.bK; - if (this.bK <= 0) { - if (this.bL) { - Iterator iterator = this.trades.iterator(); - - while (iterator.hasNext()) { - MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next(); - - if (merchantrecipe.h()) { - // CraftBukkit start - int bonus = this.random.nextInt(6) + this.random.nextInt(6) + 2; - VillagerReplenishTradeEvent event = new VillagerReplenishTradeEvent((Villager) this.getBukkitEntity(), merchantrecipe.asBukkit(), bonus); - Bukkit.getPluginManager().callEvent(event); - if (!event.isCancelled()) { - merchantrecipe.a(event.getBonus()); - } - // CraftBukkit end - } - } - + this.world.getMethodProfiler().enter("brain"); + this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error + this.world.getMethodProfiler().exit(); + if (!this.dY() && this.bE > 0) { + --this.bE; + if (this.bE <= 0) { + if (this.bF) { this.populateTrades(); - this.bL = false; - if (this.village != null && this.bO != null) { - this.world.broadcastEntityEffect(this, (byte) 14); - this.village.a(this.bO, 1); - } + this.bF = false; } this.addEffect(new MobEffect(MobEffects.REGENERATION, 200, 0), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.VILLAGER_TRADE); // CraftBukkit } } + if (this.bG != null && this.world instanceof WorldServer) { + ((WorldServer) this.world).a(ReputationEvent.e, (Entity) this.bG, (ReputationHandler) this); + this.world.broadcastEntityEffect(this, (byte) 14); + this.bG = null; + } + + if (!this.isNoAI() && this.random.nextInt(100) == 0) { + Raid raid = ((WorldServer) this.world).c_(new BlockPosition(this)); + + if (raid != null && raid.v() && !raid.a()) { + this.world.broadcastEntityEffect(this, (byte) 42); + } + } + + if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.dY()) { + this.ed(); + } + super.mobTick(); } + @Override + public void tick() { + super.tick(); + if (this.dV() > 0) { + this.r(this.dV() - 1); + } + + this.eF(); + } + + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); boolean flag = itemstack.getItem() == Items.NAME_TAG; @@ -178,470 +198,561 @@ public class EntityVillager extends EntityAgeable implements NPC, IMerchant { if (flag) { itemstack.a(entityhuman, (EntityLiving) this, enumhand); return true; - } else if (itemstack.getItem() != Items.VILLAGER_SPAWN_EGG && this.isAlive() && !this.dB() && !this.isBaby()) { - if (this.trades == null) { - this.populateTrades(); - } - - if (enumhand == EnumHand.MAIN_HAND) { - entityhuman.a(StatisticList.TALKED_TO_VILLAGER); - } - - if (!this.world.isClientSide && !this.trades.isEmpty()) { - this.setTradingPlayer(entityhuman); - entityhuman.openTrade(this); - } else if (this.trades.isEmpty()) { + } else if (itemstack.getItem() != Items.VILLAGER_SPAWN_EGG && this.isAlive() && !this.dY() && !this.isSleeping()) { + if (this.isBaby()) { + this.et(); return super.a(entityhuman, enumhand); - } + } else { + boolean flag1 = this.getOffers().isEmpty(); - return true; + if (enumhand == EnumHand.MAIN_HAND) { + if (flag1 && !this.world.isClientSide) { + this.et(); + } + + entityhuman.a(StatisticList.TALKED_TO_VILLAGER); + } + + if (flag1) { + return super.a(entityhuman, enumhand); + } else { + if (!this.world.isClientSide && !this.trades.isEmpty()) { + this.g(entityhuman); + } + + return true; + } + } } else { return super.a(entityhuman, enumhand); } } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityVillager.bD, 0); + private void et() { + this.r(40); + if (!this.world.e()) { + this.a(SoundEffects.ENTITY_VILLAGER_NO, this.getSoundVolume(), this.cV()); + } + } + private void g(EntityHuman entityhuman) { + this.h(entityhuman); + this.setTradingPlayer(entityhuman); + this.openTrade(entityhuman, this.getScoreboardDisplayName(), this.getVillagerData().getLevel()); + } + + @Override + public void setTradingPlayer(@Nullable EntityHuman entityhuman) { + boolean flag = this.getTrader() != null && entityhuman == null; + + super.setTradingPlayer(entityhuman); + if (flag) { + this.ed(); + } + + } + + @Override + protected void ed() { + super.ed(); + this.eu(); + } + + private void eu() { + Iterator iterator = this.getOffers().iterator(); + + while (iterator.hasNext()) { + MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next(); + + merchantrecipe.setSpecialPrice(); + } + + } + + @Override + public boolean ei() { + return true; + } + + public void ej() { + this.ey(); + Iterator iterator = this.getOffers().iterator(); + + while (iterator.hasNext()) { + MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next(); + + merchantrecipe.resetUses(); + } + + if (this.getVillagerData().getProfession() == VillagerProfession.FARMER) { + this.eE(); + } + + this.bN = this.world.getTime(); + ++this.bO; + } + + private boolean ev() { + Iterator iterator = this.getOffers().iterator(); + + MerchantRecipe merchantrecipe; + + do { + if (!iterator.hasNext()) { + return false; + } + + merchantrecipe = (MerchantRecipe) iterator.next(); + } while (!merchantrecipe.isFullyUsed()); + + return true; + } + + private boolean ew() { + return this.bO < 2 && this.world.getTime() > this.bN + 2400L; + } + + public boolean ek() { + long i = this.bN + 12000L; + boolean flag = this.world.getTime() > i; + long j = this.world.getDayTime(); + + if (this.bP > 0L) { + long k = this.bP / 24000L; + long l = j / 24000L; + + flag |= l > k; + } + + this.bP = j; + if (flag) { + this.eH(); + } + + return this.ew() && this.ev(); + } + + private void ex() { + int i = 2 - this.bO; + + if (i > 0) { + Iterator iterator = this.getOffers().iterator(); + + while (iterator.hasNext()) { + MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next(); + + merchantrecipe.resetUses(); + } + } + + for (int j = 0; j < i; ++j) { + this.ey(); + } + + } + + private void ey() { + Iterator iterator = this.getOffers().iterator(); + + while (iterator.hasNext()) { + MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next(); + + merchantrecipe.e(); + } + + } + + private void h(EntityHuman entityhuman) { + int i = this.f(entityhuman); + + if (i != 0) { + Iterator iterator = this.getOffers().iterator(); + + while (iterator.hasNext()) { + MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next(); + + // CraftBukkit start + int bonus = -MathHelper.d((float) i * merchantrecipe.getPriceMultiplier()); + VillagerReplenishTradeEvent event = new VillagerReplenishTradeEvent((Villager) this.getBukkitEntity(), merchantrecipe.asBukkit(), bonus); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) { + merchantrecipe.increaseSpecialPrice(event.getBonus()); + } + // CraftBukkit end + } + } + + if (entityhuman.hasEffect(MobEffects.HERO_OF_THE_VILLAGE)) { + MobEffect mobeffect = entityhuman.getEffect(MobEffects.HERO_OF_THE_VILLAGE); + int j = mobeffect.getAmplifier(); + Iterator iterator1 = this.getOffers().iterator(); + + while (iterator1.hasNext()) { + MerchantRecipe merchantrecipe1 = (MerchantRecipe) iterator1.next(); + double d0 = 0.3D + 0.0625D * (double) j; + int k = (int) Math.floor(d0 * (double) merchantrecipe1.a().getCount()); + + merchantrecipe1.increaseSpecialPrice(-Math.max(k, 1)); + } + } + + } + + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityVillager.bC, new VillagerData(VillagerType.PLAINS, VillagerProfession.NONE, 1)); + } + + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setInt("Profession", this.getProfession()); - nbttagcompound.setInt("Riches", this.riches); - nbttagcompound.setInt("Career", this.careerId); - nbttagcompound.setInt("CareerLevel", this.careerLevel); - nbttagcompound.setBoolean("Willing", this.bM); - if (this.trades != null) { - nbttagcompound.set("Offers", this.trades.a()); - } - - NBTTagList nbttaglist = new NBTTagList(); - - for (int i = 0; i < this.inventory.getSize(); ++i) { - ItemStack itemstack = this.inventory.getItem(i); - - if (!itemstack.isEmpty()) { - nbttaglist.add((NBTBase) itemstack.save(new NBTTagCompound())); - } - } - - nbttagcompound.set("Inventory", nbttaglist); + nbttagcompound.set("VillagerData", (NBTBase) this.getVillagerData().a(DynamicOpsNBT.a)); + nbttagcompound.setByte("FoodLevel", this.bI); + nbttagcompound.set("Gossips", (NBTBase) this.bJ.a((DynamicOps) DynamicOpsNBT.a).getValue()); + nbttagcompound.setInt("Xp", this.bM); + nbttagcompound.setLong("LastRestock", this.bN); + nbttagcompound.setLong("LastGossipDecay", this.bL); + nbttagcompound.setInt("RestocksToday", this.bO); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.setProfession(nbttagcompound.getInt("Profession")); - this.riches = nbttagcompound.getInt("Riches"); - this.careerId = nbttagcompound.getInt("Career"); - this.careerLevel = nbttagcompound.getInt("CareerLevel"); - this.bM = nbttagcompound.getBoolean("Willing"); + if (nbttagcompound.hasKeyOfType("VillagerData", 10)) { + this.setVillagerData(new VillagerData(new Dynamic(DynamicOpsNBT.a, nbttagcompound.get("VillagerData")))); + } + if (nbttagcompound.hasKeyOfType("Offers", 10)) { - NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Offers"); - - this.trades = new MerchantRecipeList(nbttagcompound1); + this.trades = new MerchantRecipeList(nbttagcompound.getCompound("Offers")); } - NBTTagList nbttaglist = nbttagcompound.getList("Inventory", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - ItemStack itemstack = ItemStack.a(nbttaglist.getCompound(i)); - - if (!itemstack.isEmpty()) { - this.inventory.a(itemstack); - } + if (nbttagcompound.hasKeyOfType("FoodLevel", 1)) { + this.bI = nbttagcompound.getByte("FoodLevel"); } - this.p(true); - this.dJ(); + NBTTagList nbttaglist = nbttagcompound.getList("Gossips", 10); + + this.bJ.a(new Dynamic(DynamicOpsNBT.a, nbttaglist)); + if (nbttagcompound.hasKeyOfType("Xp", 3)) { + this.bM = nbttagcompound.getInt("Xp"); + } + + this.bN = nbttagcompound.getLong("LastRestock"); + this.bL = nbttagcompound.getLong("LastGossipDecay"); + this.setCanPickupLoot(true); + this.a((WorldServer) this.world); + this.bO = nbttagcompound.getInt("RestocksToday"); } - public boolean isTypeNotPersistent() { + @Override + public boolean isTypeNotPersistent(double d0) { return false; } - protected SoundEffect D() { - return this.dB() ? SoundEffects.ENTITY_VILLAGER_TRADE : SoundEffects.ENTITY_VILLAGER_AMBIENT; + @Nullable + @Override + protected SoundEffect getSoundAmbient() { + return this.isSleeping() ? null : (this.dY() ? SoundEffects.ENTITY_VILLAGER_TRADE : SoundEffects.ENTITY_VILLAGER_AMBIENT); } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_VILLAGER_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_VILLAGER_DEATH; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.aA; - } + public void el() { + SoundEffect soundeffect = this.getVillagerData().getProfession().b().e(); - public void setProfession(int i) { - this.datawatcher.set(EntityVillager.bD, i); - } - - public int getProfession() { - return Math.max((Integer) this.datawatcher.get(EntityVillager.bD) % 6, 0); - } - - public boolean isInLove() { - return this.bF; - } - - public void s(boolean flag) { - this.bF = flag; - } - - public void t(boolean flag) { - this.bG = flag; - } - - public boolean dA() { - return this.bG; - } - - public void setLastDamager(@Nullable EntityLiving entityliving) { - super.setLastDamager(entityliving); - if (this.village != null && entityliving != null) { - this.village.a(entityliving); - if (entityliving instanceof EntityHuman) { - byte b0 = -1; - - if (this.isBaby()) { - b0 = -3; - } - - this.village.a(((EntityHuman) entityliving).getProfile().getName(), b0); - if (this.isAlive()) { - this.world.broadcastEntityEffect(this, (byte) 13); - } - } + if (soundeffect != null) { + this.a(soundeffect, this.getSoundVolume(), this.cV()); } } - public void die(DamageSource damagesource) { - if (this.village != null) { - Entity entity = damagesource.getEntity(); + public void setVillagerData(VillagerData villagerdata) { + VillagerData villagerdata1 = this.getVillagerData(); - if (entity != null) { - if (entity instanceof EntityHuman) { - this.village.a(((EntityHuman) entity).getProfile().getName(), -2); - } else if (entity instanceof IMonster) { - this.village.h(); - } - } else { - EntityHuman entityhuman = this.world.findNearbyPlayer(this, 16.0D); - - if (entityhuman != null) { - this.village.h(); - } - } + if (villagerdata1.getProfession() != villagerdata.getProfession()) { + this.trades = null; } - super.die(damagesource); + this.datawatcher.set(EntityVillager.bC, villagerdata); } - public void setTradingPlayer(@Nullable EntityHuman entityhuman) { - this.tradingPlayer = entityhuman; + @Override + public VillagerData getVillagerData() { + return (VillagerData) this.datawatcher.get(EntityVillager.bC); } - @Nullable - public EntityHuman getTrader() { - return this.tradingPlayer; - } - - public boolean dB() { - return this.tradingPlayer != null; - } - - public boolean u(boolean flag) { - if (!this.bM && flag && this.dE()) { - boolean flag1 = false; - - for (int i = 0; i < this.inventory.getSize(); ++i) { - ItemStack itemstack = this.inventory.getItem(i); - - if (!itemstack.isEmpty()) { - if (itemstack.getItem() == Items.BREAD && itemstack.getCount() >= 3) { - flag1 = true; - this.inventory.splitStack(i, 3); - } else if ((itemstack.getItem() == Items.POTATO || itemstack.getItem() == Items.CARROT) && itemstack.getCount() >= 12) { - flag1 = true; - this.inventory.splitStack(i, 12); - } - } - - if (flag1) { - this.world.broadcastEntityEffect(this, (byte) 18); - this.bM = true; - break; - } - } - } - - return this.bM; - } - - public void v(boolean flag) { - this.bM = flag; - } - - public void a(MerchantRecipe merchantrecipe) { - merchantrecipe.increaseUses(); - this.a_ = -this.z(); - this.a(SoundEffects.ENTITY_VILLAGER_YES, this.cD(), this.cE()); + @Override + protected void b(MerchantRecipe merchantrecipe) { int i = 3 + this.random.nextInt(4); - if (merchantrecipe.e() == 1 || this.random.nextInt(5) == 0) { - this.bK = 40; - this.bL = true; - this.bM = true; - if (this.tradingPlayer != null) { - this.bO = this.tradingPlayer.getProfile().getName(); - } else { - this.bO = null; - } - + this.bM += merchantrecipe.getXp(); + this.bG = this.getTrader(); + if (this.eB()) { + this.bE = 40; + this.bF = true; i += 5; } - if (merchantrecipe.getBuyItem1().getItem() == Items.EMERALD) { - this.riches += merchantrecipe.getBuyItem1().getCount(); - } - - if (merchantrecipe.j()) { - this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY + 0.5D, this.locZ, i, org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, tradingPlayer, this)); // Paper - } - - if (this.tradingPlayer instanceof EntityPlayer) { - CriterionTriggers.s.a((EntityPlayer) this.tradingPlayer, this, merchantrecipe.getBuyItem3()); + if (merchantrecipe.isRewardExp()) { + this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY + 0.5D, this.locZ, i, org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, this.getTrader(), this)); // Paper } } - public void a(ItemStack itemstack) { - if (!this.world.isClientSide && this.a_ > -this.z() + 20) { - this.a_ = -this.z(); - this.a(itemstack.isEmpty() ? SoundEffects.ENTITY_VILLAGER_NO : SoundEffects.ENTITY_VILLAGER_YES, this.cD(), this.cE()); + @Override + public void setLastDamager(@Nullable EntityLiving entityliving) { + if (entityliving != null && this.world instanceof WorldServer) { + ((WorldServer) this.world).a(ReputationEvent.c, (Entity) entityliving, (ReputationHandler) this); + if (this.isAlive() && entityliving instanceof EntityHuman) { + this.world.broadcastEntityEffect(this, (byte) 13); + } } + super.setLastDamager(entityliving); } - @Nullable - public MerchantRecipeList getOffers(EntityHuman entityhuman) { - if (this.trades == null) { - this.populateTrades(); + @Override + public void die(DamageSource damagesource) { + Entity entity = damagesource.getEntity(); + + if (entity != null) { + this.a(entity); } - return this.trades; + this.a(MemoryModuleType.HOME); + this.a(MemoryModuleType.JOB_SITE); + this.a(MemoryModuleType.MEETING_POINT); + super.die(damagesource); } - public void populateTrades() { - EntityVillager.IMerchantRecipeOption[][][] aentityvillager_imerchantrecipeoption = EntityVillager.bU[this.getProfession()]; + private void a(Entity entity) { + if (this.world instanceof WorldServer) { + Optional> optional = this.br.getMemory(MemoryModuleType.VISIBLE_MOBS); - if (this.careerId != 0 && this.careerLevel != 0) { - ++this.careerLevel; - } else { - this.careerId = this.random.nextInt(aentityvillager_imerchantrecipeoption.length) + 1; - this.careerLevel = 1; + if (optional.isPresent()) { + WorldServer worldserver = (WorldServer) this.world; + + ((List) optional.get()).stream().filter((entityliving) -> { + return entityliving instanceof ReputationHandler; + }).forEach((entityliving) -> { + worldserver.a(ReputationEvent.d, entity, (ReputationHandler) entityliving); + }); + } } + } - if (this.trades == null) { - this.trades = new MerchantRecipeList(); + public void a(MemoryModuleType memorymoduletype) { + if (this.world instanceof WorldServer) { + MinecraftServer minecraftserver = ((WorldServer) this.world).getMinecraftServer(); + + this.br.getMemory(memorymoduletype).ifPresent((globalpos) -> { + WorldServer worldserver = minecraftserver.getWorldServer(globalpos.getDimensionManager()); + VillagePlace villageplace = worldserver.B(); + Optional optional = villageplace.c(globalpos.getBlockPosition()); + BiPredicate bipredicate = (BiPredicate) EntityVillager.bB.get(memorymoduletype); + + if (optional.isPresent() && bipredicate.test(this, optional.get())) { + villageplace.b(globalpos.getBlockPosition()); + PacketDebug.c(worldserver, globalpos.getBlockPosition()); + } + + }); } + } - int i = this.careerId - 1; - int j = this.careerLevel - 1; + public boolean canBreed() { + return this.bI + this.eD() >= 12 && this.getAge() == 0; + } - if (i >= 0 && i < aentityvillager_imerchantrecipeoption.length) { - EntityVillager.IMerchantRecipeOption[][] aentityvillager_imerchantrecipeoption1 = aentityvillager_imerchantrecipeoption[i]; + private boolean ez() { + return this.bI < 12; + } - if (j >= 0 && j < aentityvillager_imerchantrecipeoption1.length) { - EntityVillager.IMerchantRecipeOption[] aentityvillager_imerchantrecipeoption2 = aentityvillager_imerchantrecipeoption1[j]; - EntityVillager.IMerchantRecipeOption[] aentityvillager_imerchantrecipeoption3 = aentityvillager_imerchantrecipeoption2; - int k = aentityvillager_imerchantrecipeoption2.length; + private void eA() { + if (this.ez() && this.eD() != 0) { + for (int i = 0; i < this.getInventory().getSize(); ++i) { + ItemStack itemstack = this.getInventory().getItem(i); - for (int l = 0; l < k; ++l) { - EntityVillager.IMerchantRecipeOption entityvillager_imerchantrecipeoption = aentityvillager_imerchantrecipeoption3[l]; + if (!itemstack.isEmpty()) { + Integer integer = (Integer) EntityVillager.bA.get(itemstack.getItem()); - // CraftBukkit start - // this is a hack. this must be done because otherwise, if - // mojang adds a new type of villager merchant option, it will need to - // have event handling added manually. this is better than having to do that. - MerchantRecipeList list = new MerchantRecipeList(); - entityvillager_imerchantrecipeoption.a(this, list, this.random); - for (MerchantRecipe recipe : list) { - VillagerAcquireTradeEvent event = new VillagerAcquireTradeEvent((Villager) getBukkitEntity(), recipe.asBukkit()); - Bukkit.getPluginManager().callEvent(event); - if (!event.isCancelled()) { - this.trades.add(CraftMerchantRecipe.fromBukkit(event.getRecipe()).toMinecraft()); + if (integer != null) { + int j = itemstack.getCount(); + + for (int k = j; k > 0; --k) { + this.bI = (byte) (this.bI + integer); + this.getInventory().splitStack(i, 1); + if (!this.ez()) { + return; + } } } - // CraftBukkit end } } } } - public World getWorld() { - return this.world; + public int f(EntityHuman entityhuman) { + return this.bJ.a(entityhuman.getUniqueID(), (reputationtype) -> { + return true; + }); } - public BlockPosition getPosition() { - return new BlockPosition(this); + private void u(int i) { + this.bI = (byte) (this.bI - i); } + public void eo() { + this.eA(); + this.u(12); + } + + public void b(MerchantRecipeList merchantrecipelist) { + this.trades = merchantrecipelist; + } + + private boolean eB() { + int i = this.getVillagerData().getLevel(); + + return VillagerData.d(i) && this.bM >= VillagerData.c(i); + } + + public void populateTrades() { + this.setVillagerData(this.getVillagerData().withLevel(this.getVillagerData().getLevel() + 1)); + this.eh(); + } + + @Override public IChatBaseComponent getScoreboardDisplayName() { ScoreboardTeamBase scoreboardteambase = this.getScoreboardTeam(); IChatBaseComponent ichatbasecomponent = this.getCustomName(); if (ichatbasecomponent != null) { return ScoreboardTeam.a(scoreboardteambase, ichatbasecomponent).a((chatmodifier) -> { - chatmodifier.setChatHoverable(this.bC()).setInsertion(this.bu()); + chatmodifier.setChatHoverable(this.bK()).setInsertion(this.getUniqueIDString()); }); } else { - if (this.trades == null) { - this.populateTrades(); + VillagerProfession villagerprofession = this.getVillagerData().getProfession(); + IChatBaseComponent ichatbasecomponent1 = (new ChatMessage(this.getEntityType().f() + '.' + IRegistry.VILLAGER_PROFESSION.getKey(villagerprofession).getKey(), new Object[0])).a((chatmodifier) -> { + chatmodifier.setChatHoverable(this.bK()).setInsertion(this.getUniqueIDString()); + }); + + if (scoreboardteambase != null) { + ichatbasecomponent1.a(scoreboardteambase.getColor()); } - String s = null; - - switch (this.getProfession()) { - case 0: - if (this.careerId == 1) { - s = "farmer"; - } else if (this.careerId == 2) { - s = "fisherman"; - } else if (this.careerId == 3) { - s = "shepherd"; - } else if (this.careerId == 4) { - s = "fletcher"; - } - break; - case 1: - if (this.careerId == 1) { - s = "librarian"; - } else if (this.careerId == 2) { - s = "cartographer"; - } - break; - case 2: - s = "cleric"; - break; - case 3: - if (this.careerId == 1) { - s = "armorer"; - } else if (this.careerId == 2) { - s = "weapon_smith"; - } else if (this.careerId == 3) { - s = "tool_smith"; - } - break; - case 4: - if (this.careerId == 1) { - s = "butcher"; - } else if (this.careerId == 2) { - s = "leatherworker"; - } - break; - case 5: - s = "nitwit"; - } - - if (s != null) { - IChatBaseComponent ichatbasecomponent1 = (new ChatMessage(this.P().d() + '.' + s, new Object[0])).a((chatmodifier) -> { - chatmodifier.setChatHoverable(this.bC()).setInsertion(this.bu()); - }); - - if (scoreboardteambase != null) { - ichatbasecomponent1.a(scoreboardteambase.getColor()); - } - - return ichatbasecomponent1; - } else { - return super.getScoreboardDisplayName(); - } + return ichatbasecomponent1; } } - public float getHeadHeight() { - return this.isBaby() ? 0.81F : 1.62F; - } - @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - return this.a(difficultydamagescaler, groupdataentity, nbttagcompound, true); - } - - public GroupDataEntity a(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound, boolean flag) { - groupdataentity = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); - if (flag) { - this.setProfession(this.world.random.nextInt(6)); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + if (enummobspawn == EnumMobSpawn.BREEDING) { + this.setVillagerData(this.getVillagerData().withProfession(VillagerProfession.NONE)); } - this.dJ(); - this.populateTrades(); - return groupdataentity; - } - - public void dC() { - this.bR = true; + if (enummobspawn == EnumMobSpawn.COMMAND || enummobspawn == EnumMobSpawn.SPAWN_EGG || enummobspawn == EnumMobSpawn.SPAWNER) { + this.setVillagerData(this.getVillagerData().withType(VillagerType.a(generatoraccess.getBiome(new BlockPosition(this))))); + } + + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } + @Override public EntityVillager createChild(EntityAgeable entityageable) { - EntityVillager entityvillager = EntityTypes.VILLAGER.create(world); // Paper + double d0 = this.random.nextDouble(); + VillagerType villagertype; - entityvillager.prepare(this.world.getDamageScaler(new BlockPosition(entityvillager)), (GroupDataEntity) null, (NBTTagCompound) null); + if (d0 < 0.5D) { + villagertype = VillagerType.a(this.world.getBiome(new BlockPosition(this))); + } else if (d0 < 0.75D) { + villagertype = this.getVillagerData().getType(); + } else { + villagertype = ((EntityVillager) entityageable).getVillagerData().getType(); + } + + EntityVillager entityvillager = new EntityVillager(EntityTypes.VILLAGER, this.world, villagertype); + + entityvillager.prepare(this.world, this.world.getDamageScaler(new BlockPosition(entityvillager)), EnumMobSpawn.BREEDING, (GroupDataEntity) null, (NBTTagCompound) null); return entityvillager; } - public boolean a(EntityHuman entityhuman) { - return false; - } - + @Override public void onLightningStrike(EntityLightning entitylightning) { - if (!this.world.isClientSide && !this.dead) { - EntityWitch entitywitch = EntityTypes.WITCH.create(world); // Paper + EntityWitch entitywitch = (EntityWitch) EntityTypes.WITCH.a(this.world); - // Paper start - if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, entitylightning, entitywitch).isCancelled()) { - return; - } - // Paper end - - entitywitch.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); - entitywitch.prepare(this.world.getDamageScaler(new BlockPosition(entitywitch)), (GroupDataEntity) null, (NBTTagCompound) null); - entitywitch.setNoAI(this.isNoAI()); - if (this.hasCustomName()) { - entitywitch.setCustomName(this.getCustomName()); - entitywitch.setCustomNameVisible(this.getCustomNameVisible()); - } - - // CraftBukkit start - if (CraftEventFactory.callEntityTransformEvent(this, entitywitch, EntityTransformEvent.TransformReason.LIGHTNING).isCancelled()) { - return; - } - if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entitywitch.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.LIGHTNING).callEvent()) return; // Paper - this.world.addEntity(entitywitch, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); - // CraftBukkit end - this.die(); + // Paper start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, entitylightning, entitywitch).isCancelled()) { + return; } + // Paper end + + entitywitch.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + entitywitch.prepare(this.world, this.world.getDamageScaler(new BlockPosition(entitywitch)), EnumMobSpawn.CONVERSION, (GroupDataEntity) null, (NBTTagCompound) null); + entitywitch.setNoAI(this.isNoAI()); + if (this.hasCustomName()) { + entitywitch.setCustomName(this.getCustomName()); + entitywitch.setCustomNameVisible(this.getCustomNameVisible()); + } + + // CraftBukkit start + if (CraftEventFactory.callEntityTransformEvent(this, entitywitch, EntityTransformEvent.TransformReason.LIGHTNING).isCancelled()) { + return; + } + if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entitywitch.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.LIGHTNING).callEvent()) return; // Paper + this.world.addEntity(entitywitch, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); + // CraftBukkit end + this.die(); } - public InventorySubcontainer dD() { - return this.inventory; - } - + @Override protected void a(EntityItem entityitem) { ItemStack itemstack = entityitem.getItemStack(); Item item = itemstack.getItem(); - if (this.a(item)) { - ItemStack itemstack1 = this.inventory.a(itemstack); + if (this.b(item)) { + InventorySubcontainer inventorysubcontainer = this.getInventory(); + boolean flag = false; + ItemStack itemstack1; + int i; + + for (i = 0; i < inventorysubcontainer.getSize(); ++i) { + itemstack1 = inventorysubcontainer.getItem(i); + if (itemstack1.isEmpty() || itemstack1.getItem() == item && itemstack1.getCount() < itemstack1.getMaxStackSize()) { + flag = true; + break; + } + } + + if (!flag) { + return; + } + + i = inventorysubcontainer.a(item); + if (i == 256) { + return; + } + + if (i > 256) { + inventorysubcontainer.a(item, i - 256); + return; + } + + this.receive(entityitem, itemstack.getCount()); + itemstack1 = inventorysubcontainer.a(itemstack); if (itemstack1.isEmpty()) { entityitem.die(); } else { @@ -651,243 +762,224 @@ public class EntityVillager extends EntityAgeable implements NPC, IMerchant { } - private boolean a(Item item) { - return item == Items.BREAD || item == Items.POTATO || item == Items.CARROT || item == Items.WHEAT || item == Items.WHEAT_SEEDS || item == Items.BEETROOT || item == Items.BEETROOT_SEEDS; + public boolean b(Item item) { + return EntityVillager.bD.contains(item) || this.getVillagerData().getProfession().c().contains(item); } - public boolean dE() { - return this.p(1); + public boolean ep() { + return this.eD() >= 24; } - public boolean dF() { - return this.p(2); + public boolean eq() { + return this.eD() < 12; } - public boolean dG() { - boolean flag = this.getProfession() == 0; + private int eD() { + InventorySubcontainer inventorysubcontainer = this.getInventory(); - return flag ? !this.p(5) : !this.p(1); + return EntityVillager.bA.entrySet().stream().mapToInt((entry) -> { + return inventorysubcontainer.a((Item) entry.getKey()) * (Integer) entry.getValue(); + }).sum(); } - private boolean p(int i) { - boolean flag = this.getProfession() == 0; + private void eE() { + InventorySubcontainer inventorysubcontainer = this.getInventory(); + int i = inventorysubcontainer.a(Items.WHEAT); + int j = i / 3; - for (int j = 0; j < this.inventory.getSize(); ++j) { - ItemStack itemstack = this.inventory.getItem(j); - Item item = itemstack.getItem(); - int k = itemstack.getCount(); + if (j != 0) { + int k = j * 3; - if (item == Items.BREAD && k >= 3 * i || item == Items.POTATO && k >= 12 * i || item == Items.CARROT && k >= 12 * i || item == Items.BEETROOT && k >= 12 * i) { - return true; + inventorysubcontainer.a(Items.WHEAT, k); + ItemStack itemstack = inventorysubcontainer.a(new ItemStack(Items.BREAD, j)); + + if (!itemstack.isEmpty()) { + this.a(itemstack, 0.5F); } - if (flag && item == Items.WHEAT && k >= 9 * i) { - return true; + } + } + + public boolean er() { + InventorySubcontainer inventorysubcontainer = this.getInventory(); + + return inventorysubcontainer.a((Set) ImmutableSet.of(Items.WHEAT_SEEDS, Items.POTATO, Items.CARROT, Items.BEETROOT_SEEDS)); + } + + @Override + protected void eh() { + VillagerData villagerdata = this.getVillagerData(); + Int2ObjectMap int2objectmap = (Int2ObjectMap) VillagerTrades.a.get(villagerdata.getProfession()); + + if (int2objectmap != null && !int2objectmap.isEmpty()) { + VillagerTrades.IMerchantRecipeOption[] avillagertrades_imerchantrecipeoption = (VillagerTrades.IMerchantRecipeOption[]) int2objectmap.get(villagerdata.getLevel()); + + if (avillagertrades_imerchantrecipeoption != null) { + MerchantRecipeList merchantrecipelist = this.getOffers(); + + this.a(merchantrecipelist, avillagertrades_imerchantrecipeoption, 2); } } - - return false; } - public boolean dH() { - for (int i = 0; i < this.inventory.getSize(); ++i) { - Item item = this.inventory.getItem(i).getItem(); + public void a(EntityVillager entityvillager, long i) { + if ((i < this.bK || i >= this.bK + 1200L) && (i < entityvillager.bK || i >= entityvillager.bK + 1200L)) { + this.bJ.a(entityvillager.bJ, this.random, 10); + this.bK = i; + entityvillager.bK = i; + this.a(i, 5); + } + } - if (item == Items.WHEAT_SEEDS || item == Items.POTATO || item == Items.CARROT || item == Items.BEETROOT_SEEDS) { - return true; + private void eF() { + long i = this.world.getTime(); + + if (this.bL == 0L) { + this.bL = i; + } else if (i >= this.bL + 24000L) { + this.bJ.b(); + this.bL = i; + } + } + + public void a(long i, int j) { + if (this.a(i)) { + AxisAlignedBB axisalignedbb = this.getBoundingBox().grow(10.0D, 10.0D, 10.0D); + List list = this.world.a(EntityVillager.class, axisalignedbb); + List list1 = (List) list.stream().filter((entityvillager) -> { + return entityvillager.a(i); + }).limit(5L).collect(Collectors.toList()); + + if (list1.size() >= j) { + EntityIronGolem entityirongolem = this.eG(); + + if (entityirongolem != null) { + list.forEach((entityvillager) -> { + entityvillager.b(i); + }); + } } } - - return false; } - public boolean c(int i, ItemStack itemstack) { - if (super.c(i, itemstack)) { - return true; + private void b(long i) { + this.br.setMemory(MemoryModuleType.GOLEM_LAST_SEEN_TIME, i); // CraftBukkit - decompile error + } + + private boolean c(long i) { + Optional optional = this.br.getMemory(MemoryModuleType.GOLEM_LAST_SEEN_TIME); + + if (!optional.isPresent()) { + return false; } else { - int j = i - 300; + Long olong = (Long) optional.get(); - if (j >= 0 && j < this.inventory.getSize()) { - this.inventory.setItem(j, itemstack); - return true; - } else { - return false; - } + return i - olong <= 600L; } } - static class MerchantRecipeOptionProcess implements EntityVillager.IMerchantRecipeOption { + public boolean a(long i) { + VillagerData villagerdata = this.getVillagerData(); - public ItemStack a; - public EntityVillager.MerchantOptionRandomRange b; - public ItemStack c; - public EntityVillager.MerchantOptionRandomRange d; - - public MerchantRecipeOptionProcess(IMaterial imaterial, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange, Item item, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange1) { - this.a = new ItemStack(imaterial); - this.b = entityvillager_merchantoptionrandomrange; - this.c = new ItemStack(item); - this.d = entityvillager_merchantoptionrandomrange1; - } - - public void a(IMerchant imerchant, MerchantRecipeList merchantrecipelist, Random random) { - int i = this.b.a(random); - int j = this.d.a(random); - - merchantrecipelist.add(new MerchantRecipe(new ItemStack(this.a.getItem(), i), new ItemStack(Items.EMERALD), new ItemStack(this.c.getItem(), j))); - } + return villagerdata.getProfession() != VillagerProfession.NONE && villagerdata.getProfession() != VillagerProfession.NITWIT ? (!this.d(this.world.getTime()) ? false : !this.c(i)) : false; } - static class h implements EntityVillager.IMerchantRecipeOption { + @Nullable + private EntityIronGolem eG() { + BlockPosition blockposition = new BlockPosition(this); + int i = 0; - public EntityVillager.MerchantOptionRandomRange a; - public String b; - public MapIcon.Type c; + while (i < 10) { + double d0 = (double) (this.world.random.nextInt(16) - 8); + double d1 = (double) (this.world.random.nextInt(16) - 8); + double d2 = 6.0D; + int j = 0; - public h(EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange, String s, MapIcon.Type mapicon_type) { - this.a = entityvillager_merchantoptionrandomrange; - this.b = s; - this.c = mapicon_type; - } + while (true) { + if (j >= -12) { + BlockPosition blockposition1 = blockposition.a(d0, d2 + (double) j, d1); - public void a(IMerchant imerchant, MerchantRecipeList merchantrecipelist, Random random) { - int i = this.a.a(random); - World world = imerchant.getWorld(); - if (!world.paperConfig.enableTreasureMaps) return; //Paper - BlockPosition blockposition = world.a(this.b, imerchant.getPosition(), 100, true); + if (!this.world.getType(blockposition1).isAir() && !this.world.getType(blockposition1).getMaterial().isLiquid() || !this.world.getType(blockposition1.down()).getMaterial().f()) { + --j; + continue; + } - if (blockposition != null) { - ItemStack itemstack = ItemWorldMap.createFilledMapView(world, blockposition.getX(), blockposition.getZ(), (byte) 2, true, true); + d2 += (double) j; + } - ItemWorldMap.applySepiaFilter(world, itemstack); - WorldMap.decorateMap(itemstack, blockposition, "+", this.c); - itemstack.a((IChatBaseComponent) (new ChatMessage("filled_map." + this.b.toLowerCase(Locale.ROOT), new Object[0]))); - merchantrecipelist.add(new MerchantRecipe(new ItemStack(Items.EMERALD, i), new ItemStack(Items.COMPASS), itemstack)); + BlockPosition blockposition2 = blockposition.a(d0, d2, d1); + EntityIronGolem entityirongolem = (EntityIronGolem) EntityTypes.IRON_GOLEM.b(this.world, (NBTTagCompound) null, (IChatBaseComponent) null, (EntityHuman) null, blockposition2, EnumMobSpawn.MOB_SUMMONED, false, false); + + if (entityirongolem != null) { + if (entityirongolem.a((GeneratorAccess) this.world, EnumMobSpawn.MOB_SUMMONED) && entityirongolem.a((IWorldReader) this.world)) { + this.world.addEntity(entityirongolem, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE); // CraftBukkit + return entityirongolem; + } + + entityirongolem.die(); + } + + ++i; + break; } - } + + return null; } - static class MerchantRecipeOptionBook implements EntityVillager.IMerchantRecipeOption { - - public MerchantRecipeOptionBook() {} - - public void a(IMerchant imerchant, MerchantRecipeList merchantrecipelist, Random random) { - Enchantment enchantment = (Enchantment) IRegistry.ENCHANTMENT.a(random); - int i = MathHelper.nextInt(random, enchantment.getStartLevel(), enchantment.getMaxLevel()); - ItemStack itemstack = ItemEnchantedBook.a(new WeightedRandomEnchant(enchantment, i)); - int j = 2 + random.nextInt(5 + i * 10) + 3 * i; - - if (enchantment.isTreasure()) { - j *= 2; - } - - if (j > 64) { - j = 64; - } - - merchantrecipelist.add(new MerchantRecipe(new ItemStack(Items.BOOK), new ItemStack(Items.EMERALD, j), itemstack)); + @Override + public void a(ReputationEvent reputationevent, Entity entity) { + if (reputationevent == ReputationEvent.a) { + this.bJ.a(entity.getUniqueID(), ReputationType.MAJOR_POSITIVE, 20); + this.bJ.a(entity.getUniqueID(), ReputationType.MINOR_POSITIVE, 25); + } else if (reputationevent == ReputationEvent.e) { + this.bJ.a(entity.getUniqueID(), ReputationType.TRADING, 2); + } else if (reputationevent == ReputationEvent.c) { + this.bJ.a(entity.getUniqueID(), ReputationType.MINOR_NEGATIVE, 25); + } else if (reputationevent == ReputationEvent.d) { + this.bJ.a(entity.getUniqueID(), ReputationType.MAJOR_NEGATIVE, 25); } + } - static class MerchantRecipeOptionEnchant implements EntityVillager.IMerchantRecipeOption { - - public ItemStack a; - public EntityVillager.MerchantOptionRandomRange b; - - public MerchantRecipeOptionEnchant(Item item, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange) { - this.a = new ItemStack(item); - this.b = entityvillager_merchantoptionrandomrange; - } - - public void a(IMerchant imerchant, MerchantRecipeList merchantrecipelist, Random random) { - int i = 1; - - if (this.b != null) { - i = this.b.a(random); - } - - ItemStack itemstack = new ItemStack(Items.EMERALD, i); - ItemStack itemstack1 = EnchantmentManager.a(random, new ItemStack(this.a.getItem()), 5 + random.nextInt(15), false); - - merchantrecipelist.add(new MerchantRecipe(itemstack, itemstack1)); - } + @Override + public int getExperience() { + return this.bM; } - static class MerchantRecipeOptionSell implements EntityVillager.IMerchantRecipeOption { - - public ItemStack a; - public EntityVillager.MerchantOptionRandomRange b; - - public MerchantRecipeOptionSell(Block block, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange) { - this(new ItemStack(block), entityvillager_merchantoptionrandomrange); - } - - public MerchantRecipeOptionSell(Item item, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange) { - this(new ItemStack(item), entityvillager_merchantoptionrandomrange); - } - - public MerchantRecipeOptionSell(ItemStack itemstack, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange) { - this.a = itemstack; - this.b = entityvillager_merchantoptionrandomrange; - } - - public void a(IMerchant imerchant, MerchantRecipeList merchantrecipelist, Random random) { - int i = 1; - - if (this.b != null) { - i = this.b.a(random); - } - - ItemStack itemstack; - ItemStack itemstack1; - - if (i < 0) { - itemstack = new ItemStack(Items.EMERALD); - itemstack1 = new ItemStack(this.a.getItem(), -i); - } else { - itemstack = new ItemStack(Items.EMERALD, i); - itemstack1 = new ItemStack(this.a.getItem()); - } - - merchantrecipelist.add(new MerchantRecipe(itemstack, itemstack1)); - } + public void setExperience(int i) { + this.bM = i; } - static class MerchantRecipeOptionBuy implements EntityVillager.IMerchantRecipeOption { - - public Item a; - public EntityVillager.MerchantOptionRandomRange b; - - public MerchantRecipeOptionBuy(IMaterial imaterial, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange) { - this.a = imaterial.getItem(); - this.b = entityvillager_merchantoptionrandomrange; - } - - public void a(IMerchant imerchant, MerchantRecipeList merchantrecipelist, Random random) { - ItemStack itemstack = new ItemStack(this.a, this.b == null ? 1 : this.b.a(random)); - - merchantrecipelist.add(new MerchantRecipe(itemstack, Items.EMERALD)); - } + private void eH() { + this.ex(); + this.bO = 0; } - interface IMerchantRecipeOption { - - void a(IMerchant imerchant, MerchantRecipeList merchantrecipelist, Random random); + public Reputation es() { + return this.bJ; } - static class MerchantOptionRandomRange extends Tuple { + public void a(NBTBase nbtbase) { + this.bJ.a(new Dynamic(DynamicOpsNBT.a, nbtbase)); + } - public MerchantOptionRandomRange(int i, int j) { - super(i, j); - if (j < i) { - EntityVillager.bC.warn("PriceRange({}, {}) invalid, {} smaller than {}", i, j, j, i); - } + @Override + protected void K() { + super.K(); + PacketDebug.a(this); + } - } + @Override + public void e(BlockPosition blockposition) { + super.e(blockposition); + this.br.setMemory(MemoryModuleType.LAST_SLEPT, MinecraftSerializableLong.a(this.world.getTime())); // CraftBukkit - decompile error + } - public int a(Random random) { - return (Integer) this.a() >= (Integer) this.b() ? (Integer) this.a() : (Integer) this.a() + random.nextInt((Integer) this.b() - (Integer) this.a() + 1); - } + private boolean d(long i) { + Optional optional = this.br.getMemory(MemoryModuleType.LAST_SLEPT); + Optional optional1 = this.br.getMemory(MemoryModuleType.LAST_WORKED_AT_POI); + + return optional.isPresent() && optional1.isPresent() ? i - ((MinecraftSerializableLong) optional.get()).a() < 24000L && i - ((MinecraftSerializableLong) optional1.get()).a() < 36000L : false; } } diff --git a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java new file mode 100644 index 000000000..f161ccb97 --- /dev/null +++ b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java @@ -0,0 +1,253 @@ +package net.minecraft.server; + +import com.google.common.collect.Sets; +import java.util.Iterator; +import java.util.Set; +import javax.annotation.Nullable; +// CraftBukkit start +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.inventory.CraftMerchant; +import org.bukkit.craftbukkit.inventory.CraftMerchantRecipe; +import org.bukkit.entity.AbstractVillager; +import org.bukkit.event.entity.VillagerAcquireTradeEvent; +// CraftBukkit end + +public abstract class EntityVillagerAbstract extends EntityAgeable implements NPC, IMerchant { + + // CraftBukkit start + private CraftMerchant craftMerchant; + + @Override + public CraftMerchant getCraftMerchant() { + return (craftMerchant == null) ? craftMerchant = new CraftMerchant(this) : craftMerchant; + } + // CraftBukkit end + private static final DataWatcherObject bA = DataWatcher.a(EntityVillagerAbstract.class, DataWatcherRegistry.b); + @Nullable + private EntityHuman tradingPlayer; + @Nullable + protected MerchantRecipeList trades; + private final InventorySubcontainer inventory = new InventorySubcontainer(8, (org.bukkit.craftbukkit.entity.CraftAbstractVillager) this.getBukkitEntity()); // CraftBukkit add argument + + public EntityVillagerAbstract(EntityTypes entitytypes, World world) { + super(entitytypes, world); + } + + public int dV() { + return (Integer) this.datawatcher.get(EntityVillagerAbstract.bA); + } + + public void r(int i) { + this.datawatcher.set(EntityVillagerAbstract.bA, i); + } + + @Override + public int getExperience() { + return 0; + } + + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return this.isBaby() ? 0.81F : 1.62F; + } + + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.datawatcher.register(EntityVillagerAbstract.bA, 0); + } + + @Override + public void setTradingPlayer(@Nullable EntityHuman entityhuman) { + this.tradingPlayer = entityhuman; + } + + @Nullable + @Override + public EntityHuman getTrader() { + return this.tradingPlayer; + } + + public boolean dY() { + return this.tradingPlayer != null; + } + + @Override + public MerchantRecipeList getOffers() { + if (this.trades == null) { + this.trades = new MerchantRecipeList(); + this.eh(); + } + + return this.trades; + } + + @Override + public void s(int i) {} + + @Override + public void a(MerchantRecipe merchantrecipe) { + merchantrecipe.increaseUses(); + this.e = -this.A(); + this.b(merchantrecipe); + if (this.tradingPlayer instanceof EntityPlayer) { + CriterionTriggers.s.a((EntityPlayer) this.tradingPlayer, this, merchantrecipe.getSellingItem()); + } + + } + + protected abstract void b(MerchantRecipe merchantrecipe); + + @Override + public boolean ea() { + return true; + } + + @Override + public void i(ItemStack itemstack) { + if (!this.world.isClientSide && this.e > -this.A() + 20) { + this.e = -this.A(); + this.a(this.r(!itemstack.isEmpty()), this.getSoundVolume(), this.cV()); + } + + } + + @Override + public SoundEffect eb() { + return SoundEffects.ENTITY_VILLAGER_YES; + } + + protected SoundEffect r(boolean flag) { + return flag ? SoundEffects.ENTITY_VILLAGER_YES : SoundEffects.ENTITY_VILLAGER_NO; + } + + public void ec() { + this.a(SoundEffects.ENTITY_VILLAGER_CELEBRATE, this.getSoundVolume(), this.cV()); + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + MerchantRecipeList merchantrecipelist = this.getOffers(); + + if (!merchantrecipelist.isEmpty()) { + nbttagcompound.set("Offers", merchantrecipelist.a()); + } + + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.inventory.getSize(); ++i) { + ItemStack itemstack = this.inventory.getItem(i); + + if (!itemstack.isEmpty()) { + nbttaglist.add(itemstack.save(new NBTTagCompound())); + } + } + + nbttagcompound.set("Inventory", nbttaglist); + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("Offers", 10)) { + this.trades = new MerchantRecipeList(nbttagcompound.getCompound("Offers")); + } + + NBTTagList nbttaglist = nbttagcompound.getList("Inventory", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + ItemStack itemstack = ItemStack.a(nbttaglist.getCompound(i)); + + if (!itemstack.isEmpty()) { + this.inventory.a(itemstack); + } + } + + } + + @Nullable + @Override + public Entity a(DimensionManager dimensionmanager) { + this.ed(); + return super.a(dimensionmanager); + } + + protected void ed() { + this.setTradingPlayer((EntityHuman) null); + } + + @Override + public void die(DamageSource damagesource) { + super.die(damagesource); + this.ed(); + } + + @Override + public boolean a(EntityHuman entityhuman) { + return false; + } + + public InventorySubcontainer getInventory() { + return this.inventory; + } + + @Override + public boolean a_(int i, ItemStack itemstack) { + if (super.a_(i, itemstack)) { + return true; + } else { + int j = i - 300; + + if (j >= 0 && j < this.inventory.getSize()) { + this.inventory.setItem(j, itemstack); + return true; + } else { + return false; + } + } + } + + @Override + public World getWorld() { + return this.world; + } + + protected abstract void eh(); + + protected void a(MerchantRecipeList merchantrecipelist, VillagerTrades.IMerchantRecipeOption[] avillagertrades_imerchantrecipeoption, int i) { + Set set = Sets.newHashSet(); + + if (avillagertrades_imerchantrecipeoption.length > i) { + while (set.size() < i) { + set.add(this.random.nextInt(avillagertrades_imerchantrecipeoption.length)); + } + } else { + for (int j = 0; j < avillagertrades_imerchantrecipeoption.length; ++j) { + set.add(j); + } + } + + Iterator iterator = set.iterator(); + + while (iterator.hasNext()) { + Integer integer = (Integer) iterator.next(); + VillagerTrades.IMerchantRecipeOption villagertrades_imerchantrecipeoption = avillagertrades_imerchantrecipeoption[integer]; + MerchantRecipe merchantrecipe = villagertrades_imerchantrecipeoption.a(this, this.random); + + if (merchantrecipe != null) { + // CraftBukkit start + VillagerAcquireTradeEvent event = new VillagerAcquireTradeEvent((AbstractVillager) getBukkitEntity(), merchantrecipe.asBukkit()); + // Suppress during worldgen + if (this.valid) { + Bukkit.getPluginManager().callEvent(event); + } + if (!event.isCancelled()) { + merchantrecipelist.add(CraftMerchantRecipe.fromBukkit(event.getRecipe()).toMinecraft()); + } + // CraftBukkit end + } + } + + } +} diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java new file mode 100644 index 000000000..a24e7127d --- /dev/null +++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java @@ -0,0 +1,267 @@ +package net.minecraft.server; + +import java.util.EnumSet; +import javax.annotation.Nullable; +// CraftBukkit start +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.inventory.CraftMerchantRecipe; +import org.bukkit.entity.AbstractVillager; +import org.bukkit.event.entity.VillagerAcquireTradeEvent; +// CraftBukkit end + +public class EntityVillagerTrader extends EntityVillagerAbstract { + + @Nullable + private BlockPosition bA; + private int bB; + + public EntityVillagerTrader(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.attachedToPlayer = true; + } + + @Override + protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, PotionUtil.a(new ItemStack(Items.POTION), Potions.INVISIBILITY), SoundEffects.ENTITY_WANDERING_TRADER_DISAPPEARED, (entityvillagertrader) -> { + return !this.world.J() && !entityvillagertrader.isInvisible(); + })); + this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, new ItemStack(Items.MILK_BUCKET), SoundEffects.ENTITY_WANDERING_TRADER_REAPPEARED, (entityvillagertrader) -> { + return this.world.J() && entityvillagertrader.isInvisible(); + })); + this.goalSelector.a(1, new PathfinderGoalTradeWithPlayer(this)); + this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityZombie.class, 8.0F, 0.5D, 0.5D)); + this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityEvoker.class, 12.0F, 0.5D, 0.5D)); + this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityVindicator.class, 8.0F, 0.5D, 0.5D)); + this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityVex.class, 8.0F, 0.5D, 0.5D)); + this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityPillager.class, 15.0F, 0.5D, 0.5D)); + this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityIllagerIllusioner.class, 12.0F, 0.5D, 0.5D)); + this.goalSelector.a(1, new PathfinderGoalPanic(this, 0.5D)); + this.goalSelector.a(1, new PathfinderGoalLookAtTradingPlayer(this)); + this.goalSelector.a(2, new EntityVillagerTrader.a(this, 2.0D, 0.35D)); + this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); + this.goalSelector.a(8, new PathfinderGoalRandomStrollLand(this, 0.35D)); + this.goalSelector.a(9, new PathfinderGoalInteract(this, EntityHuman.class, 3.0F, 1.0F)); + this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + } + + @Nullable + @Override + public EntityAgeable createChild(EntityAgeable entityageable) { + return null; + } + + @Override + public boolean ea() { + return false; + } + + @Override + public boolean a(EntityHuman entityhuman, EnumHand enumhand) { + ItemStack itemstack = entityhuman.b(enumhand); + boolean flag = itemstack.getItem() == Items.NAME_TAG; + + if (flag) { + itemstack.a(entityhuman, (EntityLiving) this, enumhand); + return true; + } else if (itemstack.getItem() != Items.VILLAGER_SPAWN_EGG && this.isAlive() && !this.dY() && !this.isBaby()) { + if (enumhand == EnumHand.MAIN_HAND) { + entityhuman.a(StatisticList.TALKED_TO_VILLAGER); + } + + if (this.getOffers().isEmpty()) { + return super.a(entityhuman, enumhand); + } else { + if (!this.world.isClientSide) { + this.setTradingPlayer(entityhuman); + this.openTrade(entityhuman, this.getScoreboardDisplayName(), 1); + } + + return true; + } + } else { + return super.a(entityhuman, enumhand); + } + } + + @Override + protected void eh() { + VillagerTrades.IMerchantRecipeOption[] avillagertrades_imerchantrecipeoption = (VillagerTrades.IMerchantRecipeOption[]) VillagerTrades.b.get(1); + VillagerTrades.IMerchantRecipeOption[] avillagertrades_imerchantrecipeoption1 = (VillagerTrades.IMerchantRecipeOption[]) VillagerTrades.b.get(2); + + if (avillagertrades_imerchantrecipeoption != null && avillagertrades_imerchantrecipeoption1 != null) { + MerchantRecipeList merchantrecipelist = this.getOffers(); + + this.a(merchantrecipelist, avillagertrades_imerchantrecipeoption, 5); + int i = this.random.nextInt(avillagertrades_imerchantrecipeoption1.length); + VillagerTrades.IMerchantRecipeOption villagertrades_imerchantrecipeoption = avillagertrades_imerchantrecipeoption1[i]; + MerchantRecipe merchantrecipe = villagertrades_imerchantrecipeoption.a(this, this.random); + + if (merchantrecipe != null) { + // CraftBukkit start + VillagerAcquireTradeEvent event = new VillagerAcquireTradeEvent((AbstractVillager) getBukkitEntity(), merchantrecipe.asBukkit()); + // Suppress during worldgen + if (this.valid) { + Bukkit.getPluginManager().callEvent(event); + } + if (!event.isCancelled()) { + merchantrecipelist.add(CraftMerchantRecipe.fromBukkit(event.getRecipe()).toMinecraft()); + } + // CraftBukkit end + } + + } + } + + @Override + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("DespawnDelay", this.bB); + if (this.bA != null) { + nbttagcompound.set("WanderTarget", GameProfileSerializer.a(this.bA)); + } + + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("DespawnDelay", 99)) { + this.bB = nbttagcompound.getInt("DespawnDelay"); + } + + if (nbttagcompound.hasKey("WanderTarget")) { + this.bA = GameProfileSerializer.c(nbttagcompound.getCompound("WanderTarget")); + } + + this.setAgeRaw(Math.max(0, this.getAge())); + } + + @Override + public boolean isTypeNotPersistent(double d0) { + return false; + } + + @Override + protected void b(MerchantRecipe merchantrecipe) { + if (merchantrecipe.isRewardExp()) { + int i = 3 + this.random.nextInt(4); + + this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY + 0.5D, this.locZ, i, org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, this.getTrader(), this)); // Paper + } + + } + + @Override + protected SoundEffect getSoundAmbient() { + return this.dY() ? SoundEffects.ENTITY_WANDERING_TRADER_TRADE : SoundEffects.ENTITY_WANDERING_TRADER_AMBIENT; + } + + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { + return SoundEffects.ENTITY_WANDERING_TRADER_HURT; + } + + @Override + protected SoundEffect getSoundDeath() { + return SoundEffects.ENTITY_WANDERING_TRADER_DEATH; + } + + @Override + protected SoundEffect c(ItemStack itemstack) { + Item item = itemstack.getItem(); + + return item == Items.MILK_BUCKET ? SoundEffects.ENTITY_WANDERING_TRADER_DRINK_MILK : SoundEffects.ENTITY_WANDERING_TRADER_DRINK_POTION; + } + + @Override + protected SoundEffect r(boolean flag) { + return flag ? SoundEffects.ENTITY_WANDERING_TRADER_YES : SoundEffects.ENTITY_WANDERING_TRADER_NO; + } + + @Override + public SoundEffect eb() { + return SoundEffects.ENTITY_WANDERING_TRADER_YES; + } + + public void t(int i) { + this.bB = i; + } + + public int ef() { + return this.bB; + } + + @Override + public void movementTick() { + super.movementTick(); + if (!this.world.isClientSide) { + this.ej(); + } + + } + + private void ej() { + if (this.bB > 0 && !this.dY() && --this.bB == 0) { + this.die(); + } + + } + + public void g(@Nullable BlockPosition blockposition) { + this.bA = blockposition; + } + + @Nullable + private BlockPosition ek() { + return this.bA; + } + + class a extends PathfinderGoal { + + final EntityVillagerTrader a; + final double b; + final double c; + + a(EntityVillagerTrader entityvillagertrader, double d0, double d1) { + this.a = entityvillagertrader; + this.b = d0; + this.c = d1; + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); + } + + @Override + public void d() { + this.a.g((BlockPosition) null); + EntityVillagerTrader.this.navigation.o(); + } + + @Override + public boolean a() { + BlockPosition blockposition = this.a.ek(); + + return blockposition != null && this.a(blockposition, this.b); + } + + @Override + public void e() { + BlockPosition blockposition = this.a.ek(); + + if (blockposition != null && EntityVillagerTrader.this.navigation.n()) { + if (this.a(blockposition, 10.0D)) { + Vec3D vec3d = (new Vec3D((double) blockposition.getX() - this.a.locX, (double) blockposition.getY() - this.a.locY, (double) blockposition.getZ() - this.a.locZ)).d(); + Vec3D vec3d1 = vec3d.a(10.0D).add(this.a.locX, this.a.locY, this.a.locZ); + + EntityVillagerTrader.this.navigation.a(vec3d1.x, vec3d1.y, vec3d1.z, this.c); + } else { + EntityVillagerTrader.this.navigation.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), this.c); + } + } + + } + + private boolean a(BlockPosition blockposition, double d0) { + return !blockposition.a((IPosition) this.a.getPositionVector(), d0); + } + } +} diff --git a/src/main/java/net/minecraft/server/EntityVindicator.java b/src/main/java/net/minecraft/server/EntityVindicator.java index 4bbb4817b..ffbd6e926 100644 --- a/src/main/java/net/minecraft/server/EntityVindicator.java +++ b/src/main/java/net/minecraft/server/EntityVindicator.java @@ -1,120 +1,216 @@ package net.minecraft.server; +import com.google.common.collect.Maps; +import java.util.EnumSet; +import java.util.Map; import java.util.function.Predicate; import javax.annotation.Nullable; public class EntityVindicator extends EntityIllagerAbstract { - private boolean b; public boolean isJohnny() { return b; } public void setJohnny(boolean johnny) { b = johnny; } // Paper - OBFHELPER - private static final Predicate c = (entity) -> { - return entity instanceof EntityLiving && ((EntityLiving) entity).df(); + private static final Predicate b = (enumdifficulty) -> { + return enumdifficulty == EnumDifficulty.NORMAL || enumdifficulty == EnumDifficulty.HARD; }; + private boolean bz; public boolean isJohnny() { return bz; } public void setJohnny(boolean johnny) { bz = johnny; } // Paper - OBFHELPER - public EntityVindicator(World world) { - super(EntityTypes.VINDICATOR, world); - this.setSize(0.6F, 1.95F); + public EntityVindicator(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - protected void n() { - super.n(); + @Override + protected void initPathfinder() { + super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); - this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false)); + this.goalSelector.a(1, new EntityVindicator.a(this)); + this.goalSelector.a(2, new EntityIllagerAbstract.b(this)); + this.goalSelector.a(3, new EntityRaider.a(this, 10.0F)); + this.goalSelector.a(4, new EntityVindicator.c(this)); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // Paper - decompile fix + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, true)); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); + this.targetSelector.a(4, new EntityVindicator.b(this)); this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[] { EntityVindicator.class})); - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, true)); - this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); - this.targetSelector.a(4, new EntityVindicator.a(this)); } + @Override + protected void mobTick() { + if (!this.isNoAI()) { + if (((WorldServer) this.world).d_(new BlockPosition(this))) { + ((Navigation) this.getNavigation()).a(true); + } else { + ((Navigation) this.getNavigation()).a(false); + } + } + + super.mobTick(); + } + + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.3499999940395355D); this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(12.0D); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(24.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(24.0D); this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(5.0D); } - protected void x_() { - super.x_(); - } - - protected MinecraftKey getDefaultLootTable() { - return LootTables.aC; - } - - public void a(boolean flag) { - this.a(1, flag); - } - + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - if (this.b) { + if (this.bz) { nbttagcompound.setBoolean("Johnny", true); } } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKeyOfType("Johnny", 99)) { - this.b = nbttagcompound.getBoolean("Johnny"); + this.bz = nbttagcompound.getBoolean("Johnny"); } } - @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - GroupDataEntity groupdataentity1 = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + @Override + public SoundEffect dV() { + return SoundEffects.ENTITY_VINDICATOR_CELEBRATE; + } + @Nullable + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + GroupDataEntity groupdataentity1 = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + + ((Navigation) this.getNavigation()).a(true); this.a(difficultydamagescaler); this.b(difficultydamagescaler); return groupdataentity1; } + @Override protected void a(DifficultyDamageScaler difficultydamagescaler) { - this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.IRON_AXE)); - } - - protected void mobTick() { - super.mobTick(); - this.a(this.getGoalTarget() != null); + if (this.ej() == null) { + this.setSlot(EnumItemSlot.MAINHAND, new ItemStack(Items.IRON_AXE)); + } + } + @Override public boolean r(Entity entity) { return super.r(entity) ? true : (entity instanceof EntityLiving && ((EntityLiving) entity).getMonsterType() == EnumMonsterType.ILLAGER ? this.getScoreboardTeam() == null && entity.getScoreboardTeam() == null : false); } + @Override public void setCustomName(@Nullable IChatBaseComponent ichatbasecomponent) { super.setCustomName(ichatbasecomponent); - if (!this.b && ichatbasecomponent != null && ichatbasecomponent.getString().equals("Johnny")) { - this.b = true; + if (!this.bz && ichatbasecomponent != null && ichatbasecomponent.getString().equals("Johnny")) { + this.bz = true; } } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_VINDICATOR_AMBIENT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_VINDICATOR_DEATH; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_VINDICATOR_HURT; } - static class a extends PathfinderGoalNearestAttackableTarget { + @Override + public void a(int i, boolean flag) { + ItemStack itemstack = new ItemStack(Items.IRON_AXE); + Raid raid = this.ej(); + byte b0 = 1; - public a(EntityVindicator entityvindicator) { - super(entityvindicator, EntityLiving.class, 0, true, true, EntityVindicator.c); + if (i > raid.a(EnumDifficulty.NORMAL)) { + b0 = 2; } + boolean flag1 = this.random.nextFloat() <= raid.w(); + + if (flag1) { + Map map = Maps.newHashMap(); + + map.put(Enchantments.DAMAGE_ALL, Integer.valueOf(b0)); + EnchantmentManager.a((Map) map, itemstack); + } + + this.setSlot(EnumItemSlot.MAINHAND, itemstack); + } + + static class b extends PathfinderGoalNearestAttackableTarget { + + public b(EntityVindicator entityvindicator) { + super(entityvindicator, EntityLiving.class, 0, true, true, EntityLiving::du); + } + + @Override public boolean a() { - return ((EntityVindicator) this.e).b && super.a(); + return ((EntityVindicator) this.e).bz && super.a(); + } + + @Override + public void c() { + super.c(); + this.e.n(0); + } + } + + static class a extends PathfinderGoalBreakDoor { + + public a(EntityInsentient entityinsentient) { + super(entityinsentient, 6, EntityVindicator.b); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); + } + + @Override + public boolean b() { + EntityVindicator entityvindicator = (EntityVindicator) this.entity; + + return entityvindicator.ek() && super.b(); + } + + @Override + public boolean a() { + EntityVindicator entityvindicator = (EntityVindicator) this.entity; + + return entityvindicator.ek() && entityvindicator.random.nextInt(10) == 0 && super.a(); + } + + @Override + public void c() { + super.c(); + this.entity.n(0); + } + } + + class c extends PathfinderGoalMeleeAttack { + + public c(EntityVindicator entityvindicator) { + super(entityvindicator, 1.0D, false); + } + + @Override + protected double a(EntityLiving entityliving) { + if (this.a.getVehicle() instanceof EntityRavager) { + float f = this.a.getVehicle().getWidth() - 0.1F; + + return (double) (f * 2.0F * f * 2.0F + entityliving.getWidth()); + } else { + return super.a(entityliving); + } } } } diff --git a/src/main/java/net/minecraft/server/EntityWitch.java b/src/main/java/net/minecraft/server/EntityWitch.java index 955e0e19b..0b849f37c 100644 --- a/src/main/java/net/minecraft/server/EntityWitch.java +++ b/src/main/java/net/minecraft/server/EntityWitch.java @@ -9,68 +9,89 @@ import org.bukkit.entity.Witch; import java.util.Iterator; import java.util.List; import java.util.UUID; -import javax.annotation.Nullable; +import java.util.function.Predicate; -public class EntityWitch extends EntityMonster implements IRangedEntity { +public class EntityWitch extends EntityRaider implements IRangedEntity { - private static final UUID a = UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E"); - private static final AttributeModifier b = (new AttributeModifier(EntityWitch.a, "Drinking speed penalty", -0.25D, 0)).a(false); private static final AttributeModifier DRINKING_SPEED = b; // Paper - OBFHELPER - private static final DataWatcherObject c = DataWatcher.a(EntityWitch.class, DataWatcherRegistry.i); - private int bC; public int getPotionUseTimeLeft() { return bC; } public void setPotionUseTimeLeft(int timeLeft) { bC = timeLeft; } // Paper - OBFHELPER + private static final UUID b = UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E"); + private static final AttributeModifier bz = (new AttributeModifier(EntityWitch.b, "Drinking speed penalty", -0.25D, AttributeModifier.Operation.ADDITION)).a(false); private static final AttributeModifier DRINKING_SPEED = bz; // Paper - OBFHELPER + private static final DataWatcherObject bA = DataWatcher.a(EntityWitch.class, DataWatcherRegistry.i); + private int bB; public int getPotionUseTimeLeft() { return bB; } public void setPotionUseTimeLeft(int timeLeft) { bB = timeLeft; } // Paper - OBFHELPER + private PathfinderGoalNearestHealableRaider bC; + private PathfinderGoalNearestAttackableTargetWitch bD; - public EntityWitch(World world) { - super(EntityTypes.WITCH, world); - this.setSize(0.6F, 1.95F); + public EntityWitch(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - protected void n() { + @Override + protected void initPathfinder() { + super.initPathfinder(); + this.bC = new PathfinderGoalNearestHealableRaider<>(this, EntityRaider.class, true, (entityliving) -> { + return entityliving != null && this.ek() && entityliving.getEntityType() != EntityTypes.WITCH; + }); + this.bD = new PathfinderGoalNearestAttackableTargetWitch<>(this, EntityHuman.class, 10, true, false, (Predicate) null); this.goalSelector.a(1, new PathfinderGoalFloat(this)); this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 60, 10.0F)); this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(3, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})); + this.targetSelector.a(2, this.bC); + this.targetSelector.a(3, this.bD); } - protected void x_() { - super.x_(); - this.getDataWatcher().register(EntityWitch.c, false); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.getDataWatcher().register(EntityWitch.bA, false); } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_WITCH_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_WITCH_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_WITCH_DEATH; } - public void setDrinkingPotion(boolean drinkingPotion) { a(drinkingPotion); } // Paper - OBFHELPER - public void a(boolean flag) { - this.getDataWatcher().set(EntityWitch.c, flag); + public void setDrinkingPotion(boolean drinkingPotion) { s(drinkingPotion); } // Paper - OBFHELPER + public void s(boolean flag) { + this.getDataWatcher().set(EntityWitch.bA, flag); } public boolean isDrinkingPotion() { return l(); } // Paper - OBFHELPER public boolean l() { - return (Boolean) this.getDataWatcher().get(EntityWitch.c); + return (Boolean) this.getDataWatcher().get(EntityWitch.bA); } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(26.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(26.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); } + @Override public void movementTick() { - if (!this.world.isClientSide) { + if (!this.world.isClientSide && this.isAlive()) { + this.bC.j(); + if (this.bC.h() <= 0) { + this.bD.a(true); + } else { + this.bD.a(false); + } + if (this.l()) { - if (this.bC-- <= 0) { - this.a(false); + if (this.bB-- <= 0) { + this.s(false); ItemStack itemstack = this.getItemInMainHand(); this.setSlot(EnumItemSlot.MAINHAND, ItemStack.a); @@ -92,32 +113,35 @@ public class EntityWitch extends EntityMonster implements IRangedEntity { } } - this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).c(EntityWitch.b); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).removeModifier(EntityWitch.bz); } } else { PotionRegistry potionregistry = null; if (this.random.nextFloat() < 0.15F && this.a(TagsFluid.WATER) && !this.hasEffect(MobEffects.WATER_BREATHING)) { - potionregistry = Potions.x; - } else if (this.random.nextFloat() < 0.15F && (this.isBurning() || this.cr() != null && this.cr().p()) && !this.hasEffect(MobEffects.FIRE_RESISTANCE)) { - potionregistry = Potions.m; + potionregistry = Potions.WATER_BREATHING; + } else if (this.random.nextFloat() < 0.15F && (this.isBurning() || this.cE() != null && this.cE().p()) && !this.hasEffect(MobEffects.FIRE_RESISTANCE)) { + potionregistry = Potions.FIRE_RESISTANCE; } else if (this.random.nextFloat() < 0.05F && this.getHealth() < this.getMaxHealth()) { - potionregistry = Potions.z; - } else if (this.random.nextFloat() < 0.5F && this.getGoalTarget() != null && !this.hasEffect(MobEffects.FASTER_MOVEMENT) && this.getGoalTarget().h(this) > 121.0D) { - potionregistry = Potions.o; + potionregistry = Potions.HEALING; + } else if (this.random.nextFloat() < 0.5F && this.getGoalTarget() != null && !this.hasEffect(MobEffects.FASTER_MOVEMENT) && this.getGoalTarget().h((Entity) this) > 121.0D) { + potionregistry = Potions.SWIFTNESS; } if (potionregistry != null) { - // Paper start - moved all this down into its own method - //this.setSlot(EnumItemSlot.MAINHAND, PotionUtil.a(new ItemStack(Items.POTION), potionregistry)); - //this.bC = this.getItemInMainHand().k(); - //this.a(true); - //this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_WITCH_DRINK, this.bV(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); - //AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); - //attributeinstance.c(EntityWitch.b); - //attributeinstance.b(EntityWitch.b); - - setDrinkingPotion(PotionUtil.addPotionToItemStack(new ItemStack(Items.POTION), potionregistry)); + // Paper start - move all this down into its own method +// ItemStack potion = PotionUtil.a(new ItemStack(Items.POTION), potionregistry); +// org.bukkit.inventory.ItemStack bukkitStack = com.destroystokyo.paper.event.entity.WitchReadyPotionEvent.process((org.bukkit.entity.Witch) this.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(potion)); +// this.setSlot(EnumItemSlot.MAINHAND, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(bukkitStack)); +// // Paper end +// this.bB = this.getItemInMainHand().k(); +// this.s(true); +// this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_WITCH_DRINK, this.getSoundCategory(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); +// AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); +// +// attributeinstance.removeModifier(EntityWitch.bz); +// attributeinstance.addModifier(EntityWitch.bz); + this.setDrinkingPotion(PotionUtil.addPotionToItemStack(new ItemStack(Items.POTION), potionregistry)); // Paper end } } @@ -142,6 +166,12 @@ public class EntityWitch extends EntityMonster implements IRangedEntity { } // Paper end + @Override + public SoundEffect dV() { + return SoundEffects.ENTITY_WITCH_CELEBRATE; + } + + @Override protected float applyMagicModifier(DamageSource damagesource, float f) { f = super.applyMagicModifier(damagesource, f); if (damagesource.getEntity() == this) { @@ -155,26 +185,30 @@ public class EntityWitch extends EntityMonster implements IRangedEntity { return f; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.v; - } - + @Override public void a(EntityLiving entityliving, float f) { if (!this.l()) { - double d0 = entityliving.locY + (double) entityliving.getHeadHeight() - 1.100000023841858D; - double d1 = entityliving.locX + entityliving.motX - this.locX; - double d2 = d0 - this.locY; - double d3 = entityliving.locZ + entityliving.motZ - this.locZ; - float f1 = MathHelper.sqrt(d1 * d1 + d3 * d3); - PotionRegistry potionregistry = Potions.B; + Vec3D vec3d = entityliving.getMot(); + double d0 = entityliving.locX + vec3d.x - this.locX; + double d1 = entityliving.locY + (double) entityliving.getHeadHeight() - 1.100000023841858D - this.locY; + double d2 = entityliving.locZ + vec3d.z - this.locZ; + float f1 = MathHelper.sqrt(d0 * d0 + d2 * d2); + PotionRegistry potionregistry = Potions.HARMING; - if (f1 >= 8.0F && !entityliving.hasEffect(MobEffects.SLOWER_MOVEMENT)) { - potionregistry = Potions.r; + if (entityliving instanceof EntityRaider) { + if (entityliving.getHealth() <= 4.0F) { + potionregistry = Potions.HEALING; + } else { + potionregistry = Potions.REGENERATION; + } + + this.setGoalTarget((EntityLiving) null); + } else if (f1 >= 8.0F && !entityliving.hasEffect(MobEffects.SLOWER_MOVEMENT)) { + potionregistry = Potions.SLOWNESS; } else if (entityliving.getHealth() >= 8.0F && !entityliving.hasEffect(MobEffects.POISON)) { - potionregistry = Potions.D; + potionregistry = Potions.POISON; } else if (f1 <= 3.0F && !entityliving.hasEffect(MobEffects.WEAKNESS) && this.random.nextFloat() < 0.25F) { - potionregistry = Potions.M; + potionregistry = Potions.WEAKNESS; } // Paper start @@ -184,19 +218,26 @@ public class EntityWitch extends EntityMonster implements IRangedEntity { return; } potion = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getPotion()); - EntityPotion entitypotion = new EntityPotion(this.world, this, potion); + EntityPotion entitypotion = new EntityPotion(this.world, this); + entitypotion.setItem(potion); // Paper end - entitypotion.pitch -= -20.0F; - entitypotion.shoot(d1, d2 + (double) (f1 * 0.2F), d3, 0.75F, 8.0F); - this.world.a((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_WITCH_THROW, this.bV(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); + entitypotion.shoot(d0, d1 + (double) (f1 * 0.2F), d2, 0.75F, 8.0F); + this.world.playSound((EntityHuman) null, this.locX, this.locY, this.locZ, SoundEffects.ENTITY_WITCH_THROW, this.getSoundCategory(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F); this.world.addEntity(entitypotion); } } - public float getHeadHeight() { + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { return 1.62F; } - public void s(boolean flag) {} + @Override + public void a(int i, boolean flag) {} + + @Override + public boolean dX() { + return false; + } } diff --git a/src/main/java/net/minecraft/server/EntityWither.java b/src/main/java/net/minecraft/server/EntityWither.java index 4b7fd2b98..8b3052b11 100644 --- a/src/main/java/net/minecraft/server/EntityWither.java +++ b/src/main/java/net/minecraft/server/EntityWither.java @@ -1,6 +1,7 @@ package net.minecraft.server; import com.google.common.collect.ImmutableList; +import java.util.EnumSet; import java.util.List; import java.util.function.Predicate; import javax.annotation.Nullable; @@ -14,114 +15,118 @@ import org.bukkit.event.entity.ExplosionPrimeEvent; public class EntityWither extends EntityMonster implements IRangedEntity { - private static final DataWatcherObject a = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); private static final DataWatcherObject b = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); private static final DataWatcherObject c = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); - private static final List> bC = ImmutableList.of(EntityWither.a, EntityWither.b, EntityWither.c); - private static final DataWatcherObject bD = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); + private static final DataWatcherObject d = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); + private static final List> bz = ImmutableList.of(EntityWither.b, EntityWither.c, EntityWither.d); + private static final DataWatcherObject bA = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); + private final float[] bB = new float[2]; + private final float[] bC = new float[2]; + private final float[] bD = new float[2]; private final float[] bE = new float[2]; - private final float[] bF = new float[2]; - private final float[] bG = new float[2]; - private final float[] bH = new float[2]; - private final int[] bI = new int[2]; - private final int[] bJ = new int[2]; - private int bK; + private final int[] bF = new int[2]; + private final int[] bG = new int[2]; + private int bH; public final BossBattleServer bossBattle; - private static final Predicate bM = (entity) -> { - return entity instanceof EntityLiving && ((EntityLiving) entity).getMonsterType() != EnumMonsterType.UNDEAD && ((EntityLiving) entity).df(); + private static final Predicate bJ = (entityliving) -> { + return entityliving.getMonsterType() != EnumMonsterType.UNDEAD && entityliving.du(); }; + private static final PathfinderTargetCondition bK = (new PathfinderTargetCondition()).a(20.0D).a(EntityWither.bJ); - public EntityWither(World world) { - super(EntityTypes.WITHER, world); + public EntityWither(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.bossBattle = (BossBattleServer) (new BossBattleServer(this.getScoreboardDisplayName(), BossBattle.BarColor.PURPLE, BossBattle.BarStyle.PROGRESS)).setDarkenSky(true); this.setHealth(this.getMaxHealth()); - this.setSize(0.9F, 3.5F); - this.fireProof = true; - ((Navigation) this.getNavigation()).d(true); - this.b_ = 50; + this.getNavigation().d(true); + this.f = 50; } - protected void n() { + @Override + protected void initPathfinder() { this.goalSelector.a(0, new EntityWither.a()); this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 40, 20.0F)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); - this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 0, false, false, EntityWither.bM)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0])); + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 0, false, false, EntityWither.bJ)); } - protected void x_() { - super.x_(); - this.datawatcher.register(EntityWither.a, 0); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); this.datawatcher.register(EntityWither.b, 0); this.datawatcher.register(EntityWither.c, 0); - this.datawatcher.register(EntityWither.bD, 0); + this.datawatcher.register(EntityWither.d, 0); + this.datawatcher.register(EntityWither.bA, 0); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setInt("Invul", this.dz()); + nbttagcompound.setInt("Invul", this.dV()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.d(nbttagcompound.getInt("Invul")); + this.r(nbttagcompound.getInt("Invul")); if (this.hasCustomName()) { this.bossBattle.a(this.getScoreboardDisplayName()); } } + @Override public void setCustomName(@Nullable IChatBaseComponent ichatbasecomponent) { super.setCustomName(ichatbasecomponent); this.bossBattle.a(this.getScoreboardDisplayName()); } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_WITHER_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_WITHER_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_WITHER_DEATH; } + @Override public void movementTick() { - this.motY *= 0.6000000238418579D; - double d0; - double d1; - double d2; + Vec3D vec3d = this.getMot().d(1.0D, 0.6D, 1.0D); - if (!this.world.isClientSide && this.p(0) > 0) { - Entity entity = this.world.getEntity(this.p(0)); + if (!this.world.isClientSide && this.getHeadTarget(0) > 0) { + Entity entity = this.world.getEntity(this.getHeadTarget(0)); if (entity != null) { - if (this.locY < entity.locY || !this.dA() && this.locY < entity.locY + 5.0D) { - if (this.motY < 0.0D) { - this.motY = 0.0D; - } + double d0 = vec3d.y; - this.motY += (0.5D - this.motY) * 0.6000000238418579D; + if (this.locY < entity.locY || !this.dW() && this.locY < entity.locY + 5.0D) { + d0 = Math.max(0.0D, d0); + d0 += 0.3D - d0 * 0.6000000238418579D; } - double d3 = entity.locX - this.locX; + vec3d = new Vec3D(vec3d.x, d0, vec3d.z); + Vec3D vec3d1 = new Vec3D(entity.locX - this.locX, 0.0D, entity.locZ - this.locZ); - d0 = entity.locZ - this.locZ; - d1 = d3 * d3 + d0 * d0; - if (d1 > 9.0D) { - d2 = (double) MathHelper.sqrt(d1); - this.motX += (d3 / d2 * 0.5D - this.motX) * 0.6000000238418579D; - this.motZ += (d0 / d2 * 0.5D - this.motZ) * 0.6000000238418579D; + if (b(vec3d1) > 9.0D) { + Vec3D vec3d2 = vec3d1.d(); + + vec3d = vec3d.add(vec3d2.x * 0.3D - vec3d.x * 0.6D, 0.0D, vec3d2.z * 0.3D - vec3d.z * 0.6D); } } } - if (this.motX * this.motX + this.motZ * this.motZ > 0.05000000074505806D) { - this.yaw = (float) MathHelper.c(this.motZ, this.motX) * 57.295776F - 90.0F; + this.setMot(vec3d); + if (b(vec3d) > 0.05D) { + this.yaw = (float) MathHelper.d(vec3d.z, vec3d.x) * 57.295776F - 90.0F; } super.movementTick(); @@ -129,14 +134,14 @@ public class EntityWither extends EntityMonster implements IRangedEntity { int i; for (i = 0; i < 2; ++i) { - this.bH[i] = this.bF[i]; - this.bG[i] = this.bE[i]; + this.bE[i] = this.bC[i]; + this.bD[i] = this.bB[i]; } int j; for (i = 0; i < 2; ++i) { - j = this.p(i + 1); + j = this.getHeadTarget(i + 1); Entity entity1 = null; if (j > 0) { @@ -144,71 +149,68 @@ public class EntityWither extends EntityMonster implements IRangedEntity { } if (entity1 != null) { - d0 = this.q(i + 1); - d1 = this.r(i + 1); - d2 = this.s(i + 1); - double d4 = entity1.locX - d0; - double d5 = entity1.locY + (double) entity1.getHeadHeight() - d1; - double d6 = entity1.locZ - d2; + double d1 = this.t(i + 1); + double d2 = this.u(i + 1); + double d3 = this.v(i + 1); + double d4 = entity1.locX - d1; + double d5 = entity1.locY + (double) entity1.getHeadHeight() - d2; + double d6 = entity1.locZ - d3; double d7 = (double) MathHelper.sqrt(d4 * d4 + d6 * d6); - float f = (float) (MathHelper.c(d6, d4) * 57.2957763671875D) - 90.0F; - float f1 = (float) (-(MathHelper.c(d5, d7) * 57.2957763671875D)); + float f = (float) (MathHelper.d(d6, d4) * 57.2957763671875D) - 90.0F; + float f1 = (float) (-(MathHelper.d(d5, d7) * 57.2957763671875D)); - this.bE[i] = this.c(this.bE[i], f1, 40.0F); - this.bF[i] = this.c(this.bF[i], f, 10.0F); + this.bB[i] = this.a(this.bB[i], f1, 40.0F); + this.bC[i] = this.a(this.bC[i], f, 10.0F); } else { - this.bF[i] = this.c(this.bF[i], this.aQ, 10.0F); + this.bC[i] = this.a(this.bC[i], this.aK, 10.0F); } } - // Akarin start - this handle by client - /* - boolean flag = this.dA(); + boolean flag = this.dW(); for (j = 0; j < 3; ++j) { - double d8 = this.q(j); - double d9 = this.r(j); - double d10 = this.s(j); + double d8 = this.t(j); + double d9 = this.u(j); + double d10 = this.v(j); - this.world.addParticle(Particles.M, d8 + this.random.nextGaussian() * 0.30000001192092896D, d9 + this.random.nextGaussian() * 0.30000001192092896D, d10 + this.random.nextGaussian() * 0.30000001192092896D, 0.0D, 0.0D, 0.0D); + this.world.addParticle(Particles.SMOKE, d8 + this.random.nextGaussian() * 0.30000001192092896D, d9 + this.random.nextGaussian() * 0.30000001192092896D, d10 + this.random.nextGaussian() * 0.30000001192092896D, 0.0D, 0.0D, 0.0D); if (flag && this.world.random.nextInt(4) == 0) { - this.world.addParticle(Particles.s, d8 + this.random.nextGaussian() * 0.30000001192092896D, d9 + this.random.nextGaussian() * 0.30000001192092896D, d10 + this.random.nextGaussian() * 0.30000001192092896D, 0.699999988079071D, 0.699999988079071D, 0.5D); + this.world.addParticle(Particles.ENTITY_EFFECT, d8 + this.random.nextGaussian() * 0.30000001192092896D, d9 + this.random.nextGaussian() * 0.30000001192092896D, d10 + this.random.nextGaussian() * 0.30000001192092896D, 0.699999988079071D, 0.699999988079071D, 0.5D); } } - if (this.dz() > 0) { + if (this.dV() > 0) { for (j = 0; j < 3; ++j) { - this.world.addParticle(Particles.s, this.locX + this.random.nextGaussian(), this.locY + (double) (this.random.nextFloat() * 3.3F), this.locZ + this.random.nextGaussian(), 0.699999988079071D, 0.699999988079071D, 0.8999999761581421D); + this.world.addParticle(Particles.ENTITY_EFFECT, this.locX + this.random.nextGaussian(), this.locY + (double) (this.random.nextFloat() * 3.3F), this.locZ + this.random.nextGaussian(), 0.699999988079071D, 0.699999988079071D, 0.8999999761581421D); } } - */ - // Akarin end } + @Override protected void mobTick() { int i; - if (this.dz() > 0) { - i = this.dz() - 1; + if (this.dV() > 0) { + i = this.dV() - 1; if (i <= 0) { + Explosion.Effect explosion_effect = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? Explosion.Effect.DESTROY : Explosion.Effect.NONE; // CraftBukkit start - // this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, 7.0F, false, this.world.getGameRules().getBoolean("mobGriefing")); + // this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, 7.0F, false, explosion_effect); ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false); this.world.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { - this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, event.getRadius(), event.getFire(), this.world.getGameRules().getBoolean("mobGriefing")); + this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, event.getRadius(), event.getFire(), explosion_effect); } // CraftBukkit end // CraftBukkit start - Use relative location for far away sounds - // this.world.a(1023, new BlockPosition(this), 0); + // this.world.b(1023, new BlockPosition(this), 0); // Paper start - //int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API - for (EntityHuman human : world.players) { - EntityPlayer player = (EntityPlayer) human; - int viewDistance = player.getViewDistance(); + int viewDistance = ((WorldServer) this.world).spigotConfig.viewDistance * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API + for (EntityPlayer player : ((WorldServer)world).getPlayers()) { + //final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch // Paper end double deltaX = this.locX - player.locX; double deltaZ = this.locZ - player.locZ; @@ -226,7 +228,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity { // CraftBukkit end } - this.d(i); + this.r(i); if (this.ticksLived % 10 == 0) { this.heal(10.0F, EntityRegainHealthEvent.RegainReason.WITHER_SPAWN); // CraftBukkit } @@ -237,13 +239,13 @@ public class EntityWither extends EntityMonster implements IRangedEntity { int j; for (i = 1; i < 3; ++i) { - if (this.ticksLived >= this.bI[i - 1]) { - this.bI[i - 1] = this.ticksLived + 10 + this.random.nextInt(10); + if (this.ticksLived >= this.bF[i - 1]) { + this.bF[i - 1] = this.ticksLived + 10 + this.random.nextInt(10); if (this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) { int k = i - 1; - int l = this.bJ[i - 1]; + int l = this.bG[i - 1]; - this.bJ[k] = this.bJ[i - 1] + 1; + this.bG[k] = this.bG[i - 1] + 1; if (l > 15) { float f = 10.0F; float f1 = 5.0F; @@ -252,27 +254,27 @@ public class EntityWither extends EntityMonster implements IRangedEntity { double d2 = MathHelper.a(this.random, this.locZ - 10.0D, this.locZ + 10.0D); this.a(i + 1, d0, d1, d2, true); - this.bJ[i - 1] = 0; + this.bG[i - 1] = 0; } } - j = this.p(i); + j = this.getHeadTarget(i); if (j > 0) { Entity entity = this.world.getEntity(j); if (entity != null && entity.isAlive() && this.h(entity) <= 900.0D && this.hasLineOfSight(entity)) { if (entity instanceof EntityHuman && ((EntityHuman) entity).abilities.isInvulnerable) { - this.a(i, 0); + this.setHeadTarget(i, 0); } else { this.a(i + 1, (EntityLiving) entity); - this.bI[i - 1] = this.ticksLived + 40 + this.random.nextInt(20); - this.bJ[i - 1] = 0; + this.bF[i - 1] = this.ticksLived + 40 + this.random.nextInt(20); + this.bG[i - 1] = 0; } } else { - this.a(i, 0); + this.setHeadTarget(i, 0); } } else { - List list = this.world.a(EntityLiving.class, this.getBoundingBox().grow(20.0D, 8.0D, 20.0D), EntityWither.bM.and(IEntitySelector.f)); + List list = this.world.a(EntityLiving.class, EntityWither.bK, this, this.getBoundingBox().grow(20.0D, 8.0D, 20.0D)); for (int i1 = 0; i1 < 10 && !list.isEmpty(); ++i1) { EntityLiving entityliving = (EntityLiving) list.get(this.random.nextInt(list.size())); @@ -281,11 +283,11 @@ public class EntityWither extends EntityMonster implements IRangedEntity { if (entityliving instanceof EntityHuman) { if (!((EntityHuman) entityliving).abilities.isInvulnerable) { if (CraftEventFactory.callEntityTargetLivingEvent(this, entityliving, EntityTargetEvent.TargetReason.CLOSEST_PLAYER).isCancelled()) continue; // CraftBukkit - this.a(i, entityliving.getId()); + this.setHeadTarget(i, entityliving.getId()); } } else { if (CraftEventFactory.callEntityTargetLivingEvent(this, entityliving, EntityTargetEvent.TargetReason.CLOSEST_ENTITY).isCancelled()) continue; // CraftBukkit - this.a(i, entityliving.getId()); + this.setHeadTarget(i, entityliving.getId()); } break; } @@ -297,14 +299,14 @@ public class EntityWither extends EntityMonster implements IRangedEntity { } if (this.getGoalTarget() != null) { - this.a(0, this.getGoalTarget().getId()); + this.setHeadTarget(0, this.getGoalTarget().getId()); } else { - this.a(0, 0); + this.setHeadTarget(0, 0); } - if (this.bK > 0) { - --this.bK; - if (this.bK == 0 && this.world.getGameRules().getBoolean("mobGriefing")) { + if (this.bH > 0) { + --this.bH; + if (this.bH == 0 && this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { i = MathHelper.floor(this.locY); j = MathHelper.floor(this.locX); int j1 = MathHelper.floor(this.locZ); @@ -318,15 +320,14 @@ public class EntityWither extends EntityMonster implements IRangedEntity { int l2 = j1 + l1; BlockPosition blockposition = new BlockPosition(j2, k2, l2); IBlockData iblockdata = this.world.getType(blockposition); - Block block = iblockdata.getBlock(); - if (!iblockdata.isAir() && a(block)) { + if (b(iblockdata)) { // CraftBukkit start if (CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { continue; } // CraftBukkit end - flag = this.world.setAir(blockposition, true) || flag; + flag = this.world.b(blockposition, true) || flag; } } } @@ -346,54 +347,57 @@ public class EntityWither extends EntityMonster implements IRangedEntity { } } - public static boolean a(Block block) { - return block != Blocks.BEDROCK && block != Blocks.END_PORTAL && block != Blocks.END_PORTAL_FRAME && block != Blocks.COMMAND_BLOCK && block != Blocks.REPEATING_COMMAND_BLOCK && block != Blocks.CHAIN_COMMAND_BLOCK && block != Blocks.BARRIER && block != Blocks.STRUCTURE_BLOCK && block != Blocks.STRUCTURE_VOID && block != Blocks.MOVING_PISTON && block != Blocks.END_GATEWAY; + public static boolean b(IBlockData iblockdata) { + return !iblockdata.isAir() && !TagsBlock.WITHER_IMMUNE.isTagged(iblockdata.getBlock()); } public void l() { - this.d(220); + this.r(220); this.setHealth(this.getMaxHealth() / 3.0F); } - public void bh() {} + @Override + public void a(IBlockData iblockdata, Vec3D vec3d) {} + @Override public void b(EntityPlayer entityplayer) { super.b(entityplayer); this.bossBattle.addPlayer(entityplayer); } + @Override public void c(EntityPlayer entityplayer) { super.c(entityplayer); this.bossBattle.removePlayer(entityplayer); } - private double q(int i) { + private double t(int i) { if (i <= 0) { return this.locX; } else { - float f = (this.aQ + (float) (180 * (i - 1))) * 0.017453292F; + float f = (this.aK + (float) (180 * (i - 1))) * 0.017453292F; float f1 = MathHelper.cos(f); return this.locX + (double) f1 * 1.3D; } } - private double r(int i) { + private double u(int i) { return i <= 0 ? this.locY + 3.0D : this.locY + 2.2D; } - private double s(int i) { + private double v(int i) { if (i <= 0) { return this.locZ; } else { - float f = (this.aQ + (float) (180 * (i - 1))) * 0.017453292F; + float f = (this.aK + (float) (180 * (i - 1))) * 0.017453292F; float f1 = MathHelper.sin(f); return this.locZ + (double) f1 * 1.3D; } } - private float c(float f, float f1, float f2) { + private float a(float f, float f1, float f2) { float f3 = MathHelper.g(f1 - f); if (f3 > f2) { @@ -413,9 +417,9 @@ public class EntityWither extends EntityMonster implements IRangedEntity { private void a(int i, double d0, double d1, double d2, boolean flag) { this.world.a((EntityHuman) null, 1024, new BlockPosition(this), 0); - double d3 = this.q(i); - double d4 = this.r(i); - double d5 = this.s(i); + double d3 = this.t(i); + double d4 = this.u(i); + double d5 = this.v(i); double d6 = d0 - d3; double d7 = d1 - d4; double d8 = d2 - d5; @@ -431,20 +435,22 @@ public class EntityWither extends EntityMonster implements IRangedEntity { this.world.addEntity(entitywitherskull); } + @Override public void a(EntityLiving entityliving, float f) { this.a(0, entityliving); } + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; } else if (damagesource != DamageSource.DROWN && !(damagesource.getEntity() instanceof EntityWither)) { - if (this.dz() > 0 && damagesource != DamageSource.OUT_OF_WORLD) { + if (this.dV() > 0 && damagesource != DamageSource.OUT_OF_WORLD) { return false; } else { Entity entity; - if (this.dA()) { + if (this.dW()) { entity = damagesource.j(); if (entity instanceof EntityArrow) { return false; @@ -455,12 +461,12 @@ public class EntityWither extends EntityMonster implements IRangedEntity { if (entity != null && !(entity instanceof EntityHuman) && entity instanceof EntityLiving && ((EntityLiving) entity).getMonsterType() == this.getMonsterType()) { return false; } else { - if (this.bK <= 0) { - this.bK = 20; + if (this.bH <= 0) { + this.bH = 20; } - for (int i = 0; i < this.bJ.length; ++i) { - this.bJ[i] += 3; + for (int i = 0; i < this.bG.length; ++i) { + this.bG[i] += 3; } return super.damageEntity(damagesource, f); @@ -471,7 +477,9 @@ public class EntityWither extends EntityMonster implements IRangedEntity { } } - protected void dropDeathLoot(boolean flag, int i) { + @Override + protected void dropDeathLoot(DamageSource damagesource, int i, boolean flag) { + super.dropDeathLoot(damagesource, i, flag); EntityItem entityitem = this.a((IMaterial) Items.NETHER_STAR); if (entityitem != null) { @@ -480,66 +488,77 @@ public class EntityWither extends EntityMonster implements IRangedEntity { } - protected void I() { + @Override + protected void checkDespawn() { this.ticksFarFromPlayer = 0; } - public void c(float f, float f1) {} + @Override + public void b(float f, float f1) {} + @Override public boolean addEffect(MobEffect mobeffect) { return false; } + @Override protected void initAttributes() { super.initAttributes(); - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(300.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(300.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.6000000238418579D); this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(40.0D); - this.getAttributeInstance(GenericAttributes.h).setValue(4.0D); + this.getAttributeInstance(GenericAttributes.ARMOR).setValue(4.0D); } - public int dz() { - return (Integer) this.datawatcher.get(EntityWither.bD); + public int dV() { + return (Integer) this.datawatcher.get(EntityWither.bA); } - public void d(int i) { - this.datawatcher.set(EntityWither.bD, i); + public void r(int i) { + this.datawatcher.set(EntityWither.bA, i); } - public int p(int i) { - return (Integer) this.datawatcher.get((DataWatcherObject) EntityWither.bC.get(i)); + public int getHeadTarget(int i) { + return (Integer) this.datawatcher.get((DataWatcherObject) EntityWither.bz.get(i)); } - public void a(int i, int j) { - this.datawatcher.set((DataWatcherObject) EntityWither.bC.get(i), j); + public void setHeadTarget(int i, int j) { + this.datawatcher.set((DataWatcherObject) EntityWither.bz.get(i), j); } - public boolean dA() { + public boolean dW() { return this.getHealth() <= this.getMaxHealth() / 2.0F; } + @Override public EnumMonsterType getMonsterType() { return EnumMonsterType.UNDEAD; } + @Override protected boolean n(Entity entity) { return false; } - public boolean bm() { + @Override + public boolean canPortal() { return false; } - public void s(boolean flag) {} + @Override + public boolean d(MobEffect mobeffect) { + return mobeffect.getMobEffect() == MobEffects.WITHER ? false : super.d(mobeffect); + } class a extends PathfinderGoal { public a() { - this.a(7); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.JUMP, PathfinderGoal.Type.LOOK)); } + @Override public boolean a() { - return EntityWither.this.dz() > 0; + return EntityWither.this.dV() > 0; } } } diff --git a/src/main/java/net/minecraft/server/EntityWitherSkull.java b/src/main/java/net/minecraft/server/EntityWitherSkull.java index ea1ab45f3..2a056024f 100644 --- a/src/main/java/net/minecraft/server/EntityWitherSkull.java +++ b/src/main/java/net/minecraft/server/EntityWitherSkull.java @@ -4,47 +4,53 @@ import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit public class EntityWitherSkull extends EntityFireball { - private static final DataWatcherObject e = DataWatcher.a(EntityWitherSkull.class, DataWatcherRegistry.i); + private static final DataWatcherObject f = DataWatcher.a(EntityWitherSkull.class, DataWatcherRegistry.i); - public EntityWitherSkull(World world) { - super(EntityTypes.WITHER_SKULL, world, 0.3125F, 0.3125F); + public EntityWitherSkull(EntityTypes entitytypes, World world) { + super(entitytypes, world); } public EntityWitherSkull(World world, EntityLiving entityliving, double d0, double d1, double d2) { - super(EntityTypes.WITHER_SKULL, entityliving, d0, d1, d2, world, 0.3125F, 0.3125F); + super(EntityTypes.WITHER_SKULL, entityliving, d0, d1, d2, world); } + @Override protected float k() { return this.isCharged() ? 0.73F : super.k(); } + @Override public boolean isBurning() { return false; } + @Override public float a(Explosion explosion, IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid, float f) { - return this.isCharged() && EntityWither.a(iblockdata.getBlock()) ? Math.min(0.8F, f) : f; + return this.isCharged() && EntityWither.b(iblockdata) ? Math.min(0.8F, f) : f; } + @Override protected void a(MovingObjectPosition movingobjectposition) { if (!this.world.isClientSide) { - if (movingobjectposition.entity != null) { + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + Entity entity = ((MovingObjectPositionEntity) movingobjectposition).getEntity(); + // Spigot start boolean didDamage = false; if (this.shooter != null) { - didDamage = movingobjectposition.entity.damageEntity(DamageSource.projectile(this, shooter), 8.0F); + didDamage = entity.damageEntity(DamageSource.projectile(this, shooter), 8.0F); if (didDamage) { // CraftBukkit - if (movingobjectposition.entity.isAlive()) { - this.a(this.shooter, movingobjectposition.entity); + if (entity.isAlive()) { + this.a(this.shooter, entity); } else { this.shooter.heal(5.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.WITHER); // CraftBukkit } } } else { - didDamage = movingobjectposition.entity.damageEntity(DamageSource.MAGIC, 5.0F); + didDamage = entity.damageEntity(DamageSource.MAGIC, 5.0F); } - if (didDamage && movingobjectposition.entity instanceof EntityLiving) { + if (didDamage && entity instanceof EntityLiving) { // Spigot end byte b0 = 0; @@ -55,18 +61,20 @@ public class EntityWitherSkull extends EntityFireball { } if (b0 > 0) { - ((EntityLiving) movingobjectposition.entity).addEffect(new MobEffect(MobEffects.WITHER, 20 * b0, 1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit + ((EntityLiving) entity).addEffect(new MobEffect(MobEffects.WITHER, 20 * b0, 1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit } } } + Explosion.Effect explosion_effect = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? Explosion.Effect.DESTROY : Explosion.Effect.NONE; + // CraftBukkit start - // this.world.createExplosion(this, this.locX, this.locY, this.locZ, 1.0F, false, this.world.getGameRules().getBoolean("mobGriefing")); + // this.world.createExplosion(this, this.locX, this.locY, this.locZ, 1.0F, false, explosion_effect); ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 1.0F, false); this.world.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { - this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), this.world.getGameRules().getBoolean("mobGriefing")); + this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), explosion_effect); } // CraftBukkit end this.die(); @@ -74,27 +82,31 @@ public class EntityWitherSkull extends EntityFireball { } + @Override public boolean isInteractable() { return false; } + @Override public boolean damageEntity(DamageSource damagesource, float f) { return false; } - protected void x_() { - this.datawatcher.register(EntityWitherSkull.e, false); + @Override + protected void initDatawatcher() { + this.datawatcher.register(EntityWitherSkull.f, false); } public boolean isCharged() { - return (Boolean) this.datawatcher.get(EntityWitherSkull.e); + return (Boolean) this.datawatcher.get(EntityWitherSkull.f); } public void setCharged(boolean flag) { - this.datawatcher.set(EntityWitherSkull.e, flag); + this.datawatcher.set(EntityWitherSkull.f, flag); } - protected boolean f() { + @Override + protected boolean K_() { return false; } } diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java index ca8e19985..02492663a 100644 --- a/src/main/java/net/minecraft/server/EntityWolf.java +++ b/src/main/java/net/minecraft/server/EntityWolf.java @@ -1,6 +1,7 @@ package net.minecraft.server; import java.util.UUID; +import java.util.function.Predicate; import javax.annotation.Nullable; // CraftBukkit start @@ -11,22 +12,27 @@ import org.bukkit.event.entity.EntityTargetEvent.TargetReason; public class EntityWolf extends EntityTameableAnimal { private static final DataWatcherObject DATA_HEALTH = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.c); - private static final DataWatcherObject bH = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.i); - private static final DataWatcherObject bI = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.b); - private float bJ; - private float bK; - private boolean bL; - private boolean bM; - private float bN; - private float bO; + private static final DataWatcherObject bE = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.i); + private static final DataWatcherObject bF = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.b); + public static final Predicate bC = (entityliving) -> { + EntityTypes entitytypes = entityliving.getEntityType(); - public EntityWolf(World world) { - super(EntityTypes.WOLF, world); - this.setSize(0.6F, 0.85F); + return entitytypes == EntityTypes.SHEEP || entitytypes == EntityTypes.RABBIT || entitytypes == EntityTypes.FOX; + }; + private float bG; + private float bH; + private boolean bI; + private boolean bJ; + private float bK; + private float bL; + + public EntityWolf(EntityTypes entitytypes, World world) { + super(entitytypes, world); this.setTamed(false); } - protected void n() { + @Override + protected void initPathfinder() { this.goalSit = new PathfinderGoalSit(this); this.goalSelector.a(1, new PathfinderGoalFloat(this)); this.goalSelector.a(2, this.goalSit); @@ -41,21 +47,20 @@ public class EntityWolf extends EntityTameableAnimal { this.goalSelector.a(10, new PathfinderGoalRandomLookaround(this)); this.targetSelector.a(1, new PathfinderGoalOwnerHurtByTarget(this)); this.targetSelector.a(2, new PathfinderGoalOwnerHurtTarget(this)); - this.targetSelector.a(3, new PathfinderGoalHurtByTarget(this, true, new Class[0])); - this.targetSelector.a(4, new PathfinderGoalRandomTargetNonTamed<>(this, EntityAnimal.class, false, (entityanimal) -> { - return entityanimal instanceof EntitySheep || entityanimal instanceof EntityRabbit; - })); - this.targetSelector.a(4, new PathfinderGoalRandomTargetNonTamed<>(this, EntityTurtle.class, false, EntityTurtle.bC)); + this.targetSelector.a(3, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error + this.targetSelector.a(4, new PathfinderGoalRandomTargetNonTamed<>(this, EntityAnimal.class, false, EntityWolf.bC)); + this.targetSelector.a(4, new PathfinderGoalRandomTargetNonTamed<>(this, EntityTurtle.class, false, EntityTurtle.bz)); this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget<>(this, EntitySkeletonAbstract.class, false)); } + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); if (this.isTamed()) { - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(20.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(20.0D); } else { - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(8.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(8.0D); } this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(2.0D); @@ -77,6 +82,7 @@ public class EntityWolf extends EntityTameableAnimal { } // CraftBukkit end + @Override public void setGoalTarget(@Nullable EntityLiving entityliving) { super.setGoalTarget(entityliving); if (entityliving == null) { @@ -87,127 +93,149 @@ public class EntityWolf extends EntityTameableAnimal { } + @Override protected void mobTick() { this.datawatcher.set(EntityWolf.DATA_HEALTH, this.getHealth()); } - protected void x_() { - super.x_(); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); this.datawatcher.register(EntityWolf.DATA_HEALTH, this.getHealth()); - this.datawatcher.register(EntityWolf.bH, false); - this.datawatcher.register(EntityWolf.bI, EnumColor.RED.getColorIndex()); + this.datawatcher.register(EntityWolf.bE, false); + this.datawatcher.register(EntityWolf.bF, EnumColor.RED.getColorIndex()); } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { this.a(SoundEffects.ENTITY_WOLF_STEP, 0.15F, 1.0F); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); nbttagcompound.setBoolean("Angry", this.isAngry()); nbttagcompound.setByte("CollarColor", (byte) this.getCollarColor().getColorIndex()); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); this.setAngry(nbttagcompound.getBoolean("Angry")); + // CraftBukkit start - moved from below, SPIGOT-4893 + if (this.getGoalTarget() == null && this.isAngry()) { + this.setAngry(false); + } + // CraftBukkit end if (nbttagcompound.hasKeyOfType("CollarColor", 99)) { this.setCollarColor(EnumColor.fromColorIndex(nbttagcompound.getInt("CollarColor"))); } } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return this.isAngry() ? SoundEffects.ENTITY_WOLF_GROWL : (this.random.nextInt(3) == 0 ? (this.isTamed() && (Float) this.datawatcher.get(EntityWolf.DATA_HEALTH) < 10.0F ? SoundEffects.ENTITY_WOLF_WHINE : SoundEffects.ENTITY_WOLF_PANT) : SoundEffects.ENTITY_WOLF_AMBIENT); } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_WOLF_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_WOLF_DEATH; } - protected float cD() { + @Override + protected float getSoundVolume() { return 0.4F; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.U; - } - + @Override public void movementTick() { super.movementTick(); - if (!this.world.isClientSide && this.bL && !this.bM && !this.dr() && this.onGround) { - this.bM = true; - this.bN = 0.0F; - this.bO = 0.0F; + if (!this.world.isClientSide && this.bI && !this.bJ && !this.dT() && this.onGround) { + this.bJ = true; + this.bK = 0.0F; + this.bL = 0.0F; this.world.broadcastEntityEffect(this, (byte) 8); } - if (!this.world.isClientSide && this.getGoalTarget() == null && this.isAngry()) { + if (false && !this.world.isClientSide && this.getGoalTarget() == null && this.isAngry()) { // CraftBukkit - SPIGOT-4893 this.setAngry(false); } } + @Override public void tick() { super.tick(); - this.bK = this.bJ; - if (this.dL()) { - this.bJ += (1.0F - this.bJ) * 0.4F; - } else { - this.bJ += (0.0F - this.bJ) * 0.4F; - } - - if (this.ap()) { - this.bL = true; - this.bM = false; - this.bN = 0.0F; - this.bO = 0.0F; - } else if ((this.bL || this.bM) && this.bM) { - if (this.bN == 0.0F) { - this.a(SoundEffects.ENTITY_WOLF_SHAKE, this.cD(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + if (this.isAlive()) { + this.bH = this.bG; + if (this.ei()) { + this.bG += (1.0F - this.bG) * 0.4F; + } else { + this.bG += (0.0F - this.bG) * 0.4F; } - this.bO = this.bN; - this.bN += 0.05F; - if (this.bO >= 2.0F) { - this.bL = false; - this.bM = false; - this.bO = 0.0F; - this.bN = 0.0F; - } + if (this.au()) { + this.bI = true; + this.bJ = false; + this.bK = 0.0F; + this.bL = 0.0F; + } else if ((this.bI || this.bJ) && this.bJ) { + if (this.bK == 0.0F) { + this.a(SoundEffects.ENTITY_WOLF_SHAKE, this.getSoundVolume(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + } - // Akarin start - this handle by client - /* - if (this.bN > 0.4F) { - float f = (float) this.getBoundingBox().minY; - int i = (int) (MathHelper.sin((this.bN - 0.4F) * 3.1415927F) * 7.0F); + this.bL = this.bK; + this.bK += 0.05F; + if (this.bL >= 2.0F) { + this.bI = false; + this.bJ = false; + this.bL = 0.0F; + this.bK = 0.0F; + } - for (int j = 0; j < i; ++j) { - float f1 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; - float f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; + if (this.bK > 0.4F) { + float f = (float) this.getBoundingBox().minY; + int i = (int) (MathHelper.sin((this.bK - 0.4F) * 3.1415927F) * 7.0F); + Vec3D vec3d = this.getMot(); - this.world.addParticle(Particles.R, this.locX + (double) f1, (double) (f + 0.8F), this.locZ + (double) f2, this.motX, this.motY, this.motZ); + for (int j = 0; j < i; ++j) { + float f1 = (this.random.nextFloat() * 2.0F - 1.0F) * this.getWidth() * 0.5F; + float f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.getWidth() * 0.5F; + + this.world.addParticle(Particles.SPLASH, this.locX + (double) f1, (double) (f + 0.8F), this.locZ + (double) f2, vec3d.x, vec3d.y, vec3d.z); + } } } - */ - // Akarin end + } - } - public float getHeadHeight() { - return this.length * 0.8F; + @Override + public void die(DamageSource damagesource) { + this.bI = false; + this.bJ = false; + this.bL = 0.0F; + this.bK = 0.0F; + super.die(damagesource); } - public int K() { - return this.isSitting() ? 20 : super.K(); + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return entitysize.height * 0.8F; } + @Override + public int M() { + return this.isSitting() ? 20 : super.M(); + } + + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (this.isInvulnerable(damagesource)) { return false; @@ -227,7 +255,8 @@ public class EntityWolf extends EntityTameableAnimal { } } - public boolean B(Entity entity) { + @Override + public boolean C(Entity entity) { boolean flag = entity.damageEntity(DamageSource.mobAttack(this), (float) ((int) this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).getValue())); if (flag) { @@ -237,32 +266,32 @@ public class EntityWolf extends EntityTameableAnimal { return flag; } + @Override public void setTamed(boolean flag) { super.setTamed(flag); if (flag) { - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(20.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(20.0D); } else { - this.getAttributeInstance(GenericAttributes.maxHealth).setValue(8.0D); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(8.0D); } this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(4.0D); } + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); Item item = itemstack.getItem(); if (this.isTamed()) { if (!itemstack.isEmpty()) { - if (item instanceof ItemFood) { - ItemFood itemfood = (ItemFood) item; - - if (itemfood.d() && (Float) this.datawatcher.get(EntityWolf.DATA_HEALTH) < 20.0F) { + if (item.isFood()) { + if (item.getFoodInfo().c() && (Float) this.datawatcher.get(EntityWolf.DATA_HEALTH) < 20.0F) { if (!entityhuman.abilities.canInstantlyBuild) { itemstack.subtract(1); } - this.heal((float) itemfood.getNutrition(itemstack), org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit + this.heal((float) item.getFoodInfo().getNutrition(), org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit return true; } } else if (item instanceof ItemDye) { @@ -279,10 +308,10 @@ public class EntityWolf extends EntityTameableAnimal { } } - if (this.f((EntityLiving) entityhuman) && !this.world.isClientSide && !this.f(itemstack)) { + if (this.h((EntityLiving) entityhuman) && !this.world.isClientSide && !this.i(itemstack)) { this.goalSit.setSitting(!this.isSitting()); - this.bg = false; - this.navigation.q(); + this.jumping = false; + this.navigation.o(); this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason } } else if (item == Items.BONE && !this.isAngry()) { @@ -293,15 +322,15 @@ public class EntityWolf extends EntityTameableAnimal { if (!this.world.isClientSide) { // CraftBukkit - added event call and isCancelled check. if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { - this.c(entityhuman); - this.navigation.q(); + this.tame(entityhuman); + this.navigation.o(); this.setGoalTarget((EntityLiving) null); this.goalSit.setSitting(true); this.setHealth(this.getMaxHealth()); // CraftBukkit - 20.0 -> getMaxHealth() - this.s(true); + this.r(true); this.world.broadcastEntityEffect(this, (byte) 7); } else { - this.s(false); + this.r(false); this.world.broadcastEntityEffect(this, (byte) 6); } } @@ -312,41 +341,44 @@ public class EntityWolf extends EntityTameableAnimal { return super.a(entityhuman, enumhand); } - public boolean f(ItemStack itemstack) { + @Override + public boolean i(ItemStack itemstack) { Item item = itemstack.getItem(); - return item instanceof ItemFood && ((ItemFood) item).d(); + return item.isFood() && item.getFoodInfo().c(); } - public int dg() { + @Override + public int dC() { return 8; } public boolean isAngry() { - return ((Byte) this.datawatcher.get(EntityWolf.bC) & 2) != 0; + return ((Byte) this.datawatcher.get(EntityWolf.bz) & 2) != 0; } public void setAngry(boolean flag) { - byte b0 = (Byte) this.datawatcher.get(EntityWolf.bC); + byte b0 = (Byte) this.datawatcher.get(EntityWolf.bz); if (flag) { - this.datawatcher.set(EntityWolf.bC, (byte) (b0 | 2)); + this.datawatcher.set(EntityWolf.bz, (byte) (b0 | 2)); } else { - this.datawatcher.set(EntityWolf.bC, (byte) (b0 & -3)); + this.datawatcher.set(EntityWolf.bz, (byte) (b0 & -3)); } } public EnumColor getCollarColor() { - return EnumColor.fromColorIndex((Integer) this.datawatcher.get(EntityWolf.bI)); + return EnumColor.fromColorIndex((Integer) this.datawatcher.get(EntityWolf.bF)); } public void setCollarColor(EnumColor enumcolor) { - this.datawatcher.set(EntityWolf.bI, enumcolor.getColorIndex()); + this.datawatcher.set(EntityWolf.bF, enumcolor.getColorIndex()); } + @Override public EntityWolf createChild(EntityAgeable entityageable) { - EntityWolf entitywolf = EntityTypes.WOLF.create(world); // Paper + EntityWolf entitywolf = (EntityWolf) EntityTypes.WOLF.a(this.world); UUID uuid = this.getOwnerUUID(); if (uuid != null) { @@ -357,10 +389,11 @@ public class EntityWolf extends EntityTameableAnimal { return entitywolf; } - public void w(boolean flag) { - this.datawatcher.set(EntityWolf.bH, flag); + public void v(boolean flag) { + this.datawatcher.set(EntityWolf.bE, flag); } + @Override public boolean mate(EntityAnimal entityanimal) { if (entityanimal == this) { return false; @@ -375,10 +408,11 @@ public class EntityWolf extends EntityTameableAnimal { } } - public boolean dL() { - return (Boolean) this.datawatcher.get(EntityWolf.bH); + public boolean ei() { + return (Boolean) this.datawatcher.get(EntityWolf.bE); } + @Override public boolean a(EntityLiving entityliving, EntityLiving entityliving1) { if (!(entityliving instanceof EntityCreeper) && !(entityliving instanceof EntityGhast)) { if (entityliving instanceof EntityWolf) { @@ -389,38 +423,42 @@ public class EntityWolf extends EntityTameableAnimal { } } - return entityliving instanceof EntityHuman && entityliving1 instanceof EntityHuman && !((EntityHuman) entityliving1).a((EntityHuman) entityliving) ? false : !(entityliving instanceof EntityHorseAbstract) || !((EntityHorseAbstract) entityliving).isTamed(); + return entityliving instanceof EntityHuman && entityliving1 instanceof EntityHuman && !((EntityHuman) entityliving1).a((EntityHuman) entityliving) ? false : (entityliving instanceof EntityHorseAbstract && ((EntityHorseAbstract) entityliving).isTamed() ? false : !(entityliving instanceof EntityCat) || !((EntityCat) entityliving).isTamed()); } else { return false; } } + @Override public boolean a(EntityHuman entityhuman) { return !this.isAngry() && super.a(entityhuman); } - class a extends PathfinderGoalAvoidTarget { + class a extends PathfinderGoalAvoidTarget { - private final EntityWolf d; + private final EntityWolf j; public a(EntityWolf entitywolf, Class oclass, float f, double d0, double d1) { super(entitywolf, oclass, f, d0, d1); - this.d = entitywolf; + this.j = entitywolf; } + @Override public boolean a() { - return super.a() && this.b instanceof EntityLlama ? !this.d.isTamed() && this.a((EntityLlama) this.b) : false; + return super.a() && this.b instanceof EntityLlama ? !this.j.isTamed() && this.a((EntityLlama) this.b) : false; } private boolean a(EntityLlama entityllama) { return entityllama.getStrength() >= EntityWolf.this.random.nextInt(5); } + @Override public void c() { EntityWolf.this.setGoalTarget((EntityLiving) null); super.c(); } + @Override public void e() { EntityWolf.this.setGoalTarget((EntityLiving) null); super.e(); diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java index bf2bed002..d747d36f8 100644 --- a/src/main/java/net/minecraft/server/EntityZombie.java +++ b/src/main/java/net/minecraft/server/EntityZombie.java @@ -1,13 +1,16 @@ package net.minecraft.server; +import com.mojang.datafixers.types.DynamicOps; import java.time.LocalDate; import java.time.temporal.ChronoField; import java.util.List; import java.util.UUID; +import java.util.function.Predicate; import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.Zombie; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityCombustByEntityEvent; import org.bukkit.event.entity.EntityTargetEvent; @@ -16,36 +19,34 @@ import org.bukkit.event.entity.EntityTransformEvent; public class EntityZombie extends EntityMonster { - protected static final IAttribute c = (new AttributeRanged((IAttribute) null, "zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).a("Spawn Reinforcements Chance"); - private static final UUID a = UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836"); - private final AttributeModifier babyModifier = new AttributeModifier(EntityZombie.a, "Baby speed boost", world.paperConfig.babyZombieMovementSpeed, 1); // Paper - Remove static - Make baby speed configurable - private static final DataWatcherObject bC = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.i); - private static final DataWatcherObject bD = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.b); - private static final DataWatcherObject bE = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.i); private static final DataWatcherObject armsRaised = bE; // Paper - OBFHELPER - public static final DataWatcherObject DROWN_CONVERTING = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.i); private static final DataWatcherObject drowning = DROWN_CONVERTING; // Paper - OBFHELPER - private final PathfinderGoalBreakDoor bG; - private boolean bH; - private int bI; + protected static final IAttribute d = (new AttributeRanged((IAttribute) null, "zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).a("Spawn Reinforcements Chance"); + private static final UUID b = UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836"); + private final AttributeModifier c = new AttributeModifier(EntityZombie.b, "Baby speed boost", world.paperConfig.babyZombieMovementModifier, AttributeModifier.Operation.MULTIPLY_BASE); private final AttributeModifier babyModifier = this.c; // Paper - remove static - Make baby speed configurable + private static final DataWatcherObject bz = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.i); + private static final DataWatcherObject bA = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.b); + public static final DataWatcherObject DROWN_CONVERTING = DataWatcher.a(EntityZombie.class, DataWatcherRegistry.i); + private static final Predicate bC = (enumdifficulty) -> { + return enumdifficulty == EnumDifficulty.HARD; + }; + private final PathfinderGoalBreakDoor bD; + private boolean bE; + private int bF; public int drownedConversionTime; - private float bK; - private float bL; private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field private boolean shouldBurnInDay = true; // Paper - public EntityZombie(EntityTypes entitytypes, World world) { + public EntityZombie(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.bG = new PathfinderGoalBreakDoor(this); - this.bK = -1.0F; - this.setSize(0.6F, 1.95F); + this.bD = new PathfinderGoalBreakDoor(this, EntityZombie.bC); } public EntityZombie(World world) { this(EntityTypes.ZOMBIE, world); } - protected void n() { - this.goalSelector.a(4, new EntityZombie.a(Blocks.TURTLE_EGG, this, 1.0D, 3)); - this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); + @Override + protected void initPathfinder() { + this.goalSelector.a(4, new EntityZombie.a(this, 1.0D, 3)); this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); this.l(); @@ -53,29 +54,30 @@ public class EntityZombie extends EntityMonster { protected void l() { this.goalSelector.a(2, new PathfinderGoalZombieAttack(this, 1.0D, false)); - this.goalSelector.a(6, new PathfinderGoalMoveThroughVillage(this, 1.0D, false)); + this.goalSelector.a(6, new PathfinderGoalMoveThroughVillage(this, 1.0D, true, 4, this::ed)); this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D)); - this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[] { EntityPigZombie.class})); + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(EntityPigZombie.class)); this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); - if ( world.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); // Spigot + if ( world.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)); // Spigot this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); - this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, true, false, EntityTurtle.bC)); + this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, true, false, EntityTurtle.bz)); } + @Override protected void initAttributes() { super.initAttributes(); this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(35.0D); this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.23000000417232513D); this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D); - this.getAttributeInstance(GenericAttributes.h).setValue(2.0D); - this.getAttributeMap().b(EntityZombie.c).setValue(this.random.nextDouble() * 0.10000000149011612D); + this.getAttributeInstance(GenericAttributes.ARMOR).setValue(2.0D); + this.getAttributeMap().b(EntityZombie.d).setValue(this.random.nextDouble() * 0.10000000149011612D); } - protected void x_() { - super.x_(); - this.getDataWatcher().register(EntityZombie.bC, false); - this.getDataWatcher().register(EntityZombie.bD, 0); - this.getDataWatcher().register(EntityZombie.bE, false); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); + this.getDataWatcher().register(EntityZombie.bz, false); + this.getDataWatcher().register(EntityZombie.bA, 0); this.getDataWatcher().register(EntityZombie.DROWN_CONVERTING, false); } @@ -84,101 +86,93 @@ public class EntityZombie extends EntityMonster { return (Boolean) this.getDataWatcher().get(EntityZombie.DROWN_CONVERTING); } - public void setArmsRaised(boolean raised) { s(raised); } // Paper - OBFHELPER + public boolean ed() { + return this.bE; + } + public void s(boolean flag) { - this.getDataWatcher().set(EntityZombie.bE, flag); - } - - // Paper start - public boolean isArmsRaised() { - return ((Boolean) this.getDataWatcher().get(EntityZombie.armsRaised)).booleanValue(); - } - // Paper end - - public boolean dH() { - return this.bH; - } - - public void t(boolean flag) { - if (this.dz()) { - if (this.bH != flag) { - this.bH = flag; + if (this.dV()) { + if (this.bE != flag) { + this.bE = flag; ((Navigation) this.getNavigation()).a(flag); if (flag) { - this.goalSelector.a(1, this.bG); + this.goalSelector.a(1, this.bD); } else { - this.goalSelector.a((PathfinderGoal) this.bG); + this.goalSelector.a((PathfinderGoal) this.bD); } } - } else if (this.bH) { - this.goalSelector.a((PathfinderGoal) this.bG); - this.bH = false; + } else if (this.bE) { + this.goalSelector.a((PathfinderGoal) this.bD); + this.bE = false; } } - protected boolean dz() { + protected boolean dV() { return true; } + @Override public boolean isBaby() { - return (Boolean) this.getDataWatcher().get(EntityZombie.bC); + return (Boolean) this.getDataWatcher().get(EntityZombie.bz); } + @Override protected int getExpValue(EntityHuman entityhuman) { if (this.isBaby()) { - this.b_ = (int) ((float) this.b_ * 2.5F); + this.f = (int) ((float) this.f * 2.5F); } return super.getExpValue(entityhuman); } public void setBaby(boolean flag) { - this.getDataWatcher().set(EntityZombie.bC, flag); + this.getDataWatcher().set(EntityZombie.bz, flag); if (this.world != null && !this.world.isClientSide) { AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); - attributeinstance.c(this.babyModifier); // Paper + attributeinstance.removeModifier(this.babyModifier); // Paper if (flag) { - attributeinstance.b(this.babyModifier); // Paper + attributeinstance.addModifier(this.babyModifier); // Paper } } - this.v(flag); } + @Override public void a(DataWatcherObject datawatcherobject) { - if (EntityZombie.bC.equals(datawatcherobject)) { - this.v(this.isBaby()); + if (EntityZombie.bz.equals(datawatcherobject)) { + this.updateSize(); } super.a(datawatcherobject); } - protected boolean dC() { + protected boolean dY() { return true; } + @Override public void tick() { - if (!this.world.isClientSide) { - // CraftBukkit start - Use wall time instead of ticks for conversion - if (this.isDrownConverting() && this.isAlive()) { + if (!this.world.isClientSide && this.isAlive()) { + if (this.isDrownConverting()) { + // CraftBukkit start - Use wall time instead of ticks for conversion int elapsedTicks = MinecraftServer.currentTick - this.lastTick; this.lastTick = MinecraftServer.currentTick; this.drownedConversionTime -= elapsedTicks; // CraftBukkit end if (this.drownedConversionTime < 0) { - this.dE(); + this.ea(); } - } else if (this.dC()) { + } else if (this.dY()) { if (this.a(TagsFluid.WATER)) { - ++this.bI; - if (this.bI >= 600) { + ++this.bF; + if (this.bF >= 600) { this.startDrownedConversion(300); this.lastTick = MinecraftServer.currentTick; // Paper - Make sure this is set at start of process - GH-1887 } } else { - this.bI = -1; + this.bF = -1; } } } @@ -186,26 +180,29 @@ public class EntityZombie extends EntityMonster { super.tick(); } + @Override public void movementTick() { - boolean flag = this.L_() && this.dq(); - - if (flag) { - ItemStack itemstack = this.getEquipment(EnumItemSlot.HEAD); - - if (!itemstack.isEmpty()) { - if (itemstack.e()) { - itemstack.setDamage(itemstack.getDamage() + this.random.nextInt(2)); - if (itemstack.getDamage() >= itemstack.h()) { - this.c(itemstack); - this.setSlot(EnumItemSlot.HEAD, ItemStack.a); - } - } - - flag = false; - } + if (this.isAlive()) { + boolean flag = this.I_() && this.dS(); if (flag) { - this.setOnFire(8); + ItemStack itemstack = this.getEquipment(EnumItemSlot.HEAD); + + if (!itemstack.isEmpty()) { + if (itemstack.e()) { + itemstack.setDamage(itemstack.getDamage() + this.random.nextInt(2)); + if (itemstack.getDamage() >= itemstack.h()) { + this.c(EnumItemSlot.HEAD); + this.setSlot(EnumItemSlot.HEAD, ItemStack.a); + } + } + + flag = false; + } + + if (flag) { + this.setOnFire(8); + } } } @@ -213,6 +210,7 @@ public class EntityZombie extends EntityMonster { } public void startDrownedConversion(int i) { + this.lastTick = MinecraftServer.currentTick; // CraftBukkit this.drownedConversionTime = i; this.getDataWatcher().set(EntityZombie.DROWN_CONVERTING, true); } @@ -220,19 +218,25 @@ public class EntityZombie extends EntityMonster { // Paper start public void stopDrowning() { this.drownedConversionTime = -1; - this.getDataWatcher().set(EntityZombie.drowning, Boolean.valueOf(false)); + this.getDataWatcher().set(EntityZombie.DROWN_CONVERTING, false); } // Paper end - protected void dE() { - this.a((EntityZombie) EntityTypes.DROWNED.create(world)); // Paper - this.world.a((EntityHuman) null, 1040, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0); + protected void ea() { + this.b(EntityTypes.DROWNED); + this.world.a((EntityHuman) null, 1040, new BlockPosition(this), 0); } - protected void a(EntityZombie entityzombie) { - if (!this.world.isClientSide && !this.dead) { + protected void b(EntityTypes entitytypes) { + if (!this.dead) { + EntityZombie entityzombie = (EntityZombie) entitytypes.a(this.world); + entityzombie.u(this); - entityzombie.a(this.dj(), this.dH(), this.isBaby(), this.isNoAI()); + entityzombie.setCanPickupLoot(this.canPickupLoot()); + entityzombie.s(entityzombie.dV() && this.ed()); + entityzombie.v(entityzombie.world.getDamageScaler(new BlockPosition(entityzombie)).d()); + entityzombie.setBaby(this.isBaby()); + entityzombie.setNoAI(this.isNoAI()); EnumItemSlot[] aenumitemslot = EnumItemSlot.values(); int i = aenumitemslot.length; @@ -241,8 +245,9 @@ public class EntityZombie extends EntityMonster { ItemStack itemstack = this.getEquipment(enumitemslot); if (!itemstack.isEmpty()) { - entityzombie.setSlot(enumitemslot, itemstack); - entityzombie.a(enumitemslot, this.c(enumitemslot)); + entityzombie.setSlot(enumitemslot, itemstack.cloneItemStack()); + entityzombie.a(enumitemslot, this.d(enumitemslot)); + itemstack.setCount(0); } } @@ -253,6 +258,7 @@ public class EntityZombie extends EntityMonster { // CraftBukkit start if (CraftEventFactory.callEntityTransformEvent(this, entityzombie, EntityTransformEvent.TransformReason.DROWNED).isCancelled()) { + ((Zombie) getBukkitEntity()).setConversionTime(-1); // SPIGOT-5208: End conversion to stop event spam return; } // CraftBukkit end @@ -262,9 +268,9 @@ public class EntityZombie extends EntityMonster { } } - public boolean shouldBurnInDay() { return L_(); } // Paper - OBFHELPER - protected boolean L_() { - return shouldBurnInDay; // Paper + public boolean shouldBurnInDay() { return I_(); } // Paper - OBFHELPER + protected boolean I_() { + return shouldBurnInDay; } // Paper start @@ -273,6 +279,7 @@ public class EntityZombie extends EntityMonster { } // Paper end + @Override public boolean damageEntity(DamageSource damagesource, float f) { if (super.damageEntity(damagesource, f)) { EntityLiving entityliving = this.getGoalTarget(); @@ -281,25 +288,26 @@ public class EntityZombie extends EntityMonster { entityliving = (EntityLiving) damagesource.getEntity(); } - if (entityliving != null && this.world.getDifficulty() == EnumDifficulty.HARD && (double) this.random.nextFloat() < this.getAttributeInstance(EntityZombie.c).getValue() && this.world.getGameRules().getBoolean("doMobSpawning")) { + if (entityliving != null && this.world.getDifficulty() == EnumDifficulty.HARD && (double) this.random.nextFloat() < this.getAttributeInstance(EntityZombie.d).getValue() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING)) { int i = MathHelper.floor(this.locX); int j = MathHelper.floor(this.locY); int k = MathHelper.floor(this.locZ); - EntityZombie entityzombie = EntityTypes.ZOMBIE.create(world); // Paper + EntityZombie entityzombie = new EntityZombie(this.world); for (int l = 0; l < 50; ++l) { int i1 = i + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1); int j1 = j + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1); int k1 = k + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1); + BlockPosition blockposition = new BlockPosition(i1, j1 - 1, k1); - if (this.world.getType(new BlockPosition(i1, j1 - 1, k1)).q() && !this.world.isLightLevel(new BlockPosition(i1, j1, k1), 10)) { // Paper + if (this.world.getType(blockposition).a((IBlockAccess) this.world, blockposition, (Entity) entityzombie) && this.world.getLightLevel(new BlockPosition(i1, j1, k1)) < 10) { entityzombie.setPosition((double) i1, (double) j1, (double) k1); - if (!this.world.isPlayerNearby((double) i1, (double) j1, (double) k1, 7.0D) && this.world.a_(entityzombie, entityzombie.getBoundingBox()) && this.world.getCubes(entityzombie, entityzombie.getBoundingBox()) && !this.world.containsLiquid(entityzombie.getBoundingBox())) { + if (!this.world.isPlayerNearby((double) i1, (double) j1, (double) k1, 7.0D) && this.world.i((Entity) entityzombie) && this.world.getCubes(entityzombie) && !this.world.containsLiquid(entityzombie.getBoundingBox())) { this.world.addEntity(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit entityzombie.setGoalTarget(entityliving, EntityTargetEvent.TargetReason.REINFORCEMENT_TARGET, true); // CraftBukkit - entityzombie.prepare(this.world.getDamageScaler(new BlockPosition(entityzombie)), (GroupDataEntity) null, (NBTTagCompound) null); - this.getAttributeInstance(EntityZombie.c).b(new AttributeModifier("Zombie reinforcement caller charge", -0.05000000074505806D, 0)); - entityzombie.getAttributeInstance(EntityZombie.c).b(new AttributeModifier("Zombie reinforcement callee charge", -0.05000000074505806D, 0)); + entityzombie.prepare(this.world, this.world.getDamageScaler(new BlockPosition(entityzombie)), EnumMobSpawn.REINFORCEMENT, (GroupDataEntity) null, (NBTTagCompound) null); + this.getAttributeInstance(EntityZombie.d).addModifier(new AttributeModifier("Zombie reinforcement caller charge", -0.05000000074505806D, AttributeModifier.Operation.ADDITION)); + entityzombie.getAttributeInstance(EntityZombie.d).addModifier(new AttributeModifier("Zombie reinforcement callee charge", -0.05000000074505806D, AttributeModifier.Operation.ADDITION)); break; } } @@ -312,8 +320,9 @@ public class EntityZombie extends EntityMonster { } } - public boolean B(Entity entity) { - boolean flag = super.B(entity); + @Override + public boolean C(Entity entity) { + boolean flag = super.C(entity); if (flag) { float f = this.world.getDamageScaler(new BlockPosition(this)).b(); @@ -333,35 +342,36 @@ public class EntityZombie extends EntityMonster { return flag; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_ZOMBIE_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_ZOMBIE_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_ZOMBIE_DEATH; } - protected SoundEffect dA() { + protected SoundEffect getSoundStep() { return SoundEffects.ENTITY_ZOMBIE_STEP; } + @Override protected void a(BlockPosition blockposition, IBlockData iblockdata) { - this.a(this.dA(), 0.15F, 1.0F); + this.a(this.getSoundStep(), 0.15F, 1.0F); } + @Override public EnumMonsterType getMonsterType() { return EnumMonsterType.UNDEAD; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.at; - } - + @Override protected void a(DifficultyDamageScaler difficultydamagescaler) { super.a(difficultydamagescaler); if (this.random.nextFloat() < (this.world.getDifficulty() == EnumDifficulty.HARD ? 0.05F : 0.01F)) { @@ -376,26 +386,28 @@ public class EntityZombie extends EntityMonster { } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); if (this.isBaby()) { nbttagcompound.setBoolean("IsBaby", true); } - nbttagcompound.setBoolean("CanBreakDoors", this.dH()); - nbttagcompound.setInt("InWaterTime", this.isInWater() ? this.bI : -1); + nbttagcompound.setBoolean("CanBreakDoors", this.ed()); + nbttagcompound.setInt("InWaterTime", this.isInWater() ? this.bF : -1); nbttagcompound.setInt("DrownedConversionTime", this.isDrownConverting() ? this.drownedConversionTime : -1); nbttagcompound.setBoolean("Paper.ShouldBurnInDay", shouldBurnInDay); // Paper } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.getBoolean("IsBaby")) { this.setBaby(true); } - this.t(nbttagcompound.getBoolean("CanBreakDoors")); - this.bI = nbttagcompound.getInt("InWaterTime"); + this.s(nbttagcompound.getBoolean("CanBreakDoors")); + this.bF = nbttagcompound.getInt("InWaterTime"); if (nbttagcompound.hasKeyOfType("DrownedConversionTime", 99) && nbttagcompound.getInt("DrownedConversionTime") > -1) { this.startDrownedConversion(nbttagcompound.getInt("DrownedConversionTime")); } @@ -406,6 +418,7 @@ public class EntityZombie extends EntityMonster { // Paper end } + @Override public void b(EntityLiving entityliving) { super.b(entityliving); if ((this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) && entityliving instanceof EntityVillager) { @@ -414,12 +427,15 @@ public class EntityZombie extends EntityMonster { } EntityVillager entityvillager = (EntityVillager) entityliving; - EntityZombieVillager entityzombievillager = EntityTypes.ZOMBIE_VILLAGER.create(world); // Paper + EntityZombieVillager entityzombievillager = (EntityZombieVillager) EntityTypes.ZOMBIE_VILLAGER.a(this.world); entityzombievillager.u(entityvillager); - // this.world.kill(entityvillager); // CraftBukkit - moved down - entityzombievillager.prepare(this.world.getDamageScaler(new BlockPosition(entityzombievillager)), new EntityZombie.GroupDataZombie(false), (NBTTagCompound) null); - entityzombievillager.setProfession(entityvillager.getProfession()); + // entityvillager.die(); // CraftBukkit - moved down + entityzombievillager.prepare(this.world, this.world.getDamageScaler(new BlockPosition(entityzombievillager)), EnumMobSpawn.CONVERSION, new EntityZombie.GroupDataZombie(false), (NBTTagCompound) null); + entityzombievillager.setVillagerData(entityvillager.getVillagerData()); + entityzombievillager.a((NBTBase) entityvillager.es().a((DynamicOps) DynamicOpsNBT.a).getValue()); + entityzombievillager.setOffers(entityvillager.getOffers().a()); + entityzombievillager.a(entityvillager.getExperience()); entityzombievillager.setBaby(entityvillager.isBaby()); entityzombievillager.setNoAI(entityvillager.isNoAI()); if (entityvillager.hasCustomName()) { @@ -432,7 +448,7 @@ public class EntityZombie extends EntityMonster { return; } if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entityvillager.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.INFECTED).callEvent()) return; // Paper - this.world.kill(entityvillager); // CraftBukkit - from above + entityvillager.die(); // CraftBukkit - from above this.world.addEntity(entityzombievillager, CreatureSpawnEvent.SpawnReason.INFECTION); // CraftBukkit - add SpawnReason // CraftBukkit end this.world.a((EntityHuman) null, 1026, new BlockPosition(this), 0); @@ -440,28 +456,25 @@ public class EntityZombie extends EntityMonster { } - public float getHeadHeight() { - float f = 1.74F; - - if (this.isBaby()) { - f = (float) ((double) f - 0.81D); - } - - return f; + @Override + protected float b(EntityPose entitypose, EntitySize entitysize) { + return this.isBaby() ? 0.93F : 1.74F; } - protected boolean d(ItemStack itemstack) { - return itemstack.getItem() == Items.EGG && this.isBaby() && this.isPassenger() ? false : super.d(itemstack); + @Override + protected boolean g(ItemStack itemstack) { + return itemstack.getItem() == Items.EGG && this.isBaby() && this.isPassenger() ? false : super.g(itemstack); } @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - Object object = super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + Object object = super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); float f = difficultydamagescaler.d(); - this.p(this.random.nextFloat() < 0.55F * f); + this.setCanPickupLoot(this.random.nextFloat() < 0.55F * f); if (object == null) { - object = new EntityZombie.GroupDataZombie(this.world.random.nextFloat() < 0.05F); + object = new EntityZombie.GroupDataZombie(generatoraccess.getRandom().nextFloat() < 0.05F); } if (object instanceof EntityZombie.GroupDataZombie) { @@ -469,27 +482,27 @@ public class EntityZombie extends EntityMonster { if (entityzombie_groupdatazombie.a) { this.setBaby(true); - if ((double) this.world.random.nextFloat() < 0.05D) { - List list = this.world.a(EntityChicken.class, this.getBoundingBox().grow(5.0D, 3.0D, 5.0D), IEntitySelector.c); + if ((double) generatoraccess.getRandom().nextFloat() < 0.05D) { + List list = generatoraccess.a(EntityChicken.class, this.getBoundingBox().grow(5.0D, 3.0D, 5.0D), IEntitySelector.c); if (!list.isEmpty()) { EntityChicken entitychicken = (EntityChicken) list.get(0); - entitychicken.s(true); + entitychicken.r(true); this.startRiding(entitychicken); } - } else if ((double) this.world.random.nextFloat() < 0.05D) { - EntityChicken entitychicken1 = EntityTypes.CHICKEN.create(world); // Paper + } else if ((double) generatoraccess.getRandom().nextFloat() < 0.05D) { + EntityChicken entitychicken1 = (EntityChicken) EntityTypes.CHICKEN.a(this.world); entitychicken1.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); - entitychicken1.prepare(difficultydamagescaler, (GroupDataEntity) null, (NBTTagCompound) null); - entitychicken1.s(true); - this.world.addEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit + entitychicken1.prepare(generatoraccess, difficultydamagescaler, EnumMobSpawn.JOCKEY, (GroupDataEntity) null, (NBTTagCompound) null); + entitychicken1.r(true); + generatoraccess.addEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit this.startRiding(entitychicken1); } } - this.t(this.dz() && this.random.nextFloat() < f * 0.1F); + this.s(this.dV() && this.random.nextFloat() < f * 0.1F); this.a(difficultydamagescaler); this.b(difficultydamagescaler); } @@ -505,101 +518,80 @@ public class EntityZombie extends EntityMonster { } } - this.a(f); + this.v(f); return (GroupDataEntity) object; } - protected void a(boolean flag, boolean flag1, boolean flag2, boolean flag3) { - this.p(flag); - this.t(this.dz() && flag1); - this.a(this.world.getDamageScaler(new BlockPosition(this)).d()); - this.setBaby(flag2); - this.setNoAI(flag3); - } - - protected void a(float f) { - this.getAttributeInstance(GenericAttributes.c).b(new AttributeModifier("Random spawn bonus", this.random.nextDouble() * 0.05000000074505806D, 0)); + protected void v(float f) { + this.getAttributeInstance(GenericAttributes.KNOCKBACK_RESISTANCE).addModifier(new AttributeModifier("Random spawn bonus", this.random.nextDouble() * 0.05000000074505806D, AttributeModifier.Operation.ADDITION)); double d0 = this.random.nextDouble() * 1.5D * (double) f; if (d0 > 1.0D) { - this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).b(new AttributeModifier("Random zombie-spawn bonus", d0, 2)); + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).addModifier(new AttributeModifier("Random zombie-spawn bonus", d0, AttributeModifier.Operation.MULTIPLY_TOTAL)); } if (this.random.nextFloat() < f * 0.05F) { - this.getAttributeInstance(EntityZombie.c).b(new AttributeModifier("Leader zombie bonus", this.random.nextDouble() * 0.25D + 0.5D, 0)); - this.getAttributeInstance(GenericAttributes.maxHealth).b(new AttributeModifier("Leader zombie bonus", this.random.nextDouble() * 3.0D + 1.0D, 2)); - this.t(this.dz()); + this.getAttributeInstance(EntityZombie.d).addModifier(new AttributeModifier("Leader zombie bonus", this.random.nextDouble() * 0.25D + 0.5D, AttributeModifier.Operation.ADDITION)); + this.getAttributeInstance(GenericAttributes.MAX_HEALTH).addModifier(new AttributeModifier("Leader zombie bonus", this.random.nextDouble() * 3.0D + 1.0D, AttributeModifier.Operation.MULTIPLY_TOTAL)); + this.s(this.dV()); } } - public void v(boolean flag) { - this.v(flag ? 0.5F : 1.0F); - } - - public final void setSize(float f, float f1) { - boolean flag = this.bK > 0.0F && this.bL > 0.0F; - - this.bK = f; - this.bL = f1; - if (!flag) { - this.v(1.0F); - } - - } - - protected final void v(float f) { - super.setSize(this.bK * f, this.bL * f); - } - - public double aI() { + @Override + public double aO() { return this.isBaby() ? 0.0D : -0.45D; } - public void die(DamageSource damagesource) { - // super.die(damagesource); // CraftBukkit - if (damagesource.getEntity() instanceof EntityCreeper) { - EntityCreeper entitycreeper = (EntityCreeper) damagesource.getEntity(); + @Override + protected void dropDeathLoot(DamageSource damagesource, int i, boolean flag) { + super.dropDeathLoot(damagesource, i, flag); + Entity entity = damagesource.getEntity(); - if (entitycreeper.isPowered() && entitycreeper.canCauseHeadDrop()) { + if (entity instanceof EntityCreeper) { + EntityCreeper entitycreeper = (EntityCreeper) entity; + + if (entitycreeper.canCauseHeadDrop()) { entitycreeper.setCausedHeadDrop(); - ItemStack itemstack = this.dB(); + ItemStack itemstack = this.dX(); if (!itemstack.isEmpty()) { - this.a_(itemstack); + this.a(itemstack); } } } - super.die(damagesource); // CraftBukkit - moved from above } - protected ItemStack dB() { + protected ItemStack dX() { return new ItemStack(Items.ZOMBIE_HEAD); } class a extends PathfinderGoalRemoveBlock { - a(Block block, EntityCreature entitycreature, double d0, int i) { - super(block, entitycreature, d0, i); + a(EntityCreature entitycreature, double d0, int i) { + super(Blocks.TURTLE_EGG, entitycreature, d0, i); } + @Override public void a(GeneratorAccess generatoraccess, BlockPosition blockposition) { - generatoraccess.a((EntityHuman) null, blockposition, SoundEffects.ENTITY_ZOMBIE_DESTROY_EGG, SoundCategory.HOSTILE, 0.5F, 0.9F + EntityZombie.this.random.nextFloat() * 0.2F); + generatoraccess.playSound((EntityHuman) null, blockposition, SoundEffects.ENTITY_ZOMBIE_DESTROY_EGG, SoundCategory.HOSTILE, 0.5F, 0.9F + EntityZombie.this.random.nextFloat() * 0.2F); } + @Override public void a(World world, BlockPosition blockposition) { - world.a((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_EGG_BREAK, SoundCategory.BLOCKS, 0.7F, 0.9F + world.random.nextFloat() * 0.2F); + world.playSound((EntityHuman) null, blockposition, SoundEffects.ENTITY_TURTLE_EGG_BREAK, SoundCategory.BLOCKS, 0.7F, 0.9F + world.random.nextFloat() * 0.2F); } - public double g() { - return 1.3D; + @Override + public double h() { + return 1.14D; } } public class GroupDataZombie implements GroupDataEntity { - public boolean a; + public final boolean a; private GroupDataZombie(boolean flag) { this.a = flag; diff --git a/src/main/java/net/minecraft/server/EntityZombieHusk.java b/src/main/java/net/minecraft/server/EntityZombieHusk.java index 0cca7b6d5..4c8b2dd09 100644 --- a/src/main/java/net/minecraft/server/EntityZombieHusk.java +++ b/src/main/java/net/minecraft/server/EntityZombieHusk.java @@ -1,44 +1,45 @@ package net.minecraft.server; -import javax.annotation.Nullable; +import java.util.Random; public class EntityZombieHusk extends EntityZombie { - public EntityZombieHusk(World world) { - super(EntityTypes.HUSK, world); + public EntityZombieHusk(EntityTypes entitytypes, World world) { + super(entitytypes, world); } - public boolean a(GeneratorAccess generatoraccess, boolean flag) { - return super.a(generatoraccess, flag) && (flag || generatoraccess.e(new BlockPosition(this))); + public static boolean b(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { + return c(entitytypes, generatoraccess, enummobspawn, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || generatoraccess.f(blockposition)); } - protected boolean L_() { + @Override + protected boolean I_() { return false; } - protected SoundEffect D() { + @Override + protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_HUSK_AMBIENT; } - protected SoundEffect d(DamageSource damagesource) { + @Override + protected SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_HUSK_HURT; } - protected SoundEffect cs() { + @Override + protected SoundEffect getSoundDeath() { return SoundEffects.ENTITY_HUSK_DEATH; } - protected SoundEffect dA() { + @Override + protected SoundEffect getSoundStep() { return SoundEffects.ENTITY_HUSK_STEP; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.ay; - } - - public boolean B(Entity entity) { - boolean flag = super.B(entity); + @Override + public boolean C(Entity entity) { + boolean flag = super.C(entity); if (flag && this.getItemInMainHand().isEmpty() && entity instanceof EntityLiving) { float f = this.world.getDamageScaler(new BlockPosition(this)).b(); @@ -49,16 +50,19 @@ public class EntityZombieHusk extends EntityZombie { return flag; } - protected boolean dC() { + @Override + protected boolean dY() { return true; } - protected void dE() { - this.a(EntityTypes.ZOMBIE.create(world)); // Paper - this.world.a((EntityHuman) null, 1041, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0); + @Override + protected void ea() { + this.b(EntityTypes.ZOMBIE); + this.world.a((EntityHuman) null, 1041, new BlockPosition(this), 0); } - protected ItemStack dB() { + @Override + protected ItemStack dX() { return ItemStack.a; } } diff --git a/src/main/java/net/minecraft/server/EntityZombieVillager.java b/src/main/java/net/minecraft/server/EntityZombieVillager.java index fb96743af..d2bd3bb31 100644 --- a/src/main/java/net/minecraft/server/EntityZombieVillager.java +++ b/src/main/java/net/minecraft/server/EntityZombieVillager.java @@ -1,66 +1,86 @@ package net.minecraft.server; +import com.mojang.datafixers.Dynamic; import java.util.UUID; import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.ZombieVillager; import org.bukkit.event.entity.EntityTransformEvent; // CraftBukkit end -public class EntityZombieVillager extends EntityZombie { +public class EntityZombieVillager extends EntityZombie implements VillagerDataHolder { public static final DataWatcherObject CONVERTING = DataWatcher.a(EntityZombieVillager.class, DataWatcherRegistry.i); - private static final DataWatcherObject b = DataWatcher.a(EntityZombieVillager.class, DataWatcherRegistry.b); + private static final DataWatcherObject c = DataWatcher.a(EntityZombieVillager.class, DataWatcherRegistry.q); public int conversionTime; - private UUID bD; + public UUID conversionPlayer; + private NBTBase bB; + private NBTTagCompound bC; + private int bD; private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field - public EntityZombieVillager(World world) { - super(EntityTypes.ZOMBIE_VILLAGER, world); + public EntityZombieVillager(EntityTypes entitytypes, World world) { + super(entitytypes, world); + this.setVillagerData(this.getVillagerData().withProfession((VillagerProfession) IRegistry.VILLAGER_PROFESSION.a(this.random))); } - protected void x_() { - super.x_(); + @Override + protected void initDatawatcher() { + super.initDatawatcher(); this.datawatcher.register(EntityZombieVillager.CONVERTING, false); - this.datawatcher.register(EntityZombieVillager.b, 0); - } - - public void setProfession(int i) { - this.datawatcher.set(EntityZombieVillager.b, i); - } - - public int getProfession() { - return Math.max((Integer) this.datawatcher.get(EntityZombieVillager.b) % 6, 0); + this.datawatcher.register(EntityZombieVillager.c, new VillagerData(VillagerType.PLAINS, VillagerProfession.NONE, 1)); } + @Override public void b(NBTTagCompound nbttagcompound) { super.b(nbttagcompound); - nbttagcompound.setInt("Profession", this.getProfession()); - nbttagcompound.setInt("ConversionTime", this.isConverting() ? this.conversionTime : -1); - if (this.bD != null) { - nbttagcompound.a("ConversionPlayer", this.bD); + nbttagcompound.set("VillagerData", (NBTBase) this.getVillagerData().a(DynamicOpsNBT.a)); + if (this.bC != null) { + nbttagcompound.set("Offers", this.bC); } + if (this.bB != null) { + nbttagcompound.set("Gossips", this.bB); + } + + nbttagcompound.setInt("ConversionTime", this.isConverting() ? this.conversionTime : -1); + if (this.conversionPlayer != null) { + nbttagcompound.a("ConversionPlayer", this.conversionPlayer); + } + + nbttagcompound.setInt("Xp", this.bD); } + @Override public void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); - this.setProfession(nbttagcompound.getInt("Profession")); + if (nbttagcompound.hasKeyOfType("VillagerData", 10)) { + this.setVillagerData(new VillagerData(new Dynamic(DynamicOpsNBT.a, nbttagcompound.get("VillagerData")))); + } + + if (nbttagcompound.hasKeyOfType("Offers", 10)) { + this.bC = nbttagcompound.getCompound("Offers"); + } + + if (nbttagcompound.hasKeyOfType("Gossips", 10)) { + this.bB = nbttagcompound.getList("Gossips", 10); + } + if (nbttagcompound.hasKeyOfType("ConversionTime", 99) && nbttagcompound.getInt("ConversionTime") > -1) { this.startConversion(nbttagcompound.b("ConversionPlayer") ? nbttagcompound.a("ConversionPlayer") : null, nbttagcompound.getInt("ConversionTime")); } + if (nbttagcompound.hasKeyOfType("Xp", 3)) { + this.bD = nbttagcompound.getInt("Xp"); + } + } - @Nullable - public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { - this.setProfession(this.world.random.nextInt(6)); - return super.prepare(difficultydamagescaler, groupdataentity, nbttagcompound); - } - + @Override public void tick() { - if (!this.world.isClientSide && this.isConverting() && this.isAlive()) { // CraftBukkit - int i = this.dK(); + if (!this.world.isClientSide && this.isAlive() && this.isConverting()) { + int i = this.getConversionProgress(); // CraftBukkit start - Use wall time instead of ticks for villager conversion int elapsedTicks = MinecraftServer.currentTick - this.lastTick; this.lastTick = MinecraftServer.currentTick; @@ -69,13 +89,14 @@ public class EntityZombieVillager extends EntityZombie { this.conversionTime -= i; if (this.conversionTime <= 0) { - this.dJ(); + this.a((WorldServer) this.world); } } super.tick(); } + @Override public boolean a(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -94,11 +115,13 @@ public class EntityZombieVillager extends EntityZombie { } } - protected boolean dC() { + @Override + protected boolean dY() { return false; } - public boolean isTypeNotPersistent() { + @Override + public boolean isTypeNotPersistent(double d0) { return !this.isConverting(); } @@ -107,28 +130,37 @@ public class EntityZombieVillager extends EntityZombie { } public void startConversion(@Nullable UUID uuid, int i) { - this.bD = uuid; + this.conversionPlayer = uuid; this.conversionTime = i; this.getDataWatcher().set(EntityZombieVillager.CONVERTING, true); // CraftBukkit start + this.persistent = true; // CraftBukkit - SPIGOT-4684 update persistence this.removeEffect(MobEffects.WEAKNESS, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); this.addEffect(new MobEffect(MobEffects.INCREASE_DAMAGE, i, Math.min(this.world.getDifficulty().a() - 1, 0)), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); // CraftBukkit end this.world.broadcastEntityEffect(this, (byte) 16); } - protected void dJ() { - EntityVillager entityvillager = EntityTypes.VILLAGER.create(world); // Paper + private void a(WorldServer worldserver) { + EntityVillager entityvillager = (EntityVillager) EntityTypes.VILLAGER.a((World) worldserver); entityvillager.u(this); - entityvillager.setProfession(this.getProfession()); - entityvillager.a(this.world.getDamageScaler(new BlockPosition(entityvillager)), (GroupDataEntity) null, (NBTTagCompound) null, false); - entityvillager.dC(); + entityvillager.setVillagerData(this.getVillagerData()); + if (this.bB != null) { + entityvillager.a(this.bB); + } + + if (this.bC != null) { + entityvillager.b(new MerchantRecipeList(this.bC)); + } + + entityvillager.setExperience(this.bD); + entityvillager.prepare(worldserver, worldserver.getDamageScaler(new BlockPosition(entityvillager)), EnumMobSpawn.CONVERSION, (GroupDataEntity) null, (NBTTagCompound) null); if (this.isBaby()) { entityvillager.setAgeRaw(-24000); } - // this.world.kill(this); // CraftBukkit - moved down + // this.die(); // CraftBukkit - moved down entityvillager.setNoAI(this.isNoAI()); if (this.hasCustomName()) { entityvillager.setCustomName(this.getCustomName()); @@ -137,25 +169,27 @@ public class EntityZombieVillager extends EntityZombie { // CraftBukkit start if (CraftEventFactory.callEntityTransformEvent(this, entityvillager, EntityTransformEvent.TransformReason.CURED).isCancelled()) { + ((ZombieVillager) getBukkitEntity()).setConversionTime(-1); // SPIGOT-5208: End conversion to stop event spam return; } if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), entityvillager.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.CURED).callEvent()) return; // Paper - this.world.kill(this); // CraftBukkit - from above - this.world.addEntity(entityvillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CURED); // CraftBukkit - add SpawnReason + this.die(); // CraftBukkit - from above + worldserver.addEntity(entityvillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CURED); // CraftBukkit - add SpawnReason // CraftBukkit end - if (this.bD != null) { - EntityHuman entityhuman = this.world.b(this.bD); + if (this.conversionPlayer != null) { + EntityHuman entityhuman = worldserver.b(this.conversionPlayer); if (entityhuman instanceof EntityPlayer) { CriterionTriggers.r.a((EntityPlayer) entityhuman, this, entityvillager); + worldserver.a(ReputationEvent.a, (Entity) entityhuman, (ReputationHandler) entityvillager); } } entityvillager.addEffect(new MobEffect(MobEffects.CONFUSION, 200, 0), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); // CraftBukkit - this.world.a((EntityHuman) null, 1027, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0); + worldserver.a((EntityHuman) null, 1027, new BlockPosition(this), 0); } - protected int dK() { + private int getConversionProgress() { int i = 1; if (this.random.nextFloat() < 0.01F) { @@ -165,7 +199,7 @@ public class EntityZombieVillager extends EntityZombie { for (int k = (int) this.locX - 4; k < (int) this.locX + 4 && j < 14; ++k) { for (int l = (int) this.locY - 4; l < (int) this.locY + 4 && j < 14; ++l) { for (int i1 = (int) this.locZ - 4; i1 < (int) this.locZ + 4 && j < 14; ++i1) { - Block block = this.world.getType(blockposition_mutableblockposition.c(k, l, i1)).getBlock(); + Block block = this.world.getType(blockposition_mutableblockposition.d(k, l, i1)).getBlock(); if (block == Blocks.IRON_BARS || block instanceof BlockBed) { if (this.random.nextFloat() < 0.3F) { @@ -182,32 +216,67 @@ public class EntityZombieVillager extends EntityZombie { return i; } - protected float cE() { + @Override + protected float cV() { return this.isBaby() ? (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 2.0F : (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F; } - public SoundEffect D() { + @Override + public SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_ZOMBIE_VILLAGER_AMBIENT; } - public SoundEffect d(DamageSource damagesource) { + @Override + public SoundEffect getSoundHurt(DamageSource damagesource) { return SoundEffects.ENTITY_ZOMBIE_VILLAGER_HURT; } - public SoundEffect cs() { + @Override + public SoundEffect getSoundDeath() { return SoundEffects.ENTITY_ZOMBIE_VILLAGER_DEATH; } - public SoundEffect dA() { + @Override + public SoundEffect getSoundStep() { return SoundEffects.ENTITY_ZOMBIE_VILLAGER_STEP; } - @Nullable - protected MinecraftKey getDefaultLootTable() { - return LootTables.az; - } - - protected ItemStack dB() { + @Override + protected ItemStack dX() { return ItemStack.a; } + + public void setOffers(NBTTagCompound nbttagcompound) { + this.bC = nbttagcompound; + } + + public void a(NBTBase nbtbase) { + this.bB = nbtbase; + } + + @Nullable + @Override + public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.setVillagerData(this.getVillagerData().withType(VillagerType.a(generatoraccess.getBiome(new BlockPosition(this))))); + return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + } + + public void setVillagerData(VillagerData villagerdata) { + VillagerData villagerdata1 = this.getVillagerData(); + + if (villagerdata1.getProfession() != villagerdata.getProfession()) { + this.bC = null; + } + + this.datawatcher.set(EntityZombieVillager.c, villagerdata); + } + + @Override + public VillagerData getVillagerData() { + return (VillagerData) this.datawatcher.get(EntityZombieVillager.c); + } + + public void a(int i) { + this.bD = i; + } } diff --git a/src/main/java/net/minecraft/server/EnumCreatureType.java b/src/main/java/net/minecraft/server/EnumCreatureType.java deleted file mode 100644 index 24e9ffade..000000000 --- a/src/main/java/net/minecraft/server/EnumCreatureType.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.minecraft.server; - -public enum EnumCreatureType { - - MONSTER(IMonster.class, 70, false, false), CREATURE(EntityAnimal.class, 10, true, true), AMBIENT(EntityAmbient.class, 15, true, false), WATER_CREATURE(EntityWaterAnimal.class, 15, true, false); - - private final Class e; - private final int f; - private final boolean g; - private final boolean h; - - private EnumCreatureType(Class oclass, int i, boolean flag, boolean flag1) { - this.e = oclass; - this.f = i; - this.g = flag; - this.h = flag1; - } - - public boolean matches(Entity entity) { return innerClass().isAssignableFrom(entity.getClass()); } // Paper - public Class innerClass() { return this.a(); } // Paper - OBFHELPER - public Class a() { - return this.e; - } - - public int spawnLimit() { return this.b(); } // Akarin - public int b() { - return this.f; - } - - public boolean passive() { return c(); } // Akarin - public boolean c() { - return this.g; - } - - public boolean rare() { return d(); } // Akarin - public boolean d() { - return this.h; - } -} diff --git a/src/main/java/net/minecraft/server/EnumDirection.java b/src/main/java/net/minecraft/server/EnumDirection.java deleted file mode 100644 index ce7181127..000000000 --- a/src/main/java/net/minecraft/server/EnumDirection.java +++ /dev/null @@ -1,349 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Iterators; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Iterator; -import java.util.Map; -import java.util.Random; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import javax.annotation.Nullable; - -public enum EnumDirection implements INamable { - - DOWN(0, 1, -1, "down", EnumDirection.EnumAxisDirection.NEGATIVE, EnumDirection.EnumAxis.Y, new BaseBlockPosition(0, -1, 0)), UP(1, 0, -1, "up", EnumDirection.EnumAxisDirection.POSITIVE, EnumDirection.EnumAxis.Y, new BaseBlockPosition(0, 1, 0)), NORTH(2, 3, 2, "north", EnumDirection.EnumAxisDirection.NEGATIVE, EnumDirection.EnumAxis.Z, new BaseBlockPosition(0, 0, -1)), SOUTH(3, 2, 0, "south", EnumDirection.EnumAxisDirection.POSITIVE, EnumDirection.EnumAxis.Z, new BaseBlockPosition(0, 0, 1)), WEST(4, 5, 1, "west", EnumDirection.EnumAxisDirection.NEGATIVE, EnumDirection.EnumAxis.X, new BaseBlockPosition(-1, 0, 0)), EAST(5, 4, 3, "east", EnumDirection.EnumAxisDirection.POSITIVE, EnumDirection.EnumAxis.X, new BaseBlockPosition(1, 0, 0)); - - private final int g; - private final int h; - private final int i; - private final String j; - private final EnumDirection.EnumAxis k; - private final EnumDirection.EnumAxisDirection l; - private final BaseBlockPosition m; - private static final EnumDirection[] n = values(); - private static final Map o = (Map) Arrays.stream(EnumDirection.n).collect(Collectors.toMap(EnumDirection::j, (enumdirection) -> { - return enumdirection; - })); - private static final EnumDirection[] p = (EnumDirection[]) Arrays.stream(EnumDirection.n).sorted(Comparator.comparingInt((enumdirection) -> { - return enumdirection.g; - })).toArray((i) -> { - return new EnumDirection[i]; - }); - private static final EnumDirection[] q = (EnumDirection[]) Arrays.stream(EnumDirection.n).filter((enumdirection) -> { - return enumdirection.k().c(); - }).sorted(Comparator.comparingInt((enumdirection) -> { - return enumdirection.i; - })).toArray((i) -> { - return new EnumDirection[i]; - }); - - private EnumDirection(int i, int j, int k, String s, EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection, EnumDirection.EnumAxis enumdirection_enumaxis, BaseBlockPosition baseblockposition) { - this.g = i; - this.i = k; - this.h = j; - this.j = s; - this.k = enumdirection_enumaxis; - this.l = enumdirection_enumaxisdirection; - this.m = baseblockposition; - } - - public static EnumDirection[] a(Entity entity) { - float f = entity.g(1.0F) * 0.017453292F; - float f1 = -entity.h(1.0F) * 0.017453292F; - float f2 = MathHelper.sin(f); - float f3 = MathHelper.cos(f); - float f4 = MathHelper.sin(f1); - float f5 = MathHelper.cos(f1); - boolean flag = f4 > 0.0F; - boolean flag1 = f2 < 0.0F; - boolean flag2 = f5 > 0.0F; - float f6 = flag ? f4 : -f4; - float f7 = flag1 ? -f2 : f2; - float f8 = flag2 ? f5 : -f5; - float f9 = f6 * f3; - float f10 = f8 * f3; - EnumDirection enumdirection = flag ? EnumDirection.EAST : EnumDirection.WEST; - EnumDirection enumdirection1 = flag1 ? EnumDirection.UP : EnumDirection.DOWN; - EnumDirection enumdirection2 = flag2 ? EnumDirection.SOUTH : EnumDirection.NORTH; - - return f6 > f8 ? (f7 > f9 ? a(enumdirection1, enumdirection, enumdirection2) : (f10 > f7 ? a(enumdirection, enumdirection2, enumdirection1) : a(enumdirection, enumdirection1, enumdirection2))) : (f7 > f10 ? a(enumdirection1, enumdirection2, enumdirection) : (f9 > f7 ? a(enumdirection2, enumdirection, enumdirection1) : a(enumdirection2, enumdirection1, enumdirection))); - } - - private static EnumDirection[] a(EnumDirection enumdirection, EnumDirection enumdirection1, EnumDirection enumdirection2) { - return new EnumDirection[] { enumdirection, enumdirection1, enumdirection2, enumdirection2.opposite(), enumdirection1.opposite(), enumdirection.opposite()}; - } - - public int a() { - return this.g; - } - - public int get2DRotationValue() { - return this.i; - } - - public final EnumDirection.EnumAxisDirection getAxisDirection() { return c(); } // Paper - OBFHELPER - public EnumDirection.EnumAxisDirection c() { - return this.l; - } - - public EnumDirection opposite() { - return fromType1(this.h); - } - - public final EnumDirection rotateY() { return e(); } // Paper - OBFHELPER - public EnumDirection e() { - switch (this) { - case NORTH: - return EnumDirection.EAST; - case EAST: - return EnumDirection.SOUTH; - case SOUTH: - return EnumDirection.WEST; - case WEST: - return EnumDirection.NORTH; - default: - throw new IllegalStateException("Unable to get Y-rotated facing of " + this); - } - } - - public EnumDirection f() { - switch (this) { - case NORTH: - return EnumDirection.WEST; - case EAST: - return EnumDirection.NORTH; - case SOUTH: - return EnumDirection.EAST; - case WEST: - return EnumDirection.SOUTH; - default: - throw new IllegalStateException("Unable to get CCW facing of " + this); - } - } - - public int getAdjacentX() { - return this.k == EnumDirection.EnumAxis.X ? this.l.a() : 0; - } - - public int getAdjacentY() { - return this.k == EnumDirection.EnumAxis.Y ? this.l.a() : 0; - } - - public int getAdjacentZ() { - return this.k == EnumDirection.EnumAxis.Z ? this.l.a() : 0; - } - - public String j() { - return this.j; - } - - public EnumDirection.EnumAxis k() { - return this.k; - } - - public static EnumDirection fromType1(int i) { - return EnumDirection.p[MathHelper.a(i % EnumDirection.p.length)]; - } - - public static EnumDirection fromType2(int i) { - return EnumDirection.q[MathHelper.a(i % EnumDirection.q.length)]; - } - - public static EnumDirection fromAngle(double d0) { - return fromType2(MathHelper.floor(d0 / 90.0D + 0.5D) & 3); - } - - public static EnumDirection a(EnumDirection.EnumAxis enumdirection_enumaxis, EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection) { - switch (enumdirection_enumaxis) { - case X: - return enumdirection_enumaxisdirection == EnumDirection.EnumAxisDirection.POSITIVE ? EnumDirection.EAST : EnumDirection.WEST; - case Y: - return enumdirection_enumaxisdirection == EnumDirection.EnumAxisDirection.POSITIVE ? EnumDirection.UP : EnumDirection.DOWN; - case Z: - default: - return enumdirection_enumaxisdirection == EnumDirection.EnumAxisDirection.POSITIVE ? EnumDirection.SOUTH : EnumDirection.NORTH; - } - } - - public float l() { - return (float) ((this.i & 3) * 90); - } - - public static EnumDirection a(Random random) { - return values()[random.nextInt(values().length)]; - } - - public static EnumDirection a(double d0, double d1, double d2) { - return a((float) d0, (float) d1, (float) d2); - } - - public static EnumDirection a(float f, float f1, float f2) { - EnumDirection enumdirection = EnumDirection.NORTH; - float f3 = Float.MIN_VALUE; - EnumDirection[] aenumdirection = EnumDirection.n; - int i = aenumdirection.length; - - for (int j = 0; j < i; ++j) { - EnumDirection enumdirection1 = aenumdirection[j]; - float f4 = f * (float) enumdirection1.m.getX() + f1 * (float) enumdirection1.m.getY() + f2 * (float) enumdirection1.m.getZ(); - - if (f4 > f3) { - f3 = f4; - enumdirection = enumdirection1; - } - } - - return enumdirection; - } - - public String toString() { - return this.j; - } - - public String getName() { - return this.j; - } - - public static EnumDirection a(EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection, EnumDirection.EnumAxis enumdirection_enumaxis) { - EnumDirection[] aenumdirection = values(); - int i = aenumdirection.length; - - for (int j = 0; j < i; ++j) { - EnumDirection enumdirection = aenumdirection[j]; - - if (enumdirection.c() == enumdirection_enumaxisdirection && enumdirection.k() == enumdirection_enumaxis) { - return enumdirection; - } - } - - throw new IllegalArgumentException("No such direction: " + enumdirection_enumaxisdirection + " " + enumdirection_enumaxis); - } - - public static enum EnumDirectionLimit implements Iterable, Predicate { - - HORIZONTAL(new EnumDirection[] { EnumDirection.NORTH, EnumDirection.EAST, EnumDirection.SOUTH, EnumDirection.WEST}, new EnumDirection.EnumAxis[] { EnumDirection.EnumAxis.X, EnumDirection.EnumAxis.Z}), VERTICAL(new EnumDirection[] { EnumDirection.UP, EnumDirection.DOWN}, new EnumDirection.EnumAxis[] { EnumDirection.EnumAxis.Y}); - - private final EnumDirection[] c; - private final EnumDirection.EnumAxis[] d; - - private EnumDirectionLimit(EnumDirection[] aenumdirection, EnumDirection.EnumAxis[] aenumdirection_enumaxis) { - this.c = aenumdirection; - this.d = aenumdirection_enumaxis; - } - - public EnumDirection a(Random random) { - return this.c[random.nextInt(this.c.length)]; - } - - public boolean test(@Nullable EnumDirection enumdirection) { - return enumdirection != null && enumdirection.k().d() == this; - } - - public Iterator iterator() { - return Iterators.forArray(this.c); - } - } - - public static enum EnumAxisDirection { - - POSITIVE(1, "Towards positive"), NEGATIVE(-1, "Towards negative"); - - private final int c; - private final String d; - - private EnumAxisDirection(int i, String s) { - this.c = i; - this.d = s; - } - - public final int getOffset() { return a(); } // Paper - OBFHELPER - public int a() { - return this.c; - } - - public String toString() { - return this.d; - } - } - - public static enum EnumAxis implements Predicate, INamable { - - X("x") { - public int a(int i, int j, int k) { - return i; - } - - public double a(double d0, double d1, double d2) { - return d0; - } - }, - Y("y") { - public int a(int i, int j, int k) { - return j; - } - - public double a(double d0, double d1, double d2) { - return d1; - } - }, - Z("z") { - public int a(int i, int j, int k) { - return k; - } - - public double a(double d0, double d1, double d2) { - return d2; - } - }; - - private static final Map d = (Map) Arrays.stream(values()).collect(Collectors.toMap(EnumDirection.EnumAxis::a, (enumdirection_enumaxis) -> { - return enumdirection_enumaxis; - })); - private final String e; - - private EnumAxis(String s) { - this.e = s; - } - - public String a() { - return this.e; - } - - public boolean b() { - return this == EnumDirection.EnumAxis.Y; - } - - public boolean c() { - return this == EnumDirection.EnumAxis.X || this == EnumDirection.EnumAxis.Z; - } - - public String toString() { - return this.e; - } - - public boolean test(@Nullable EnumDirection enumdirection) { - return enumdirection != null && enumdirection.k() == this; - } - - public EnumDirection.EnumDirectionLimit d() { - switch (this) { - case X: - case Z: - return EnumDirection.EnumDirectionLimit.HORIZONTAL; - case Y: - return EnumDirection.EnumDirectionLimit.VERTICAL; - default: - throw new Error("Someone's been tampering with the universe!"); - } - } - - public String getName() { - return this.e; - } - - public abstract int a(int i, int j, int k); - - public abstract double a(double d0, double d1, double d2); - } -} diff --git a/src/main/java/net/minecraft/server/EnumItemSlot.java b/src/main/java/net/minecraft/server/EnumItemSlot.java index 8f4b5dca9..60b235f16 100644 --- a/src/main/java/net/minecraft/server/EnumItemSlot.java +++ b/src/main/java/net/minecraft/server/EnumItemSlot.java @@ -48,6 +48,21 @@ public enum EnumItemSlot { throw new IllegalArgumentException("Invalid slot '" + s + "'"); } + public static EnumItemSlot a(EnumItemSlot.Function enumitemslot_function, int i) { + EnumItemSlot[] aenumitemslot = values(); + int j = aenumitemslot.length; + + for (int k = 0; k < j; ++k) { + EnumItemSlot enumitemslot = aenumitemslot[k]; + + if (enumitemslot.a() == enumitemslot_function && enumitemslot.b() == i) { + return enumitemslot; + } + } + + throw new IllegalArgumentException("Invalid slot '" + enumitemslot_function + "': " + i); + } + public static enum Function { HAND, ARMOR; diff --git a/src/main/java/net/minecraft/server/ExpirableListEntry.java b/src/main/java/net/minecraft/server/ExpirableListEntry.java index d0e0dc3a5..79b095c05 100644 --- a/src/main/java/net/minecraft/server/ExpirableListEntry.java +++ b/src/main/java/net/minecraft/server/ExpirableListEntry.java @@ -62,10 +62,12 @@ public abstract class ExpirableListEntry extends JsonListEntry { public abstract IChatBaseComponent e(); + @Override boolean hasExpired() { return this.d == null ? false : this.d.before(new Date()); } + @Override protected void a(JsonObject jsonobject) { jsonobject.addProperty("created", ExpirableListEntry.a.format(this.b)); jsonobject.addProperty("source", this.c); diff --git a/src/main/java/net/minecraft/server/ExpiringMap.java b/src/main/java/net/minecraft/server/ExpiringMap.java deleted file mode 100644 index bf6095137..000000000 --- a/src/main/java/net/minecraft/server/ExpiringMap.java +++ /dev/null @@ -1,220 +0,0 @@ -package net.minecraft.server; - -import it.unimi.dsi.fastutil.longs.Long2LongLinkedOpenHashMap; -import it.unimi.dsi.fastutil.longs.Long2LongMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectCollection; -import it.unimi.dsi.fastutil.objects.ObjectIterator; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.LongFunction; - -public class ExpiringMap extends Long2ObjectMaps.SynchronizedMap { // paper - synchronize accesss - private final int a; - private final Long2LongMap ttl = new Long2LongLinkedOpenHashMap(); // Paper - private static final boolean DEBUG_EXPIRING_MAP = Boolean.getBoolean("debug.expiringmap"); - - public ExpiringMap(int i, int j) { - super(new Long2ObjectOpenHashMap<>(i)); // Paper - this.a = j; - } - - // Paper start - private void setAccess(long i) { a(i); } // Paper - OBFHELPER - private void a(long i) { - synchronized (this.sync) { - long j = System.currentTimeMillis(); // Paper - this.ttl.put(i, j); - if (!registered) { - registered = true; - MinecraftServer.getServer().expiringMaps.add(this); - } - } - } - - @Override - public T compute(long l, BiFunction biFunction) { - setAccess(l); - return super.compute(l, biFunction); - } - - @Override - public T putIfAbsent(long l, T t) { - setAccess(l); - return super.putIfAbsent(l, t); - } - - @Override - public T computeIfPresent(long l, BiFunction biFunction) { - setAccess(l); - return super.computeIfPresent(l, biFunction); - } - - @Override - public T computeIfAbsent(long l, LongFunction longFunction) { - setAccess(l); - return super.computeIfAbsent(l, longFunction); - } - - - @Override - public boolean replace(long l, T t, T v1) { - setAccess(l); - return super.replace(l, t, v1); - } - - @Override - public T replace(long l, T t) { - setAccess(l); - return super.replace(l, t); - } - - @Override - public T putIfAbsent(Long aLong, T t) { - setAccess(aLong); - return super.putIfAbsent(aLong, t); - } - - @Override - public boolean replace(Long aLong, T t, T v1) { - setAccess(aLong); - return super.replace(aLong, t, v1); - } - - @Override - public T replace(Long aLong, T t) { - setAccess(aLong); - return super.replace(aLong, t); - } - - @Override - public T computeIfAbsent(Long aLong, Function function) { - setAccess(aLong); - return super.computeIfAbsent(aLong, function); - } - - @Override - public T computeIfPresent(Long aLong, BiFunction biFunction) { - setAccess(aLong); - return super.computeIfPresent(aLong, biFunction); - } - - @Override - public T compute(Long aLong, BiFunction biFunction) { - setAccess(aLong); - return super.compute(aLong, biFunction); - } - - @Override - public void clear() { - synchronized (this.sync) { - ttl.clear(); - super.clear(); - } - } - - private boolean registered = false; - - // Break clean to its own method to be ticked - boolean clean() { - synchronized (this.sync) { - long now = System.currentTimeMillis(); - ObjectIterator objectiterator = this.ttl.long2LongEntrySet().iterator(); // Paper - - while (objectiterator.hasNext()) { - Long2LongMap.Entry entry = objectiterator.next(); // Paper - T object = super.get(entry.getLongKey()); // Paper - if (now - entry.getLongValue() <= (long) this.a) { - break; - } - - if (object != null && this.a(object)) { - super.remove(entry.getLongKey()); - objectiterator.remove(); - } - } - int ttlSize = this.ttl.size(); - int thisSize = this.size(); - if (ttlSize < thisSize) { - if (DEBUG_EXPIRING_MAP) { - MinecraftServer.LOGGER.warn("WARNING: ExpiringMap desync (ttl:" + ttlSize + " < actual:" + thisSize + ")"); - } - try { - for (Entry entry : this.long2ObjectEntrySet()) { - ttl.putIfAbsent(entry.getLongKey(), now); - } - } catch (Exception ignored) { - } // Ignore any como's - } else if (ttlSize > this.size()) { - if (DEBUG_EXPIRING_MAP) { - MinecraftServer.LOGGER.warn("WARNING: ExpiringMap desync (ttl:" + ttlSize + " > actual:" + thisSize + ")"); - } - try { - this.ttl.long2LongEntrySet().removeIf(entry -> !this.containsKey(entry.getLongKey())); - } catch (Exception ignored) { - } // Ignore any como's - } - if (isEmpty()) { - registered = false; - return true; - } - return false; - } - // Paper end - } - - protected boolean a(T var1) { - return true; - } - - public T put(long i, T object) { - this.a(i); - return (T)super.put(i, object); - } - - public T put(Long olong, T object) { - this.a(olong); - return (T)super.put(olong, object); - } - - public T get(long i) { - // Paper start - don't setAccess unless a hit - T t = super.get(i); - if (t != null) { - this.setAccess(i); - } - return t; - // Paper end - } - - public void putAll(Map var1) { - throw new RuntimeException("Not implemented"); - } - - public T remove(long var1) { - throw new RuntimeException("Not implemented"); - } - - public T remove(Object var1) { - throw new RuntimeException("Not implemented"); - } - - // Paper start - /* - // CraftBukkit start - @Override - public T computeIfAbsent(long l, LongFunction lf) { - this.ttl.put(l, SystemUtils.getMonotonicMillis()); // Paper - return super.computeIfAbsent(l, lf); - } - - @Override - public ObjectCollection values() { - cleanup(); - return super.values(); - } - // CraftBukkit end - */ // Paper end -} diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java index 808284ffc..8cfdac036 100644 --- a/src/main/java/net/minecraft/server/Explosion.java +++ b/src/main/java/net/minecraft/server/Explosion.java @@ -20,7 +20,7 @@ import org.bukkit.event.block.BlockExplodeEvent; public class Explosion { private final boolean a; - private final boolean b; + private final Explosion.Effect b; private final Random c = new Random(); private final World world; private final double posX; @@ -33,7 +33,7 @@ public class Explosion { private final Map l = Maps.newHashMap(); public boolean wasCanceled = false; // CraftBukkit - add field - public Explosion(World world, @Nullable Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) { + public Explosion(World world, @Nullable Entity entity, double d0, double d1, double d2, float f, boolean flag, Explosion.Effect explosion_effect) { this.world = world; this.source = entity; this.size = (float) Math.max(f, 0.0); // CraftBukkit - clamp bad values @@ -41,10 +41,45 @@ public class Explosion { this.posY = d1; this.posZ = d2; this.a = flag; - this.b = flag1; + this.b = explosion_effect; this.j = DamageSource.explosion(this); } + public static float a(Vec3D vec3d, Entity entity) { + AxisAlignedBB axisalignedbb = entity.getBoundingBox(); + double d0 = 1.0D / ((axisalignedbb.maxX - axisalignedbb.minX) * 2.0D + 1.0D); + double d1 = 1.0D / ((axisalignedbb.maxY - axisalignedbb.minY) * 2.0D + 1.0D); + double d2 = 1.0D / ((axisalignedbb.maxZ - axisalignedbb.minZ) * 2.0D + 1.0D); + double d3 = (1.0D - Math.floor(1.0D / d0) * d0) / 2.0D; + double d4 = (1.0D - Math.floor(1.0D / d2) * d2) / 2.0D; + + if (d0 >= 0.0D && d1 >= 0.0D && d2 >= 0.0D) { + int i = 0; + int j = 0; + + for (float f = 0.0F; f <= 1.0F; f = (float) ((double) f + d0)) { + for (float f1 = 0.0F; f1 <= 1.0F; f1 = (float) ((double) f1 + d1)) { + for (float f2 = 0.0F; f2 <= 1.0F; f2 = (float) ((double) f2 + d2)) { + double d5 = MathHelper.d((double) f, axisalignedbb.minX, axisalignedbb.maxX); + double d6 = MathHelper.d((double) f1, axisalignedbb.minY, axisalignedbb.maxY); + double d7 = MathHelper.d((double) f2, axisalignedbb.minZ, axisalignedbb.maxZ); + Vec3D vec3d1 = new Vec3D(d5 + d3, d6, d7 + d4); + + if (entity.world.rayTrace(new RayTrace(vec3d1, vec3d, RayTrace.BlockCollisionOption.OUTLINE, RayTrace.FluidCollisionOption.NONE, entity)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS) { + ++i; + } + + ++j; + } + } + } + + return (float) i / (float) j; + } else { + return 0.0F; + } + } + public void a() { // CraftBukkit start if (this.size < 0.1F) { @@ -79,7 +114,7 @@ public class Explosion { IBlockData iblockdata = this.world.getType(blockposition); Fluid fluid = this.world.getFluid(blockposition); - if (!iblockdata.isAir() || !fluid.e()) { + if (!iblockdata.isAir() || !fluid.isEmpty()) { float f2 = Math.max(iblockdata.getBlock().getDurability(), fluid.l()); if (this.source != null) { @@ -124,8 +159,8 @@ public class Explosion { for (int l1 = 0; l1 < list.size(); ++l1) { Entity entity = (Entity) list.get(l1); - if (!entity.bL()) { - double d7 = entity.e(this.posX, this.posY, this.posZ) / (double) f3; + if (!entity.bS()) { + double d7 = (double) (MathHelper.sqrt(entity.c(new Vec3D(this.posX, this.posY, this.posZ))) / f3); if (d7 <= 1.0D) { double d8 = entity.locX - this.posX; @@ -137,7 +172,7 @@ public class Explosion { d8 /= d11; d9 /= d11; d10 /= d11; - double d12 = this.getBlockDensity(vec3d, entity.getBoundingBox()); // Paper - Optimize explosions + double d12 = this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions double d13 = (1.0D - d7) * d12; // CraftBukkit start @@ -156,13 +191,11 @@ public class Explosion { d14 = entity instanceof EntityHuman && world.paperConfig.disableExplosionKnockback ? 0 : EnchantmentProtection.a((EntityLiving) entity, d13); // Paper - Disable explosion knockback } - entity.motX += d8 * d14; - entity.motY += d9 * d14; - entity.motZ += d10 * d14; + entity.setMot(entity.getMot().add(d8 * d14, d9 * d14, d10 * d14)); if (entity instanceof EntityHuman) { EntityHuman entityhuman = (EntityHuman) entity; - if (!entityhuman.isSpectator() && (!entityhuman.u() && !world.paperConfig.disableExplosionKnockback || !entityhuman.abilities.isFlying)) { // Paper - Disable explosion knockback + if (!entityhuman.isSpectator() && (!entityhuman.isCreative() && !world.paperConfig.disableExplosionKnockback || !entityhuman.abilities.isFlying)) { // Paper - Disable explosion knockback this.l.put(entityhuman, new Vec3D(d8 * d13, d9 * d13, d10 * d13)); } } @@ -174,30 +207,28 @@ public class Explosion { } public void a(boolean flag) { - this.world.a((EntityHuman) null, this.posX, this.posY, this.posZ, SoundEffects.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.random.nextFloat() - this.world.random.nextFloat()) * 0.2F) * 0.7F); - // Akarin start - this handle by client - /* - if (this.size >= 2.0F && this.b) { - this.world.addParticle(Particles.t, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D); + this.world.playSound((EntityHuman) null, this.posX, this.posY, this.posZ, SoundEffects.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.random.nextFloat() - this.world.random.nextFloat()) * 0.2F) * 0.7F); + boolean flag1 = this.b != Explosion.Effect.NONE; + + if (this.size >= 2.0F && flag1) { + this.world.addParticle(Particles.EXPLOSION_EMITTER, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D); } else { - this.world.addParticle(Particles.u, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D); + this.world.addParticle(Particles.EXPLOSION, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D); } - */ - // Akarin end Iterator iterator; BlockPosition blockposition; - if (this.b) { + if (flag1) { // CraftBukkit start - org.bukkit.craftbukkit.CraftWorld bworld = this.world.getWorld(); // Akarin - CraftWorld + org.bukkit.World bworld = this.world.getWorld(); org.bukkit.entity.Entity explode = this.source == null ? null : this.source.getBukkitEntity(); Location location = new Location(bworld, this.posX, this.posY, this.posZ); List blockList = Lists.newArrayList(); for (int i1 = this.blocks.size() - 1; i1 >= 0; i1--) { BlockPosition cpos = (BlockPosition) this.blocks.get(i1); - org.bukkit.block.Block bblock = bworld.getBlockAt(cpos); // Akarin + org.bukkit.block.Block bblock = bworld.getBlockAt(cpos.getX(), cpos.getY(), cpos.getZ()); if (bblock.getType() != org.bukkit.Material.AIR) { blockList.add(bblock); } @@ -208,13 +239,13 @@ public class Explosion { float yield; if (explode != null) { - EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, 1.0F / this.size); + EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, this.b == Explosion.Effect.DESTROY ? 1.0F / this.size : 1.0F); this.world.getServer().getPluginManager().callEvent(event); cancelled = event.isCancelled(); bukkitBlocks = event.blockList(); yield = event.getYield(); } else { - BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, 1.0F / this.size); + BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.b == Explosion.Effect.DESTROY ? 1.0F / this.size : 1.0F); this.world.getServer().getPluginManager().callEvent(event); cancelled = event.isCancelled(); bukkitBlocks = event.blockList(); @@ -240,8 +271,6 @@ public class Explosion { IBlockData iblockdata = this.world.getType(blockposition); Block block = iblockdata.getBlock(); - // Akarin start - this handle by client - /* if (flag) { double d0 = (double) ((float) blockposition.getX() + this.world.random.nextFloat()); double d1 = (double) ((float) blockposition.getY() + this.world.random.nextFloat()); @@ -260,16 +289,20 @@ public class Explosion { d3 *= d7; d4 *= d7; d5 *= d7; - this.world.addParticle(Particles.J, (d0 + this.posX) / 2.0D, (d1 + this.posY) / 2.0D, (d2 + this.posZ) / 2.0D, d3, d4, d5); - this.world.addParticle(Particles.M, d0, d1, d2, d3, d4, d5); + this.world.addParticle(Particles.POOF, (d0 + this.posX) / 2.0D, (d1 + this.posY) / 2.0D, (d2 + this.posZ) / 2.0D, d3, d4, d5); + this.world.addParticle(Particles.SMOKE, d0, d1, d2, d3, d4, d5); } - */ - // Akarin end if (!iblockdata.isAir()) { - if (block.a(this)) { - // CraftBukkit - add yield - iblockdata.dropNaturally(this.world, blockposition, yield, 0); + if (block.a(this) && this.world instanceof WorldServer) { + TileEntity tileentity = block.isTileEntity() ? this.world.getTileEntity(blockposition) : null; + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).a(this.world.random).set(LootContextParameters.POSITION, blockposition).set(LootContextParameters.TOOL, ItemStack.a).setOptional(LootContextParameters.BLOCK_ENTITY, tileentity); + + if (this.b == Explosion.Effect.DESTROY || yield < 1.0F) { // CraftBukkit - add yield + loottableinfo_builder.set(LootContextParameters.EXPLOSION_RADIUS, 1.0F / yield); // CraftBukkit - add yield + } + + Block.b(iblockdata, loottableinfo_builder); } this.world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); @@ -283,7 +316,7 @@ public class Explosion { while (iterator.hasNext()) { blockposition = (BlockPosition) iterator.next(); - if (this.world.getType(blockposition).isAir() && this.world.getType(blockposition.down()).f(this.world, blockposition.down()) && this.c.nextInt(3) == 0) { + if (this.world.getType(blockposition).isAir() && this.world.getType(blockposition.down()).g(this.world, blockposition.down()) && this.c.nextInt(3) == 0) { // CraftBukkit start - Ignition by explosion if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(this.world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) { this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); @@ -322,15 +355,21 @@ public class Explosion { return this.blocks; } + public static enum Effect { + + NONE, BREAK, DESTROY; + + private Effect() {} + } // Paper start - Optimize explosions - private float getBlockDensity(Vec3D vec3d, AxisAlignedBB aabb) { + private float getBlockDensity(Vec3D vec3d, Entity entity) { if (!this.world.paperConfig.optimizeExplosions) { - return this.world.a(vec3d, aabb); + return a(vec3d, entity); } - CacheKey key = new CacheKey(this, aabb); - float blockDensity = 0f; // Akarin - if (!this.world.explosionDensityCache.containsKey(key)) { // Akarin - blockDensity = this.world.a(vec3d, aabb); + CacheKey key = new CacheKey(this, entity.getBoundingBox()); + Float blockDensity = this.world.explosionDensityCache.get(key); + if (blockDensity == null) { + blockDensity = a(vec3d, entity); this.world.explosionDensityCache.put(key, blockDensity); } diff --git a/src/main/java/net/minecraft/server/FileIOThread.java b/src/main/java/net/minecraft/server/FileIOThread.java deleted file mode 100644 index 0818cf393..000000000 --- a/src/main/java/net/minecraft/server/FileIOThread.java +++ /dev/null @@ -1,106 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; - -import java.util.Collections; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class FileIOThread implements Runnable { - - private static final Logger a = LogManager.getLogger(); - private static final FileIOThread b = new FileIOThread(); - private final List c = Collections.synchronizedList(Lists.newArrayList()); private List getThreadedIOQueue() { return c; } // Paper - OBFHELPER - private volatile long d; - private volatile long e; - private volatile boolean f; - // Akarin start - private final java.util.concurrent.ExecutorService executor = java.util.concurrent.Executors.newFixedThreadPool(io.akarin.server.core.AkarinGlobalConfig.fileIOThreads, new com.google.common.util.concurrent.ThreadFactoryBuilder().setUncaughtExceptionHandler(new ThreadNamedUncaughtExceptionHandler(FileIOThread.a)).setNameFormat("Akarin File IO Thread - %1$d").setPriority(1).build()); - - @lombok.SneakyThrows - private void writeChunk(IAsyncChunkSaver iasyncchunksaver) { - if (!iasyncchunksaver.a() /* writeNextIO */) { // returns whether the writing was unsuccessful - if (com.destroystokyo.paper.PaperConfig.enableFileIOThreadSleep) { // Paper - Thread.sleep(this.f ? 0L : 2L); // Paper - } - } else { - writeChunk(iasyncchunksaver); - } - } - // Akarin end - - private FileIOThread() { - Thread thread = new Thread(this, "File IO Thread"); - - thread.setUncaughtExceptionHandler(new ThreadNamedUncaughtExceptionHandler(FileIOThread.a)); - thread.setPriority(1); - //thread.start(); // Akarin - } - - public static FileIOThread a() { - return FileIOThread.b; - } - - public void run() { - while (true) { - this.c(); - } - } - - private void c() { - for (int i = 0; i < this.c.size(); ++i) { - IAsyncChunkSaver iasyncchunksaver = (IAsyncChunkSaver) this.c.get(i); - boolean flag; - - //synchronized (iasyncchunksaver) { // Paper - remove synchronized - flag = iasyncchunksaver.a(); - //} // Paper - - if (!flag) { - this.c.remove(i--); - ++this.e; - } - - if (com.destroystokyo.paper.PaperConfig.enableFileIOThreadSleep) { // Paper - try { - Thread.sleep(this.f ? 0L : 1L); // Paper - } catch (InterruptedException interruptedexception) { - interruptedexception.printStackTrace(); - }} // Paper - } - - if (this.c.isEmpty()) { - try { - Thread.sleep(25L); - } catch (InterruptedException interruptedexception1) { - interruptedexception1.printStackTrace(); - } - } - - } - - public void a(IAsyncChunkSaver iasyncchunksaver) { - // Akarin start - //if (!this.c.contains(iasyncchunksaver)) { - // ++this.d; - // this.c.add(iasyncchunksaver); - //} - executor.execute(() -> writeChunk(iasyncchunksaver)); - // Akarin end - } - - public void b() throws InterruptedException { - this.f = true; - - while(!this.getThreadedIOQueue().isEmpty()) { // Paper - check actual list size - Thread.sleep(10L); - } - executor.shutdown(); // Akarin - executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); // Akarin - - this.f = false; - } -} diff --git a/src/main/java/net/minecraft/server/FluidTypeFlowing.java b/src/main/java/net/minecraft/server/FluidTypeFlowing.java index c0955d6ec..4660b9538 100644 --- a/src/main/java/net/minecraft/server/FluidTypeFlowing.java +++ b/src/main/java/net/minecraft/server/FluidTypeFlowing.java @@ -21,8 +21,8 @@ import org.bukkit.event.block.FluidLevelChangeEvent; public abstract class FluidTypeFlowing extends FluidType { - public static final BlockStateBoolean FALLING = BlockProperties.h; - public static final BlockStateInteger LEVEL = BlockProperties.ag; + public static final BlockStateBoolean FALLING = BlockProperties.i; + public static final BlockStateInteger LEVEL = BlockProperties.an; private static final ThreadLocal> e = ThreadLocal.withInitial(() -> { Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap = new Object2ByteLinkedOpenHashMap(200) { protected void rehash(int i) {} @@ -31,14 +31,17 @@ public abstract class FluidTypeFlowing extends FluidType { object2bytelinkedopenhashmap.defaultReturnValue((byte) 127); return object2bytelinkedopenhashmap; }); + private final Map f = Maps.newIdentityHashMap(); public FluidTypeFlowing() {} + @Override protected void a(BlockStateList.a blockstatelist_a) { blockstatelist_a.a(FluidTypeFlowing.FALLING); } - public Vec3D a(IWorldReader iworldreader, BlockPosition blockposition, Fluid fluid) { + @Override + public Vec3D a(IBlockAccess iblockaccess, BlockPosition blockposition, Fluid fluid) { double d0 = 0.0D; double d1 = 0.0D; BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); @@ -53,25 +56,26 @@ public abstract class FluidTypeFlowing extends FluidType { EnumDirection enumdirection = (EnumDirection) iterator.next(); blockposition_pooledblockposition.g(blockposition).c(enumdirection); - Fluid fluid1 = iworldreader.getFluid(blockposition_pooledblockposition); + Fluid fluid1 = iblockaccess.getFluid(blockposition_pooledblockposition); if (this.g(fluid1)) { - float f = fluid1.getHeight(); + float f = fluid1.f(); float f1 = 0.0F; if (f == 0.0F) { - if (!iworldreader.getType(blockposition_pooledblockposition).getMaterial().isSolid()) { - Fluid fluid2 = iworldreader.getFluid(blockposition_pooledblockposition.down()); + if (!iblockaccess.getType(blockposition_pooledblockposition).getMaterial().isSolid()) { + BlockPosition blockposition1 = blockposition_pooledblockposition.down(); + Fluid fluid2 = iblockaccess.getFluid(blockposition1); if (this.g(fluid2)) { - f = fluid2.getHeight(); + f = fluid2.f(); if (f > 0.0F) { - f1 = fluid.getHeight() - (f - 0.8888889F); + f1 = fluid.f() - (f - 0.8888889F); } } } } else if (f > 0.0F) { - f1 = fluid.getHeight() - f; + f1 = fluid.f() - f; } if (f1 != 0.0F) { @@ -90,14 +94,14 @@ public abstract class FluidTypeFlowing extends FluidType { EnumDirection enumdirection1 = (EnumDirection) iterator1.next(); blockposition_pooledblockposition.g(blockposition).c(enumdirection1); - if (this.a((IBlockAccess) iworldreader, (BlockPosition) blockposition_pooledblockposition, enumdirection1) || this.a((IBlockAccess) iworldreader, blockposition_pooledblockposition.up(), enumdirection1)) { - vec3d1 = vec3d1.a().add(0.0D, -6.0D, 0.0D); + if (this.a(iblockaccess, (BlockPosition) blockposition_pooledblockposition, enumdirection1) || this.a(iblockaccess, blockposition_pooledblockposition.up(), enumdirection1)) { + vec3d1 = vec3d1.d().add(0.0D, -6.0D, 0.0D); break; } } } - vec3d = vec3d1.a(); + vec3d = vec3d1.d(); } catch (Throwable throwable1) { throwable = throwable1; throw throwable1; @@ -120,35 +124,24 @@ public abstract class FluidTypeFlowing extends FluidType { } private boolean g(Fluid fluid) { - return fluid.e() || fluid.c().a((FluidType) this); + return fluid.isEmpty() || fluid.getType().a((FluidType) this); } protected boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { IBlockData iblockdata = iblockaccess.getType(blockposition); - Block block = iblockdata.getBlock(); Fluid fluid = iblockaccess.getFluid(blockposition); - if (fluid.c().a((FluidType) this)) { - return false; - } else if (enumdirection == EnumDirection.UP) { - return true; - } else if (iblockdata.getMaterial() == Material.ICE) { - return false; - } else { - boolean flag = Block.b(block) || block instanceof BlockStairs; - - return !flag && iblockdata.c(iblockaccess, blockposition, enumdirection) == EnumBlockFaceShape.SOLID; - } + return fluid.getType().a((FluidType) this) ? false : (enumdirection == EnumDirection.UP ? true : (iblockdata.getMaterial() == Material.ICE ? false : iblockdata.d(iblockaccess, blockposition, enumdirection))); } protected void a(GeneratorAccess generatoraccess, BlockPosition blockposition, Fluid fluid) { - if (!fluid.e()) { + if (!fluid.isEmpty()) { IBlockData iblockdata = generatoraccess.getType(blockposition); BlockPosition blockposition1 = blockposition.down(); IBlockData iblockdata1 = generatoraccess.getType(blockposition1); Fluid fluid1 = this.a((IWorldReader) generatoraccess, blockposition1, iblockdata1); - if (this.a(generatoraccess, blockposition, iblockdata, EnumDirection.DOWN, blockposition1, iblockdata1, generatoraccess.getFluid(blockposition1), fluid1.c())) { + if (this.a(generatoraccess, blockposition, iblockdata, EnumDirection.DOWN, blockposition1, iblockdata1, generatoraccess.getFluid(blockposition1), fluid1.getType())) { // CraftBukkit start org.bukkit.block.Block source = CraftBlock.at(generatoraccess, blockposition); BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN); @@ -162,7 +155,7 @@ public abstract class FluidTypeFlowing extends FluidType { if (this.a((IWorldReader) generatoraccess, blockposition) >= 3) { this.a(generatoraccess, blockposition, fluid, iblockdata); } - } else if (fluid.d() || !this.a((IBlockAccess) generatoraccess, fluid1.c(), blockposition, iblockdata, blockposition1, iblockdata1)) { + } else if (fluid.isSource() || !this.a((IBlockAccess) generatoraccess, fluid1.getType(), blockposition, iblockdata, blockposition1, iblockdata1)) { this.a(generatoraccess, blockposition, fluid, iblockdata); } @@ -177,7 +170,7 @@ public abstract class FluidTypeFlowing extends FluidType { } if (i > 0) { - Map map = this.b(generatoraccess, blockposition, iblockdata); + Map map = this.b((IWorldReader) generatoraccess, blockposition, iblockdata); Iterator iterator = map.entrySet().iterator(); while (iterator.hasNext()) { @@ -188,7 +181,7 @@ public abstract class FluidTypeFlowing extends FluidType { IBlockData iblockdata1 = generatoraccess.getTypeIfLoaded(blockposition1); // Paper if (iblockdata1 == null) continue; // Paper - if (this.a(generatoraccess, blockposition, iblockdata, enumdirection, blockposition1, iblockdata1, generatoraccess.getFluid(blockposition1), fluid1.c())) { + if (this.a(generatoraccess, blockposition, iblockdata, enumdirection, blockposition1, iblockdata1, generatoraccess.getFluid(blockposition1), fluid1.getType())) { // CraftBukkit start org.bukkit.block.Block source = CraftBlock.at(generatoraccess, blockposition); BlockFromToEvent event = new BlockFromToEvent(source, org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(enumdirection)); @@ -215,10 +208,10 @@ public abstract class FluidTypeFlowing extends FluidType { BlockPosition blockposition1 = blockposition.shift(enumdirection); IBlockData iblockdata1 = iworldreader.getTypeIfLoaded(blockposition1); // Paper if (iblockdata1 == null) continue; // Paper - Fluid fluid = iblockdata1.s(); + Fluid fluid = iblockdata1.p(); - if (fluid.c().a((FluidType) this) && this.a(enumdirection, (IBlockAccess) iworldreader, blockposition, iblockdata, blockposition1, iblockdata1)) { - if (fluid.d()) { + if (fluid.getType().a((FluidType) this) && this.a(enumdirection, (IBlockAccess) iworldreader, blockposition, iblockdata, blockposition1, iblockdata1)) { + if (fluid.isSource()) { ++j; } @@ -228,7 +221,7 @@ public abstract class FluidTypeFlowing extends FluidType { if (this.g() && j >= 2) { IBlockData iblockdata2 = iworldreader.getType(blockposition.down()); - Fluid fluid1 = iblockdata2.s(); + Fluid fluid1 = iblockdata2.p(); if (iblockdata2.getMaterial().isBuildable() || this.h(fluid1)) { return this.a(false); @@ -237,9 +230,9 @@ public abstract class FluidTypeFlowing extends FluidType { BlockPosition blockposition2 = blockposition.up(); IBlockData iblockdata3 = iworldreader.getType(blockposition2); - Fluid fluid2 = iblockdata3.s(); + Fluid fluid2 = iblockdata3.p(); - if (!fluid2.e() && fluid2.c().a((FluidType) this) && this.a(EnumDirection.UP, (IBlockAccess) iworldreader, blockposition, iblockdata, blockposition2, iblockdata3)) { + if (!fluid2.isEmpty() && fluid2.getType().a((FluidType) this) && this.a(EnumDirection.UP, (IBlockAccess) iworldreader, blockposition, iblockdata, blockposition2, iblockdata3)) { return this.a(8, true); } else { int k = i - this.c(iworldreader); @@ -251,7 +244,7 @@ public abstract class FluidTypeFlowing extends FluidType { private boolean a(EnumDirection enumdirection, IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, BlockPosition blockposition1, IBlockData iblockdata1) { Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; - if (!iblockdata.getBlock().s() && !iblockdata1.getBlock().s()) { + if (!iblockdata.getBlock().p() && !iblockdata1.getBlock().p()) { object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) FluidTypeFlowing.e.get(); } else { object2bytelinkedopenhashmap = null; @@ -307,7 +300,7 @@ public abstract class FluidTypeFlowing extends FluidType { this.a(generatoraccess, blockposition, iblockdata); } - generatoraccess.setTypeAndData(blockposition, fluid.i(), 3); + generatoraccess.setTypeAndData(blockposition, fluid.getBlockData(), 3); } } @@ -339,12 +332,11 @@ public abstract class FluidTypeFlowing extends FluidType { continue; } - pair = Pair.of(iblockdatax, iblockdatax.s()); + pair = Pair.of(iblockdatax, iblockdatax.p()); short2objectmap.put(short0, pair); } // Paper end - IBlockData iblockdata1 = (IBlockData) pair.getFirst(); Fluid fluid = (Fluid) pair.getSecond(); @@ -375,7 +367,7 @@ public abstract class FluidTypeFlowing extends FluidType { } private boolean a(IBlockAccess iblockaccess, FluidType fluidtype, BlockPosition blockposition, IBlockData iblockdata, BlockPosition blockposition1, IBlockData iblockdata1) { - return !this.a(EnumDirection.DOWN, iblockaccess, blockposition, iblockdata, blockposition1, iblockdata1) ? false : (iblockdata1.s().c().a((FluidType) this) ? true : this.a(iblockaccess, blockposition1, iblockdata1, fluidtype)); + return !this.a(EnumDirection.DOWN, iblockaccess, blockposition, iblockdata, blockposition1, iblockdata1) ? false : (iblockdata1.p().getType().a((FluidType) this) ? true : this.a(iblockaccess, blockposition1, iblockdata1, fluidtype)); } private boolean a(IBlockAccess iblockaccess, FluidType fluidtype, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection, BlockPosition blockposition1, IBlockData iblockdata1, Fluid fluid) { @@ -383,7 +375,7 @@ public abstract class FluidTypeFlowing extends FluidType { } private boolean h(Fluid fluid) { - return fluid.c().a((FluidType) this) && fluid.d(); + return fluid.getType().a((FluidType) this) && fluid.isSource(); } protected abstract int b(IWorldReader iworldreader); @@ -422,7 +414,7 @@ public abstract class FluidTypeFlowing extends FluidType { IBlockData iblockdatax = iworldreader.getTypeIfLoaded(blockposition1); if (iblockdatax == null) continue; - pair = Pair.of(iblockdatax, iblockdatax.s()); + pair = Pair.of(iblockdatax, iblockdatax.p()); short2objectmap.put(short0, pair); } // Paper end @@ -430,7 +422,7 @@ public abstract class FluidTypeFlowing extends FluidType { Fluid fluid = (Fluid) pair.getSecond(); Fluid fluid1 = this.a(iworldreader, blockposition1, iblockdata1); - if (this.a(iworldreader, fluid1.c(), blockposition, iblockdata, enumdirection, blockposition1, iblockdata1, fluid)) { + if (this.a(iworldreader, fluid1.getType(), blockposition, iblockdata, enumdirection, blockposition1, iblockdata1, fluid)) { BlockPosition blockposition2 = blockposition1.down(); boolean flag = short2booleanopenhashmap.computeIfAbsent(short0, (j) -> { IBlockData iblockdata2 = iworldreader.getType(blockposition2); @@ -464,7 +456,7 @@ public abstract class FluidTypeFlowing extends FluidType { if (block instanceof IFluidContainer) { return ((IFluidContainer) block).canPlace(iblockaccess, blockposition, iblockdata, fluidtype); - } else if (!(block instanceof BlockDoor) && block != Blocks.SIGN && block != Blocks.LADDER && block != Blocks.SUGAR_CANE && block != Blocks.BUBBLE_COLUMN) { + } else if (!(block instanceof BlockDoor) && !block.a(TagsBlock.SIGNS) && block != Blocks.LADDER && block != Blocks.SUGAR_CANE && block != Blocks.BUBBLE_COLUMN) { Material material = iblockdata.getMaterial(); return material != Material.PORTAL && material != Material.STRUCTURE_VOID && material != Material.WATER_PLANT && material != Material.REPLACEABLE_WATER_PLANT ? !material.isSolid() : false; @@ -474,21 +466,22 @@ public abstract class FluidTypeFlowing extends FluidType { } protected boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection, BlockPosition blockposition1, IBlockData iblockdata1, Fluid fluid, FluidType fluidtype) { - return fluid.a(fluidtype, enumdirection) && this.a(enumdirection, iblockaccess, blockposition, iblockdata, blockposition1, iblockdata1) && this.a(iblockaccess, blockposition1, iblockdata1, fluidtype); + return fluid.a(iblockaccess, blockposition1, fluidtype, enumdirection) && this.a(enumdirection, iblockaccess, blockposition, iblockdata, blockposition1, iblockdata1) && this.a(iblockaccess, blockposition1, iblockdata1, fluidtype); } protected abstract int c(IWorldReader iworldreader); - protected int a(World world, Fluid fluid, Fluid fluid1) { + protected int a(World world, BlockPosition blockposition, Fluid fluid, Fluid fluid1) { return this.a((IWorldReader) world); } + @Override public void a(World world, BlockPosition blockposition, Fluid fluid) { - if (!fluid.d()) { + if (!fluid.isSource()) { Fluid fluid1 = this.a((IWorldReader) world, blockposition, world.getType(blockposition)); - int i = this.a(world, fluid, fluid1); + int i = this.a(world, blockposition, fluid, fluid1); - if (fluid1.e()) { + if (fluid1.isEmpty()) { fluid = fluid1; // CraftBukkit start FluidLevelChangeEvent event = CraftEventFactory.callFluidLevelChangeEvent(world, blockposition, Blocks.AIR.getBlockData()); @@ -499,7 +492,7 @@ public abstract class FluidTypeFlowing extends FluidType { // CraftBukkit end } else if (!fluid1.equals(fluid)) { fluid = fluid1; - IBlockData iblockdata = fluid1.i(); + IBlockData iblockdata = fluid1.getBlockData(); // CraftBukkit start FluidLevelChangeEvent event = CraftEventFactory.callFluidLevelChangeEvent(world, blockposition, iblockdata); if (event.isCancelled()) { @@ -507,7 +500,7 @@ public abstract class FluidTypeFlowing extends FluidType { } world.setTypeAndData(blockposition, ((CraftBlockData) event.getNewData()).getState(), 2); // CraftBukkit end - world.getFluidTickList().a(blockposition, fluid1.c(), i); + world.getFluidTickList().a(blockposition, fluid1.getType(), i); world.applyPhysics(blockposition, iblockdata.getBlock()); } } @@ -516,10 +509,27 @@ public abstract class FluidTypeFlowing extends FluidType { } protected static int e(Fluid fluid) { - return fluid.d() ? 0 : 8 - Math.min(fluid.g(), 8) + ((Boolean) fluid.get(FluidTypeFlowing.FALLING) ? 8 : 0); + return fluid.isSource() ? 0 : 8 - Math.min(fluid.g(), 8) + ((Boolean) fluid.get(FluidTypeFlowing.FALLING) ? 8 : 0); } + private static boolean c(Fluid fluid, IBlockAccess iblockaccess, BlockPosition blockposition) { + return fluid.getType().a(iblockaccess.getFluid(blockposition.up()).getType()); + } + + @Override + public float a(Fluid fluid, IBlockAccess iblockaccess, BlockPosition blockposition) { + return c(fluid, iblockaccess, blockposition) ? 1.0F : fluid.f(); + } + + @Override public float a(Fluid fluid) { return (float) fluid.g() / 9.0F; } + + @Override + public VoxelShape b(Fluid fluid, IBlockAccess iblockaccess, BlockPosition blockposition) { + return fluid.g() == 9 && c(fluid, iblockaccess, blockposition) ? VoxelShapes.b() : (VoxelShape) this.f.computeIfAbsent(fluid, (fluid1) -> { + return VoxelShapes.create(0.0D, 0.0D, 0.0D, 1.0D, (double) fluid1.getHeight(iblockaccess, blockposition), 1.0D); + }); + } } diff --git a/src/main/java/net/minecraft/server/FluidTypeLava.java b/src/main/java/net/minecraft/server/FluidTypeLava.java index be77fd399..ff677c59e 100644 --- a/src/main/java/net/minecraft/server/FluidTypeLava.java +++ b/src/main/java/net/minecraft/server/FluidTypeLava.java @@ -6,28 +6,32 @@ public abstract class FluidTypeLava extends FluidTypeFlowing { public FluidTypeLava() {} + @Override public FluidType e() { return FluidTypes.FLOWING_LAVA; } + @Override public FluidType f() { return FluidTypes.LAVA; } + @Override public Item b() { return Items.LAVA_BUCKET; } + @Override public void b(World world, BlockPosition blockposition, Fluid fluid, Random random) { - if (world.getGameRules().getBoolean("doFireTick")) { + if (world.getGameRules().getBoolean(GameRules.DO_FIRE_TICK)) { int i = random.nextInt(3); if (i > 0) { BlockPosition blockposition1 = blockposition; for (int j = 0; j < i; ++j) { - blockposition1 = blockposition1.a(random.nextInt(3) - 1, 1, random.nextInt(3) - 1); - if (!world.p(blockposition1)) { + blockposition1 = blockposition1.b(random.nextInt(3) - 1, 1, random.nextInt(3) - 1); + if (!world.n(blockposition1)) { return; } @@ -36,7 +40,7 @@ public abstract class FluidTypeLava extends FluidTypeFlowing { if (iblockdata.isAir()) { if (this.a((IWorldReader) world, blockposition1)) { // CraftBukkit start - Prevent lava putting something on fire - if (world.getType(blockposition1) != Blocks.FIRE) { + if (world.getType(blockposition1).getBlock() != Blocks.FIRE) { if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition1, blockposition).isCancelled()) { continue; } @@ -51,16 +55,16 @@ public abstract class FluidTypeLava extends FluidTypeFlowing { } } else { for (int k = 0; k < 3; ++k) { - BlockPosition blockposition2 = blockposition.a(random.nextInt(3) - 1, 0, random.nextInt(3) - 1); + BlockPosition blockposition2 = blockposition.b(random.nextInt(3) - 1, 0, random.nextInt(3) - 1); - if (!world.p(blockposition2)) { + if (!world.n(blockposition2)) { return; } if (world.isEmpty(blockposition2.up()) && this.b(world, blockposition2)) { // CraftBukkit start - Prevent lava putting something on fire BlockPosition up = blockposition2.up(); - if (world.getType(up) != Blocks.FIRE) { + if (world.getType(up).getBlock() != Blocks.FIRE) { if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, up, blockposition).isCancelled()) { continue; } @@ -93,69 +97,62 @@ public abstract class FluidTypeLava extends FluidTypeFlowing { return blockposition.getY() >= 0 && blockposition.getY() < 256 && !iworldreader.isLoaded(blockposition) ? false : iworldreader.getType(blockposition).getMaterial().isBurnable(); } + @Override protected void a(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata) { this.a(generatoraccess, blockposition); } + @Override public int b(IWorldReader iworldreader) { - return iworldreader.o().isNether() ? 4 : 2; + return iworldreader.getWorldProvider().isNether() ? 4 : 2; } + @Override public IBlockData b(Fluid fluid) { return (IBlockData) Blocks.LAVA.getBlockData().set(BlockFluids.LEVEL, e(fluid)); } + @Override public boolean a(FluidType fluidtype) { return fluidtype == FluidTypes.LAVA || fluidtype == FluidTypes.FLOWING_LAVA; } + @Override public int c(IWorldReader iworldreader) { - return iworldreader.o().isNether() ? 1 : 2; + return iworldreader.getWorldProvider().isNether() ? 1 : 2; } - public boolean a(Fluid fluid, FluidType fluidtype, EnumDirection enumdirection) { - return fluid.getHeight() >= 0.44444445F && fluidtype.a(TagsFluid.WATER); + @Override + public boolean a(Fluid fluid, IBlockAccess iblockaccess, BlockPosition blockposition, FluidType fluidtype, EnumDirection enumdirection) { + return fluid.getHeight(iblockaccess, blockposition) >= 0.44444445F && fluidtype.a(TagsFluid.WATER); } + @Override public int a(IWorldReader iworldreader) { - return iworldreader.o().h() ? 10 : 30; + return iworldreader.getWorldProvider().h() ? 10 : 30; } - public int a(World world, Fluid fluid, Fluid fluid1) { + @Override + public int a(World world, BlockPosition blockposition, Fluid fluid, Fluid fluid1) { int i = this.a((IWorldReader) world); - if (!fluid.e() && !fluid1.e() && !(Boolean) fluid.get(FluidTypeLava.FALLING) && !(Boolean) fluid1.get(FluidTypeLava.FALLING) && fluid1.getHeight() > fluid.getHeight() && world.m().nextInt(4) != 0) { + if (!fluid.isEmpty() && !fluid1.isEmpty() && !(Boolean) fluid.get(FluidTypeLava.FALLING) && !(Boolean) fluid1.get(FluidTypeLava.FALLING) && fluid1.getHeight(world, blockposition) > fluid.getHeight(world, blockposition) && world.getRandom().nextInt(4) != 0) { i *= 4; } return i; } - protected void a(GeneratorAccess generatoraccess, BlockPosition blockposition) { - // Akarin start - /* - double d0 = (double) blockposition.getX(); - double d1 = (double) blockposition.getY(); - double d2 = (double) blockposition.getZ(); - */ - // Akarin end - - generatoraccess.a((EntityHuman) null, blockposition, SoundEffects.BLOCK_LAVA_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, 2.6F + (generatoraccess.m().nextFloat() - generatoraccess.m().nextFloat()) * 0.8F); - - // Akarin start - this handle by client - /* - for (int i = 0; i < 8; ++i) { - generatoraccess.addParticle(Particles.F, d0 + Math.random(), d1 + 1.2D, d2 + Math.random(), 0.0D, 0.0D, 0.0D); - } - */ - // Akarin end - + private void a(GeneratorAccess generatoraccess, BlockPosition blockposition) { + generatoraccess.triggerEffect(1501, blockposition, 0); } + @Override protected boolean g() { return false; } + @Override protected void a(GeneratorAccess generatoraccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection, Fluid fluid) { if (enumdirection == EnumDirection.DOWN) { Fluid fluid1 = generatoraccess.getFluid(blockposition); @@ -177,10 +174,12 @@ public abstract class FluidTypeLava extends FluidTypeFlowing { super.a(generatoraccess, blockposition, iblockdata, enumdirection, fluid); } + @Override protected boolean k() { return true; } + @Override protected float d() { return 100.0F; } @@ -189,15 +188,18 @@ public abstract class FluidTypeLava extends FluidTypeFlowing { public a() {} + @Override protected void a(BlockStateList.a blockstatelist_a) { super.a(blockstatelist_a); blockstatelist_a.a(FluidTypeLava.a.LEVEL); } + @Override public int d(Fluid fluid) { return (Integer) fluid.get(FluidTypeLava.a.LEVEL); } + @Override public boolean c(Fluid fluid) { return false; } @@ -207,10 +209,12 @@ public abstract class FluidTypeLava extends FluidTypeFlowing { public b() {} + @Override public int d(Fluid fluid) { return 8; } + @Override public boolean c(Fluid fluid) { return true; } diff --git a/src/main/java/net/minecraft/server/FoodMetaData.java b/src/main/java/net/minecraft/server/FoodMetaData.java index aed3606bd..ea4041190 100644 --- a/src/main/java/net/minecraft/server/FoodMetaData.java +++ b/src/main/java/net/minecraft/server/FoodMetaData.java @@ -23,18 +23,22 @@ public class FoodMetaData { this.saturationLevel = Math.min(this.saturationLevel + (float) i * f * 2.0F, (float) this.foodLevel); } - public void a(ItemFood itemfood, ItemStack itemstack) { - // CraftBukkit start - int oldFoodLevel = foodLevel; + public void a(Item item, ItemStack itemstack) { + if (item.isFood()) { + FoodInfo foodinfo = item.getFoodInfo(); + // CraftBukkit start + int oldFoodLevel = foodLevel; - org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityhuman, itemfood.getNutrition(itemstack) + oldFoodLevel); + org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityhuman, foodinfo.getNutrition() + oldFoodLevel, itemstack); - if (!event.isCancelled()) { - this.eat(event.getFoodLevel() - oldFoodLevel, itemfood.getSaturationModifier(itemstack)); + if (!event.isCancelled()) { + this.eat(event.getFoodLevel() - oldFoodLevel, foodinfo.getSaturationModifier()); + } + + ((EntityPlayer) entityhuman).getBukkitEntity().sendHealthUpdate(); + // CraftBukkit end } - ((EntityPlayer) entityhuman).getBukkitEntity().sendHealthUpdate(); - // CraftBukkit end } public void a(EntityHuman entityhuman) { @@ -58,9 +62,9 @@ public class FoodMetaData { } } - boolean flag = entityhuman.world.getGameRules().getBoolean("naturalRegeneration"); + boolean flag = entityhuman.world.getGameRules().getBoolean(GameRules.NATURAL_REGENERATION); - if (flag && this.saturationLevel > 0.0F && entityhuman.dx() && this.foodLevel >= 20) { + if (flag && this.saturationLevel > 0.0F && entityhuman.dP() && this.foodLevel >= 20) { ++this.foodTickTimer; if (this.foodTickTimer >= 10) { float f = Math.min(this.saturationLevel, 6.0F); @@ -69,7 +73,7 @@ public class FoodMetaData { this.a(f); this.foodTickTimer = 0; } - } else if (flag && this.foodLevel >= 18 && entityhuman.dx()) { + } else if (flag && this.foodLevel >= 18 && entityhuman.dP()) { ++this.foodTickTimer; if (this.foodTickTimer >= 80) { entityhuman.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.SATIATED); // CraftBukkit - added RegainReason diff --git a/src/main/java/net/minecraft/server/FurnaceRecipe.java b/src/main/java/net/minecraft/server/FurnaceRecipe.java index ed18b60b6..0b15f2530 100644 --- a/src/main/java/net/minecraft/server/FurnaceRecipe.java +++ b/src/main/java/net/minecraft/server/FurnaceRecipe.java @@ -1,7 +1,5 @@ package net.minecraft.server; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; // CraftBukkit start import java.util.ArrayList; import java.util.List; @@ -13,57 +11,15 @@ import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.inventory.Recipe; // CraftBukkit end -public class FurnaceRecipe implements IRecipe { - - private final MinecraftKey key; - private final String group; - private final RecipeItemStack ingredient; - private final ItemStack result; - private final float experience; - private final int cookingTime; +public class FurnaceRecipe extends RecipeCooking { public FurnaceRecipe(MinecraftKey minecraftkey, String s, RecipeItemStack recipeitemstack, ItemStack itemstack, float f, int i) { - this.key = minecraftkey; - this.group = s; - this.ingredient = recipeitemstack; - this.result = itemstack; - this.experience = f; - this.cookingTime = i; + super(Recipes.SMELTING, minecraftkey, s, recipeitemstack, itemstack, f, i); } - public boolean a(IInventory iinventory, World world) { - return iinventory instanceof TileEntityFurnace && this.ingredient.test(iinventory.getItem(0)); - } - - public ItemStack craftItem(IInventory iinventory) { - return this.result.cloneItemStack(); - } - - public RecipeSerializer a() { - return RecipeSerializers.p; - } - - public NonNullList e() { - NonNullList nonnulllist = NonNullList.a(); - - nonnulllist.add(this.ingredient); - return nonnulllist; - } - - public float g() { - return this.experience; - } - - public ItemStack d() { - return this.result; - } - - public int h() { - return this.cookingTime; - } - - public MinecraftKey getKey() { - return this.key; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.p; } @Override @@ -75,55 +31,4 @@ public class FurnaceRecipe implements IRecipe { return recipe; } - - public static class a implements RecipeSerializer { - - public a() {} - - public FurnaceRecipe a(MinecraftKey minecraftkey, JsonObject jsonobject) { - String s = ChatDeserializer.a(jsonobject, "group", ""); - RecipeItemStack recipeitemstack; - - if (ChatDeserializer.d(jsonobject, "ingredient")) { - recipeitemstack = RecipeItemStack.a((JsonElement) ChatDeserializer.u(jsonobject, "ingredient")); - } else { - recipeitemstack = RecipeItemStack.a((JsonElement) ChatDeserializer.t(jsonobject, "ingredient")); - } - - String s1 = ChatDeserializer.h(jsonobject, "result"); - Item item = (Item) IRegistry.ITEM.get(new MinecraftKey(s1)); - - if (item != null) { - ItemStack itemstack = new ItemStack(item); - float f = ChatDeserializer.a(jsonobject, "experience", 0.0F); - int i = ChatDeserializer.a(jsonobject, "cookingtime", 200); - - return new FurnaceRecipe(minecraftkey, s, recipeitemstack, itemstack, f, i); - } else { - throw new IllegalStateException(s1 + " did not exist"); - } - } - - public FurnaceRecipe a(MinecraftKey minecraftkey, PacketDataSerializer packetdataserializer) { - String s = packetdataserializer.e(32767); - RecipeItemStack recipeitemstack = RecipeItemStack.b(packetdataserializer); - ItemStack itemstack = packetdataserializer.k(); - float f = packetdataserializer.readFloat(); - int i = packetdataserializer.g(); - - return new FurnaceRecipe(minecraftkey, s, recipeitemstack, itemstack, f, i); - } - - public void a(PacketDataSerializer packetdataserializer, FurnaceRecipe furnacerecipe) { - packetdataserializer.a(furnacerecipe.group); - furnacerecipe.ingredient.a(packetdataserializer); - packetdataserializer.a(furnacerecipe.result); - packetdataserializer.writeFloat(furnacerecipe.experience); - packetdataserializer.d(furnacerecipe.cookingTime); - } - - public String a() { - return "smelting"; - } - } } diff --git a/src/main/java/net/minecraft/server/GameProfileBanEntry.java b/src/main/java/net/minecraft/server/GameProfileBanEntry.java index cb47697a0..120c71766 100644 --- a/src/main/java/net/minecraft/server/GameProfileBanEntry.java +++ b/src/main/java/net/minecraft/server/GameProfileBanEntry.java @@ -14,13 +14,14 @@ public class GameProfileBanEntry extends ExpirableListEntry { } public GameProfileBanEntry(GameProfile gameprofile, @Nullable Date date, @Nullable String s, @Nullable Date date1, @Nullable String s1) { - super(gameprofile, date, s, date1, s1); // Spigot + super(gameprofile, date, s, date1, s1); } public GameProfileBanEntry(JsonObject jsonobject) { super(b(jsonobject), jsonobject); } + @Override protected void a(JsonObject jsonobject) { if (this.getKey() != null) { jsonobject.addProperty("uuid", ((GameProfile) this.getKey()).getId() == null ? "" : ((GameProfile) this.getKey()).getId().toString()); @@ -29,6 +30,7 @@ public class GameProfileBanEntry extends ExpirableListEntry { } } + @Override public IChatBaseComponent e() { GameProfile gameprofile = (GameProfile) this.getKey(); diff --git a/src/main/java/net/minecraft/server/GameProfileBanList.java b/src/main/java/net/minecraft/server/GameProfileBanList.java deleted file mode 100644 index e1e87138e..000000000 --- a/src/main/java/net/minecraft/server/GameProfileBanList.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.minecraft.server; - -import com.google.gson.JsonObject; -import com.mojang.authlib.GameProfile; -import java.io.File; -import java.util.Iterator; - -public class GameProfileBanList extends JsonList { - - public GameProfileBanList(File file) { - super(file); - } - - protected JsonListEntry a(JsonObject jsonobject) { - return new GameProfileBanEntry(jsonobject); - } - - public boolean isBanned(GameProfile gameprofile) { - return this.d(gameprofile); - } - - public String[] getEntries() { - String[] astring = new String[this.e().size()]; - int i = 0; - - JsonListEntry jsonlistentry; - - for (Iterator iterator = this.e().iterator(); iterator.hasNext(); astring[i++] = ((GameProfile) jsonlistentry.getKey()).getName()) { - jsonlistentry = (JsonListEntry) iterator.next(); - } - - return astring; - } - - protected String a(GameProfile gameprofile) { - return AkarinUserCache.isOnlineMode() ? gameprofile.getId().toString() : gameprofile.getName(); // Akarin - } -} diff --git a/src/main/java/net/minecraft/server/GameRules.java b/src/main/java/net/minecraft/server/GameRules.java index 3379752f9..45d5675ad 100644 --- a/src/main/java/net/minecraft/server/GameRules.java +++ b/src/main/java/net/minecraft/server/GameRules.java @@ -1,245 +1,320 @@ package net.minecraft.server; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; -import com.koloboke.collect.map.hash.HashObjObjMap; -import com.koloboke.collect.map.hash.HashObjObjMaps; import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.BoolArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType; -import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.context.CommandContext; - -import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; -import java.util.Set; -import java.util.TreeMap; +import java.util.Map; import java.util.Map.Entry; import java.util.function.BiConsumer; -import java.util.function.BiFunction; +import java.util.function.Function; import java.util.function.Supplier; import javax.annotation.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class GameRules { - // Paper start - Optimize GameRules - private static final int RULES_SIZE = 256; - - private static java.util.LinkedHashMap linkedMapOf(final int capacity, final TreeMap map) { - final java.util.LinkedHashMap ret = new java.util.LinkedHashMap<>(capacity); - ret.putAll(map); - return ret; - } - - private static final java.util.LinkedHashMap a = GameRules.linkedMapOf(RULES_SIZE, SystemUtils.a(new TreeMap(), (treemap) -> { // Paper - decompile fix - // Paper end - treemap.put("doFireTick", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("mobGriefing", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("keepInventory", new GameRules.GameRuleDefinition("false", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("doMobSpawning", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("doMobLoot", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("doTileDrops", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("doEntityDrops", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("commandBlockOutput", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("naturalRegeneration", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("doDaylightCycle", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("logAdminCommands", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("showDeathMessages", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("randomTickSpeed", new GameRules.GameRuleDefinition("3", GameRules.EnumGameRuleType.NUMERICAL_VALUE)); - treemap.put("sendCommandFeedback", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("reducedDebugInfo", new GameRules.GameRuleDefinition("false", GameRules.EnumGameRuleType.BOOLEAN_VALUE, (minecraftserver, gamerules_gamerulevalue) -> { - int i = gamerules_gamerulevalue.b() ? 22 : 23; - Iterator iterator = minecraftserver.getPlayerList().v().iterator(); - - while (iterator.hasNext()) { - EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - - entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) i)); - } - - })); - treemap.put("spectatorsGenerateChunks", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("spawnRadius", new GameRules.GameRuleDefinition("10", GameRules.EnumGameRuleType.NUMERICAL_VALUE)); - treemap.put("disableElytraMovementCheck", new GameRules.GameRuleDefinition("false", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("maxEntityCramming", new GameRules.GameRuleDefinition("24", GameRules.EnumGameRuleType.NUMERICAL_VALUE)); - treemap.put("doWeatherCycle", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("doLimitedCrafting", new GameRules.GameRuleDefinition("false", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - treemap.put("maxCommandChainLength", new GameRules.GameRuleDefinition("65536", GameRules.EnumGameRuleType.NUMERICAL_VALUE)); - treemap.put("announceAdvancements", new GameRules.GameRuleDefinition("true", GameRules.EnumGameRuleType.BOOLEAN_VALUE)); - })); // Paper - Optimize GameRules - private final java.util.LinkedHashMap b = new java.util.LinkedHashMap<>(RULES_SIZE); // Paper - Optimize GameRules - - public GameRules() { - Iterator iterator = GameRules.a.entrySet().iterator(); + private static final Logger LOGGER = LogManager.getLogger(); + private static final Map, GameRules.GameRuleDefinition> z = Maps.newTreeMap(Comparator.comparing((gamerules_gamerulekey) -> { + return gamerules_gamerulekey.a; + })); + public static final GameRules.GameRuleKey DO_FIRE_TICK = a("doFireTick", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey MOB_GRIEFING = a("mobGriefing", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey KEEP_INVENTORY = a("keepInventory", GameRules.GameRuleBoolean.b(false)); + public static final GameRules.GameRuleKey DO_MOB_SPAWNING = a("doMobSpawning", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey DO_MOB_LOOT = a("doMobLoot", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey DO_TILE_DROPS = a("doTileDrops", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey DO_ENTITY_DROPS = a("doEntityDrops", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey COMMAND_BLOCK_OUTPUT = a("commandBlockOutput", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey NATURAL_REGENERATION = a("naturalRegeneration", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey DO_DAYLIGHT_CYCLE = a("doDaylightCycle", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey LOG_ADMIN_COMMANDS = a("logAdminCommands", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey SHOW_DEATH_MESSAGES = a("showDeathMessages", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey RANDOM_TICK_SPEED = a("randomTickSpeed", GameRules.GameRuleInt.b(3)); + public static final GameRules.GameRuleKey SEND_COMMAND_FEEDBACK = a("sendCommandFeedback", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey REDUCED_DEBUG_INFO = a("reducedDebugInfo", GameRules.GameRuleBoolean.b(false, (minecraftserver, gamerules_gameruleboolean) -> { + int i = gamerules_gameruleboolean.a() ? 22 : 23; + Iterator iterator = minecraftserver.getPlayerList().getPlayers().iterator(); while (iterator.hasNext()) { - Entry entry = (Entry) iterator.next(); + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - this.b.put(entry.getKey(), ((GameRules.GameRuleDefinition) entry.getValue()).a()); + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) i)); } - } + })); + public static final GameRules.GameRuleKey SPECTATORS_GENERATE_CHUNKS = a("spectatorsGenerateChunks", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey SPAWN_RADIUS = a("spawnRadius", GameRules.GameRuleInt.b(10)); + public static final GameRules.GameRuleKey DISABLE_ELYTRA_MOVEMENT_CHECK = a("disableElytraMovementCheck", GameRules.GameRuleBoolean.b(false)); + public static final GameRules.GameRuleKey MAX_ENTITY_CRAMMING = a("maxEntityCramming", GameRules.GameRuleInt.b(24)); + public static final GameRules.GameRuleKey DO_WEATHER_CYCLE = a("doWeatherCycle", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey DO_LIMITED_CRAFTING = a("doLimitedCrafting", GameRules.GameRuleBoolean.b(false)); + public static final GameRules.GameRuleKey MAX_COMMAND_CHAIN_LENGTH = a("maxCommandChainLength", GameRules.GameRuleInt.b(65536)); + public static final GameRules.GameRuleKey ANNOUNCE_ADVANCEMENTS = a("announceAdvancements", GameRules.GameRuleBoolean.b(true)); + public static final GameRules.GameRuleKey x = a("disableRaids", GameRules.GameRuleBoolean.b(false)); + private final Map, GameRules.GameRuleValue> A; - public void set(String s, String s1, @Nullable MinecraftServer minecraftserver) { - GameRules.GameRuleValue gamerules_gamerulevalue = (GameRules.GameRuleValue) this.b.get(s); + private static > GameRules.GameRuleKey a(String s, GameRules.GameRuleDefinition gamerules_gameruledefinition) { + GameRules.GameRuleKey gamerules_gamerulekey = new GameRules.GameRuleKey<>(s); + GameRules.GameRuleDefinition gamerules_gameruledefinition1 = (GameRules.GameRuleDefinition) GameRules.z.put(gamerules_gamerulekey, gamerules_gameruledefinition); - if (gamerules_gamerulevalue != null) { - gamerules_gamerulevalue.a(s1, minecraftserver); + if (gamerules_gameruledefinition1 != null) { + throw new IllegalStateException("Duplicate game rule registration for " + s); + } else { + return gamerules_gamerulekey; } - } - public boolean getBoolean(String s) { - GameRules.GameRuleValue gamerules_gamerulevalue = (GameRules.GameRuleValue) this.b.get(s); - - return gamerules_gamerulevalue != null ? gamerules_gamerulevalue.b() : false; + public GameRules() { + this.A = (Map) GameRules.z.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> { + return ((GameRules.GameRuleDefinition) entry.getValue()).getValue(); + })); } - public int c(String s) { - GameRules.GameRuleValue gamerules_gamerulevalue = (GameRules.GameRuleValue) this.b.get(s); - - return gamerules_gamerulevalue != null ? gamerules_gamerulevalue.c() : 0; + public > T get(GameRules.GameRuleKey gamerules_gamerulekey) { + return (T) this.A.get(gamerules_gamerulekey); // CraftBukkit - decompile error } public NBTTagCompound a() { NBTTagCompound nbttagcompound = new NBTTagCompound(); - Iterator iterator = this.b.keySet().iterator(); - - while (iterator.hasNext()) { - String s = (String) iterator.next(); - GameRules.GameRuleValue gamerules_gamerulevalue = (GameRules.GameRuleValue) this.b.get(s); - - nbttagcompound.setString(s, gamerules_gamerulevalue.a()); - } + this.A.forEach((gamerules_gamerulekey, gamerules_gamerulevalue) -> { + nbttagcompound.setString(gamerules_gamerulekey.a, gamerules_gamerulevalue.getValue()); + }); return nbttagcompound; } public void a(NBTTagCompound nbttagcompound) { - Set set = nbttagcompound.getKeys(); - Iterator iterator = set.iterator(); + this.A.forEach((gamerules_gamerulekey, gamerules_gamerulevalue) -> { + gamerules_gamerulevalue.setValue(nbttagcompound.getString(gamerules_gamerulekey.a)); + }); + } - while (iterator.hasNext()) { - String s = (String) iterator.next(); + public static void a(GameRules.GameRuleVisitor gamerules_gamerulevisitor) { + GameRules.z.forEach((gamerules_gamerulekey, gamerules_gameruledefinition) -> { + a(gamerules_gamerulevisitor, gamerules_gamerulekey, gamerules_gameruledefinition); + }); + } - this.set(s, nbttagcompound.getString(s), (MinecraftServer) null); + private static > void a(GameRules.GameRuleVisitor gamerules_gamerulevisitor, GameRules.GameRuleKey gamerules_gamerulekey, GameRules.GameRuleDefinition gamerules_gameruledefinition) { + gamerules_gamerulevisitor.a((GameRules.GameRuleKey) gamerules_gamerulekey, (GameRules.GameRuleDefinition) gamerules_gameruledefinition); // CraftBukkit - decompile error + } + + public boolean getBoolean(GameRules.GameRuleKey gamerules_gamerulekey) { + return ((GameRules.GameRuleBoolean) this.get(gamerules_gamerulekey)).a(); + } + + public int getInt(GameRules.GameRuleKey gamerules_gamerulekey) { + return ((GameRules.GameRuleInt) this.get(gamerules_gamerulekey)).a(); + } + + public static class GameRuleBoolean extends GameRules.GameRuleValue { + + private boolean a; + + private static GameRules.GameRuleDefinition b(boolean flag, BiConsumer biconsumer) { + return new GameRules.GameRuleDefinition<>(BoolArgumentType::bool, (gamerules_gameruledefinition) -> { + return new GameRules.GameRuleBoolean(gamerules_gameruledefinition, flag); + }, biconsumer); } + private static GameRules.GameRuleDefinition b(boolean flag) { + return b(flag, (minecraftserver, gamerules_gameruleboolean) -> { + }); + } + + public GameRuleBoolean(GameRules.GameRuleDefinition gamerules_gameruledefinition, boolean flag) { + super(gamerules_gameruledefinition); + this.a = flag; + } + + @Override + protected void a(CommandContext commandcontext, String s) { + this.a = BoolArgumentType.getBool(commandcontext, s); + } + + public boolean a() { + return this.a; + } + + public void a(boolean flag, @Nullable MinecraftServer minecraftserver) { + this.a = flag; + this.onChange(minecraftserver); + } + + @Override + protected String getValue() { + return Boolean.toString(this.a); + } + + @Override + public void setValue(String s) { // PAIL - private->public + this.a = Boolean.parseBoolean(s); + } + + @Override + public int getIntValue() { + return this.a ? 1 : 0; + } + + @Override + protected GameRules.GameRuleBoolean e() { + return this; + } } - public GameRules.GameRuleValue get(String s) { - return (GameRules.GameRuleValue) this.b.get(s); + public static class GameRuleInt extends GameRules.GameRuleValue { + + private int a; + + private static GameRules.GameRuleDefinition a(int i, BiConsumer biconsumer) { + return new GameRules.GameRuleDefinition<>(IntegerArgumentType::integer, (gamerules_gameruledefinition) -> { + return new GameRules.GameRuleInt(gamerules_gameruledefinition, i); + }, biconsumer); + } + + private static GameRules.GameRuleDefinition b(int i) { + return a(i, (minecraftserver, gamerules_gameruleint) -> { + }); + } + + public GameRuleInt(GameRules.GameRuleDefinition gamerules_gameruledefinition, int i) { + super(gamerules_gameruledefinition); + this.a = i; + } + + @Override + protected void a(CommandContext commandcontext, String s) { + this.a = IntegerArgumentType.getInteger(commandcontext, s); + } + + public int a() { + return this.a; + } + + @Override + protected String getValue() { + return Integer.toString(this.a); + } + + @Override + public void setValue(String s) { // PAIL - private->public + this.a = b(s); + } + + private static int b(String s) { + if (!s.isEmpty()) { + try { + return Integer.parseInt(s); + } catch (NumberFormatException numberformatexception) { + GameRules.LOGGER.warn("Failed to parse integer {}", s); + } + } + + return 0; + } + + @Override + public int getIntValue() { + return this.a; + } + + @Override + protected GameRules.GameRuleInt e() { + return this; + } } - public static java.util.LinkedHashMap getGameRules() { // Paper - Optimize GameRules - return GameRules.a; + public abstract static class GameRuleValue> { + + private final GameRules.GameRuleDefinition a; + + public GameRuleValue(GameRules.GameRuleDefinition gamerules_gameruledefinition) { + this.a = gamerules_gameruledefinition; + } + + protected abstract void a(CommandContext commandcontext, String s); + + public void b(CommandContext commandcontext, String s) { + this.a(commandcontext, s); + this.onChange(((CommandListenerWrapper) commandcontext.getSource()).getServer()); + } + + public void onChange(@Nullable MinecraftServer minecraftserver) { + if (minecraftserver != null) { + this.a.c.accept(minecraftserver, this.e()); + } + + } + + public abstract void setValue(String s); // PAIL - private->public + + protected abstract String getValue(); + + public String toString() { + return this.getValue(); + } + + public abstract int getIntValue(); + + protected abstract T e(); } - public static enum EnumGameRuleType { + public static class GameRuleDefinition> { - ANY_VALUE(StringArgumentType::greedyString, (commandcontext, s) -> { - return (String) commandcontext.getArgument(s, String.class); - }), BOOLEAN_VALUE(BoolArgumentType::bool, (commandcontext, s) -> { - return ((Boolean) commandcontext.getArgument(s, Boolean.class)).toString(); - }), NUMERICAL_VALUE(IntegerArgumentType::integer, (commandcontext, s) -> { - return ((Integer) commandcontext.getArgument(s, Integer.class)).toString(); - }); + private final Supplier> a; + private final Function, T> b; + private final BiConsumer c; - private final Supplier> d; - private final BiFunction, String, String> e; - - private EnumGameRuleType(Supplier supplier, BiFunction, String, String> bifunction) { // Paper - decompile fix - this.d = supplier; - this.e = bifunction; + private GameRuleDefinition(Supplier> supplier, Function, T> function, BiConsumer biconsumer) { + this.a = supplier; + this.b = function; + this.c = biconsumer; } public RequiredArgumentBuilder a(String s) { - return CommandDispatcher.a(s, (ArgumentType) this.d.get()); + return CommandDispatcher.a(s, (ArgumentType) this.a.get()); } - public void a(CommandContext commandcontext, String s, GameRules.GameRuleValue gamerules_gamerulevalue) { - gamerules_gamerulevalue.a((String) this.e.apply(commandcontext, s), ((CommandListenerWrapper) commandcontext.getSource()).getServer()); + public T getValue() { + return this.b.apply(this); // CraftBukkit - decompile error } } - public static class GameRuleValue { + public static final class GameRuleKey> { - private String a; - private boolean b; - private int c; - private double d; - private final GameRules.EnumGameRuleType e; - private final BiConsumer f; + private final String a; - public GameRuleValue(String s, GameRules.EnumGameRuleType gamerules_enumgameruletype, BiConsumer biconsumer) { - this.e = gamerules_enumgameruletype; - this.f = biconsumer; - this.a(s, (MinecraftServer) null); + public GameRuleKey(String s) { + this.a = s; } - public void a(String s, @Nullable MinecraftServer minecraftserver) { - this.a = s; - this.b = Boolean.parseBoolean(s); - this.c = this.b ? 1 : 0; + public String toString() { + return this.a; + } - try { - this.c = Integer.parseInt(s); - } catch (NumberFormatException numberformatexception) { - ; - } - - try { - this.d = Double.parseDouble(s); - } catch (NumberFormatException numberformatexception1) { - ; - } - - if (minecraftserver != null) { - this.f.accept(minecraftserver, this); - } + public boolean equals(Object object) { + return this == object ? true : object instanceof GameRules.GameRuleKey && ((GameRules.GameRuleKey) object).a.equals(this.a); + } + public int hashCode() { + return this.a.hashCode(); } public String a() { return this.a; } - - public boolean b() { - return this.b; - } - - public int c() { - return this.c; - } - - public GameRules.EnumGameRuleType getType() { - return this.e; - } } - public static class GameRuleDefinition { + @FunctionalInterface + public interface GameRuleVisitor { - private final GameRules.EnumGameRuleType a; - private final String b; - private final BiConsumer c; - - public GameRuleDefinition(String s, GameRules.EnumGameRuleType gamerules_enumgameruletype) { - this(s, gamerules_enumgameruletype, (minecraftserver, gamerules_gamerulevalue) -> { - }); - } - - public GameRuleDefinition(String s, GameRules.EnumGameRuleType gamerules_enumgameruletype, BiConsumer biconsumer) { - this.a = gamerules_enumgameruletype; - this.b = s; - this.c = biconsumer; - } - - public GameRules.GameRuleValue a() { - return new GameRules.GameRuleValue(this.b, this.a, this.c); - } - - public GameRules.EnumGameRuleType b() { - return this.a; - } + > void a(GameRules.GameRuleKey gamerules_gamerulekey, GameRules.GameRuleDefinition gamerules_gameruledefinition); } } diff --git a/src/main/java/net/minecraft/server/GenericAttributes.java b/src/main/java/net/minecraft/server/GenericAttributes.java index 90367a53e..469e293c2 100644 --- a/src/main/java/net/minecraft/server/GenericAttributes.java +++ b/src/main/java/net/minecraft/server/GenericAttributes.java @@ -9,18 +9,19 @@ import org.apache.logging.log4j.Logger; public class GenericAttributes { - private static final Logger k = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); // Spigot start - public static final IAttribute maxHealth = (new AttributeRanged((IAttribute) null, "generic.maxHealth", 20.0D, 0.0D, org.spigotmc.SpigotConfig.maxHealth)).a("Max Health").a(true); + public static final IAttribute MAX_HEALTH = (new AttributeRanged((IAttribute) null, "generic.maxHealth", 20.0D, 0.0D, org.spigotmc.SpigotConfig.maxHealth)).a("Max Health").a(true); public static final IAttribute FOLLOW_RANGE = (new AttributeRanged((IAttribute) null, "generic.followRange", 32.0D, 0.0D, 2048.0D)).a("Follow Range"); - public static final IAttribute c = (new AttributeRanged((IAttribute) null, "generic.knockbackResistance", 0.0D, 0.0D, 1.0D)).a("Knockback Resistance"); + public static final IAttribute KNOCKBACK_RESISTANCE = (new AttributeRanged((IAttribute) null, "generic.knockbackResistance", 0.0D, 0.0D, 1.0D)).a("Knockback Resistance"); public static final IAttribute MOVEMENT_SPEED = (new AttributeRanged((IAttribute) null, "generic.movementSpeed", 0.699999988079071D, 0.0D, org.spigotmc.SpigotConfig.movementSpeed)).a("Movement Speed").a(true); - public static final IAttribute e = (new AttributeRanged((IAttribute) null, "generic.flyingSpeed", 0.4000000059604645D, 0.0D, 1024.0D)).a("Flying Speed").a(true); + public static final IAttribute FLYING_SPEED = (new AttributeRanged((IAttribute) null, "generic.flyingSpeed", 0.4000000059604645D, 0.0D, 1024.0D)).a("Flying Speed").a(true); public static final IAttribute ATTACK_DAMAGE = new AttributeRanged((IAttribute) null, "generic.attackDamage", 2.0D, 0.0D, org.spigotmc.SpigotConfig.attackDamage); - public static final IAttribute g = (new AttributeRanged((IAttribute) null, "generic.attackSpeed", 4.0D, 0.0D, 1024.0D)).a(true); - public static final IAttribute h = (new AttributeRanged((IAttribute) null, "generic.armor", 0.0D, 0.0D, 30.0D)).a(true); - public static final IAttribute i = (new AttributeRanged((IAttribute) null, "generic.armorToughness", 0.0D, 0.0D, 20.0D)).a(true); - public static final IAttribute j = (new AttributeRanged((IAttribute) null, "generic.luck", 0.0D, -1024.0D, 1024.0D)).a(true); + public static final IAttribute ATTACK_KNOCKBACK = new AttributeRanged((IAttribute) null, "generic.attackKnockback", 0.0D, 0.0D, 5.0D); + public static final IAttribute ATTACK_SPEED = (new AttributeRanged((IAttribute) null, "generic.attackSpeed", 4.0D, 0.0D, 1024.0D)).a(true); + public static final IAttribute ARMOR = (new AttributeRanged((IAttribute) null, "generic.armor", 0.0D, 0.0D, 30.0D)).a(true); + public static final IAttribute ARMOR_TOUGHNESS = (new AttributeRanged((IAttribute) null, "generic.armorToughness", 0.0D, 0.0D, 20.0D)).a(true); + public static final IAttribute LUCK = (new AttributeRanged((IAttribute) null, "generic.luck", 0.0D, -1024.0D, 1024.0D)).a(true); // Spigot end public static NBTTagList a(AttributeMapBase attributemapbase) { @@ -30,7 +31,7 @@ public class GenericAttributes { while (iterator.hasNext()) { AttributeInstance attributeinstance = (AttributeInstance) iterator.next(); - nbttaglist.add((NBTBase) a(attributeinstance)); + nbttaglist.add(a(attributeinstance)); } return nbttaglist; @@ -41,8 +42,8 @@ public class GenericAttributes { IAttribute iattribute = attributeinstance.getAttribute(); nbttagcompound.setString("Name", iattribute.getName()); - nbttagcompound.setDouble("Base", attributeinstance.b()); - Collection collection = attributeinstance.c(); + nbttagcompound.setDouble("Base", attributeinstance.getBaseValue()); + Collection collection = attributeinstance.getModifiers(); if (collection != null && !collection.isEmpty()) { NBTTagList nbttaglist = new NBTTagList(); @@ -52,7 +53,7 @@ public class GenericAttributes { AttributeModifier attributemodifier = (AttributeModifier) iterator.next(); if (attributemodifier.e()) { - nbttaglist.add((NBTBase) a(attributemodifier)); + nbttaglist.add(a(attributemodifier)); } } @@ -65,10 +66,10 @@ public class GenericAttributes { public static NBTTagCompound a(AttributeModifier attributemodifier) { NBTTagCompound nbttagcompound = new NBTTagCompound(); - nbttagcompound.setString("Name", attributemodifier.b()); - nbttagcompound.setDouble("Amount", attributemodifier.d()); - nbttagcompound.setInt("Operation", attributemodifier.c()); - nbttagcompound.a("UUID", attributemodifier.a()); + nbttagcompound.setString("Name", attributemodifier.getName()); + nbttagcompound.setDouble("Amount", attributemodifier.getAmount()); + nbttagcompound.setInt("Operation", attributemodifier.getOperation().a()); + nbttagcompound.a("UUID", attributemodifier.getUniqueId()); return nbttagcompound; } @@ -78,7 +79,7 @@ public class GenericAttributes { AttributeInstance attributeinstance = attributemapbase.a(nbttagcompound.getString("Name")); if (attributeinstance == null) { - GenericAttributes.k.warn("Ignoring unknown attribute '{}'", nbttagcompound.getString("Name")); + GenericAttributes.LOGGER.warn("Ignoring unknown attribute '{}'", nbttagcompound.getString("Name")); } else { a(attributeinstance, nbttagcompound); } @@ -95,13 +96,13 @@ public class GenericAttributes { AttributeModifier attributemodifier = a(nbttaglist.getCompound(i)); if (attributemodifier != null) { - AttributeModifier attributemodifier1 = attributeinstance.a(attributemodifier.a()); + AttributeModifier attributemodifier1 = attributeinstance.a(attributemodifier.getUniqueId()); if (attributemodifier1 != null) { - attributeinstance.c(attributemodifier1); + attributeinstance.removeModifier(attributemodifier1); } - attributeinstance.b(attributemodifier); + attributeinstance.addModifier(attributemodifier); } } } @@ -113,9 +114,11 @@ public class GenericAttributes { UUID uuid = nbttagcompound.a("UUID"); try { - return new AttributeModifier(uuid, nbttagcompound.getString("Name"), nbttagcompound.getDouble("Amount"), nbttagcompound.getInt("Operation")); + AttributeModifier.Operation attributemodifier_operation = AttributeModifier.Operation.a(nbttagcompound.getInt("Operation")); + + return new AttributeModifier(uuid, nbttagcompound.getString("Name"), nbttagcompound.getDouble("Amount"), attributemodifier_operation); } catch (Exception exception) { - GenericAttributes.k.warn("Unable to create attribute: {}", exception.getMessage()); + GenericAttributes.LOGGER.warn("Unable to create attribute: {}", exception.getMessage()); return null; } } diff --git a/src/main/java/net/minecraft/server/HandshakeListener.java b/src/main/java/net/minecraft/server/HandshakeListener.java index 7ddfedb55..9a8e5e121 100644 --- a/src/main/java/net/minecraft/server/HandshakeListener.java +++ b/src/main/java/net/minecraft/server/HandshakeListener.java @@ -3,17 +3,13 @@ package net.minecraft.server; // CraftBukkit start import java.net.InetAddress; import java.util.HashMap; - -import com.koloboke.collect.map.hash.HashObjLongMap; -import com.koloboke.collect.map.hash.HashObjLongMaps; -import com.koloboke.function.ObjLongPredicate; // CraftBukkit end public class HandshakeListener implements PacketHandshakingInListener { private static final com.google.gson.Gson gson = new com.google.gson.Gson(); // Spigot // CraftBukkit start - add fields - private static final HashObjLongMap throttleTracker = HashObjLongMaps.newMutableMap(); + private static final HashMap throttleTracker = new HashMap(); private static int throttleCounter = 0; // CraftBukkit end @@ -26,51 +22,58 @@ public class HandshakeListener implements PacketHandshakingInListener { this.b = networkmanager; } + @Override public void a(PacketHandshakingInSetProtocol packethandshakinginsetprotocol) { switch (packethandshakinginsetprotocol.b()) { - case LOGIN: - this.b.setProtocol(EnumProtocol.LOGIN); - ChatMessage chatmessage; + case LOGIN: + this.b.setProtocol(EnumProtocol.LOGIN); + ChatMessage chatmessage; - // CraftBukkit start - Connection throttle - try { - long currentTime = System.currentTimeMillis(); - long connectionThrottle = MinecraftServer.getServer().server.getConnectionThrottle(); - InetAddress address = ((java.net.InetSocketAddress) this.b.getSocketAddress()).getAddress(); + // CraftBukkit start - Connection throttle + try { + long currentTime = System.currentTimeMillis(); + long connectionThrottle = MinecraftServer.getServer().server.getConnectionThrottle(); + InetAddress address = ((java.net.InetSocketAddress) this.b.getSocketAddress()).getAddress(); - synchronized (throttleTracker) { - if (throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - throttleTracker.get(address) < connectionThrottle) { - throttleTracker.put(address, currentTime); + synchronized (throttleTracker) { + if (throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - throttleTracker.get(address) < connectionThrottle) { + throttleTracker.put(address, currentTime); chatmessage = new ChatMessage(com.destroystokyo.paper.PaperConfig.connectionThrottleKickMessage); // Paper - Configurable connection throttle kick message - this.b.sendPacket(new PacketLoginOutDisconnect(chatmessage)); - this.b.close(chatmessage); - return; - } + this.b.sendPacket(new PacketLoginOutDisconnect(chatmessage)); + this.b.close(chatmessage); + return; + } - throttleTracker.put(address, currentTime); - throttleCounter++; - if (throttleCounter > 200) { - throttleCounter = 0; + throttleTracker.put(address, currentTime); + throttleCounter++; + if (throttleCounter > 200) { + throttleCounter = 0; - // Cleanup stale entries - throttleTracker.removeIf((InetAddress, value) -> value > connectionThrottle); // Akarin + // Cleanup stale entries + java.util.Iterator iter = throttleTracker.entrySet().iterator(); + while (iter.hasNext()) { + java.util.Map.Entry entry = (java.util.Map.Entry) iter.next(); + if (entry.getValue() > connectionThrottle) { + iter.remove(); + } + } + } } + } catch (Throwable t) { + org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); } - } catch (Throwable t) { - org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); - } - // CraftBukkit end + // CraftBukkit end - if (packethandshakinginsetprotocol.c() > 404) { - chatmessage = new ChatMessage( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), "1.13.2" ) ); // Spigot - this.b.sendPacket(new PacketLoginOutDisconnect(chatmessage)); - this.b.close(chatmessage); - } else if (packethandshakinginsetprotocol.c() < 404) { - chatmessage = new ChatMessage( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), "1.13.2" ) ); // Spigot - this.b.sendPacket(new PacketLoginOutDisconnect(chatmessage)); - this.b.close(chatmessage); - } else { - this.b.setPacketListener(new LoginListener(this.a, this.b)); + if (packethandshakinginsetprotocol.c() > SharedConstants.a().getProtocolVersion()) { + chatmessage = new ChatMessage( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.a().getName() ) ); // Spigot + this.b.sendPacket(new PacketLoginOutDisconnect(chatmessage)); + this.b.close(chatmessage); + } else if (packethandshakinginsetprotocol.c() < SharedConstants.a().getProtocolVersion()) { + chatmessage = new ChatMessage( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.a().getName() ) ); // Spigot + this.b.sendPacket(new PacketLoginOutDisconnect(chatmessage)); + this.b.close(chatmessage); + } else { + this.b.setPacketListener(new LoginListener(this.a, this.b)); // Paper start - handshake event boolean proxyLogicEnabled = org.spigotmc.SpigotConfig.bungee; boolean handledByEvent = false; @@ -86,45 +89,45 @@ public class HandshakeListener implements PacketHandshakingInListener { return; } - if (event.getServerHostname() != null) packethandshakinginsetprotocol.hostname = event.getServerHostname(); // Akarin - add null check - if (event.getSocketAddressHostname() != null) this.b.socketAddress = new java.net.InetSocketAddress(event.getSocketAddressHostname(), ((java.net.InetSocketAddress) this.b.getSocketAddress()).getPort()); // Akarin - add null check + packethandshakinginsetprotocol.hostname = event.getServerHostname(); + this.b.socketAddress = new java.net.InetSocketAddress(event.getSocketAddressHostname(), ((java.net.InetSocketAddress) this.b.getSocketAddress()).getPort()); this.b.spoofedUUID = event.getUniqueId(); this.b.spoofedProfile = gson.fromJson(event.getPropertiesJson(), com.mojang.authlib.properties.Property[].class); handledByEvent = true; // Hooray, we did it! } } // Don't try and handle default logic if it's been handled by the event. - if (!handledByEvent && org.spigotmc.SpigotConfig.bungee) { // Akarin - recheck for plugin hacking + if (!handledByEvent && proxyLogicEnabled) { // Paper end - // Spigot Start + // Spigot Start //if (org.spigotmc.SpigotConfig.bungee) { // Paper - comment out, we check above! - String[] split = packethandshakinginsetprotocol.hostname.split("\00"); - if ( split.length == 3 || split.length == 4 ) { - packethandshakinginsetprotocol.hostname = split[0]; - b.socketAddress = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) b.getSocketAddress()).getPort()); - b.spoofedUUID = com.mojang.util.UUIDTypeAdapter.fromString( split[2] ); - } else - { - chatmessage = new ChatMessage("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!"); - this.b.sendPacket(new PacketLoginOutDisconnect(chatmessage)); - this.b.close(chatmessage); - return; - } - if ( split.length == 4 ) - { - b.spoofedProfile = gson.fromJson(split[3], com.mojang.authlib.properties.Property[].class); + String[] split = packethandshakinginsetprotocol.hostname.split("\00"); + if ( split.length == 3 || split.length == 4 ) { + packethandshakinginsetprotocol.hostname = split[0]; + b.socketAddress = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) b.getSocketAddress()).getPort()); + b.spoofedUUID = com.mojang.util.UUIDTypeAdapter.fromString( split[2] ); + } else + { + chatmessage = new ChatMessage("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!"); + this.b.sendPacket(new PacketLoginOutDisconnect(chatmessage)); + this.b.close(chatmessage); + return; + } + if ( split.length == 4 ) + { + b.spoofedProfile = gson.fromJson(split[3], com.mojang.authlib.properties.Property[].class); + } } + // Spigot End + ((LoginListener) this.b.i()).hostname = packethandshakinginsetprotocol.hostname + ":" + packethandshakinginsetprotocol.port; // CraftBukkit - set hostname } - // Spigot End - ((LoginListener) this.b.i()).hostname = packethandshakinginsetprotocol.hostname + ":" + packethandshakinginsetprotocol.port; // CraftBukkit - set hostname - } - break; - case STATUS: - this.b.setProtocol(EnumProtocol.STATUS); - this.b.setPacketListener(new PacketStatusListener(this.a, this.b)); - break; - default: - throw new UnsupportedOperationException("Invalid intention " + packethandshakinginsetprotocol.b()); + break; + case STATUS: + this.b.setProtocol(EnumProtocol.STATUS); + this.b.setPacketListener(new PacketStatusListener(this.a, this.b)); + break; + default: + throw new UnsupportedOperationException("Invalid intention " + packethandshakinginsetprotocol.b()); } // Paper start - NetworkClient implementation @@ -133,5 +136,11 @@ public class HandshakeListener implements PacketHandshakingInListener { // Paper end } + @Override public void a(IChatBaseComponent ichatbasecomponent) {} + + @Override + public NetworkManager a() { + return this.b; + } } diff --git a/src/main/java/net/minecraft/server/HeightMap.java b/src/main/java/net/minecraft/server/HeightMap.java deleted file mode 100644 index 275a4b65a..000000000 --- a/src/main/java/net/minecraft/server/HeightMap.java +++ /dev/null @@ -1,159 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Maps; -import java.util.HashMap; -import java.util.Map; -import javax.annotation.Nullable; - -public class HeightMap { - - private final DataBits a = new DataBits(9, 256); - private final PredicateBlock b; - private final IChunkAccess c; - - public HeightMap(IChunkAccess ichunkaccess, HeightMap.Type heightmap_type) { - this.b = PredicateBlocks.a(PredicateBlocks.b(heightmap_type.a())); - this.c = ichunkaccess; - } - - public void a() { - int i = this.c.b() + 16; - BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); - Throwable throwable = null; - - try { - for (int j = 0; j < 16; ++j) { - for (int k = 0; k < 16; ++k) { - this.a(j, k, this.a(blockposition_pooledblockposition, j, k, this.b, i)); - } - } - } catch (Throwable throwable1) { - throwable = throwable1; - throw throwable1; - } finally { - if (blockposition_pooledblockposition != null) { - if (throwable != null) { - try { - blockposition_pooledblockposition.close(); - } catch (Throwable throwable2) { - throwable.addSuppressed(throwable2); - } - } else { - blockposition_pooledblockposition.close(); - } - } - - } - - } - - public boolean a(int i, int j, int k, @Nullable IBlockData iblockdata) { - int l = this.a(i, k); - - if (j <= l - 2) { - return false; - } else { - if (this.b.test(iblockdata, this.c, new BlockPosition(i, j, k))) { - if (j >= l) { - this.a(i, k, j + 1); - return true; - } - } else if (l - 1 == j) { - this.a(i, k, this.a((BlockPosition.MutableBlockPosition) null, i, k, this.b, j)); - return true; - } - - return false; - } - } - - private int a(@Nullable BlockPosition.MutableBlockPosition blockposition_mutableblockposition, int i, int j, PredicateBlock predicateblock, int k) { - if (blockposition_mutableblockposition == null) { - blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - } - - for (int l = k - 1; l >= 0; --l) { - blockposition_mutableblockposition.c(i, l, j); - IBlockData iblockdata = this.c.getType(blockposition_mutableblockposition); - - if (predicateblock.test(iblockdata, this.c, blockposition_mutableblockposition)) { - return l + 1; - } - } - - return 0; - } - - public int a(int i, int j) { - return this.a(b(i, j)); - } - - private synchronized int a(int i) { // Akarin - synchronized - return this.a.a(i); - } - - private synchronized void a(int i, int j, int k) { // Akarin - synchronized - this.a.a(b(i, j), k); - } - - public void a(long[] along) { - System.arraycopy(along, 0, this.a.a(), 0, along.length); - } - - public synchronized long[] b() { // Akarin - synchronized - return this.a.a(); - } - - private static int b(int i, int j) { - return i + j * 16; - } - - public static enum Type { - - WORLD_SURFACE_WG("WORLD_SURFACE_WG", HeightMap.Use.WORLDGEN, new PredicateBlock[] { PredicateBlockType.a(Blocks.AIR)}), OCEAN_FLOOR_WG("OCEAN_FLOOR_WG", HeightMap.Use.WORLDGEN, new PredicateBlock[] { PredicateBlockType.a(Blocks.AIR), PredicateBlockLiquid.a()}), LIGHT_BLOCKING("LIGHT_BLOCKING", HeightMap.Use.LIVE_WORLD, new PredicateBlock[] { PredicateBlockType.a(Blocks.AIR), PredicateBlockLightTransmission.a()}), MOTION_BLOCKING("MOTION_BLOCKING", HeightMap.Use.LIVE_WORLD, new PredicateBlock[] { PredicateBlockType.a(Blocks.AIR), PredicateBlockNotSolidOrLiquid.a()}), MOTION_BLOCKING_NO_LEAVES("MOTION_BLOCKING_NO_LEAVES", HeightMap.Use.LIVE_WORLD, new PredicateBlock[] { PredicateBlockType.a(Blocks.AIR), PredicateBlockTag.a(TagsBlock.LEAVES), PredicateBlockNotSolidOrLiquid.a()}), OCEAN_FLOOR("OCEAN_FLOOR", HeightMap.Use.LIVE_WORLD, new PredicateBlock[] { PredicateBlockType.a(Blocks.AIR), PredicateBlockSolid.a()}), WORLD_SURFACE("WORLD_SURFACE", HeightMap.Use.LIVE_WORLD, new PredicateBlock[] { PredicateBlockType.a(Blocks.AIR)}); - - private final PredicateBlock[] h; - private final String i; - private final HeightMap.Use j; - private static final Map k = (Map) SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // Akarin - fixes decompile error - HeightMap.Type[] aheightmap_type = values(); - int i = aheightmap_type.length; - - for (int j = 0; j < i; ++j) { - HeightMap.Type heightmap_type = aheightmap_type[j]; - - hashmap.put(heightmap_type.i, heightmap_type); - } - - }); - - private Type(String s, HeightMap.Use heightmap_use, PredicateBlock... apredicateblock) { - this.i = s; - this.h = apredicateblock; - this.j = heightmap_use; - } - - public PredicateBlock[] a() { - return this.h; - } - - public String b() { - return this.i; - } - - public HeightMap.Use c() { - return this.j; - } - - public static HeightMap.Type a(String s) { - return (HeightMap.Type) HeightMap.Type.k.get(s); - } - } - - public static enum Use { - - WORLDGEN, LIVE_WORLD; - - private Use() {} - } -} diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java index 640965d20..84024e6ba 100644 --- a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java +++ b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java @@ -1,15 +1,142 @@ package net.minecraft.server; -import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.collect.Queues; +import java.util.Queue; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.locks.LockSupport; +import java.util.function.BooleanSupplier; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; -public interface IAsyncTaskHandler { +public abstract class IAsyncTaskHandler implements Mailbox, Executor { - ListenableFuture postToMainThread(Runnable runnable); + private final String b; + private static final Logger LOGGER = LogManager.getLogger(); + private final Queue d = Queues.newConcurrentLinkedQueue(); + private int e; + + protected IAsyncTaskHandler(String s) { + this.b = s; + } + + protected abstract R postToMainThread(Runnable runnable); + + protected abstract boolean canExecute(R r0); + + public boolean isMainThread() { + return Thread.currentThread() == this.getThread(); + } + + protected abstract Thread getThread(); + + protected boolean isNotMainThread() { + return !this.isMainThread(); + } + + public int be() { + return this.d.size(); + } + + @Override + public String bf() { + return this.b; + } + + private CompletableFuture executeFuture(Runnable runnable) { + return CompletableFuture.supplyAsync(() -> { + runnable.run(); + return null; + }, this); + } + + public CompletableFuture e(Runnable runnable) { + if (this.isNotMainThread()) { + return this.executeFuture(runnable); + } else { + runnable.run(); + return CompletableFuture.completedFuture(null); // Paper - decompile fix + } + } + + public void executeSync(Runnable runnable) { + if (!this.isMainThread()) { + this.executeFuture(runnable).join(); + } else { + runnable.run(); + } + + } + + // Paper start + public void scheduleOnMain(Runnable r0) { + // postToMainThread does not work the same as older versions of mc + // This method is actually used to create a TickTask, which can then be posted onto main + this.addTask(this.postToMainThread(r0)); + } + // Paper end + + public void addTask(R r0) { a(r0); }; // Paper - OBFHELPER + public void a(R r0) { + this.d.add(r0); + LockSupport.unpark(this.getThread()); + } + + public void execute(Runnable runnable) { + if (this.isNotMainThread()) { + this.a(this.postToMainThread(runnable)); + } else { + runnable.run(); + } + + } + + public void executeAll() { // Paper - protected -> public + while (this.executeNext()) { + ; + } + + } + + protected boolean executeNext() { + R r0 = this.d.peek(); // Paper - decompile fix + + if (r0 == null) { + return false; + } else if (this.e == 0 && !this.canExecute(r0)) { + return false; + } else { + this.executeTask(this.d.remove()); // Paper - decompile fix + return true; + } + } + + public void awaitTasks(BooleanSupplier booleansupplier) { + ++this.e; + + try { + while (!booleansupplier.getAsBoolean()) { + if (!this.executeNext()) { + this.bi(); + } + } + } finally { + --this.e; + } + + } + + protected void bi() { + Thread.yield(); + LockSupport.parkNanos("waiting for tasks", 100000L); + } + + protected void executeTask(R r0) { + try { + r0.run(); + } catch (Exception exception) { + IAsyncTaskHandler.LOGGER.fatal("Error executing task on {}", this.bf(), exception); + } - boolean isMainThread(); - // Akarin start - public default void ensuresMainThread(Runnable runnable) { - postToMainThread(runnable); } - // Akarin end } diff --git a/src/main/java/net/minecraft/server/IBlockAccess.java b/src/main/java/net/minecraft/server/IBlockAccess.java new file mode 100644 index 000000000..29cdc0087 --- /dev/null +++ b/src/main/java/net/minecraft/server/IBlockAccess.java @@ -0,0 +1,157 @@ +package net.minecraft.server; + +import java.util.function.BiFunction; +import java.util.function.Function; +import javax.annotation.Nullable; + +public interface IBlockAccess { + + @Nullable + TileEntity getTileEntity(BlockPosition blockposition); + + IBlockData getTypeIfLoaded(BlockPosition blockposition); // Paper - if loaded util + IBlockData getType(BlockPosition blockposition); + + Fluid getFluidIfLoaded(BlockPosition blockposition); // Paper - if loaded util + Fluid getFluid(BlockPosition blockposition); + + // Paper start - if loaded util + default Material getMaterialIfLoaded(BlockPosition blockposition) { + IBlockData type = this.getTypeIfLoaded(blockposition); + return type == null ? null : type.getMaterial(); + } + + default Block getBlockIfLoaded(BlockPosition blockposition) { + IBlockData type = this.getTypeIfLoaded(blockposition); + return type == null ? null : type.getBlock(); + } + // Paper end + + default int h(BlockPosition blockposition) { + return this.getType(blockposition).h(); + } + + default int H() { + return 15; + } + + default int getBuildHeight() { + return 256; + } + + // CraftBukkit start - moved block handling into separate method for use by Block#rayTrace + default MovingObjectPositionBlock rayTraceBlock(RayTrace raytrace1, BlockPosition blockposition) { + // Paper start - Prevent raytrace from loading chunks + IBlockData iblockdata = this.getTypeIfLoaded(blockposition); + if (iblockdata == null) { + // copied the last function parameter (listed below) + Vec3D vec3d = raytrace1.b().d(raytrace1.a()); + + return MovingObjectPositionBlock.a(raytrace1.a(), EnumDirection.a(vec3d.x, vec3d.y, vec3d.z), new BlockPosition(raytrace1.a())); + } + // Paper end + Fluid fluid = this.getFluid(blockposition); + Vec3D vec3d = raytrace1.b(); + Vec3D vec3d1 = raytrace1.a(); + VoxelShape voxelshape = raytrace1.a(iblockdata, this, blockposition); + MovingObjectPositionBlock movingobjectpositionblock = this.rayTrace(vec3d, vec3d1, blockposition, voxelshape, iblockdata); + VoxelShape voxelshape1 = raytrace1.a(fluid, this, blockposition); + MovingObjectPositionBlock movingobjectpositionblock1 = voxelshape1.rayTrace(vec3d, vec3d1, blockposition); + double d0 = movingobjectpositionblock == null ? Double.MAX_VALUE : raytrace1.b().distanceSquared(movingobjectpositionblock.getPos()); + double d1 = movingobjectpositionblock1 == null ? Double.MAX_VALUE : raytrace1.b().distanceSquared(movingobjectpositionblock1.getPos()); + + return d0 <= d1 ? movingobjectpositionblock : movingobjectpositionblock1; + } + // CraftBukkit end + + default MovingObjectPositionBlock rayTrace(RayTrace raytrace) { + return (MovingObjectPositionBlock) a(raytrace, (raytrace1, blockposition) -> { + return this.rayTraceBlock(raytrace1, blockposition); // CraftBukkit - moved into separate method + }, (raytrace1) -> { + Vec3D vec3d = raytrace1.b().d(raytrace1.a()); + + return MovingObjectPositionBlock.a(raytrace1.a(), EnumDirection.a(vec3d.x, vec3d.y, vec3d.z), new BlockPosition(raytrace1.a())); + }); + } + + @Nullable + default MovingObjectPositionBlock rayTrace(Vec3D vec3d, Vec3D vec3d1, BlockPosition blockposition, VoxelShape voxelshape, IBlockData iblockdata) { + MovingObjectPositionBlock movingobjectpositionblock = voxelshape.rayTrace(vec3d, vec3d1, blockposition); + + if (movingobjectpositionblock != null) { + MovingObjectPositionBlock movingobjectpositionblock1 = iblockdata.k(this, blockposition).rayTrace(vec3d, vec3d1, blockposition); + + if (movingobjectpositionblock1 != null && movingobjectpositionblock1.getPos().d(vec3d).g() < movingobjectpositionblock.getPos().d(vec3d).g()) { + return movingobjectpositionblock.a(movingobjectpositionblock1.getDirection()); + } + } + + return movingobjectpositionblock; + } + + static T a(RayTrace raytrace, BiFunction bifunction, Function function) { + Vec3D vec3d = raytrace.b(); + Vec3D vec3d1 = raytrace.a(); + + if (vec3d.equals(vec3d1)) { + return function.apply(raytrace); + } else { + double d0 = MathHelper.d(-1.0E-7D, vec3d1.x, vec3d.x); + double d1 = MathHelper.d(-1.0E-7D, vec3d1.y, vec3d.y); + double d2 = MathHelper.d(-1.0E-7D, vec3d1.z, vec3d.z); + double d3 = MathHelper.d(-1.0E-7D, vec3d.x, vec3d1.x); + double d4 = MathHelper.d(-1.0E-7D, vec3d.y, vec3d1.y); + double d5 = MathHelper.d(-1.0E-7D, vec3d.z, vec3d1.z); + int i = MathHelper.floor(d3); + int j = MathHelper.floor(d4); + int k = MathHelper.floor(d5); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(i, j, k); + T t0 = bifunction.apply(raytrace, blockposition_mutableblockposition); + + if (t0 != null) { + return t0; + } else { + double d6 = d0 - d3; + double d7 = d1 - d4; + double d8 = d2 - d5; + int l = MathHelper.k(d6); + int i1 = MathHelper.k(d7); + int j1 = MathHelper.k(d8); + double d9 = l == 0 ? Double.MAX_VALUE : (double) l / d6; + double d10 = i1 == 0 ? Double.MAX_VALUE : (double) i1 / d7; + double d11 = j1 == 0 ? Double.MAX_VALUE : (double) j1 / d8; + double d12 = d9 * (l > 0 ? 1.0D - MathHelper.h(d3) : MathHelper.h(d3)); + double d13 = d10 * (i1 > 0 ? 1.0D - MathHelper.h(d4) : MathHelper.h(d4)); + double d14 = d11 * (j1 > 0 ? 1.0D - MathHelper.h(d5) : MathHelper.h(d5)); + + T object; // CraftBukkit - decompile error + + do { + if (d12 > 1.0D && d13 > 1.0D && d14 > 1.0D) { + return function.apply(raytrace); + } + + if (d12 < d13) { + if (d12 < d14) { + i += l; + d12 += d9; + } else { + k += j1; + d14 += d11; + } + } else if (d13 < d14) { + j += i1; + d13 += d10; + } else { + k += j1; + d14 += d11; + } + + object = bifunction.apply(raytrace, blockposition_mutableblockposition.d(i, j, k)); + } while (object == null); + + return object; + } + } + } +} diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java index aa3547690..21f734a73 100644 --- a/src/main/java/net/minecraft/server/IBlockData.java +++ b/src/main/java/net/minecraft/server/IBlockData.java @@ -1,295 +1,390 @@ package net.minecraft.server; -import it.unimi.dsi.fastutil.objects.Object2ByteMap; -import it.unimi.dsi.fastutil.objects.Object2ByteOpenHashMap; +import com.google.common.collect.ImmutableMap; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.DynamicOps; +import com.mojang.datafixers.util.Pair; +import org.bukkit.craftbukkit.block.data.CraftBlockData; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Random; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import javax.annotation.Nullable; -public interface IBlockData extends IBlockDataHolder { +public class IBlockData extends BlockDataAbstract implements IBlockDataHolder { - ThreadLocal> a = ThreadLocal.withInitial(() -> { - Object2ByteOpenHashMap object2byteopenhashmap = new Object2ByteOpenHashMap(); + @Nullable + private IBlockData.a c; + private final int d; + private final boolean e; - object2byteopenhashmap.defaultReturnValue((byte) 127); - return object2byteopenhashmap; - }); - ThreadLocal> b = ThreadLocal.withInitial(() -> { - Object2ByteOpenHashMap object2byteopenhashmap = new Object2ByteOpenHashMap(); - - object2byteopenhashmap.defaultReturnValue((byte) 127); - return object2byteopenhashmap; - }); - ThreadLocal> c = ThreadLocal.withInitial(() -> { - Object2ByteOpenHashMap object2byteopenhashmap = new Object2ByteOpenHashMap(); - - object2byteopenhashmap.defaultReturnValue((byte) 127); - return object2byteopenhashmap; - }); - - Block getBlock(); - - org.bukkit.craftbukkit.block.data.CraftBlockData createCraftBlockData(); // Paper - property for converting IBlockData to CraftBlockData, should only be used by CraftBlockData#fromData and should return a clone - - default Material getMaterial() { - return this.getBlock().n(this); + public IBlockData(Block block, ImmutableMap, Comparable> immutablemap) { + super(block, immutablemap); + this.d = block.a(this); + this.e = block.n(this); } - default boolean a(Entity entity) { - return this.getBlock().a(this, entity); - } - - default boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) { - Block block = this.getBlock(); - Object2ByteMap object2bytemap = block.s() ? null : (Object2ByteMap) IBlockData.a.get(); - - if (object2bytemap != null) { - byte b0 = object2bytemap.getByte(this); - - if (b0 != object2bytemap.defaultReturnValue()) { - return b0 != 0; - } + public void c() { + if (!this.getBlock().p()) { + this.c = new IBlockData.a(this); } - boolean flag = block.a_(this, iblockaccess, blockposition); - - if (object2bytemap != null) { - object2bytemap.put(this, (byte) (flag ? 1 : 0)); - } - - return flag; } - default int b(IBlockAccess iblockaccess, BlockPosition blockposition) { - Block block = this.getBlock(); - Object2ByteMap object2bytemap = block.s() ? null : (Object2ByteMap) IBlockData.b.get(); - - if (object2bytemap != null) { - byte b0 = object2bytemap.getByte(this); - - if (b0 != object2bytemap.defaultReturnValue()) { - return b0; - } - } - - int i = block.j(this, iblockaccess, blockposition); - - if (object2bytemap != null) { - object2bytemap.put(this, (byte) Math.min(i, iblockaccess.K())); - } - - return i; + public Block getBlock() { + return (Block) this.a; } - default int e() { - return this.getBlock().m(this); + // Paper start - impl cached craft block data, lazy load to fix issue with loading at the wrong time + private CraftBlockData cachedCraftBlockData; + + public CraftBlockData createCraftBlockData() { + if(cachedCraftBlockData == null) cachedCraftBlockData = CraftBlockData.createData(this); + return (CraftBlockData) cachedCraftBlockData.clone(); + } + // Paper end + + public Material getMaterial() { + return this.getBlock().l(this); } - default boolean isAir() { + public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, EntityTypes entitytypes) { + return this.getBlock().a(this, iblockaccess, blockposition, entitytypes); + } + + public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.c != null ? this.c.d : this.getBlock().b(this, iblockaccess, blockposition); + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.c != null ? this.c.e : this.getBlock().k(this, iblockaccess, blockposition); + } + + public VoxelShape a(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + return this.c != null && this.c.f != null ? this.c.f[enumdirection.ordinal()] : VoxelShapes.a(this.j(iblockaccess, blockposition), enumdirection); + } + + public boolean f() { + return this.c == null || this.c.h; + } + + public boolean g() { + return this.e; + } + + public int h() { + return this.d; + } + + public boolean isAir() { return this.getBlock().e(this); } - default boolean c(IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.getBlock().k(this, iblockaccess, blockposition); - } - - default MaterialMapColor d(IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.getBlock().c(this, iblockaccess, blockposition); - } - - default IBlockData a(EnumBlockRotation enumblockrotation) { - return this.getBlock().a(this, enumblockrotation); - } - - default IBlockData a(EnumBlockMirror enumblockmirror) { - return this.getBlock().a(this, enumblockmirror); - } - - default boolean g() { - return this.getBlock().a(this); - } - - default EnumRenderType i() { - return this.getBlock().c(this); - } - - default boolean k() { - return this.getBlock().o(this); - } - - default boolean isOccluding() { - return this.getBlock().isOccluding(this); - } - - default boolean isPowerSource() { - return this.getBlock().isPowerSource(this); - } - - default int a(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - return this.getBlock().a(this, iblockaccess, blockposition, enumdirection); - } - - default boolean isComplexRedstone() { - return this.getBlock().isComplexRedstone(this); - } - - default int a(World world, BlockPosition blockposition) { - return this.getBlock().a(this, world, blockposition); - } - - default float e(IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.getBlock().d(this, iblockaccess, blockposition); - } - - default float getDamage(EntityHuman entityhuman, IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.getBlock().getDamage(this, entityhuman, iblockaccess, blockposition); - } - - default int b(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - return this.getBlock().b(this, iblockaccess, blockposition, enumdirection); - } - - default EnumPistonReaction getPushReaction() { - return this.getBlock().getPushReaction(this); - } - - default boolean f(IBlockAccess iblockaccess, BlockPosition blockposition) { - Block block = this.getBlock(); - Object2ByteMap object2bytemap = block.s() ? null : (Object2ByteMap) IBlockData.c.get(); - - if (object2bytemap != null) { - byte b0 = object2bytemap.getByte(this); - - if (b0 != object2bytemap.defaultReturnValue()) { - return b0 != 0; - } - } - - boolean flag = block.i(this, iblockaccess, blockposition); - - if (object2bytemap != null) { - object2bytemap.put(this, (byte) (flag ? 1 : 0)); - } - - return flag; - } - - default boolean p() { - return this.getBlock().f(this); - } - - default VoxelShape getShape(IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.getBlock().a(this, iblockaccess, blockposition); - } - - default VoxelShape getCollisionShape(IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.getBlock().f(this, iblockaccess, blockposition); - } - - default VoxelShape i(IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.getBlock().g(this, iblockaccess, blockposition); - } - - default VoxelShape j(IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.getBlock().h(this, iblockaccess, blockposition); - } - - default boolean q() { - return this.getBlock().r(this); - } - - default Vec3D k(IBlockAccess iblockaccess, BlockPosition blockposition) { - return this.getBlock().l(this, iblockaccess, blockposition); - } - - default boolean a(World world, BlockPosition blockposition, int i, int j) { - return this.getBlock().a(this, world, blockposition, i, j); - } - - default void doPhysics(World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) { - this.getBlock().doPhysics(this, world, blockposition, block, blockposition1); - } - - default void a(GeneratorAccess generatoraccess, BlockPosition blockposition, int i) { - this.getBlock().a(this, generatoraccess, blockposition, i); - } - - default void b(GeneratorAccess generatoraccess, BlockPosition blockposition, int i) { - this.getBlock().b(this, generatoraccess, blockposition, i); - } - - default void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { - this.getBlock().onPlace(this, world, blockposition, iblockdata); - } - - default void remove(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { - this.getBlock().remove(this, world, blockposition, iblockdata, flag); - } - - default void a(World world, BlockPosition blockposition, Random random) { - this.getBlock().a(this, world, blockposition, random); - } - - default void b(World world, BlockPosition blockposition, Random random) { - this.getBlock().b(this, world, blockposition, random); - } - - default void a(World world, BlockPosition blockposition, Entity entity) { - this.getBlock().a(this, world, blockposition, entity); - } - - default void dropNaturally(World world, BlockPosition blockPosition, int i) { a(world, blockPosition, i);} // Paper - OBFHELPER - default void a(World world, BlockPosition blockposition, int i) { - this.dropNaturally(world, blockposition, 1.0F, i); - } - - default void dropNaturally(World world, BlockPosition blockposition, float f, int i) { - this.getBlock().dropNaturally(this, world, blockposition, f, i); - } - - default boolean interact(World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, EnumDirection enumdirection, float f, float f1, float f2) { - return this.getBlock().interact(this, world, blockposition, entityhuman, enumhand, enumdirection, f, f1, f2); - } - - default void attack(World world, BlockPosition blockposition, EntityHuman entityhuman) { - this.getBlock().attack(this, world, blockposition, entityhuman); - } - - default boolean r() { - return this.getBlock().q(this); - } - - default EnumBlockFaceShape c(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { - return this.getBlock().a(iblockaccess, this, blockposition, enumdirection); - } - - default IBlockData updateState(EnumDirection enumdirection, IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - return this.getBlock().updateState(this, enumdirection, iblockdata, generatoraccess, blockposition, blockposition1); - } - - default boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { - return this.getBlock().a(this, iblockaccess, blockposition, pathmode); - } - - default boolean a(BlockActionContext blockactioncontext) { - return this.getBlock().a(this, blockactioncontext); - } - - default boolean canPlace(IWorldReader iworldreader, BlockPosition blockposition) { - return this.getBlock().canPlace(this, iworldreader, blockposition); - } - - default boolean l(IBlockAccess iblockaccess, BlockPosition blockposition) { + public MaterialMapColor c(IBlockAccess iblockaccess, BlockPosition blockposition) { return this.getBlock().e(this, iblockaccess, blockposition); } - default boolean a(Tag tag) { + public IBlockData a(EnumBlockRotation enumblockrotation) { + return this.getBlock().a(this, enumblockrotation); + } + + public IBlockData a(EnumBlockMirror enumblockmirror) { + return this.getBlock().a(this, enumblockmirror); + } + + public EnumRenderType k() { + return this.getBlock().c(this); + } + + public boolean isOccluding(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.getBlock().isOccluding(this, iblockaccess, blockposition); + } + + public boolean isPowerSource() { + return this.getBlock().isPowerSource(this); + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + return this.getBlock().a(this, iblockaccess, blockposition, enumdirection); + } + + public boolean isComplexRedstone() { + return this.getBlock().isComplexRedstone(this); + } + + public int a(World world, BlockPosition blockposition) { + return this.getBlock().a(this, world, blockposition); + } + + public float f(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.getBlock().f(this, iblockaccess, blockposition); + } + + public float getDamage(EntityHuman entityhuman, IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.getBlock().getDamage(this, entityhuman, iblockaccess, blockposition); + } + + public int c(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + return this.getBlock().b(this, iblockaccess, blockposition, enumdirection); + } + + public EnumPistonReaction getPushReaction() { + return this.getBlock().getPushReaction(this); + } + + public boolean g(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.c != null ? this.c.c : this.getBlock().j(this, iblockaccess, blockposition); + } + + public boolean o() { + return this.c != null ? this.c.b : this.getBlock().f(this); + } + + public VoxelShape getShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.a(iblockaccess, blockposition, VoxelShapeCollision.a()); + } + + public VoxelShape a(IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return this.getBlock().a(this, iblockaccess, blockposition, voxelshapecollision); + } + + public VoxelShape getCollisionShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.c != null ? this.c.g : this.b(iblockaccess, blockposition, VoxelShapeCollision.a()); + } + + public final VoxelShape getCollisionShape(IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { return this.b(iblockaccess, blockposition, voxelshapecollision); } // Paper - OBFHELPER + public VoxelShape b(IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return this.getBlock().b(this, iblockaccess, blockposition, voxelshapecollision); + } + + public VoxelShape j(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.getBlock().h(this, iblockaccess, blockposition); + } + + public VoxelShape k(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.getBlock().i(this, iblockaccess, blockposition); + } + + public final boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, Entity entity) { + return Block.a(this.b(iblockaccess, blockposition, VoxelShapeCollision.a(entity)), EnumDirection.UP); + } + + public Vec3D l(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.getBlock().l(this, iblockaccess, blockposition); + } + + public boolean a(World world, BlockPosition blockposition, int i, int j) { + return this.getBlock().a(this, world, blockposition, i, j); + } + + public void doPhysics(World world, BlockPosition blockposition, Block block, BlockPosition blockposition1, boolean flag) { + this.getBlock().doPhysics(this, world, blockposition, block, blockposition1, flag); + } + + public void a(GeneratorAccess generatoraccess, BlockPosition blockposition, int i) { + this.getBlock().a(this, generatoraccess, blockposition, i); + } + + public void b(GeneratorAccess generatoraccess, BlockPosition blockposition, int i) { + this.getBlock().b(this, generatoraccess, blockposition, i); + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + this.getBlock().onPlace(this, world, blockposition, iblockdata, flag); + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + this.getBlock().remove(this, world, blockposition, iblockdata, flag); + } + + public void a(World world, BlockPosition blockposition, Random random) { + this.getBlock().tick(this, world, blockposition, random); + } + + public void b(World world, BlockPosition blockposition, Random random) { + this.getBlock().c(this, world, blockposition, random); + } + + public void a(World world, BlockPosition blockposition, Entity entity) { + this.getBlock().a(this, world, blockposition, entity); + } + + public void dropNaturally(World world, BlockPosition blockposition, ItemStack itemstack) { + this.getBlock().dropNaturally(this, world, blockposition, itemstack); + } + + public List a(LootTableInfo.Builder loottableinfo_builder) { + return this.getBlock().a(this, loottableinfo_builder); + } + + public boolean interact(World world, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { + return this.getBlock().interact(this, world, movingobjectpositionblock.getBlockPosition(), entityhuman, enumhand, movingobjectpositionblock); + } + + public void attack(World world, BlockPosition blockposition, EntityHuman entityhuman) { + this.getBlock().attack(this, world, blockposition, entityhuman); + } + + public boolean m(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.getBlock().c(this, iblockaccess, blockposition); + } + + public IBlockData updateState(EnumDirection enumdirection, IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { + return this.getBlock().updateState(this, enumdirection, iblockdata, generatoraccess, blockposition, blockposition1); + } + + public boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, PathMode pathmode) { + return this.getBlock().a(this, iblockaccess, blockposition, pathmode); + } + + public boolean a(BlockActionContext blockactioncontext) { + return this.getBlock().a(this, blockactioncontext); + } + + public boolean canPlace(IWorldReader iworldreader, BlockPosition blockposition) { + return this.getBlock().canPlace(this, iworldreader, blockposition); + } + + public boolean n(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.getBlock().g(this, iblockaccess, blockposition); + } + + @Nullable + public ITileInventory b(World world, BlockPosition blockposition) { + return this.getBlock().getInventory(this, world, blockposition); + } + + public boolean a(Tag tag) { return this.getBlock().a(tag); } - default Fluid s() { - return this.getBlock().h(this); + public Fluid p() { + return this.getBlock().g(this); } - default boolean t() { + public boolean q() { return this.getBlock().isTicking(this); } + + public final SoundEffectType getStepSound() { return this.r(); } // Paper - OBFHELPER + public SoundEffectType r() { + return this.getBlock().getStepSound(this); + } + + public void a(World world, IBlockData iblockdata, MovingObjectPositionBlock movingobjectpositionblock, Entity entity) { + this.getBlock().a(world, iblockdata, movingobjectpositionblock, entity); + } + + public boolean d(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + return this.c != null ? this.c.i[enumdirection.ordinal()] : Block.d(this, iblockaccess, blockposition, enumdirection); + } + + public boolean o(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.c != null ? this.c.j : Block.a(this.getCollisionShape(iblockaccess, blockposition)); + } + + public static Dynamic a(DynamicOps dynamicops, IBlockData iblockdata) { + ImmutableMap, Comparable> immutablemap = iblockdata.getStateMap(); + T object; // Paper - decompile fix + + if (immutablemap.isEmpty()) { + object = dynamicops.createMap(ImmutableMap.of(dynamicops.createString("Name"), dynamicops.createString(IRegistry.BLOCK.getKey(iblockdata.getBlock()).toString()))); + } else { + object = dynamicops.createMap(ImmutableMap.of(dynamicops.createString("Name"), dynamicops.createString(IRegistry.BLOCK.getKey(iblockdata.getBlock()).toString()), dynamicops.createString("Properties"), dynamicops.createMap(immutablemap.entrySet().stream().map((entry) -> { // Paper - decompile fix + return Pair.of(dynamicops.createString(((IBlockState) entry.getKey()).a()), dynamicops.createString(IBlockDataHolder.b((IBlockState) entry.getKey(), (Comparable) entry.getValue()))); + }).collect(Collectors.toMap(Pair::getFirst, Pair::getSecond))))); + } + + return new Dynamic(dynamicops, object); + } + + public static IBlockData a(Dynamic dynamic) { + RegistryBlocks registryblocks = IRegistry.BLOCK; + Optional optional = dynamic.getElement("Name"); + DynamicOps dynamicops = dynamic.getOps(); + + dynamicops.getClass(); + Block block = (Block) registryblocks.get(new MinecraftKey((String) optional.flatMap(dynamicops::getStringValue).orElse("minecraft:air"))); + Map map = dynamic.get("Properties").asMap((dynamic1) -> { + return dynamic1.asString(""); + }, (dynamic1) -> { + return dynamic1.asString(""); + }); + IBlockData iblockdata = block.getBlockData(); + BlockStateList blockstatelist = block.getStates(); + Iterator iterator = map.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + String s = (String) entry.getKey(); + IBlockState iblockstate = blockstatelist.a(s); + + if (iblockstate != null) { + iblockdata = (IBlockData) IBlockDataHolder.a(iblockdata, iblockstate, s, dynamic.toString(), (String) entry.getValue()); + } + } + + return iblockdata; + } + + static final class a { + + private static final EnumDirection[] a = EnumDirection.values(); + private final boolean b; + private final boolean c; + private final boolean d; + private final int e; + private final VoxelShape[] f; + private final VoxelShape g; + private final boolean h; + private final boolean[] i; + private final boolean j; + + private a(IBlockData iblockdata) { + Block block = iblockdata.getBlock(); + + this.b = block.f(iblockdata); + this.c = block.j(iblockdata, BlockAccessAir.INSTANCE, BlockPosition.ZERO); + this.d = block.b(iblockdata, (IBlockAccess) BlockAccessAir.INSTANCE, BlockPosition.ZERO); + this.e = block.k(iblockdata, BlockAccessAir.INSTANCE, BlockPosition.ZERO); + int i; + + if (!iblockdata.o()) { + this.f = null; + } else { + this.f = new VoxelShape[a.length]; // Paper - decompile fix + VoxelShape voxelshape = block.h(iblockdata, BlockAccessAir.INSTANCE, BlockPosition.ZERO); + EnumDirection[] aenumdirection = a; // Paper - decompile fix + + i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + this.f[enumdirection.ordinal()] = VoxelShapes.a(voxelshape, enumdirection); + } + } + + this.g = block.b(iblockdata, BlockAccessAir.INSTANCE, BlockPosition.ZERO, VoxelShapeCollision.a()); + this.h = Arrays.stream(EnumDirection.EnumAxis.values()).anyMatch((enumdirection_enumaxis) -> { + return this.g.b(enumdirection_enumaxis) < 0.0D || this.g.c(enumdirection_enumaxis) > 1.0D; + }); + this.i = new boolean[6]; + EnumDirection[] aenumdirection1 = a; // Paper - decompile fix + int k = aenumdirection1.length; + + for (i = 0; i < k; ++i) { + EnumDirection enumdirection1 = aenumdirection1[i]; + + this.i[enumdirection1.ordinal()] = Block.d(iblockdata, BlockAccessAir.INSTANCE, BlockPosition.ZERO, enumdirection1); + } + + this.j = Block.a(iblockdata.getCollisionShape(BlockAccessAir.INSTANCE, BlockPosition.ZERO)); + } + } } diff --git a/src/main/java/net/minecraft/server/IChatBaseComponent.java b/src/main/java/net/minecraft/server/IChatBaseComponent.java index 48fecffdf..9ccf7f8d6 100644 --- a/src/main/java/net/minecraft/server/IChatBaseComponent.java +++ b/src/main/java/net/minecraft/server/IChatBaseComponent.java @@ -98,7 +98,7 @@ public interface IChatBaseComponent extends Message, Iterable a(); + List getSiblings(); Stream c(); @@ -116,7 +116,7 @@ public interface IChatBaseComponent extends Message, Iterable { GsonBuilder gsonbuilder = new GsonBuilder(); + gsonbuilder.disableHtmlEscaping(); gsonbuilder.registerTypeHierarchyAdapter(IChatBaseComponent.class, new IChatBaseComponent.ChatSerializer()); gsonbuilder.registerTypeHierarchyAdapter(ChatModifier.class, new ChatModifier.ChatModifierSerializer()); gsonbuilder.registerTypeAdapterFactory(new ChatTypeAdapterFactory()); @@ -245,52 +246,68 @@ public interface IChatBaseComponent extends Message, Iterable 0) { + jsonobject.addProperty("translate", chatmessage.getKey()); + if (chatmessage.getArgs() != null && chatmessage.getArgs().length > 0) { JsonArray jsonarray1 = new JsonArray(); - Object[] aobject = chatmessage.l(); + Object[] aobject = chatmessage.getArgs(); int i = aobject.length; for (int j = 0; j < i; ++j) { @@ -377,14 +394,32 @@ public interface IChatBaseComponent extends Message, Iterable consumer) throws IOException; // Paper - Async Chunks + protected final DataFixer b; @Nullable - Chunk a(GeneratorAccess generatoraccess, int i, int j, Consumer consumer) throws IOException; + private volatile PersistentStructureLegacy a; // Paper - async chunk loading - @Nullable - ProtoChunk b(GeneratorAccess generatoraccess, int i, int j, Consumer consumer) throws IOException; + private final Object persistentDataLock = new Object(); // Paper - void saveChunk(World world, IChunkAccess ichunkaccess) throws IOException, ExceptionWorldConflict; + public IChunkLoader(File file, DataFixer datafixer) { + super(file); + this.b = datafixer; + } - void saveChunk(World world, IChunkAccess ichunkaccess, boolean unloaded) throws IOException, ExceptionWorldConflict; // Spigot + // CraftBukkit start + private boolean check(ChunkProviderServer cps, int x, int z) throws IOException { + ChunkCoordIntPair pos = new ChunkCoordIntPair(x, z); + if (cps != null) { + //com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread"); // Paper - this function is now MT-Safe + if (cps.getChunkAtIfCachedImmediately(x, z) != null) { // Paper - isLoaded is a ticket level check, not a chunk loaded check! + return true; + } + } - void b(); + if (this.chunkExists(pos)) { + // Paper start - prioritize + NBTTagCompound nbt = cps == null ? read(pos) : + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.loadChunkData((WorldServer)cps.getWorld(), x, z, + com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHER_PRIORITY, false, true).chunkData; + // Paper end + if (nbt != null) { + NBTTagCompound level = nbt.getCompound("Level"); + if (level.getBoolean("TerrainPopulated")) { + return true; + } + + ChunkStatus status = ChunkStatus.a(level.getString("Status")); + if (status != null && status.b(ChunkStatus.FEATURES)) { + return true; + } + } + } + + return false; + } + // CraftBukkit end + + public NBTTagCompound getChunkData(DimensionManager dimensionmanager, Supplier supplier, NBTTagCompound nbttagcompound, ChunkCoordIntPair pos, @Nullable GeneratorAccess generatoraccess) throws IOException { + int i = a(nbttagcompound); + boolean flag = true; + + // CraftBukkit start + if (i < 1466) { + NBTTagCompound level = nbttagcompound.getCompound("Level"); + if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) { + ChunkProviderServer cps = (generatoraccess == null) ? null : ((WorldServer) generatoraccess).getChunkProvider(); + if (check(cps, pos.x - 1, pos.z) && check(cps, pos.x - 1, pos.z - 1) && check(cps, pos.x, pos.z - 1)) { + level.setBoolean("LightPopulated", true); + } + } + } + // CraftBukkit end + + if (i < 1493) { + nbttagcompound = GameProfileSerializer.a(this.b, DataFixTypes.CHUNK, nbttagcompound, i, 1493); + if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) { + synchronized (this.persistentDataLock) { // Paper - Async chunk loading + if (this.a == null) { + this.a = PersistentStructureLegacy.a(dimensionmanager.getType(), (WorldPersistentData) supplier.get()); // CraftBukkit - getType + } + + nbttagcompound = this.a.a(nbttagcompound); + } // Paper - Async chunk loading + } + } + + nbttagcompound = GameProfileSerializer.a(this.b, DataFixTypes.CHUNK, nbttagcompound, Math.max(1493, i)); + if (i < SharedConstants.a().getWorldVersion()) { + nbttagcompound.setInt("DataVersion", SharedConstants.a().getWorldVersion()); + } + + return nbttagcompound; + } + + public static int a(NBTTagCompound nbttagcompound) { + return nbttagcompound.hasKeyOfType("DataVersion", 99) ? nbttagcompound.getInt("DataVersion") : -1; + } + + @Override + public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { + super.write(chunkcoordintpair, nbttagcompound); + if (this.a != null) { + synchronized (this.persistentDataLock) { // Paper - Async chunk loading + this.a.a(chunkcoordintpair.pair()); + } // Paper - Async chunk loading + } + + } } diff --git a/src/main/java/net/minecraft/server/ICommandListener.java b/src/main/java/net/minecraft/server/ICommandListener.java index f0ed7a5f1..c930ba660 100644 --- a/src/main/java/net/minecraft/server/ICommandListener.java +++ b/src/main/java/net/minecraft/server/ICommandListener.java @@ -2,13 +2,40 @@ package net.minecraft.server; public interface ICommandListener { + ICommandListener DUMMY = new ICommandListener() { + @Override + public void sendMessage(IChatBaseComponent ichatbasecomponent) {} + + @Override + public boolean shouldSendSuccess() { + return false; + } + + @Override + public boolean shouldSendFailure() { + return false; + } + + @Override + public boolean shouldBroadcastCommands() { + return false; + } + + // CraftBukkit start + @Override + public org.bukkit.command.CommandSender getBukkitSender(CommandListenerWrapper wrapper) { + throw new UnsupportedOperationException("Not supported yet."); + } + // CraftBukkit end + }; + void sendMessage(IChatBaseComponent ichatbasecomponent); - boolean a(); + boolean shouldSendSuccess(); - boolean b(); + boolean shouldSendFailure(); - boolean B_(); + boolean shouldBroadcastCommands(); org.bukkit.command.CommandSender getBukkitSender(CommandListenerWrapper wrapper); // CraftBukkit } diff --git a/src/main/java/net/minecraft/server/IDataManager.java b/src/main/java/net/minecraft/server/IDataManager.java deleted file mode 100644 index 2333fbbd9..000000000 --- a/src/main/java/net/minecraft/server/IDataManager.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.minecraft.server; - -import com.mojang.datafixers.DataFixer; -import java.io.File; -import javax.annotation.Nullable; - -public interface IDataManager { - - @Nullable - WorldData getWorldData(); - - void checkSession() throws ExceptionWorldConflict; - - IChunkLoader createChunkLoader(WorldProvider worldprovider); - - void saveWorldData(WorldData worlddata, NBTTagCompound nbttagcompound); - - void saveWorldData(WorldData worlddata); - - IPlayerFileData getPlayerFileData(); - - void a(); - - File getDirectory(); - - @Nullable - File getDataFile(DimensionManager dimensionmanager, String s); - - DefinedStructureManager h(); - - DataFixer i(); - - java.util.UUID getUUID(); // CraftBukkit -} diff --git a/src/main/java/net/minecraft/server/IDispenseBehavior.java b/src/main/java/net/minecraft/server/IDispenseBehavior.java new file mode 100644 index 000000000..fe3d9d5fa --- /dev/null +++ b/src/main/java/net/minecraft/server/IDispenseBehavior.java @@ -0,0 +1,757 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; +// CraftBukkit start +import org.bukkit.Location; +import org.bukkit.TreeType; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.DummyGeneratorAccess; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.world.StructureGrowEvent; +// CraftBukkit end + +public interface IDispenseBehavior { + + IDispenseBehavior NONE = (isourceblock, itemstack) -> { + return itemstack; + }; + + ItemStack dispense(ISourceBlock isourceblock, ItemStack itemstack); + + static void c() { + BlockDispenser.a((IMaterial) Items.ARROW, (IDispenseBehavior) (new DispenseBehaviorProjectile() { + @Override + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + EntityTippedArrow entitytippedarrow = new EntityTippedArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); + + entitytippedarrow.fromPlayer = EntityArrow.PickupStatus.ALLOWED; + return entitytippedarrow; + } + })); + BlockDispenser.a((IMaterial) Items.TIPPED_ARROW, (IDispenseBehavior) (new DispenseBehaviorProjectile() { + @Override + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + EntityTippedArrow entitytippedarrow = new EntityTippedArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); + + entitytippedarrow.b(itemstack); + entitytippedarrow.fromPlayer = EntityArrow.PickupStatus.ALLOWED; + return entitytippedarrow; + } + })); + BlockDispenser.a((IMaterial) Items.SPECTRAL_ARROW, (IDispenseBehavior) (new DispenseBehaviorProjectile() { + @Override + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + EntitySpectralArrow entityspectralarrow = new EntitySpectralArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); + + entityspectralarrow.fromPlayer = EntityArrow.PickupStatus.ALLOWED; + return entityspectralarrow; + } + })); + BlockDispenser.a((IMaterial) Items.EGG, (IDispenseBehavior) (new DispenseBehaviorProjectile() { + @Override + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + return (IProjectile) SystemUtils.a((new EntityEgg(world, iposition.getX(), iposition.getY(), iposition.getZ())), (entityegg) -> { // CraftBukkit - decompile error + entityegg.setItem(itemstack); + }); + } + })); + BlockDispenser.a((IMaterial) Items.SNOWBALL, (IDispenseBehavior) (new DispenseBehaviorProjectile() { + @Override + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + return (IProjectile) SystemUtils.a((new EntitySnowball(world, iposition.getX(), iposition.getY(), iposition.getZ())), (entitysnowball) -> { // CraftBukkit - decompile error + entitysnowball.setItem(itemstack); + }); + } + })); + BlockDispenser.a((IMaterial) Items.EXPERIENCE_BOTTLE, (IDispenseBehavior) (new DispenseBehaviorProjectile() { + @Override + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + return (IProjectile) SystemUtils.a((new EntityThrownExpBottle(world, iposition.getX(), iposition.getY(), iposition.getZ())), (entitythrownexpbottle) -> { // CraftBukkit - decompile error + entitythrownexpbottle.setItem(itemstack); + }); + } + + @Override + protected float a() { + return super.a() * 0.5F; + } + + @Override + protected float getPower() { + return super.getPower() * 1.25F; + } + })); + BlockDispenser.a((IMaterial) Items.SPLASH_POTION, new IDispenseBehavior() { + @Override + public ItemStack dispense(ISourceBlock isourceblock, ItemStack itemstack) { + return (new DispenseBehaviorProjectile() { + @Override + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack1) { + return (IProjectile) SystemUtils.a((new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ())), (entitypotion) -> { // CraftBukkit - decompile error + entitypotion.setItem(itemstack1); + }); + } + + @Override + protected float a() { + return super.a() * 0.5F; + } + + @Override + protected float getPower() { + return super.getPower() * 1.25F; + } + }).dispense(isourceblock, itemstack); + } + }); + BlockDispenser.a((IMaterial) Items.LINGERING_POTION, new IDispenseBehavior() { + @Override + public ItemStack dispense(ISourceBlock isourceblock, ItemStack itemstack) { + return (new DispenseBehaviorProjectile() { + @Override + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack1) { + return (IProjectile) SystemUtils.a((new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ())), (entitypotion) -> { // CraftBukkit - decompile error + entitypotion.setItem(itemstack1); + }); + } + + @Override + protected float a() { + return super.a() * 0.5F; + } + + @Override + protected float getPower() { + return super.getPower() * 1.25F; + } + }).dispense(isourceblock, itemstack); + } + }); + DispenseBehaviorItem dispensebehavioritem = new DispenseBehaviorItem() { + @Override + public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); + EntityTypes entitytypes = ((ItemMonsterEgg) itemstack.getItem()).b(itemstack.getTag()); + + // CraftBukkit start + World world = isourceblock.getWorld(); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + + try { // Paper + entitytypes.spawnCreature(isourceblock.getWorld(), itemstack, (EntityHuman) null, isourceblock.getBlockPosition().shift(enumdirection), EnumMobSpawn.DISPENSER, enumdirection != EnumDirection.UP, false); + // Paper start + } catch (Exception ex){ + MinecraftServer.LOGGER.warn("An exception occurred dispensing entity at {}[{}]", world.getWorld().getName(), isourceblock.getBlockPosition(), ex); + } + // Paper end + + // itemstack.subtract(1); // Handled during event processing + // CraftBukkit end + return itemstack; + } + }; + Iterator iterator = ItemMonsterEgg.d().iterator(); + + while (iterator.hasNext()) { + ItemMonsterEgg itemmonsteregg = (ItemMonsterEgg) iterator.next(); + + BlockDispenser.a((IMaterial) itemmonsteregg, (IDispenseBehavior) dispensebehavioritem); + } + + BlockDispenser.a((IMaterial) Items.FIREWORK_ROCKET, (IDispenseBehavior) (new DispenseBehaviorItem() { + @Override + public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); + double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); + double d1 = (double) ((float) isourceblock.getBlockPosition().getY() + 0.2F); + double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); + // CraftBukkit start + World world = isourceblock.getWorld(); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + + itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); + isourceblock.getWorld().addEntity(new EntityFireworks(isourceblock.getWorld(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), itemstack1)); + // itemstack.subtract(1); // Handled during event processing + // CraftBukkit end + return itemstack; + } + + @Override + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1004, isourceblock.getBlockPosition(), 0); + } + })); + BlockDispenser.a((IMaterial) Items.FIRE_CHARGE, (IDispenseBehavior) (new DispenseBehaviorItem() { + @Override + public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); + IPosition iposition = BlockDispenser.a(isourceblock); + double d0 = iposition.getX() + (double) ((float) enumdirection.getAdjacentX() * 0.3F); + double d1 = iposition.getY() + (double) ((float) enumdirection.getAdjacentY() * 0.3F); + double d2 = iposition.getZ() + (double) ((float) enumdirection.getAdjacentZ() * 0.3F); + World world = isourceblock.getWorld(); + Random random = world.random; + double d3 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentX(); + double d4 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentY(); + double d5 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentZ(); + + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d3, d4, d5)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + + EntitySmallFireball entitysmallfireball = new EntitySmallFireball(world, d0, d1, d2, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); + entitysmallfireball.b(itemstack); + entitysmallfireball.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) isourceblock.getTileEntity()); + + world.addEntity(entitysmallfireball); + // itemstack.subtract(1); // Handled during event processing + // CraftBukkit end + return itemstack; + } + + @Override + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1018, isourceblock.getBlockPosition(), 0); + } + })); + BlockDispenser.a((IMaterial) Items.OAK_BOAT, (IDispenseBehavior) (new DispenseBehaviorBoat(EntityBoat.EnumBoatType.OAK))); + BlockDispenser.a((IMaterial) Items.SPRUCE_BOAT, (IDispenseBehavior) (new DispenseBehaviorBoat(EntityBoat.EnumBoatType.SPRUCE))); + BlockDispenser.a((IMaterial) Items.BIRCH_BOAT, (IDispenseBehavior) (new DispenseBehaviorBoat(EntityBoat.EnumBoatType.BIRCH))); + BlockDispenser.a((IMaterial) Items.JUNGLE_BOAT, (IDispenseBehavior) (new DispenseBehaviorBoat(EntityBoat.EnumBoatType.JUNGLE))); + BlockDispenser.a((IMaterial) Items.DARK_OAK_BOAT, (IDispenseBehavior) (new DispenseBehaviorBoat(EntityBoat.EnumBoatType.DARK_OAK))); + BlockDispenser.a((IMaterial) Items.ACACIA_BOAT, (IDispenseBehavior) (new DispenseBehaviorBoat(EntityBoat.EnumBoatType.ACACIA))); + DispenseBehaviorItem dispensebehavioritem1 = new DispenseBehaviorItem() { + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + + @Override + public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + ItemBucket itembucket = (ItemBucket) itemstack.getItem(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING)); + World world = isourceblock.getWorld(); + + // CraftBukkit start + int x = blockposition.getX(); + int y = blockposition.getY(); + int z = blockposition.getZ(); + IBlockData iblockdata = world.getType(blockposition); + Material material = iblockdata.getMaterial(); + if (world.isEmpty(blockposition) || !material.isBuildable() || material.isReplaceable() || ((iblockdata.getBlock() instanceof IFluidContainer) && ((IFluidContainer) iblockdata.getBlock()).canPlace(world, blockposition, iblockdata, itembucket.fluidType))) { + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + + itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); + } + // CraftBukkit end + + if (itembucket.a((EntityHuman) null, world, blockposition, (MovingObjectPositionBlock) null)) { + itembucket.a(world, itemstack, blockposition); + // CraftBukkit start - Handle stacked buckets + Item item = Items.BUCKET; + itemstack.subtract(1); + if (itemstack.isEmpty()) { + itemstack.setItem(Items.BUCKET); + itemstack.setCount(1); + } else if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { + this.b.dispense(isourceblock, new ItemStack(item)); + } + // CraftBukkit end + return itemstack; + } else { + return this.b.dispense(isourceblock, itemstack); + } + } + }; + + BlockDispenser.a((IMaterial) Items.LAVA_BUCKET, (IDispenseBehavior) dispensebehavioritem1); + BlockDispenser.a((IMaterial) Items.WATER_BUCKET, (IDispenseBehavior) dispensebehavioritem1); + BlockDispenser.a((IMaterial) Items.SALMON_BUCKET, (IDispenseBehavior) dispensebehavioritem1); + BlockDispenser.a((IMaterial) Items.COD_BUCKET, (IDispenseBehavior) dispensebehavioritem1); + BlockDispenser.a((IMaterial) Items.PUFFERFISH_BUCKET, (IDispenseBehavior) dispensebehavioritem1); + BlockDispenser.a((IMaterial) Items.TROPICAL_FISH_BUCKET, (IDispenseBehavior) dispensebehavioritem1); + BlockDispenser.a((IMaterial) Items.BUCKET, (IDispenseBehavior) (new DispenseBehaviorItem() { + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + + @Override + public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING)); + IBlockData iblockdata = world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (block instanceof IFluidSource) { + FluidType fluidtype = ((IFluidSource) block).removeFluid(DummyGeneratorAccess.INSTANCE, blockposition, iblockdata); // CraftBukkit + + if (!(fluidtype instanceof FluidTypeFlowing)) { + return super.a(isourceblock, itemstack); + } else { + Item item = fluidtype.b(); + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + + fluidtype = ((IFluidSource) block).removeFluid(world, blockposition, iblockdata); // From above + // CraftBukkit end + + itemstack.subtract(1); + if (itemstack.isEmpty()) { + return new ItemStack(item); + } else { + if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { + this.b.dispense(isourceblock, new ItemStack(item)); + } + + return itemstack; + } + } + } else { + return super.a(isourceblock, itemstack); + } + } + })); + BlockDispenser.a((IMaterial) Items.FLINT_AND_STEEL, (IDispenseBehavior) (new DispenseBehaviorMaybe() { + @Override + protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + this.dispensed = true; + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING)); + IBlockData iblockdata = world.getType(blockposition); + + if (ItemFlintAndSteel.a(iblockdata, (GeneratorAccess) world, blockposition)) { + // CraftBukkit start - Ignition by dispensing flint and steel + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, isourceblock.getBlockPosition()).isCancelled()) { + world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + } + // CraftBukkit end + } else if (ItemFlintAndSteel.a(iblockdata)) { + world.setTypeUpdate(blockposition, (IBlockData) iblockdata.set(BlockProperties.r, true)); + } else if (iblockdata.getBlock() instanceof BlockTNT) { + BlockTNT.a(world, blockposition); + world.a(blockposition, false); + } else { + this.dispensed = false; + } + + if (this.dispensed && itemstack.isDamaged(1, world.random, (EntityPlayer) null)) { + itemstack.setCount(0); + } + + return itemstack; + } + })); + BlockDispenser.a((IMaterial) Items.BONE_MEAL, (IDispenseBehavior) (new DispenseBehaviorMaybe() { + @Override + protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + this.dispensed = true; + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING)); + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + + world.captureTreeGeneration = true; + // CraftBukkit end + + if (!ItemBoneMeal.a(itemstack, world, blockposition) && !ItemBoneMeal.a(itemstack, world, blockposition, (EnumDirection) null)) { + this.dispensed = false; + } else if (!world.isClientSide) { + world.triggerEffect(2005, blockposition, 0); + } + // CraftBukkit start + world.captureTreeGeneration = false; + if (world.capturedBlockStates.size() > 0) { + TreeType treeType = BlockSapling.treeType; + BlockSapling.treeType = null; + Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); + List blocks = (List) world.capturedBlockStates.clone(); + world.capturedBlockStates.clear(); + StructureGrowEvent structureEvent = null; + if (treeType != null) { + structureEvent = new StructureGrowEvent(location, treeType, false, null, blocks); + org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent); + } + if (structureEvent == null || !structureEvent.isCancelled()) { + for (org.bukkit.block.BlockState blockstate : blocks) { + blockstate.update(true); + } + } + } + // CraftBukkit end + + return itemstack; + } + })); + BlockDispenser.a((IMaterial) Blocks.TNT, (IDispenseBehavior) (new DispenseBehaviorItem() { + @Override + protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING)); + // EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, (EntityLiving) null); + + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), (EntityLiving) null); + // CraftBukkit end + + world.addEntity(entitytntprimed); + world.playSound((EntityHuman) null, entitytntprimed.locX, entitytntprimed.locY, entitytntprimed.locZ, SoundEffects.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F); + // itemstack.subtract(1); // CraftBukkit - handled above + return itemstack; + } + })); + DispenseBehaviorMaybe dispensebehaviormaybe = new DispenseBehaviorMaybe() { + @Override + protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + this.dispensed = !ItemArmor.a(isourceblock, itemstack).isEmpty(); + return itemstack; + } + }; + + BlockDispenser.a((IMaterial) Items.CREEPER_HEAD, (IDispenseBehavior) dispensebehaviormaybe); + BlockDispenser.a((IMaterial) Items.ZOMBIE_HEAD, (IDispenseBehavior) dispensebehaviormaybe); + BlockDispenser.a((IMaterial) Items.DRAGON_HEAD, (IDispenseBehavior) dispensebehaviormaybe); + BlockDispenser.a((IMaterial) Items.SKELETON_SKULL, (IDispenseBehavior) dispensebehaviormaybe); + BlockDispenser.a((IMaterial) Items.PLAYER_HEAD, (IDispenseBehavior) dispensebehaviormaybe); + BlockDispenser.a((IMaterial) Items.WITHER_SKELETON_SKULL, (IDispenseBehavior) (new DispenseBehaviorMaybe() { + @Override + protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + this.dispensed = true; + if (world.isEmpty(blockposition) && BlockWitherSkull.b(world, blockposition, itemstack)) { + world.setTypeAndData(blockposition, (IBlockData) Blocks.WITHER_SKELETON_SKULL.getBlockData().set(BlockSkull.a, enumdirection.k() == EnumDirection.EnumAxis.Y ? 0 : enumdirection.opposite().get2DRotationValue() * 4), 3); + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntitySkull) { + BlockWitherSkull.a(world, blockposition, (TileEntitySkull) tileentity); + } + + itemstack.subtract(1); + } else if (ItemArmor.a(isourceblock, itemstack).isEmpty()) { + this.dispensed = false; + } + + return itemstack; + } + })); + BlockDispenser.a((IMaterial) Blocks.CARVED_PUMPKIN, (IDispenseBehavior) (new DispenseBehaviorMaybe() { + @Override + protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING)); + BlockPumpkinCarved blockpumpkincarved = (BlockPumpkinCarved) Blocks.CARVED_PUMPKIN; + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + this.dispensed = true; + if (world.isEmpty(blockposition) && blockpumpkincarved.a((IWorldReader) world, blockposition)) { + if (!world.isClientSide) { + world.setTypeAndData(blockposition, blockpumpkincarved.getBlockData(), 3); + } + + itemstack.subtract(1); + } else { + ItemStack itemstack1 = ItemArmor.a(isourceblock, itemstack); + + if (itemstack1.isEmpty()) { + this.dispensed = false; + } + } + + return itemstack; + } + })); + BlockDispenser.a((IMaterial) Blocks.SHULKER_BOX.getItem(), (IDispenseBehavior) (new DispenseBehaviorShulkerBox())); + EnumColor[] aenumcolor = EnumColor.values(); + int i = aenumcolor.length; + + for (int j = 0; j < i; ++j) { + EnumColor enumcolor = aenumcolor[j]; + + BlockDispenser.a((IMaterial) BlockShulkerBox.a(enumcolor).getItem(), (IDispenseBehavior) (new DispenseBehaviorShulkerBox())); + } + + BlockDispenser.a((IMaterial) Items.SHEARS.getItem(), (IDispenseBehavior) (new DispenseBehaviorMaybe() { + @Override + protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.dispense(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + if (!world.e()) { + this.dispensed = false; + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING)); + List list = world.a(EntitySheep.class, new AxisAlignedBB(blockposition)); + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { + EntitySheep entitysheep = (EntitySheep) iterator1.next(); + + if (entitysheep.isAlive() && !entitysheep.isSheared() && !entitysheep.isBaby()) { + // CraftBukkit start + if (CraftEventFactory.callBlockShearEntityEvent(entitysheep, bukkitBlock, craftItem).isCancelled()) { + continue; + } + // CraftBukkit end + entitysheep.shear(); + if (itemstack.isDamaged(1, world.random, (EntityPlayer) null)) { + itemstack.setCount(0); + } + + this.dispensed = true; + break; + } + } + } + + return itemstack; + } + })); + } +} diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java new file mode 100644 index 000000000..dca18afdb --- /dev/null +++ b/src/main/java/net/minecraft/server/IEntityAccess.java @@ -0,0 +1,232 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.stream.Stream; +import javax.annotation.Nullable; + +public interface IEntityAccess { + + List getEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate); + + List a(Class oclass, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate); + + default List b(Class oclass, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate) { + return this.a(oclass, axisalignedbb, predicate); + } + + List getPlayers(); + + default List getEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { + return this.getEntities(entity, axisalignedbb, IEntitySelector.f); + } + + default boolean a(@Nullable Entity entity, VoxelShape voxelshape) { + return voxelshape.isEmpty() ? true : this.getEntities(entity, voxelshape.getBoundingBox()).stream().filter((entity1) -> { + return !entity1.dead && entity1.i && (entity == null || !entity1.x(entity)); + }).noneMatch((entity1) -> { + return VoxelShapes.c(voxelshape, VoxelShapes.a(entity1.getBoundingBox()), OperatorBoolean.AND); + }); + } + + default List a(Class oclass, AxisAlignedBB axisalignedbb) { + return this.a(oclass, axisalignedbb, IEntitySelector.f); + } + + default List b(Class oclass, AxisAlignedBB axisalignedbb) { + return this.b(oclass, axisalignedbb, IEntitySelector.f); + } + + default Stream a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { + if (axisalignedbb.a() < 1.0E-7D) { + return Stream.empty(); + } else { + AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D); + Stream stream = this.getEntities(entity, axisalignedbb1).stream().filter((entity1) -> { // Paper - decompile fix + return !set.contains(entity1); + }).filter((entity1) -> { + return entity == null || !entity.x(entity1); + }).flatMap((entity1) -> { + return Stream.of(entity1.aq(), entity == null ? null : entity.j(entity1)); + }).filter(Objects::nonNull); + + return stream.filter(axisalignedbb1::c).map(VoxelShapes::a); + } + } + + @Nullable + default EntityHuman a(double d0, double d1, double d2, double d3, @Nullable Predicate predicate) { + double d4 = -1.0D; + EntityHuman entityhuman = null; + Iterator iterator = this.getPlayers().iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman1 = (EntityHuman) iterator.next(); + + if (predicate == null || predicate.test(entityhuman1)) { + double d5 = entityhuman1.e(d0, d1, d2); + + if ((d3 < 0.0D || d5 < d3 * d3) && (d4 == -1.0D || d5 < d4)) { + d4 = d5; + entityhuman = entityhuman1; + } + } + } + + return entityhuman; + } + + @Nullable + default EntityHuman findNearbyPlayer(Entity entity, double d0) { + return this.a(entity.locX, entity.locY, entity.locZ, d0, false); + } + + @Nullable + default EntityHuman a(double d0, double d1, double d2, double d3, boolean flag) { + Predicate predicate = flag ? IEntitySelector.e : IEntitySelector.f; + + return this.a(d0, d1, d2, d3, predicate); + } + + @Nullable + default EntityHuman a(double d0, double d1, double d2) { + double d3 = -1.0D; + EntityHuman entityhuman = null; + Iterator iterator = this.getPlayers().iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman1 = (EntityHuman) iterator.next(); + + if (IEntitySelector.f.test(entityhuman1)) { + double d4 = entityhuman1.e(d0, entityhuman1.locY, d1); + + if ((d2 < 0.0D || d4 < d2 * d2) && (d3 == -1.0D || d4 < d3)) { + d3 = d4; + entityhuman = entityhuman1; + } + } + } + + return entityhuman; + } + + default boolean isPlayerNearby(double d0, double d1, double d2, double d3) { + Iterator iterator = this.getPlayers().iterator(); + + double d4; + + do { + EntityHuman entityhuman; + + do { + do { + if (!iterator.hasNext()) { + return false; + } + + entityhuman = (EntityHuman) iterator.next(); + } while (!IEntitySelector.f.test(entityhuman)); + } while (!IEntitySelector.b.test(entityhuman)); + + d4 = entityhuman.e(d0, d1, d2); + } while (d3 >= 0.0D && d4 >= d3 * d3); + + return true; + } + + @Nullable + default EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving) { + return (EntityHuman) this.a(this.getPlayers(), pathfindertargetcondition, entityliving, entityliving.locX, entityliving.locY, entityliving.locZ); + } + + @Nullable + default EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving, double d0, double d1, double d2) { + return (EntityHuman) this.a(this.getPlayers(), pathfindertargetcondition, entityliving, d0, d1, d2); + } + + @Nullable + default EntityHuman a(PathfinderTargetCondition pathfindertargetcondition, double d0, double d1, double d2) { + return (EntityHuman) this.a(this.getPlayers(), pathfindertargetcondition, (EntityLiving) null, d0, d1, d2); + } + + @Nullable + default T a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { + return this.a(this.a(oclass, axisalignedbb, null), pathfindertargetcondition, entityliving, d0, d1, d2); // Paper - decompile fix + } + + @Nullable + default T b(Class oclass, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2, AxisAlignedBB axisalignedbb) { + return this.a(this.b(oclass, axisalignedbb, null), pathfindertargetcondition, entityliving, d0, d1, d2); // Paper - decompile fix + } + + @Nullable + default T a(List list, PathfinderTargetCondition pathfindertargetcondition, @Nullable EntityLiving entityliving, double d0, double d1, double d2) { + double d3 = -1.0D; + T t0 = null; + Iterator iterator = list.iterator(); // Paper - decompile fix + + while (iterator.hasNext()) { + T t1 = iterator.next(); // Paper - decompile fix + + if (pathfindertargetcondition.a(entityliving, t1)) { + double d4 = t1.e(d0, d1, d2); + + if (d3 == -1.0D || d4 < d3) { + d3 = d4; + t0 = t1; + } + } + } + + return t0; + } + + default List a(PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving, AxisAlignedBB axisalignedbb) { + List list = Lists.newArrayList(); + Iterator iterator = this.getPlayers().iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + if (axisalignedbb.e(entityhuman.locX, entityhuman.locY, entityhuman.locZ) && pathfindertargetcondition.a(entityliving, entityhuman)) { + list.add(entityhuman); + } + } + + return list; + } + + default List a(Class oclass, PathfinderTargetCondition pathfindertargetcondition, EntityLiving entityliving, AxisAlignedBB axisalignedbb) { + List list = this.a(oclass, axisalignedbb, (Predicate) null); + List list1 = Lists.newArrayList(); + Iterator iterator = list.iterator(); // Paper - decompile fix + + while (iterator.hasNext()) { + T t0 = iterator.next(); // Paper - decompile fix + + if (pathfindertargetcondition.a(entityliving, t0)) { + list1.add(t0); + } + } + + return list1; + } + + @Nullable + default EntityHuman b(UUID uuid) { + for (int i = 0; i < this.getPlayers().size(); ++i) { + EntityHuman entityhuman = (EntityHuman) this.getPlayers().get(i); + + if (uuid.equals(entityhuman.getUniqueID())) { + return entityhuman; + } + } + + return null; + } +} diff --git a/src/main/java/net/minecraft/server/IEntitySelector.java b/src/main/java/net/minecraft/server/IEntitySelector.java index 71f08d53c..56739e6ed 100644 --- a/src/main/java/net/minecraft/server/IEntitySelector.java +++ b/src/main/java/net/minecraft/server/IEntitySelector.java @@ -17,18 +17,18 @@ public final class IEntitySelector { }; public static Predicate canAITarget() { return e; } // Paper - OBFHELPER public static final Predicate e = (entity) -> { - return !(entity instanceof EntityHuman) || !((EntityHuman) entity).isSpectator() && !((EntityHuman) entity).u(); + return !(entity instanceof EntityHuman) || !entity.isSpectator() && !((EntityHuman) entity).isCreative(); }; public static Predicate notSpectator() { return f; } // Paper - OBFHELPER public static final Predicate f = (entity) -> { - return !(entity instanceof EntityHuman) || !((EntityHuman) entity).isSpectator(); + return !entity.isSpectator(); }; public static Predicate a(double d0, double d1, double d2, double d3) { double d4 = d3 * d3; return (entity) -> { - return entity != null && entity.d(d0, d1, d2) <= d4; + return entity != null && entity.e(d0, d1, d2) <= d4; }; } @@ -39,7 +39,7 @@ public final class IEntitySelector { return (Predicate) (scoreboardteambase_enumteampush == ScoreboardTeamBase.EnumTeamPush.NEVER ? Predicates.alwaysFalse() : IEntitySelector.f.and((entity1) -> { if (!entity1.isCollidable()) { return false; - } else if (entity.world.isClientSide && (!(entity1 instanceof EntityHuman) || !((EntityHuman) entity1).dn())) { + } else if (entity.world.isClientSide && (!(entity1 instanceof EntityHuman) || !((EntityHuman) entity1).dG())) { return false; } else { ScoreboardTeamBase scoreboardteambase1 = entity1.getScoreboardTeam(); @@ -88,9 +88,8 @@ public final class IEntitySelector { return false; } else { EntityLiving entityliving = (EntityLiving) entity; - EnumItemSlot enumitemslot = EntityInsentient.e(this.a); - return !entityliving.getEquipment(enumitemslot).isEmpty() ? false : (entityliving instanceof EntityInsentient ? ((EntityInsentient) entityliving).dj() : (entityliving instanceof EntityArmorStand ? !((EntityArmorStand) entityliving).c(enumitemslot) : entityliving instanceof EntityHuman)); + return entityliving.e(this.a); } } } diff --git a/src/main/java/net/minecraft/server/IInventory.java b/src/main/java/net/minecraft/server/IInventory.java index bdec27c9d..874f9db9e 100644 --- a/src/main/java/net/minecraft/server/IInventory.java +++ b/src/main/java/net/minecraft/server/IInventory.java @@ -1,12 +1,13 @@ package net.minecraft.server; +import java.util.Set; import org.bukkit.craftbukkit.entity.CraftHumanEntity; // CraftBukkit -public interface IInventory extends INamableTileEntity { +public interface IInventory extends Clearable { int getSize(); - boolean P_(); + boolean isNotEmpty(); ItemStack getItem(int i); @@ -16,32 +17,44 @@ public interface IInventory extends INamableTileEntity { void setItem(int i, ItemStack itemstack); - int getMaxStackSize(); + int getMaxStackSize(); // CraftBukkit void update(); boolean a(EntityHuman entityhuman); - void startOpen(EntityHuman entityhuman); + default void startOpen(EntityHuman entityhuman) {} - void closeContainer(EntityHuman entityhuman); + default void closeContainer(EntityHuman entityhuman) {} - boolean b(int i, ItemStack itemstack); - - int getProperty(int i); - - void setProperty(int i, int j); - - int h(); - - void clear(); - - default int n() { - return 0; + default boolean b(int i, ItemStack itemstack) { + return true; } - default int U_() { - return 0; + default int a(Item item) { + int i = 0; + + for (int j = 0; j < this.getSize(); ++j) { + ItemStack itemstack = this.getItem(j); + + if (itemstack.getItem().equals(item)) { + i += itemstack.getCount(); + } + } + + return i; + } + + default boolean a(Set set) { + for (int i = 0; i < this.getSize(); ++i) { + ItemStack itemstack = this.getItem(i); + + if (set.contains(itemstack.getItem()) && itemstack.getCount() > 0) { + return true; + } + } + + return false; } // CraftBukkit start diff --git a/src/main/java/net/minecraft/server/IMerchant.java b/src/main/java/net/minecraft/server/IMerchant.java new file mode 100644 index 000000000..cf164fbfe --- /dev/null +++ b/src/main/java/net/minecraft/server/IMerchant.java @@ -0,0 +1,49 @@ +package net.minecraft.server; + +import java.util.OptionalInt; +import javax.annotation.Nullable; + +public interface IMerchant { + + void setTradingPlayer(@Nullable EntityHuman entityhuman); + + @Nullable + EntityHuman getTrader(); + + MerchantRecipeList getOffers(); + + void a(MerchantRecipe merchantrecipe); + + void i(ItemStack itemstack); + + World getWorld(); + + int getExperience(); + + void s(int i); + + boolean ea(); + + SoundEffect eb(); + + default boolean ei() { + return false; + } + + default void openTrade(EntityHuman entityhuman, IChatBaseComponent ichatbasecomponent, int i) { + OptionalInt optionalint = entityhuman.openContainer(new TileInventory((j, playerinventory, entityhuman1) -> { + return new ContainerMerchant(j, playerinventory, this); + }, ichatbasecomponent)); + + if (optionalint.isPresent()) { + MerchantRecipeList merchantrecipelist = this.getOffers(); + + if (!merchantrecipelist.isEmpty()) { + entityhuman.openTrade(optionalint.getAsInt(), merchantrecipelist, i, this.getExperience(), this.ea(), this.ei()); + } + } + + } + + org.bukkit.craftbukkit.inventory.CraftMerchant getCraftMerchant(); // CraftBukkit +} diff --git a/src/main/java/net/minecraft/server/IRangedEntity.java b/src/main/java/net/minecraft/server/IRangedEntity.java index b763bd11d..9b79ac77d 100644 --- a/src/main/java/net/minecraft/server/IRangedEntity.java +++ b/src/main/java/net/minecraft/server/IRangedEntity.java @@ -4,5 +4,6 @@ public interface IRangedEntity { void a(EntityLiving entityliving, float f); default void rangedAttack(EntityLiving entityliving, float f) { a(entityliving, f); } // Paper - OBFHELPER - void s(boolean flag); default void setChargingAttack(boolean flag) { s(flag); } // Paper - OBFHELPER + // - see EntitySkeletonAbstract melee goal + void q(boolean flag); default void setChargingAttack(boolean charging) { q(charging); }; // Paper } diff --git a/src/main/java/net/minecraft/server/IRecipe.java b/src/main/java/net/minecraft/server/IRecipe.java index 0075fe09e..2da873e25 100644 --- a/src/main/java/net/minecraft/server/IRecipe.java +++ b/src/main/java/net/minecraft/server/IRecipe.java @@ -1,38 +1,40 @@ package net.minecraft.server; -public interface IRecipe { +public interface IRecipe { - boolean a(IInventory iinventory, World world); + boolean a(C c0, World world); - ItemStack craftItem(IInventory iinventory); + ItemStack a(C c0); - ItemStack d(); + ItemStack c(); - default NonNullList b(IInventory iinventory) { - NonNullList nonnulllist = NonNullList.a(iinventory.getSize(), ItemStack.a); + default NonNullList b(C c0) { + NonNullList nonnulllist = NonNullList.a(c0.getSize(), ItemStack.a); for (int i = 0; i < nonnulllist.size(); ++i) { - Item item = iinventory.getItem(i).getItem(); + Item item = c0.getItem(i).getItem(); - if (item.p()) { - nonnulllist.set(i, new ItemStack(item.o())); + if (item.o()) { + nonnulllist.set(i, new ItemStack(item.n())); } } return nonnulllist; } - default NonNullList e() { + default NonNullList a() { return NonNullList.a(); } - default boolean c() { + default boolean isComplex() { return false; } MinecraftKey getKey(); - RecipeSerializer a(); + RecipeSerializer getRecipeSerializer(); + + Recipes g(); org.bukkit.inventory.Recipe toBukkitRecipe(); // CraftBukkit } diff --git a/src/main/java/net/minecraft/server/IWorldReader.java b/src/main/java/net/minecraft/server/IWorldReader.java index ddcf87450..a25736e23 100644 --- a/src/main/java/net/minecraft/server/IWorldReader.java +++ b/src/main/java/net/minecraft/server/IWorldReader.java @@ -1,35 +1,33 @@ package net.minecraft.server; +import com.google.common.collect.Streams; import java.util.Collections; import java.util.Set; -import java.util.function.Predicate; +import java.util.Spliterators.AbstractSpliterator; +import java.util.function.Consumer; import java.util.stream.Stream; import java.util.stream.StreamSupport; import javax.annotation.Nullable; -import io.akarin.server.core.AkarinGlobalConfig; +public interface IWorldReader extends IIBlockAccess { -public interface IWorldReader extends IBlockAccess { + default boolean isEmpty(BlockPosition blockposition) { + return this.getType(blockposition).isAir(); + } - boolean isEmpty(BlockPosition blockposition); - - BiomeBase getBiome(BlockPosition blockposition); - - int getBrightness(EnumSkyBlock enumskyblock, BlockPosition blockposition); - - default boolean z(BlockPosition blockposition) { + default boolean u(BlockPosition blockposition) { if (blockposition.getY() >= this.getSeaLevel()) { - return this.e(blockposition); + return this.f(blockposition); } else { BlockPosition blockposition1 = new BlockPosition(blockposition.getX(), this.getSeaLevel(), blockposition.getZ()); - if (!this.e(blockposition1)) { + if (!this.f(blockposition1)) { return false; } else { for (blockposition1 = blockposition1.down(); blockposition1.getY() > blockposition.getY(); blockposition1 = blockposition1.down()) { IBlockData iblockdata = this.getType(blockposition1); - if (iblockdata.b(this, blockposition1) > 0 && !iblockdata.getMaterial().isLiquid()) { + if (iblockdata.b((IBlockAccess) this, blockposition1) > 0 && !iblockdata.getMaterial().isLiquid()) { return false; } } @@ -40,215 +38,148 @@ public interface IWorldReader extends IBlockAccess { } int getLightLevel(BlockPosition blockposition, int i); - // Paper start - default @Nullable - IBlockData getTypeIfLoaded(BlockPosition var1) { - return isLoaded(var1) ? getType(var1) : null; - } - default @Nullable - Block getBlockIfLoaded(BlockPosition var1) { - return isLoaded(var1) ? getType(var1).getBlock() : null; - } + @Nullable IChunkAccess getChunkIfLoadedImmediately(int x, int z); // Paper - ifLoaded api (we need this since current impl blocks if the chunk is loading) + @Nullable + IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag); - default @Nullable - Material getMaterialIfLoaded(BlockPosition var1) { - return isLoaded(var1) ? getType(var1).getMaterial() : null; - } - // Paper end + @Deprecated + boolean isChunkLoaded(int i, int j); - boolean isChunkLoaded(int i, int j, boolean flag); - - boolean e(BlockPosition blockposition); - - default BlockPosition getHighestBlockYAt(HeightMap.Type heightmap_type, BlockPosition blockposition) { - return new BlockPosition(blockposition.getX(), this.a(heightmap_type, blockposition.getX(), blockposition.getZ()), blockposition.getZ()); - } + BlockPosition getHighestBlockYAt(HeightMap.Type heightmap_type, BlockPosition blockposition); int a(HeightMap.Type heightmap_type, int i, int j); - default float A(BlockPosition blockposition) { - return this.o().i()[this.getLightLevel(blockposition)]; + default float v(BlockPosition blockposition) { + return this.getWorldProvider().i()[this.getLightLevel(blockposition)]; } - @Nullable - default EntityHuman findNearbyPlayer(Entity entity, double d0) { - return this.a(entity.locX, entity.locY, entity.locZ, d0, false); - } - - @Nullable - default EntityHuman b(Entity entity, double d0) { - return this.a(entity.locX, entity.locY, entity.locZ, d0, true); - } - - @Nullable - default EntityHuman a(double d0, double d1, double d2, double d3, boolean flag) { - Predicate predicate = flag ? IEntitySelector.e : IEntitySelector.f; - - return this.a(d0, d1, d2, d3, predicate); - } - - @Nullable - EntityHuman a(double d0, double d1, double d2, double d3, Predicate predicate); - int c(); WorldBorder getWorldBorder(); boolean a(@Nullable Entity entity, VoxelShape voxelshape); - int a(BlockPosition blockposition, EnumDirection enumdirection); + default int c(BlockPosition blockposition, EnumDirection enumdirection) { + return this.getType(blockposition).c(this, blockposition, enumdirection); + } boolean e(); int getSeaLevel(); - default boolean a(IBlockData iblockdata, BlockPosition blockposition) { - VoxelShape voxelshape = iblockdata.getCollisionShape(this, blockposition); + default IChunkAccess w(BlockPosition blockposition) { + return this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); + } + + default IChunkAccess getChunkAt(int i, int j) { + return this.getChunkAt(i, j, ChunkStatus.FULL, true); + } + + default IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus) { + return this.getChunkAt(i, j, chunkstatus, true); + } + + default ChunkStatus O() { + return ChunkStatus.EMPTY; + } + + default boolean a(IBlockData iblockdata, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + VoxelShape voxelshape = iblockdata.b((IBlockAccess) this, blockposition, voxelshapecollision); return voxelshape.isEmpty() || this.a((Entity) null, voxelshape.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ())); } - default boolean a_(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { - return this.a(entity, VoxelShapes.a(axisalignedbb)); - } - - default Stream a(VoxelShape voxelshape, VoxelShape voxelshape1, boolean flag) { - // Akarin start - return rayTrace(voxelshape, voxelshape1, flag, null); - } - - /* - * Reference on code by Colin Godsey - * https://github.com/yesdog/Paper/blob/95e5ff5e9a741c21b694fec507d48682606346b1/Spigot-Server-Patches/0424-stair-collision-for-pe-fix.patch - */ - static final VoxelShape slimShape = VoxelShapes.create(0.25, 0, 0.25, 0.75, 0.05, 0.75); - - static boolean canIgnoreRayTrace(IBlockData data) { - Block type = data.getBlock(); - - // Pull request if you want to add some more blocks - return type instanceof BlockStairs || - type instanceof BlockStepAbstract || - type instanceof BlockCarpet || - type instanceof BlockSnow || - type instanceof BlockAttachable || - type instanceof BlockAnvil || - type instanceof BlockBed || - type instanceof BlockChest || - type instanceof BlockChestTrapped; - } - - default Stream rayTrace(VoxelShape voxelshape, VoxelShape voxelshape1, boolean flag, @Nullable Entity entity) { - // Akarin end - int i = MathHelper.floor(voxelshape.b(EnumDirection.EnumAxis.X)) - 1; - int j = MathHelper.f(voxelshape.c(EnumDirection.EnumAxis.X)) + 1; - int k = MathHelper.floor(voxelshape.b(EnumDirection.EnumAxis.Y)) - 1; - int l = MathHelper.f(voxelshape.c(EnumDirection.EnumAxis.Y)) + 1; - int i1 = MathHelper.floor(voxelshape.b(EnumDirection.EnumAxis.Z)) - 1; - int j1 = MathHelper.f(voxelshape.c(EnumDirection.EnumAxis.Z)) + 1; - WorldBorder worldborder = this.getWorldBorder(); - boolean flag1 = worldborder.b() < (double) i && (double) j < worldborder.d() && worldborder.c() < (double) i1 && (double) j1 < worldborder.e(); - VoxelShapeBitSet voxelshapebitset = new VoxelShapeBitSet(j - i, l - k, j1 - i1); - Predicate predicate = (voxelshape2) -> { - return !voxelshape2.isEmpty() && VoxelShapes.c(voxelshape, voxelshape2, OperatorBoolean.AND); - }; - Stream stream = StreamSupport.stream(BlockPosition.MutableBlockPosition.b(i, k, i1, j - 1, l - 1, j1 - 1).spliterator(), false).map((blockposition_mutableblockposition) -> { - int k1 = blockposition_mutableblockposition.getX(); - int l1 = blockposition_mutableblockposition.getY(); - int i2 = blockposition_mutableblockposition.getZ(); - boolean flag2 = k1 == i || k1 == j - 1; - boolean flag3 = l1 == k || l1 == l - 1; - boolean flag4 = i2 == i1 || i2 == j1 - 1; - - if ((!flag2 || !flag3) && (!flag3 || !flag4) && (!flag4 || !flag2) && this.isLoaded(blockposition_mutableblockposition)) { - VoxelShape voxelshape2; - - if (flag && !flag1 && !worldborder.a((BlockPosition) blockposition_mutableblockposition)) { - voxelshape2 = VoxelShapes.b(); - } else { - voxelshape2 = AkarinGlobalConfig.ignoreRayTraceForSeatableBlocks && entity instanceof EntityPlayer && canIgnoreRayTrace(this.getType(blockposition_mutableblockposition)) ? slimShape : this.getType(blockposition_mutableblockposition).getCollisionShape(this, blockposition_mutableblockposition); // Akarin - } - - VoxelShape voxelshape3 = voxelshape1.a((double) (-k1), (double) (-l1), (double) (-i2)); - - if (VoxelShapes.c(voxelshape3, voxelshape2, OperatorBoolean.AND)) { - return VoxelShapes.a(); - } else if (voxelshape2 == VoxelShapes.b()) { - voxelshapebitset.a(k1 - i, l1 - k, i2 - i1, true, true); - return VoxelShapes.a(); - } else { - return voxelshape2.a((double) k1, (double) l1, (double) i2); - } - } else { - return VoxelShapes.a(); - } - }).filter(predicate); - - return Stream.concat(stream, Stream.generate(() -> { - return new VoxelShapeWorldRegion(voxelshapebitset, i, k, i1); - }).limit(1L).filter(predicate)); - } - - default Stream a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, double d0, double d1, double d2) { - return this.a(entity, axisalignedbb, Collections.emptySet(), d0, d1, d2); - } - - default Stream a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set, double d0, double d1, double d2) { - double d3 = 1.0E-7D; - VoxelShape voxelshape = VoxelShapes.a(axisalignedbb); - VoxelShape voxelshape1 = VoxelShapes.a(axisalignedbb.d(d0 > 0.0D ? -1.0E-7D : 1.0E-7D, d1 > 0.0D ? -1.0E-7D : 1.0E-7D, d2 > 0.0D ? -1.0E-7D : 1.0E-7D)); - VoxelShape voxelshape2 = VoxelShapes.b(VoxelShapes.a(axisalignedbb.b(d0, d1, d2).g(1.0E-7D)), voxelshape1, OperatorBoolean.ONLY_FIRST); - - return this.a(entity, voxelshape2, voxelshape, set); - } - - default Stream b(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { - return this.a(entity, VoxelShapes.a(axisalignedbb), VoxelShapes.a(), Collections.emptySet()); - } - - default Stream a(@Nullable Entity entity, VoxelShape voxelshape, VoxelShape voxelshape1, Set set) { - boolean flag = entity != null && entity.bG(); - boolean flag1 = entity != null && this.i(entity); - - if (entity != null && flag == flag1) { - entity.n(!flag1); - } - - return this.rayTrace(voxelshape, voxelshape1, flag1, entity); // Akarin - } - default boolean i(Entity entity) { - WorldBorder worldborder = this.getWorldBorder(); - double d0 = worldborder.b(); - double d1 = worldborder.c(); - double d2 = worldborder.d(); - double d3 = worldborder.e(); - - if (entity.bG()) { - ++d0; - ++d1; - --d2; - --d3; - } else { - --d0; - --d1; - ++d2; - ++d3; - } - - return entity.locX > d0 && entity.locX < d2 && entity.locZ > d1 && entity.locZ < d3; + return this.a(entity, VoxelShapes.a(entity.getBoundingBox())); } - default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { - return this.a(entity, VoxelShapes.a(axisalignedbb), VoxelShapes.a(), set).allMatch(VoxelShape::isEmpty); + default boolean c(AxisAlignedBB axisalignedbb) { + return this.b((Entity) null, axisalignedbb, Collections.emptySet()); } - default boolean getCubes(@Nullable Entity entity, AxisAlignedBB axisalignedbb) { - return this.a(entity, axisalignedbb, Collections.emptySet()); + default boolean getCubes(Entity entity) { + return this.b(entity, entity.getBoundingBox(), Collections.emptySet()); } - default boolean B(BlockPosition blockposition) { + default boolean getCubes(Entity entity, AxisAlignedBB axisalignedbb) { + return this.b(entity, axisalignedbb, Collections.emptySet()); + } + + default boolean b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { + return this.c(entity, axisalignedbb, set).allMatch(VoxelShape::isEmpty); + } + + default Stream a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { + return Stream.empty(); + } + + default Stream c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set set) { + return Streams.concat(new Stream[]{this.b(entity, axisalignedbb), this.a(entity, axisalignedbb, set)}); + } + + default Stream b(@Nullable final Entity entity, AxisAlignedBB axisalignedbb) { + int i = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 1; + int j = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 1; + int k = MathHelper.floor(axisalignedbb.minY - 1.0E-7D) - 1; + int l = MathHelper.floor(axisalignedbb.maxY + 1.0E-7D) + 1; + int i1 = MathHelper.floor(axisalignedbb.minZ - 1.0E-7D) - 1; + int j1 = MathHelper.floor(axisalignedbb.maxZ + 1.0E-7D) + 1; + final VoxelShapeCollision voxelshapecollision = entity == null ? VoxelShapeCollision.a() : VoxelShapeCollision.a(entity); + final CursorPosition cursorposition = new CursorPosition(i, k, i1, j, l, j1); + final BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + final VoxelShape voxelshape = VoxelShapes.a(axisalignedbb); + + return StreamSupport.stream(new AbstractSpliterator(Long.MAX_VALUE, 1280) { + boolean a = entity == null; + + public boolean tryAdvance(Consumer consumer) { + if (!this.a) { + this.a = true; + VoxelShape voxelshape1 = IWorldReader.this.getWorldBorder().a(); + boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND); + boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND); + + if (!flag && flag1) { + consumer.accept(voxelshape1); + return true; + } + } + + while (cursorposition.a()) { + int k1 = cursorposition.b(); + int l1 = cursorposition.c(); + int i2 = cursorposition.d(); + int j2 = cursorposition.e(); + + if (j2 != 3) { + int k2 = k1 >> 4; + int l2 = i2 >> 4; + IChunkAccess ichunkaccess = IWorldReader.this.getChunkAt(k2, l2, IWorldReader.this.O(), false); + + if (ichunkaccess != null) { + blockposition_mutableblockposition.d(k1, l1, i2); + IBlockData iblockdata = ichunkaccess.getType(blockposition_mutableblockposition); + + if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { + VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) IWorldReader.this, blockposition_mutableblockposition, voxelshapecollision); + VoxelShape voxelshape3 = voxelshape2.a((double) k1, (double) l1, (double) i2); + + if (VoxelShapes.c(voxelshape, voxelshape3, OperatorBoolean.AND)) { + consumer.accept(voxelshape3); + return true; + } + } + } + } + } + + return false; + } + }, false); + } + + default boolean x(BlockPosition blockposition) { return this.getFluid(blockposition).a(TagsFluid.WATER); } @@ -266,9 +197,9 @@ public interface IWorldReader extends IBlockAccess { for (int k1 = i; k1 < j; ++k1) { for (int l1 = k; l1 < l; ++l1) { for (int i2 = i1; i2 < j1; ++i2) { - IBlockData iblockdata = this.getType(blockposition_pooledblockposition.c(k1, l1, i2)); + IBlockData iblockdata = this.getType(blockposition_pooledblockposition.d(k1, l1, i2)); - if (!iblockdata.s().e()) { + if (!iblockdata.p().isEmpty()) { boolean flag = true; return flag; @@ -302,72 +233,21 @@ public interface IWorldReader extends IBlockAccess { } default int d(BlockPosition blockposition, int i) { - if (blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000) { - if (this.getType(blockposition).c(this, blockposition)) { - int j = this.getLightLevel(blockposition.up(), i); - int k = this.getLightLevel(blockposition.east(), i); - int l = this.getLightLevel(blockposition.west(), i); - int i1 = this.getLightLevel(blockposition.south(), i); - int j1 = this.getLightLevel(blockposition.north(), i); - - if (k > j) { - j = k; - } - - if (l > j) { - j = l; - } - - if (i1 > j) { - j = i1; - } - - if (j1 > j) { - j = j1; - } - - return j; - } else { - return this.getLightLevel(blockposition, i); - } - } else { - return 15; - } + return blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000 ? this.getLightLevel(blockposition, i) : 15; } + @Deprecated default boolean isLoaded(BlockPosition blockposition) { - return this.b(blockposition, true); - } - - default boolean b(BlockPosition blockposition, boolean flag) { - return this.isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4, flag); - } - - default boolean areChunksLoaded(BlockPosition blockposition, int i) { - return this.areChunksLoaded(blockposition, i, true); - } - - default boolean areChunksLoaded(BlockPosition blockposition, int i, boolean flag) { - return this.isAreaLoaded(blockposition.getX() - i, blockposition.getY() - i, blockposition.getZ() - i, blockposition.getX() + i, blockposition.getY() + i, blockposition.getZ() + i, flag); + return this.isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); } + @Deprecated default boolean areChunksLoadedBetween(BlockPosition blockposition, BlockPosition blockposition1) { - return this.areChunksLoadedBetween(blockposition, blockposition1, true); + return this.isAreaLoaded(blockposition.getX(), blockposition.getY(), blockposition.getZ(), blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); } - default boolean areChunksLoadedBetween(BlockPosition blockposition, BlockPosition blockposition1, boolean flag) { - return this.isAreaLoaded(blockposition.getX(), blockposition.getY(), blockposition.getZ(), blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), flag); - } - - default boolean a(StructureBoundingBox structureboundingbox) { - return this.a(structureboundingbox, true); - } - - default boolean a(StructureBoundingBox structureboundingbox, boolean flag) { - return this.isAreaLoaded(structureboundingbox.a, structureboundingbox.b, structureboundingbox.c, structureboundingbox.d, structureboundingbox.e, structureboundingbox.f, flag); - } - - default boolean isAreaLoaded(int i, int j, int k, int l, int i1, int j1, boolean flag) { + @Deprecated + default boolean isAreaLoaded(int i, int j, int k, int l, int i1, int j1) { if (i1 >= 0 && j < 256) { i >>= 4; k >>= 4; @@ -376,7 +256,7 @@ public interface IWorldReader extends IBlockAccess { for (int k1 = i; k1 <= l; ++k1) { for (int l1 = k; l1 <= j1; ++l1) { - if (!this.isChunkLoaded(k1, l1, flag)) { + if (!this.isChunkLoaded(k1, l1)) { return false; } } @@ -388,5 +268,5 @@ public interface IWorldReader extends IBlockAccess { } } - WorldProvider o(); + WorldProvider getWorldProvider(); } diff --git a/src/main/java/net/minecraft/server/IWorldWriter.java b/src/main/java/net/minecraft/server/IWorldWriter.java index 028e9fe25..38cb1d6e3 100644 --- a/src/main/java/net/minecraft/server/IWorldWriter.java +++ b/src/main/java/net/minecraft/server/IWorldWriter.java @@ -4,13 +4,17 @@ public interface IWorldWriter { boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i); - boolean addEntity(Entity entity); + boolean a(BlockPosition blockposition, boolean flag); - boolean addEntity(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason); // CraftBukkit + boolean b(BlockPosition blockposition, boolean flag); - boolean setAir(BlockPosition blockposition); + default boolean addEntity(Entity entity) { + return false; + } - void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i); - - boolean setAir(BlockPosition blockposition, boolean flag); + // CraftBukkit start + default boolean addEntity(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { + return false; + } + // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/IntHashMap.java b/src/main/java/net/minecraft/server/IntHashMap.java deleted file mode 100644 index 093a37c3b..000000000 --- a/src/main/java/net/minecraft/server/IntHashMap.java +++ /dev/null @@ -1,243 +0,0 @@ -package net.minecraft.server; - -import javax.annotation.Nullable; - -import com.koloboke.collect.map.hash.HashIntObjMap; -import com.koloboke.collect.map.hash.HashIntObjMaps; - -public class IntHashMap { - - private final HashIntObjMap map = HashIntObjMaps.newMutableMap(); // Akarin - @Deprecated private transient IntHashMap.IntHashMapEntry[] a = (IntHashMap.IntHashMapEntry[]) (new IntHashMap.IntHashMapEntry[16]); // Akarin - @Deprecated private transient int b; // Akarin - @Deprecated private int c = 12; // Akarin - private final float d = 0.75F; - - public IntHashMap() {} - - @Deprecated // Akarin - private static int g(int i) { - i ^= i >>> 20 ^ i >>> 12; - return i ^ i >>> 7 ^ i >>> 4; - } - - @Deprecated // Akarin - private static int a(int i, int j) { - return i & j - 1; - } - - @Nullable - public V get(int i) { - // Akarin start - /* - int j = g(i); - - for (IntHashMap.IntHashMapEntry inthashmap_inthashmapentry = this.a[a(j, this.a.length)]; inthashmap_inthashmapentry != null; inthashmap_inthashmapentry = inthashmap_inthashmapentry.c) { - if (inthashmap_inthashmapentry.a == i) { - return (V) inthashmap_inthashmapentry.b; - } - } - - return null; - */ - return map.get(i); - // Akarin end - } - - public boolean b(int i) { - return map.containsKey(i); // Akarin - } - - @Nullable - @Deprecated // Akarin - final IntHashMap.IntHashMapEntry c(int i) { - int j = g(i); - - for (IntHashMap.IntHashMapEntry inthashmap_inthashmapentry = this.a[a(j, this.a.length)]; inthashmap_inthashmapentry != null; inthashmap_inthashmapentry = inthashmap_inthashmapentry.c) { - if (inthashmap_inthashmapentry.a == i) { - return inthashmap_inthashmapentry; - } - } - - return null; - } - - public void a(int i, V v0) { - // Akarin start - /* - int j = g(i); - int k = a(j, this.a.length); - - for (IntHashMap.IntHashMapEntry inthashmap_inthashmapentry = this.a[k]; inthashmap_inthashmapentry != null; inthashmap_inthashmapentry = inthashmap_inthashmapentry.c) { - if (inthashmap_inthashmapentry.a == i) { - inthashmap_inthashmapentry.b = v0; - return; - } - } - - this.a(j, i, v0, k); - */ - map.put(i, v0); - // Akarin end - } - - @Deprecated // Akarin - private void h(int i) { - IntHashMap.IntHashMapEntry[] ainthashmap_inthashmapentry = this.a; - int j = ainthashmap_inthashmapentry.length; - - if (j == 1073741824) { - this.c = Integer.MAX_VALUE; - } else { - IntHashMap.IntHashMapEntry[] ainthashmap_inthashmapentry1 = (IntHashMap.IntHashMapEntry[]) (new IntHashMap.IntHashMapEntry[i]); - - this.a(ainthashmap_inthashmapentry1); - this.a = ainthashmap_inthashmapentry1; - this.c = (int) ((float) i * this.d); - } - } - - @Deprecated // Akarin - private void a(IntHashMap.IntHashMapEntry[] ainthashmap_inthashmapentry) { - IntHashMap.IntHashMapEntry[] ainthashmap_inthashmapentry1 = this.a; - int i = ainthashmap_inthashmapentry.length; - - for (int j = 0; j < ainthashmap_inthashmapentry1.length; ++j) { - IntHashMap.IntHashMapEntry inthashmap_inthashmapentry = ainthashmap_inthashmapentry1[j]; - - if (inthashmap_inthashmapentry != null) { - ainthashmap_inthashmapentry1[j] = null; - - IntHashMap.IntHashMapEntry inthashmap_inthashmapentry1; - - do { - inthashmap_inthashmapentry1 = inthashmap_inthashmapentry.c; - int k = a(inthashmap_inthashmapentry.d, i); - - inthashmap_inthashmapentry.c = ainthashmap_inthashmapentry[k]; - ainthashmap_inthashmapentry[k] = inthashmap_inthashmapentry; - inthashmap_inthashmapentry = inthashmap_inthashmapentry1; - } while (inthashmap_inthashmapentry1 != null); - } - } - - } - - @Nullable - public V d(int i) { - // Akarin start - /* - IntHashMap.IntHashMapEntry inthashmap_inthashmapentry = this.e(i); - - return inthashmap_inthashmapentry == null ? null : inthashmap_inthashmapentry.b; - */ - return map.remove(i); - // Akarin end - } - - @Nullable - @Deprecated // Akarin - final IntHashMap.IntHashMapEntry e(int i) { - int j = g(i); - int k = a(j, this.a.length); - IntHashMap.IntHashMapEntry inthashmap_inthashmapentry = this.a[k]; - - IntHashMap.IntHashMapEntry inthashmap_inthashmapentry1; - IntHashMap.IntHashMapEntry inthashmap_inthashmapentry2; - - for (inthashmap_inthashmapentry2 = inthashmap_inthashmapentry; inthashmap_inthashmapentry2 != null; inthashmap_inthashmapentry2 = inthashmap_inthashmapentry1) { - inthashmap_inthashmapentry1 = inthashmap_inthashmapentry2.c; - if (inthashmap_inthashmapentry2.a == i) { - --this.b; - if (inthashmap_inthashmapentry == inthashmap_inthashmapentry2) { - this.a[k] = inthashmap_inthashmapentry1; - } else { - inthashmap_inthashmapentry.c = inthashmap_inthashmapentry1; - } - - return inthashmap_inthashmapentry2; - } - - inthashmap_inthashmapentry = inthashmap_inthashmapentry2; - } - - return inthashmap_inthashmapentry2; - } - - public void c() { - // Akarin start - /* - IntHashMap.IntHashMapEntry[] ainthashmap_inthashmapentry = this.a; - - for (int i = 0; i < ainthashmap_inthashmapentry.length; ++i) { - ainthashmap_inthashmapentry[i] = null; - } - - this.b = 0; - */ - map.clear(); - // Akarin end - } - - @Deprecated // Akarin - private void a(int i, int j, V v0, int k) { - IntHashMap.IntHashMapEntry inthashmap_inthashmapentry = this.a[k]; - - this.a[k] = new IntHashMap.IntHashMapEntry<>(i, j, v0, inthashmap_inthashmapentry); - if (this.b++ >= this.c) { - this.h(2 * this.a.length); - } - - } - - @Deprecated // Akarin - static class IntHashMapEntry { - - private final int a; - private V b; - private IntHashMap.IntHashMapEntry c; - private final int d; - - IntHashMapEntry(int i, int j, V v0, IntHashMap.IntHashMapEntry inthashmap_inthashmapentry) { - this.b = v0; - this.c = inthashmap_inthashmapentry; - this.a = j; - this.d = i; - } - - public final int a() { - return this.a; - } - - public final V b() { - return this.b; - } - - public final boolean equals(Object object) { - if (!(object instanceof IntHashMap.IntHashMapEntry)) { - return false; - } else { - IntHashMap.IntHashMapEntry inthashmap_inthashmapentry = (IntHashMap.IntHashMapEntry) object; - - if (this.a == inthashmap_inthashmapentry.a) { - Object object1 = this.b(); - Object object2 = inthashmap_inthashmapentry.b(); - - if (object1 == object2 || object1 != null && object1.equals(object2)) { - return true; - } - } - - return false; - } - } - - public final int hashCode() { - return IntHashMap.g(this.a); - } - - public final String toString() { - return this.a() + "=" + this.b(); - } - } -} diff --git a/src/main/java/net/minecraft/server/InventoryCraftResult.java b/src/main/java/net/minecraft/server/InventoryCraftResult.java index ce8fa1c97..06c0bc5b1 100644 --- a/src/main/java/net/minecraft/server/InventoryCraftResult.java +++ b/src/main/java/net/minecraft/server/InventoryCraftResult.java @@ -11,7 +11,7 @@ import org.bukkit.entity.HumanEntity; public class InventoryCraftResult implements IInventory, RecipeHolder { private final NonNullList items; - private IRecipe b; + private IRecipe b; // CraftBukkit start private int maxStack = MAX_STACK; @@ -31,6 +31,11 @@ public class InventoryCraftResult implements IInventory, RecipeHolder { return new java.util.ArrayList(); } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; } @@ -45,11 +50,13 @@ public class InventoryCraftResult implements IInventory, RecipeHolder { this.items = NonNullList.a(1, ItemStack.a); } + @Override public int getSize() { return 1; } - public boolean P_() { + @Override + public boolean isNotEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -65,73 +72,47 @@ public class InventoryCraftResult implements IInventory, RecipeHolder { return false; } + @Override public ItemStack getItem(int i) { return (ItemStack) this.items.get(0); } - public IChatBaseComponent getDisplayName() { - return new ChatComponentText("Result"); - } - - public boolean hasCustomName() { - return false; - } - - @Nullable - public IChatBaseComponent getCustomName() { - return null; - } - + @Override public ItemStack splitStack(int i, int j) { return ContainerUtil.a(this.items, 0); } + @Override public ItemStack splitWithoutUpdate(int i) { return ContainerUtil.a(this.items, 0); } + @Override public void setItem(int i, ItemStack itemstack) { this.items.set(0, itemstack); } - public int getMaxStackSize() { - return maxStack; // CraftBukkit - } - + @Override public void update() {} + @Override public boolean a(EntityHuman entityhuman) { return true; } - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - - public boolean b(int i, ItemStack itemstack) { - return true; - } - - public int getProperty(int i) { - return 0; - } - - public void setProperty(int i, int j) {} - - public int h() { - return 0; - } - + @Override public void clear() { this.items.clear(); } - public void a(@Nullable IRecipe irecipe) { + @Override + public void a(@Nullable IRecipe irecipe) { this.b = irecipe; } @Nullable - public IRecipe i() { + @Override + public IRecipe U_() { return this.b; } } diff --git a/src/main/java/net/minecraft/server/InventoryCrafting.java b/src/main/java/net/minecraft/server/InventoryCrafting.java index e9c798e0c..e02de1985 100644 --- a/src/main/java/net/minecraft/server/InventoryCrafting.java +++ b/src/main/java/net/minecraft/server/InventoryCrafting.java @@ -1,7 +1,6 @@ package net.minecraft.server; import java.util.Iterator; -import javax.annotation.Nullable; // CraftBukkit start import java.util.List; import org.bukkit.Location; @@ -49,6 +48,11 @@ public class InventoryCrafting implements IInventory, AutoRecipeOutput { return (owner == null) ? null : owner.getBukkitEntity(); } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; resultInventory.setMaxStackSize(size); @@ -56,7 +60,7 @@ public class InventoryCrafting implements IInventory, AutoRecipeOutput { @Override public Location getLocation() { - return owner.getBukkitEntity().getLocation(); + return container instanceof ContainerWorkbench ? ((ContainerWorkbench) container).containerAccess.getLocation() : owner.getBukkitEntity().getLocation(); } @Override @@ -82,11 +86,13 @@ public class InventoryCrafting implements IInventory, AutoRecipeOutput { this.c = j; } + @Override public int getSize() { return this.items.size(); } - public boolean P_() { + @Override + public boolean isNotEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -102,27 +108,17 @@ public class InventoryCrafting implements IInventory, AutoRecipeOutput { return false; } + @Override public ItemStack getItem(int i) { return i >= this.getSize() ? ItemStack.a : (ItemStack) this.items.get(i); } - public IChatBaseComponent getDisplayName() { - return new ChatMessage("container.crafting", new Object[0]); - } - - public boolean hasCustomName() { - return false; - } - - @Nullable - public IChatBaseComponent getCustomName() { - return null; - } - + @Override public ItemStack splitWithoutUpdate(int i) { return ContainerUtil.a(this.items, i); } + @Override public ItemStack splitStack(int i, int j) { ItemStack itemstack = ContainerUtil.a(this.items, i, j); @@ -133,51 +129,34 @@ public class InventoryCrafting implements IInventory, AutoRecipeOutput { return itemstack; } + @Override public void setItem(int i, ItemStack itemstack) { this.items.set(i, itemstack); this.container.a((IInventory) this); } - public int getMaxStackSize() { - return 64; - } - + @Override public void update() {} + @Override public boolean a(EntityHuman entityhuman) { return true; } - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - - public boolean b(int i, ItemStack itemstack) { - return true; - } - - public int getProperty(int i) { - return 0; - } - - public void setProperty(int i, int j) {} - - public int h() { - return 0; - } - + @Override public void clear() { this.items.clear(); } - public int n() { + public int f() { return this.c; } - public int U_() { + public int g() { return this.b; } + @Override public void a(AutoRecipeStackManager autorecipestackmanager) { Iterator iterator = this.items.iterator(); diff --git a/src/main/java/net/minecraft/server/InventoryEnderChest.java b/src/main/java/net/minecraft/server/InventoryEnderChest.java index f50bae012..fd31b9a6d 100644 --- a/src/main/java/net/minecraft/server/InventoryEnderChest.java +++ b/src/main/java/net/minecraft/server/InventoryEnderChest.java @@ -20,7 +20,7 @@ public class InventoryEnderChest extends InventorySubcontainer { } public InventoryEnderChest(EntityHuman owner) { - super(new ChatMessage("container.enderchest", new Object[0]), 27); + super(27); this.owner = owner; // CraftBukkit end } @@ -47,7 +47,7 @@ public class InventoryEnderChest extends InventorySubcontainer { } - public NBTTagList i() { + public NBTTagList f() { NBTTagList nbttaglist = new NBTTagList(); for (int i = 0; i < this.getSize(); ++i) { @@ -58,28 +58,31 @@ public class InventoryEnderChest extends InventorySubcontainer { nbttagcompound.setByte("Slot", (byte) i); itemstack.save(nbttagcompound); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); } } return nbttaglist; } + @Override public boolean a(EntityHuman entityhuman) { return this.a != null && !this.a.a(entityhuman) ? false : super.a(entityhuman); } + @Override public void startOpen(EntityHuman entityhuman) { if (this.a != null) { - this.a.c(); + this.a.d(); } super.startOpen(entityhuman); } + @Override public void closeContainer(EntityHuman entityhuman) { if (this.a != null) { - this.a.d(); + this.a.f(); } super.closeContainer(entityhuman); diff --git a/src/main/java/net/minecraft/server/InventoryHorseChest.java b/src/main/java/net/minecraft/server/InventoryHorseChest.java deleted file mode 100644 index b9dd2ad5a..000000000 --- a/src/main/java/net/minecraft/server/InventoryHorseChest.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.minecraft.server; - -public class InventoryHorseChest extends InventorySubcontainer { - - // CraftBukkit start - public InventoryHorseChest(IChatBaseComponent ichatbasecomponent, int i, EntityHorseAbstract owner) { - super(ichatbasecomponent, i, (org.bukkit.entity.AbstractHorse) owner.getBukkitEntity()); - // CraftBukkit end - } -} diff --git a/src/main/java/net/minecraft/server/InventoryLargeChest.java b/src/main/java/net/minecraft/server/InventoryLargeChest.java index cfc3bef8f..d4c39f0b3 100644 --- a/src/main/java/net/minecraft/server/InventoryLargeChest.java +++ b/src/main/java/net/minecraft/server/InventoryLargeChest.java @@ -1,6 +1,5 @@ package net.minecraft.server; -import javax.annotation.Nullable; // CraftBukkit start import java.util.ArrayList; import java.util.List; @@ -10,11 +9,10 @@ import org.bukkit.craftbukkit.entity.CraftHumanEntity; import org.bukkit.entity.HumanEntity; // CraftBukkit end -public class InventoryLargeChest implements ITileInventory { +public class InventoryLargeChest implements IInventory { - private final IChatBaseComponent a; - public final ITileInventory left; - public final ITileInventory right; + public final IInventory left; + public final IInventory right; // CraftBukkit start - add fields and methods public List transaction = new java.util.ArrayList(); @@ -58,63 +56,49 @@ public class InventoryLargeChest implements ITileInventory { } // CraftBukkit end - public InventoryLargeChest(IChatBaseComponent ichatbasecomponent, ITileInventory itileinventory, ITileInventory itileinventory1) { - this.a = ichatbasecomponent; - if (itileinventory == null) { - itileinventory = itileinventory1; + public InventoryLargeChest(IInventory iinventory, IInventory iinventory1) { + if (iinventory == null) { + iinventory = iinventory1; } - if (itileinventory1 == null) { - itileinventory1 = itileinventory; - } - - this.left = itileinventory; - this.right = itileinventory1; - if (itileinventory.isLocked()) { - itileinventory1.setLock(itileinventory.getLock()); - } else if (itileinventory1.isLocked()) { - itileinventory.setLock(itileinventory1.getLock()); + if (iinventory1 == null) { + iinventory1 = iinventory; } + this.left = iinventory; + this.right = iinventory1; } + @Override public int getSize() { return this.left.getSize() + this.right.getSize(); } - public boolean P_() { - return this.left.P_() && this.right.P_(); + @Override + public boolean isNotEmpty() { + return this.left.isNotEmpty() && this.right.isNotEmpty(); } public boolean a(IInventory iinventory) { return this.left == iinventory || this.right == iinventory; } - public IChatBaseComponent getDisplayName() { - return this.left.hasCustomName() ? this.left.getDisplayName() : (this.right.hasCustomName() ? this.right.getDisplayName() : this.a); - } - - public boolean hasCustomName() { - return this.left.hasCustomName() || this.right.hasCustomName(); - } - - @Nullable - public IChatBaseComponent getCustomName() { - return this.left.hasCustomName() ? this.left.getCustomName() : this.right.getCustomName(); - } - + @Override public ItemStack getItem(int i) { return i >= this.left.getSize() ? this.right.getItem(i - this.left.getSize()) : this.left.getItem(i); } + @Override public ItemStack splitStack(int i, int j) { return i >= this.left.getSize() ? this.right.splitStack(i - this.left.getSize(), j) : this.left.splitStack(i, j); } + @Override public ItemStack splitWithoutUpdate(int i) { return i >= this.left.getSize() ? this.right.splitWithoutUpdate(i - this.left.getSize()) : this.left.splitWithoutUpdate(i); } + @Override public void setItem(int i, ItemStack itemstack) { if (i >= this.left.getSize()) { this.right.setItem(i - this.left.getSize(), itemstack); @@ -124,64 +108,40 @@ public class InventoryLargeChest implements ITileInventory { } + @Override public int getMaxStackSize() { return Math.min(this.left.getMaxStackSize(), this.right.getMaxStackSize()); // CraftBukkit - check both sides } + @Override public void update() { this.left.update(); this.right.update(); } + @Override public boolean a(EntityHuman entityhuman) { return this.left.a(entityhuman) && this.right.a(entityhuman); } + @Override public void startOpen(EntityHuman entityhuman) { this.left.startOpen(entityhuman); this.right.startOpen(entityhuman); } + @Override public void closeContainer(EntityHuman entityhuman) { this.left.closeContainer(entityhuman); this.right.closeContainer(entityhuman); } + @Override public boolean b(int i, ItemStack itemstack) { - return true; - } - - public int getProperty(int i) { - return 0; - } - - public void setProperty(int i, int j) {} - - public int h() { - return 0; - } - - public boolean isLocked() { - return this.left.isLocked() || this.right.isLocked(); - } - - public void setLock(ChestLock chestlock) { - this.left.setLock(chestlock); - this.right.setLock(chestlock); - } - - public ChestLock getLock() { - return this.left.getLock(); - } - - public String getContainerName() { - return this.left.getContainerName(); - } - - public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { - return new ContainerChest(playerinventory, this, entityhuman); + return i >= this.left.getSize() ? this.right.b(i - this.left.getSize(), itemstack) : this.left.b(i, itemstack); } + @Override public void clear() { this.left.clear(); this.right.clear(); diff --git a/src/main/java/net/minecraft/server/InventoryMerchant.java b/src/main/java/net/minecraft/server/InventoryMerchant.java index 7335f8c22..26d7bad5c 100644 --- a/src/main/java/net/minecraft/server/InventoryMerchant.java +++ b/src/main/java/net/minecraft/server/InventoryMerchant.java @@ -6,7 +6,7 @@ import javax.annotation.Nullable; import java.util.List; import org.bukkit.Location; import org.bukkit.craftbukkit.entity.CraftHumanEntity; -import org.bukkit.craftbukkit.entity.CraftVillager; +import org.bukkit.craftbukkit.entity.CraftAbstractVillager; import org.bukkit.entity.HumanEntity; // CraftBukkit end @@ -14,9 +14,10 @@ public class InventoryMerchant implements IInventory { private final IMerchant merchant; private final NonNullList itemsInSlots; - private final EntityHuman player; + @Nullable private MerchantRecipe recipe; public int selectedIndex; + private int e; // CraftBukkit start - add fields and methods public List transaction = new java.util.ArrayList(); @@ -32,18 +33,24 @@ public class InventoryMerchant implements IInventory { public void onClose(CraftHumanEntity who) { transaction.remove(who); + merchant.setTradingPlayer((EntityHuman) null); // SPIGOT-4860 } public List getViewers() { return transaction; } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int i) { maxStack = i; } public org.bukkit.inventory.InventoryHolder getOwner() { - return (merchant instanceof EntityVillager) ? (CraftVillager) ((EntityVillager) this.merchant).getBukkitEntity() : null; + return (merchant instanceof EntityVillagerAbstract) ? (CraftAbstractVillager) ((EntityVillagerAbstract) this.merchant).getBukkitEntity() : null; } @Override @@ -52,17 +59,18 @@ public class InventoryMerchant implements IInventory { } // CraftBukkit end - public InventoryMerchant(EntityHuman entityhuman, IMerchant imerchant) { + public InventoryMerchant(IMerchant imerchant) { this.itemsInSlots = NonNullList.a(3, ItemStack.a); - this.player = entityhuman; this.merchant = imerchant; } + @Override public int getSize() { return this.itemsInSlots.size(); } - public boolean P_() { + @Override + public boolean isNotEmpty() { Iterator iterator = this.itemsInSlots.iterator(); ItemStack itemstack; @@ -78,10 +86,12 @@ public class InventoryMerchant implements IInventory { return false; } + @Override public ItemStack getItem(int i) { return (ItemStack) this.itemsInSlots.get(i); } + @Override public ItemStack splitStack(int i, int j) { ItemStack itemstack = (ItemStack) this.itemsInSlots.get(i); @@ -90,125 +100,98 @@ public class InventoryMerchant implements IInventory { } else { ItemStack itemstack1 = ContainerUtil.a(this.itemsInSlots, i, j); - if (!itemstack1.isEmpty() && this.e(i)) { - this.i(); + if (!itemstack1.isEmpty() && this.d(i)) { + this.f(); } return itemstack1; } } - private boolean e(int i) { + private boolean d(int i) { return i == 0 || i == 1; } + @Override public ItemStack splitWithoutUpdate(int i) { return ContainerUtil.a(this.itemsInSlots, i); } + @Override public void setItem(int i, ItemStack itemstack) { this.itemsInSlots.set(i, itemstack); if (!itemstack.isEmpty() && itemstack.getCount() > this.getMaxStackSize()) { itemstack.setCount(this.getMaxStackSize()); } - if (this.e(i)) { - this.i(); + if (this.d(i)) { + this.f(); } } - public IChatBaseComponent getDisplayName() { - return merchant.getScoreboardDisplayName(); // CraftBukkit - } - - public boolean hasCustomName() { - return false; - } - - @Nullable - public IChatBaseComponent getCustomName() { - return null; - } - - public int getMaxStackSize() { - return maxStack; // CraftBukkit - } - + @Override public boolean a(EntityHuman entityhuman) { return this.merchant.getTrader() == entityhuman; } - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - - public boolean b(int i, ItemStack itemstack) { - return true; - } - + @Override public void update() { - this.i(); + this.f(); } - public void i() { + public void f() { this.recipe = null; - ItemStack itemstack = (ItemStack) this.itemsInSlots.get(0); - ItemStack itemstack1 = (ItemStack) this.itemsInSlots.get(1); + ItemStack itemstack; + ItemStack itemstack1; - if (itemstack.isEmpty()) { - itemstack = itemstack1; + if (((ItemStack) this.itemsInSlots.get(0)).isEmpty()) { + itemstack = (ItemStack) this.itemsInSlots.get(1); itemstack1 = ItemStack.a; + } else { + itemstack = (ItemStack) this.itemsInSlots.get(0); + itemstack1 = (ItemStack) this.itemsInSlots.get(1); } if (itemstack.isEmpty()) { this.setItem(2, ItemStack.a); + this.e = 0; } else { - MerchantRecipeList merchantrecipelist = this.merchant.getOffers(this.player); + MerchantRecipeList merchantrecipelist = this.merchant.getOffers(); - if (merchantrecipelist != null) { + if (!merchantrecipelist.isEmpty()) { MerchantRecipe merchantrecipe = merchantrecipelist.a(itemstack, itemstack1, this.selectedIndex); - if (merchantrecipe != null && !merchantrecipe.h()) { + if (merchantrecipe == null || merchantrecipe.isFullyUsed()) { this.recipe = merchantrecipe; - this.setItem(2, merchantrecipe.getBuyItem3().cloneItemStack()); - } else if (!itemstack1.isEmpty()) { merchantrecipe = merchantrecipelist.a(itemstack1, itemstack, this.selectedIndex); - if (merchantrecipe != null && !merchantrecipe.h()) { - this.recipe = merchantrecipe; - this.setItem(2, merchantrecipe.getBuyItem3().cloneItemStack()); - } else { - this.setItem(2, ItemStack.a); - } + } + + if (merchantrecipe != null && !merchantrecipe.isFullyUsed()) { + this.recipe = merchantrecipe; + this.setItem(2, merchantrecipe.f()); + this.e = merchantrecipe.getXp(); } else { this.setItem(2, ItemStack.a); + this.e = 0; } } - this.merchant.a(this.getItem(2)); + this.merchant.i(this.getItem(2)); } - } + @Nullable public MerchantRecipe getRecipe() { return this.recipe; } - public void d(int i) { + public void c(int i) { this.selectedIndex = i; - this.i(); - } - - public int getProperty(int i) { - return 0; - } - - public void setProperty(int i, int j) {} - - public int h() { - return 0; + this.f(); } + @Override public void clear() { this.itemsInSlots.clear(); } diff --git a/src/main/java/net/minecraft/server/InventorySubcontainer.java b/src/main/java/net/minecraft/server/InventorySubcontainer.java index 126929eea..af84469d9 100644 --- a/src/main/java/net/minecraft/server/InventorySubcontainer.java +++ b/src/main/java/net/minecraft/server/InventorySubcontainer.java @@ -3,10 +3,9 @@ package net.minecraft.server; import com.google.common.collect.Lists; import java.util.Iterator; import java.util.List; -import javax.annotation.Nullable; +import java.util.stream.Collectors; // CraftBukkit start -import java.util.List; import org.bukkit.Location; import org.bukkit.craftbukkit.entity.CraftHumanEntity; import org.bukkit.entity.HumanEntity; @@ -14,11 +13,9 @@ import org.bukkit.entity.HumanEntity; public class InventorySubcontainer implements IInventory, AutoRecipeOutput { - private final IChatBaseComponent a; - private final int b; + private final int a; public final NonNullList items; - private List d; - private IChatBaseComponent e; + private List c; // CraftBukkit start - add fields and methods public List transaction = new java.util.ArrayList(); @@ -41,6 +38,11 @@ public class InventorySubcontainer implements IInventory, AutoRecipeOutput { return transaction; } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int i) { maxStack = i; } @@ -54,34 +56,40 @@ public class InventorySubcontainer implements IInventory, AutoRecipeOutput { return null; } - public InventorySubcontainer(IChatBaseComponent ichatbasecomponent, int i) { - this(ichatbasecomponent, i, null); + public InventorySubcontainer(int i) { + this(i, null); } - public InventorySubcontainer(IChatBaseComponent ichatbasecomponent, int i, org.bukkit.inventory.InventoryHolder owner) { + public InventorySubcontainer(int i, org.bukkit.inventory.InventoryHolder owner) { this.bukkitOwner = owner; // CraftBukkit end - this.a = ichatbasecomponent; - this.b = i; + this.a = i; this.items = NonNullList.a(i, ItemStack.a); } + public InventorySubcontainer(ItemStack... aitemstack) { + this.a = aitemstack.length; + this.items = NonNullList.a(ItemStack.a, aitemstack); + } + public void a(IInventoryListener iinventorylistener) { - if (this.d == null) { - this.d = Lists.newArrayList(); + if (this.c == null) { + this.c = Lists.newArrayList(); } - this.d.add(iinventorylistener); + this.c.add(iinventorylistener); } public void b(IInventoryListener iinventorylistener) { - this.d.remove(iinventorylistener); + this.c.remove(iinventorylistener); } + @Override public ItemStack getItem(int i) { return i >= 0 && i < this.items.size() ? (ItemStack) this.items.get(i) : ItemStack.a; } + @Override public ItemStack splitStack(int i, int j) { ItemStack itemstack = ContainerUtil.a(this.items, i, j); @@ -92,40 +100,43 @@ public class InventorySubcontainer implements IInventory, AutoRecipeOutput { return itemstack; } + public ItemStack a(Item item, int i) { + ItemStack itemstack = new ItemStack(item, 0); + + for (int j = this.a - 1; j >= 0; --j) { + ItemStack itemstack1 = this.getItem(j); + + if (itemstack1.getItem().equals(item)) { + int k = i - itemstack.getCount(); + ItemStack itemstack2 = itemstack1.cloneAndSubtract(k); + + itemstack.add(itemstack2.getCount()); + if (itemstack.getCount() == i) { + break; + } + } + } + + if (!itemstack.isEmpty()) { + this.update(); + } + + return itemstack; + } + public ItemStack a(ItemStack itemstack) { ItemStack itemstack1 = itemstack.cloneItemStack(); - for (int i = 0; i < this.b; ++i) { - ItemStack itemstack2 = this.getItem(i); - - if (itemstack2.isEmpty()) { - this.setItem(i, itemstack1); - this.update(); - return ItemStack.a; - } - - if (ItemStack.c(itemstack2, itemstack1)) { - int j = Math.min(this.getMaxStackSize(), itemstack2.getMaxStackSize()); - int k = Math.min(itemstack1.getCount(), j - itemstack2.getCount()); - - if (k > 0) { - itemstack2.add(k); - itemstack1.subtract(k); - if (itemstack1.isEmpty()) { - this.update(); - return ItemStack.a; - } - } - } + this.c(itemstack1); + if (itemstack1.isEmpty()) { + return ItemStack.a; + } else { + this.b(itemstack1); + return itemstack1.isEmpty() ? ItemStack.a : itemstack1; } - - if (itemstack1.getCount() != itemstack.getCount()) { - this.update(); - } - - return itemstack1; } + @Override public ItemStack splitWithoutUpdate(int i) { ItemStack itemstack = (ItemStack) this.items.get(i); @@ -137,6 +148,7 @@ public class InventorySubcontainer implements IInventory, AutoRecipeOutput { } } + @Override public void setItem(int i, ItemStack itemstack) { this.items.set(i, itemstack); if (!itemstack.isEmpty() && itemstack.getCount() > this.getMaxStackSize()) { @@ -146,11 +158,13 @@ public class InventorySubcontainer implements IInventory, AutoRecipeOutput { this.update(); } + @Override public int getSize() { - return this.b; + return this.a; } - public boolean P_() { + @Override + public boolean isNotEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -166,62 +180,32 @@ public class InventorySubcontainer implements IInventory, AutoRecipeOutput { return false; } - public IChatBaseComponent getDisplayName() { - return this.e != null ? this.e : this.a; - } - - @Nullable - public IChatBaseComponent getCustomName() { - return this.e; - } - - public boolean hasCustomName() { - return this.e != null; - } - - public void a(@Nullable IChatBaseComponent ichatbasecomponent) { - this.e = ichatbasecomponent; - } - - public int getMaxStackSize() { - return 64; - } - + @Override public void update() { - if (this.d != null) { - for (int i = 0; i < this.d.size(); ++i) { - ((IInventoryListener) this.d.get(i)).a(this); + if (this.c != null) { + Iterator iterator = this.c.iterator(); + + while (iterator.hasNext()) { + IInventoryListener iinventorylistener = (IInventoryListener) iterator.next(); + + iinventorylistener.a(this); } } } + @Override public boolean a(EntityHuman entityhuman) { return true; } - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - - public boolean b(int i, ItemStack itemstack) { - return true; - } - - public int getProperty(int i) { - return 0; - } - - public void setProperty(int i, int j) {} - - public int h() { - return 0; - } - + @Override public void clear() { this.items.clear(); + this.update(); } + @Override public void a(AutoRecipeStackManager autorecipestackmanager) { Iterator iterator = this.items.iterator(); @@ -232,4 +216,49 @@ public class InventorySubcontainer implements IInventory, AutoRecipeOutput { } } + + public String toString() { + return ((List) this.items.stream().filter((itemstack) -> { + return !itemstack.isEmpty(); + }).collect(Collectors.toList())).toString(); + } + + private void b(ItemStack itemstack) { + for (int i = 0; i < this.a; ++i) { + ItemStack itemstack1 = this.getItem(i); + + if (itemstack1.isEmpty()) { + this.setItem(i, itemstack.cloneItemStack()); + itemstack.setCount(0); + return; + } + } + + } + + private void c(ItemStack itemstack) { + for (int i = 0; i < this.a; ++i) { + ItemStack itemstack1 = this.getItem(i); + + if (ItemStack.c(itemstack1, itemstack)) { + this.a(itemstack, itemstack1); + if (itemstack.isEmpty()) { + return; + } + } + } + + } + + private void a(ItemStack itemstack, ItemStack itemstack1) { + int i = Math.min(this.getMaxStackSize(), itemstack1.getMaxStackSize()); + int j = Math.min(itemstack.getCount(), i - itemstack1.getCount()); + + if (j > 0) { + itemstack1.add(j); + itemstack.subtract(j); + this.update(); + } + + } } diff --git a/src/main/java/net/minecraft/server/ItemArmor.java b/src/main/java/net/minecraft/server/ItemArmor.java index 60cd8392e..dec03e4ae 100644 --- a/src/main/java/net/minecraft/server/ItemArmor.java +++ b/src/main/java/net/minecraft/server/ItemArmor.java @@ -11,8 +11,9 @@ import org.bukkit.event.block.BlockDispenseArmorEvent; public class ItemArmor extends Item { - private static final UUID[] k = new UUID[] { UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150")}; + private static final UUID[] k = new UUID[]{UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150")}; public static final IDispenseBehavior a = new DispenseBehaviorItem() { + @Override protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { ItemStack itemstack1 = ItemArmor.a(isourceblock, itemstack); @@ -25,21 +26,21 @@ public class ItemArmor extends Item { protected final ArmorMaterial e; public static ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); + BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING)); List list = isourceblock.getWorld().a(EntityLiving.class, new AxisAlignedBB(blockposition), IEntitySelector.f.and(new IEntitySelector.EntitySelectorEquipable(itemstack))); if (list.isEmpty()) { return ItemStack.a; } else { EntityLiving entityliving = (EntityLiving) list.get(0); - EnumItemSlot enumitemslot = EntityInsentient.e(itemstack); + EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); ItemStack itemstack1 = itemstack.cloneAndSubtract(1); // CraftBukkit start World world = isourceblock.getWorld(); - org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); - BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) entityliving.bukkitEntity); + BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) entityliving.getBukkitEntity()); if (!BlockDispenser.eventFired) { world.getServer().getPluginManager().callEvent(event); } @@ -64,7 +65,7 @@ public class ItemArmor extends Item { entityliving.setSlot(enumitemslot, itemstack1); if (entityliving instanceof EntityInsentient) { ((EntityInsentient) entityliving).a(enumitemslot, 2.0F); - ((EntityInsentient) entityliving).di(); + ((EntityInsentient) entityliving).setPersistent(); } return itemstack; @@ -84,6 +85,7 @@ public class ItemArmor extends Item { return this.b; } + @Override public int c() { return this.e.a(); } @@ -92,13 +94,15 @@ public class ItemArmor extends Item { return this.e; } + @Override public boolean a(ItemStack itemstack, ItemStack itemstack1) { return this.e.c().test(itemstack1) || super.a(itemstack, itemstack1); } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); - EnumItemSlot enumitemslot = EntityInsentient.e(itemstack); + EnumItemSlot enumitemslot = EntityInsentient.h(itemstack); ItemStack itemstack1 = entityhuman.getEquipment(enumitemslot); if (itemstack1.isEmpty()) { @@ -110,12 +114,13 @@ public class ItemArmor extends Item { } } + @Override public Multimap a(EnumItemSlot enumitemslot) { Multimap multimap = super.a(enumitemslot); if (enumitemslot == this.b) { - multimap.put(GenericAttributes.h.getName(), new AttributeModifier(ItemArmor.k[enumitemslot.b()], "Armor modifier", (double) this.c, 0)); - multimap.put(GenericAttributes.i.getName(), new AttributeModifier(ItemArmor.k[enumitemslot.b()], "Armor toughness", (double) this.d, 0)); + multimap.put(GenericAttributes.ARMOR.getName(), new AttributeModifier(ItemArmor.k[enumitemslot.b()], "Armor modifier", (double) this.c, AttributeModifier.Operation.ADDITION)); + multimap.put(GenericAttributes.ARMOR_TOUGHNESS.getName(), new AttributeModifier(ItemArmor.k[enumitemslot.b()], "Armor toughness", (double) this.d, AttributeModifier.Operation.ADDITION)); } return multimap; diff --git a/src/main/java/net/minecraft/server/ItemArmorStand.java b/src/main/java/net/minecraft/server/ItemArmorStand.java index 4dd0e39ec..dfe932c16 100644 --- a/src/main/java/net/minecraft/server/ItemArmorStand.java +++ b/src/main/java/net/minecraft/server/ItemArmorStand.java @@ -9,6 +9,7 @@ public class ItemArmorStand extends Item { super(item_info); } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { EnumDirection enumdirection = itemactioncontext.getClickedFace(); @@ -32,21 +33,21 @@ public class ItemArmorStand extends Item { ItemStack itemstack = itemactioncontext.getItemStack(); if (!world.isClientSide) { - world.setAir(blockposition); - world.setAir(blockposition1); - EntityArmorStand entityarmorstand = EntityTypes.ARMOR_STAND.create(world); // Paper + world.a(blockposition, false); + world.a(blockposition1, false); + EntityArmorStand entityarmorstand = new EntityArmorStand(world, d0 + 0.5D, d1, d2 + 0.5D); float f = (float) MathHelper.d((MathHelper.g(itemactioncontext.h() - 180.0F) + 22.5F) / 45.0F) * 45.0F; entityarmorstand.setPositionRotation(d0 + 0.5D, d1, d2 + 0.5D, f, 0.0F); this.a(entityarmorstand, world.random); - EntityTypes.a(world, itemactioncontext.getEntity(), entityarmorstand, itemstack.getTag()); + EntityTypes.a(world, itemactioncontext.getEntity(), (Entity) entityarmorstand, itemstack.getTag()); // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(itemactioncontext, entityarmorstand).isCancelled()) { return EnumInteractionResult.FAIL; } // CraftBukkit end world.addEntity(entityarmorstand); - world.a((EntityHuman) null, entityarmorstand.locX, entityarmorstand.locY, entityarmorstand.locZ, SoundEffects.ENTITY_ARMOR_STAND_PLACE, SoundCategory.BLOCKS, 0.75F, 0.8F); + world.playSound((EntityHuman) null, entityarmorstand.locX, entityarmorstand.locY, entityarmorstand.locZ, SoundEffects.ENTITY_ARMOR_STAND_PLACE, SoundCategory.BLOCKS, 0.75F, 0.8F); } itemstack.subtract(1); diff --git a/src/main/java/net/minecraft/server/ItemBlock.java b/src/main/java/net/minecraft/server/ItemBlock.java index 49ad201c6..0c8b11bbe 100644 --- a/src/main/java/net/minecraft/server/ItemBlock.java +++ b/src/main/java/net/minecraft/server/ItemBlock.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.Iterator; import java.util.Map; import javax.annotation.Nullable; // CraftBukkit start @@ -18,60 +19,125 @@ public class ItemBlock extends Item { this.a = block; } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { - return this.a(new BlockActionContext(itemactioncontext)); + EnumInteractionResult enuminteractionresult = this.a(new BlockActionContext(itemactioncontext)); + + return enuminteractionresult != EnumInteractionResult.SUCCESS && this.isFood() ? this.a(itemactioncontext.e, itemactioncontext.b, itemactioncontext.c).a() : enuminteractionresult; } public EnumInteractionResult a(BlockActionContext blockactioncontext) { if (!blockactioncontext.b()) { return EnumInteractionResult.FAIL; } else { - IBlockData iblockdata = this.b(blockactioncontext); + BlockActionContext blockactioncontext1 = this.b(blockactioncontext); - if (iblockdata == null) { - return EnumInteractionResult.FAIL; - } else if (!this.a(blockactioncontext, iblockdata)) { + if (blockactioncontext1 == null) { return EnumInteractionResult.FAIL; } else { - BlockPosition blockposition = blockactioncontext.getClickPosition(); - World world = blockactioncontext.getWorld(); - EntityHuman entityhuman = blockactioncontext.getEntity(); - ItemStack itemstack = blockactioncontext.getItemStack(); - IBlockData iblockdata1 = world.getType(blockposition); - Block block = iblockdata1.getBlock(); + IBlockData iblockdata = this.c(blockactioncontext1); - if (block == iblockdata.getBlock()) { - this.a(blockposition, world, entityhuman, itemstack, iblockdata1); - block.postPlace(world, blockposition, iblockdata1, entityhuman, itemstack); - if (entityhuman instanceof EntityPlayer) { - CriterionTriggers.y.a((EntityPlayer) entityhuman, blockposition, itemstack); + if (iblockdata == null) { + return EnumInteractionResult.FAIL; + } else if (!this.a(blockactioncontext1, iblockdata)) { + return EnumInteractionResult.FAIL; + } else { + BlockPosition blockposition = blockactioncontext1.getClickPosition(); + World world = blockactioncontext1.getWorld(); + EntityHuman entityhuman = blockactioncontext1.getEntity(); + ItemStack itemstack = blockactioncontext1.getItemStack(); + IBlockData iblockdata1 = world.getType(blockposition); + Block block = iblockdata1.getBlock(); + + if (block == iblockdata.getBlock()) { + iblockdata1 = this.a(blockposition, world, itemstack, iblockdata1); + this.a(blockposition, world, entityhuman, itemstack, iblockdata1); + block.postPlace(world, blockposition, iblockdata1, entityhuman, itemstack); + if (entityhuman instanceof EntityPlayer) { + CriterionTriggers.y.a((EntityPlayer) entityhuman, blockposition, itemstack); + } } + + SoundEffectType soundeffecttype = iblockdata1.r(); + + // world.playSound(entityhuman, blockposition, this.a(iblockdata1), SoundCategory.BLOCKS, (soundeffecttype.a() + 1.0F) / 2.0F, soundeffecttype.b() * 0.8F); + itemstack.subtract(1); + return EnumInteractionResult.SUCCESS; } - - SoundEffectType soundeffecttype = block.getStepSound(); - - // world.a(entityhuman, blockposition, soundeffecttype.e(), SoundCategory.BLOCKS, (soundeffecttype.a() + 1.0F) / 2.0F, soundeffecttype.b() * 0.8F); // CraftBukkit - SPIGOT-1288 - itemstack.subtract(1); - return EnumInteractionResult.SUCCESS; } } } + protected SoundEffect a(IBlockData iblockdata) { + return iblockdata.r().e(); + } + + @Nullable + public BlockActionContext b(BlockActionContext blockactioncontext) { + return blockactioncontext; + } + protected boolean a(BlockPosition blockposition, World world, @Nullable EntityHuman entityhuman, ItemStack itemstack, IBlockData iblockdata) { return a(world, entityhuman, blockposition, itemstack); } @Nullable - protected IBlockData b(BlockActionContext blockactioncontext) { + protected IBlockData c(BlockActionContext blockactioncontext) { IBlockData iblockdata = this.getBlock().getPlacedState(blockactioncontext); return iblockdata != null && this.b(blockactioncontext, iblockdata) ? iblockdata : null; } + private IBlockData a(BlockPosition blockposition, World world, ItemStack itemstack, IBlockData iblockdata) { + IBlockData iblockdata1 = iblockdata; + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound != null) { + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("BlockStateTag"); + // CraftBukkit start + iblockdata1 = getBlockState(iblockdata1, nbttagcompound1); + } + + if (iblockdata1 != iblockdata) { + world.setTypeAndData(blockposition, iblockdata1, 2); + } + + return iblockdata1; + } + + public static IBlockData getBlockState(IBlockData iblockdata, NBTTagCompound nbttagcompound1) { + IBlockData iblockdata1 = iblockdata; + { + // CraftBukkit end + BlockStateList blockstatelist = iblockdata.getBlock().getStates(); + Iterator iterator = nbttagcompound1.getKeys().iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + IBlockState iblockstate = blockstatelist.a(s); + + if (iblockstate != null) { + String s1 = nbttagcompound1.get(s).asString(); + + iblockdata1 = a(iblockdata1, iblockstate, s1); + } + } + } + return iblockdata1; + } + + private static > IBlockData a(IBlockData iblockdata, IBlockState iblockstate, String s) { + return (IBlockData) iblockstate.b(s).map((comparable) -> { + return (IBlockData) iblockdata.set(iblockstate, comparable); + }).orElse(iblockdata); + } + protected boolean b(BlockActionContext blockactioncontext, IBlockData iblockdata) { + EntityHuman entityhuman = blockactioncontext.getEntity(); + VoxelShapeCollision voxelshapecollision = entityhuman == null ? VoxelShapeCollision.a() : VoxelShapeCollision.a((Entity) entityhuman); // CraftBukkit start - store default return - final World world = blockactioncontext.getWorld(); // Paper - boolean defaultReturn = iblockdata.canPlace(world, blockactioncontext.getClickPosition()) && world.a(iblockdata, blockactioncontext.getClickPosition()) && world.checkNoVisiblePlayerCollisions(blockactioncontext.getEntity(), iblockdata.getCollisionShape(world, blockactioncontext.getClickPosition())); // Paper - Use our entity search + World world = blockactioncontext.getWorld(); // Paper + boolean defaultReturn = (!this.d() || iblockdata.canPlace(world, blockactioncontext.getClickPosition())) && world.checkEntityCollision(iblockdata, entityhuman, voxelshapecollision, blockactioncontext.getClickPosition(), true); // Paper org.bukkit.entity.Player player = (blockactioncontext.getEntity() instanceof EntityPlayer) ? (org.bukkit.entity.Player) blockactioncontext.getEntity().getBukkitEntity() : null; BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(blockactioncontext.getWorld(), blockactioncontext.getClickPosition()), player, CraftBlockData.fromData(iblockdata), defaultReturn); @@ -81,6 +147,10 @@ public class ItemBlock extends Item { // CraftBukkit end } + protected boolean d() { + return true; + } + protected boolean a(BlockActionContext blockactioncontext, IBlockData iblockdata) { return blockactioncontext.getWorld().setTypeAndData(blockactioncontext.getClickPosition(), iblockdata, 11); } @@ -120,10 +190,12 @@ public class ItemBlock extends Item { } } + @Override public String getName() { - return this.getBlock().m(); + return this.getBlock().l(); } + @Override public void a(CreativeModeTab creativemodetab, NonNullList nonnulllist) { if (this.a(creativemodetab)) { this.getBlock().a(creativemodetab, nonnulllist); diff --git a/src/main/java/net/minecraft/server/ItemBoat.java b/src/main/java/net/minecraft/server/ItemBoat.java index 9af24b906..03956c6b5 100644 --- a/src/main/java/net/minecraft/server/ItemBoat.java +++ b/src/main/java/net/minecraft/server/ItemBoat.java @@ -1,69 +1,57 @@ package net.minecraft.server; +import java.util.Iterator; import java.util.List; +import java.util.function.Predicate; public class ItemBoat extends Item { - private final EntityBoat.EnumBoatType a; + private static final Predicate a = IEntitySelector.f.and(Entity::isInteractable); + private final EntityBoat.EnumBoatType b; public ItemBoat(EntityBoat.EnumBoatType entityboat_enumboattype, Item.Info item_info) { super(item_info); - this.a = entityboat_enumboattype; + this.b = entityboat_enumboattype; } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); - float f = 1.0F; - float f1 = entityhuman.lastPitch + (entityhuman.pitch - entityhuman.lastPitch) * 1.0F; - float f2 = entityhuman.lastYaw + (entityhuman.yaw - entityhuman.lastYaw) * 1.0F; - double d0 = entityhuman.lastX + (entityhuman.locX - entityhuman.lastX) * 1.0D; - double d1 = entityhuman.lastY + (entityhuman.locY - entityhuman.lastY) * 1.0D + (double) entityhuman.getHeadHeight(); - double d2 = entityhuman.lastZ + (entityhuman.locZ - entityhuman.lastZ) * 1.0D; - Vec3D vec3d = new Vec3D(d0, d1, d2); - float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); - float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); - float f5 = -MathHelper.cos(-f1 * 0.017453292F); - float f6 = MathHelper.sin(-f1 * 0.017453292F); - float f7 = f4 * f5; - float f8 = f3 * f5; - double d3 = 5.0D; - Vec3D vec3d1 = vec3d.add((double) f7 * 5.0D, (double) f6 * 5.0D, (double) f8 * 5.0D); - MovingObjectPosition movingobjectposition = world.rayTrace(vec3d, vec3d1, FluidCollisionOption.ALWAYS); + MovingObjectPosition movingobjectposition = a(world, entityhuman, RayTrace.FluidCollisionOption.ANY); - if (movingobjectposition == null) { + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.MISS) { return new InteractionResultWrapper<>(EnumInteractionResult.PASS, itemstack); } else { - Vec3D vec3d2 = entityhuman.f(1.0F); - boolean flag = false; - List list = world.getEntities(entityhuman, entityhuman.getBoundingBox().b(vec3d2.x * 5.0D, vec3d2.y * 5.0D, vec3d2.z * 5.0D).g(1.0D)); + Vec3D vec3d = entityhuman.f(1.0F); + double d0 = 5.0D; + List list = world.getEntities(entityhuman, entityhuman.getBoundingBox().a(vec3d.a(5.0D)).g(1.0D), ItemBoat.a); - for (int i = 0; i < list.size(); ++i) { - Entity entity = (Entity) list.get(i); + if (!list.isEmpty()) { + Vec3D vec3d1 = entityhuman.j(1.0F); + Iterator iterator = list.iterator(); - if (entity.isInteractable()) { - AxisAlignedBB axisalignedbb = entity.getBoundingBox().g((double) entity.aM()); + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + AxisAlignedBB axisalignedbb = entity.getBoundingBox().g((double) entity.aS()); - if (axisalignedbb.b(vec3d)) { - flag = true; + if (axisalignedbb.c(vec3d1)) { + return new InteractionResultWrapper<>(EnumInteractionResult.PASS, itemstack); } } } - if (flag) { - return new InteractionResultWrapper<>(EnumInteractionResult.PASS, itemstack); - } else if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK) { // CraftBukkit start - Boat placement - org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(entityhuman, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, movingobjectposition.getBlockPosition(), movingobjectposition.direction, itemstack, enumhand); + MovingObjectPositionBlock movingobjectpositionblock = (MovingObjectPositionBlock) movingobjectposition; + org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(entityhuman, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, movingobjectpositionblock.getBlockPosition(), movingobjectpositionblock.getDirection(), itemstack, enumhand); if (event.isCancelled()) { return new InteractionResultWrapper(EnumInteractionResult.PASS, itemstack); } // CraftBukkit end - BlockPosition blockposition = movingobjectposition.getBlockPosition(); - Block block = world.getType(blockposition).getBlock(); - EntityBoat entityboat = new EntityBoat(world, movingobjectposition.pos.x, movingobjectposition.pos.y, movingobjectposition.pos.z); + EntityBoat entityboat = new EntityBoat(world, movingobjectposition.getPos().x, movingobjectposition.getPos().y, movingobjectposition.getPos().z); - entityboat.setType(this.a); + entityboat.setType(this.b); entityboat.yaw = entityhuman.yaw; if (!world.getCubes(entityboat, entityboat.getBoundingBox().g(-0.1D))) { return new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); diff --git a/src/main/java/net/minecraft/server/ItemBow.java b/src/main/java/net/minecraft/server/ItemBow.java index f8dbc3c40..90592fd38 100644 --- a/src/main/java/net/minecraft/server/ItemBow.java +++ b/src/main/java/net/minecraft/server/ItemBow.java @@ -1,65 +1,36 @@ package net.minecraft.server; -import org.bukkit.craftbukkit.inventory.CraftItemStack; +import java.util.function.Predicate; -public class ItemBow extends Item { +public class ItemBow extends ItemProjectileWeapon { public ItemBow(Item.Info item_info) { super(item_info); // CraftBukkit start - obfuscator went a little crazy /* this.a(new MinecraftKey("pull"), (itemstack, world, entityliving) -> { - return entityliving == null ? 0.0F : (entityliving.cW().getItem() != Items.BOW ? 0.0F : (float) (itemstack.k() - entityliving.cX()) / 20.0F); + return entityliving == null ? 0.0F : (entityliving.dl().getItem() != Items.BOW ? 0.0F : (float) (itemstack.k() - entityliving.dm()) / 20.0F); }); this.a(new MinecraftKey("pulling"), (itemstack, world, entityliving) -> { - return entityliving != null && entityliving.isHandRaised() && entityliving.cW() == itemstack ? 1.0F : 0.0F; + return entityliving != null && entityliving.isHandRaised() && entityliving.dl() == itemstack ? 1.0F : 0.0F; }); */ // CraftBukkit end } - private ItemStack a(EntityHuman entityhuman, ItemStack bow) { // Paper - if (this.e_(entityhuman, bow, entityhuman.b(EnumHand.OFF_HAND))) { // Paper - return entityhuman.b(EnumHand.OFF_HAND); - } else if (this.e_(entityhuman, bow, entityhuman.b(EnumHand.MAIN_HAND))) { - return entityhuman.b(EnumHand.MAIN_HAND); - } else { - for (int i = 0; i < entityhuman.inventory.getSize(); ++i) { - ItemStack itemstack = entityhuman.inventory.getItem(i); - - if (this.e_(entityhuman, bow, itemstack)) { - return itemstack; - } - } - - return ItemStack.a; - } - } - - // Paper start - protected boolean e_(EntityHuman player, ItemStack bow, ItemStack itemstack) { - return itemstack.getItem() instanceof ItemArrow && ( - !(player instanceof EntityPlayer) || - new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent( - ((EntityPlayer) player).getBukkitEntity(), - CraftItemStack.asCraftMirror(bow), - CraftItemStack.asCraftMirror(itemstack) - ).callEvent()); - // Paper end - } - + @Override public void a(ItemStack itemstack, World world, EntityLiving entityliving, int i) { if (entityliving instanceof EntityHuman) { EntityHuman entityhuman = (EntityHuman) entityliving; boolean flag = entityhuman.abilities.canInstantlyBuild || EnchantmentManager.getEnchantmentLevel(Enchantments.ARROW_INFINITE, itemstack) > 0; - ItemStack itemstack1 = this.a(entityhuman, itemstack); // Paper + ItemStack itemstack1 = entityhuman.f(itemstack); if (!itemstack1.isEmpty() || flag) { if (itemstack1.isEmpty()) { itemstack1 = new ItemStack(Items.ARROW); } - int j = this.c(itemstack) - i; + int j = this.f_(itemstack) - i; float f = a(j); if ((double) f >= 0.1D) { @@ -98,9 +69,11 @@ public class ItemBow extends Item { } // CraftBukkit end - itemstack.damage(1, entityhuman); + itemstack.damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(entityhuman.getRaisedHand()); + }); consumeArrow = event.getConsumeArrow(); // Paper - if (!consumeArrow || flag1 || (entityhuman.abilities.canInstantlyBuild && ((itemstack1.getItem() == Items.SPECTRAL_ARROW) || (itemstack1.getItem() == Items.TIPPED_ARROW)))) { // Paper - add !consumeArrow + if (!consumeArrow || flag1 || (entityhuman.abilities.canInstantlyBuild && ((itemstack1.getItem() == Items.SPECTRAL_ARROW) || (itemstack1.getItem() == Items.TIPPED_ARROW)))) { // Paper - add entityarrow.fromPlayer = EntityArrow.PickupStatus.CREATIVE_ONLY; } @@ -116,7 +89,7 @@ public class ItemBow extends Item { // CraftBukkit end } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_ARROW_SHOOT, SoundCategory.PLAYERS, 1.0F, 1.0F / (ItemBow.i.nextFloat() * 0.4F + 1.2F) + f * 0.5F); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_ARROW_SHOOT, SoundCategory.PLAYERS, 1.0F, 1.0F / (ItemBow.i.nextFloat() * 0.4F + 1.2F) + f * 0.5F); if (!flag1 && !entityhuman.abilities.canInstantlyBuild && consumeArrow) { // Paper itemstack1.subtract(1); if (itemstack1.isEmpty()) { @@ -141,17 +114,20 @@ public class ItemBow extends Item { return f; } - public int c(ItemStack itemstack) { + @Override + public int f_(ItemStack itemstack) { return 72000; } - public EnumAnimation d(ItemStack itemstack) { + @Override + public EnumAnimation e_(ItemStack itemstack) { return EnumAnimation.BOW; } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); - boolean flag = !this.a(entityhuman, itemstack).isEmpty(); // Paper + boolean flag = !entityhuman.f(itemstack).isEmpty(); if (!entityhuman.abilities.canInstantlyBuild && !flag) { return flag ? new InteractionResultWrapper<>(EnumInteractionResult.PASS, itemstack) : new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); @@ -161,7 +137,8 @@ public class ItemBow extends Item { } } - public int c() { - return 1; + @Override + public Predicate b() { + return ItemBow.a; } } diff --git a/src/main/java/net/minecraft/server/ItemBucket.java b/src/main/java/net/minecraft/server/ItemBucket.java index bb74d5ab4..91ff811d8 100644 --- a/src/main/java/net/minecraft/server/ItemBucket.java +++ b/src/main/java/net/minecraft/server/ItemBucket.java @@ -18,16 +18,20 @@ public class ItemBucket extends Item { this.fluidType = fluidtype; } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); - MovingObjectPosition movingobjectposition = this.a(world, entityhuman, this.fluidType == FluidTypes.EMPTY); + MovingObjectPosition movingobjectposition = a(world, entityhuman, this.fluidType == FluidTypes.EMPTY ? RayTrace.FluidCollisionOption.SOURCE_ONLY : RayTrace.FluidCollisionOption.NONE); - if (movingobjectposition == null) { + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.MISS) { return new InteractionResultWrapper<>(EnumInteractionResult.PASS, itemstack); - } else if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { - BlockPosition blockposition = movingobjectposition.getBlockPosition(); + } else if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.BLOCK) { + return new InteractionResultWrapper<>(EnumInteractionResult.PASS, itemstack); + } else { + MovingObjectPositionBlock movingobjectpositionblock = (MovingObjectPositionBlock) movingobjectposition; + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition(); - if (world.a(entityhuman, blockposition) && entityhuman.a(blockposition, movingobjectposition.direction, itemstack)) { + if (world.a(entityhuman, blockposition) && entityhuman.a(blockposition, movingobjectpositionblock.getDirection(), itemstack)) { IBlockData iblockdata; if (this.fluidType == FluidTypes.EMPTY) { @@ -35,9 +39,10 @@ public class ItemBucket extends Item { if (iblockdata.getBlock() instanceof IFluidSource) { // CraftBukkit start FluidType dummyFluid = ((IFluidSource) iblockdata.getBlock()).removeFluid(DummyGeneratorAccess.INSTANCE, blockposition, iblockdata); - PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman, blockposition.getX(), blockposition.getY(), blockposition.getZ(), null, itemstack, dummyFluid.b(), enumhand); // Paper - add enumHand + PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(world, entityhuman, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.b(), enumhand); // Paper - add enumHand if (event.isCancelled()) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 return new InteractionResultWrapper(EnumInteractionResult.FAIL, itemstack); } @@ -60,9 +65,9 @@ public class ItemBucket extends Item { return new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); } else { iblockdata = world.getType(blockposition); - BlockPosition blockposition1 = this.a(iblockdata, blockposition, movingobjectposition); + BlockPosition blockposition1 = iblockdata.getBlock() instanceof IFluidContainer && this.fluidType == FluidTypes.WATER ? blockposition : movingobjectpositionblock.getBlockPosition().shift(movingobjectpositionblock.getDirection()); - if (this.a(entityhuman, world, blockposition1, movingobjectposition, movingobjectposition.direction, blockposition, itemstack, enumhand)) { // CraftBukkit // Paper - add enumHand + if (this.a(entityhuman, world, blockposition1, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack, enumhand)) { // CraftBukkit // Paper - add enumHand this.a(world, itemstack, blockposition1); if (entityhuman instanceof EntityPlayer) { CriterionTriggers.y.a((EntityPlayer) entityhuman, blockposition1, itemstack); @@ -77,15 +82,9 @@ public class ItemBucket extends Item { } else { return new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); } - } else { - return new InteractionResultWrapper<>(EnumInteractionResult.PASS, itemstack); } } - private BlockPosition a(IBlockData iblockdata, BlockPosition blockposition, MovingObjectPosition movingobjectposition) { - return iblockdata.getBlock() instanceof IFluidContainer ? blockposition : movingobjectposition.getBlockPosition().shift(movingobjectposition.direction); - } - protected ItemStack a(ItemStack itemstack, EntityHuman entityhuman) { return !entityhuman.abilities.canInstantlyBuild ? new ItemStack(Items.BUCKET) : itemstack; } @@ -113,16 +112,16 @@ public class ItemBucket extends Item { } // CraftBukkit start - public boolean a(@Nullable EntityHuman entityhuman, World world, BlockPosition blockposition, @Nullable MovingObjectPosition movingobjectposition) { - return a(entityhuman, world, blockposition, movingobjectposition, null, null, null); + public boolean a(@Nullable EntityHuman entityhuman, World world, BlockPosition blockposition, @Nullable MovingObjectPositionBlock movingobjectpositionblock) { + return a(entityhuman, world, blockposition, movingobjectpositionblock, null, null, null); } - public boolean a(EntityHuman entityhuman, World world, BlockPosition blockposition, @Nullable MovingObjectPosition movingobjectposition, EnumDirection enumdirection, BlockPosition clicked, ItemStack itemstack) { + public boolean a(EntityHuman entityhuman, World world, BlockPosition blockposition, @Nullable MovingObjectPositionBlock movingobjectpositionblock, EnumDirection enumdirection, BlockPosition clicked, ItemStack itemstack) { // Paper start - add enumHand - return a(entityhuman, world, blockposition, movingobjectposition, enumdirection, clicked, itemstack, null); + return a(entityhuman, world, blockposition, movingobjectpositionblock, enumdirection, clicked, itemstack, null); } - public boolean a(EntityHuman entityhuman, World world, BlockPosition blockposition, @Nullable MovingObjectPosition movingobjectposition, EnumDirection enumdirection, BlockPosition clicked, ItemStack itemstack, EnumHand enumhand) { + public boolean a(EntityHuman entityhuman, World world, BlockPosition blockposition, @Nullable MovingObjectPositionBlock movingobjectpositionblock, EnumDirection enumdirection, BlockPosition clicked, ItemStack itemstack, EnumHand enumhand) { // Paper end // CraftBukkit end if (!(this.fluidType instanceof FluidTypeFlowing)) { @@ -134,11 +133,11 @@ public class ItemBucket extends Item { boolean flag1 = material.isReplaceable(); if (!world.isEmpty(blockposition) && !flag && !flag1 && (!(iblockdata.getBlock() instanceof IFluidContainer) || !((IFluidContainer) iblockdata.getBlock()).canPlace(world, blockposition, iblockdata, this.fluidType))) { - return movingobjectposition == null ? false : this.a(entityhuman, world, movingobjectposition.getBlockPosition().shift(movingobjectposition.direction), (MovingObjectPosition) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit // Paper - add enumhand + return movingobjectpositionblock == null ? false : this.a(entityhuman, world, movingobjectpositionblock.getBlockPosition().shift(movingobjectpositionblock.getDirection()), (MovingObjectPositionBlock) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit // Paper - add enumhand } else { // CraftBukkit start if (entityhuman != null) { - PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent(entityhuman, clicked.getX(), clicked.getY(), clicked.getZ(), enumdirection, itemstack, enumhand); // Paper - add enumHand + PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent(world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); // Paper - add enumHand if (event.isCancelled()) { ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition)); // SPIGOT-4238: needed when looking through entity ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 @@ -147,34 +146,26 @@ public class ItemBucket extends Item { } // CraftBukkit end if (world.worldProvider.isNether() && this.fluidType.a(TagsFluid.WATER)) { - // Akarin start - this handle by client - /* int i = blockposition.getX(); int j = blockposition.getY(); int k = blockposition.getZ(); - */ - // Akarin end - world.a(entityhuman, blockposition, SoundEffects.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); + world.playSound(entityhuman, blockposition, SoundEffects.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); - // Akarin start - this handle by client - /* for (int l = 0; l < 8; ++l) { - world.addParticle(Particles.F, (double) i + Math.random(), (double) j + Math.random(), (double) k + Math.random(), 0.0D, 0.0D, 0.0D); + world.addParticle(Particles.LARGE_SMOKE, (double) i + Math.random(), (double) j + Math.random(), (double) k + Math.random(), 0.0D, 0.0D, 0.0D); } - */ - // Akarin end - } else if (iblockdata.getBlock() instanceof IFluidContainer) { + } else if (iblockdata.getBlock() instanceof IFluidContainer && this.fluidType == FluidTypes.WATER) { if (((IFluidContainer) iblockdata.getBlock()).place(world, blockposition, iblockdata, ((FluidTypeFlowing) this.fluidType).a(false))) { this.a(entityhuman, (GeneratorAccess) world, blockposition); } } else { if (!world.isClientSide && (flag || flag1) && !material.isLiquid()) { - world.setAir(blockposition, true); + world.b(blockposition, true); } this.a(entityhuman, (GeneratorAccess) world, blockposition); - world.setTypeAndData(blockposition, this.fluidType.i().i(), 11); + world.setTypeAndData(blockposition, this.fluidType.i().getBlockData(), 11); } return true; @@ -185,6 +176,6 @@ public class ItemBucket extends Item { protected void a(@Nullable EntityHuman entityhuman, GeneratorAccess generatoraccess, BlockPosition blockposition) { SoundEffect soundeffect = this.fluidType.a(TagsFluid.LAVA) ? SoundEffects.ITEM_BUCKET_EMPTY_LAVA : SoundEffects.ITEM_BUCKET_EMPTY; - generatoraccess.a(entityhuman, blockposition, soundeffect, SoundCategory.BLOCKS, 1.0F, 1.0F); + generatoraccess.playSound(entityhuman, blockposition, soundeffect, SoundCategory.BLOCKS, 1.0F, 1.0F); } } diff --git a/src/main/java/net/minecraft/server/ItemChorusFruit.java b/src/main/java/net/minecraft/server/ItemChorusFruit.java index 413ea313a..6b4ea5147 100644 --- a/src/main/java/net/minecraft/server/ItemChorusFruit.java +++ b/src/main/java/net/minecraft/server/ItemChorusFruit.java @@ -6,12 +6,13 @@ import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent; // CraftBukkit end -public class ItemChorusFruit extends ItemFood { +public class ItemChorusFruit extends Item { - public ItemChorusFruit(int i, float f, Item.Info item_info) { - super(i, f, false, item_info); + public ItemChorusFruit(Item.Info item_info) { + super(item_info); } + @Override public ItemStack a(ItemStack itemstack, World world, EntityLiving entityliving) { ItemStack itemstack1 = super.a(itemstack, world, entityliving); @@ -22,7 +23,7 @@ public class ItemChorusFruit extends ItemFood { for (int i = 0; i < 16; ++i) { double d3 = entityliving.locX + (entityliving.getRandom().nextDouble() - 0.5D) * 16.0D; - double d4 = MathHelper.a(entityliving.locY + (double) (entityliving.getRandom().nextInt(16) - 8), 0.0D, (double) (world.ab() - 1)); + double d4 = MathHelper.a(entityliving.locY + (double) (entityliving.getRandom().nextInt(16) - 8), 0.0D, (double) (world.getHeight() - 1)); double d5 = entityliving.locZ + (entityliving.getRandom().nextDouble() - 0.5D) * 16.0D; // CraftBukkit start @@ -43,15 +44,15 @@ public class ItemChorusFruit extends ItemFood { entityliving.stopRiding(); } - if (entityliving.j(d3, d4, d5)) { - world.a((EntityHuman) null, d0, d1, d2, SoundEffects.ITEM_CHORUS_FRUIT_TELEPORT, SoundCategory.PLAYERS, 1.0F, 1.0F); + if (entityliving.a(d3, d4, d5, true)) { + world.playSound((EntityHuman) null, d0, d1, d2, SoundEffects.ITEM_CHORUS_FRUIT_TELEPORT, SoundCategory.PLAYERS, 1.0F, 1.0F); entityliving.a(SoundEffects.ITEM_CHORUS_FRUIT_TELEPORT, 1.0F, 1.0F); break; } } if (entityliving instanceof EntityHuman) { - ((EntityHuman) entityliving).getCooldownTracker().a(this, 20); + ((EntityHuman) entityliving).getCooldownTracker().setCooldown(this, 20); } } diff --git a/src/main/java/net/minecraft/server/ItemCrossbow.java b/src/main/java/net/minecraft/server/ItemCrossbow.java new file mode 100644 index 000000000..f0d784108 --- /dev/null +++ b/src/main/java/net/minecraft/server/ItemCrossbow.java @@ -0,0 +1,383 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.List; +import java.util.Random; +import java.util.function.Predicate; + +public class ItemCrossbow extends ItemProjectileWeapon { + + private boolean c = false; + private boolean d = false; + + public ItemCrossbow(Item.Info item_info) { + super(item_info); + // CraftBukkit start - obfuscator went a little crazy + /* + this.a(new MinecraftKey("pull"), (itemstack, world, entityliving) -> { + return entityliving != null && itemstack.getItem() == this ? (d(itemstack) ? 0.0F : (float) (itemstack.k() - entityliving.dm()) / (float) e(itemstack)) : 0.0F; + }); + this.a(new MinecraftKey("pulling"), (itemstack, world, entityliving) -> { + return entityliving != null && entityliving.isHandRaised() && entityliving.dl() == itemstack && !d(itemstack) ? 1.0F : 0.0F; + }); + this.a(new MinecraftKey("charged"), (itemstack, world, entityliving) -> { + return entityliving != null && d(itemstack) ? 1.0F : 0.0F; + }); + this.a(new MinecraftKey("firework"), (itemstack, world, entityliving) -> { + return entityliving != null && d(itemstack) && a(itemstack, Items.FIREWORK_ROCKET) ? 1.0F : 0.0F; + }); + */ + // CraftBukkit end + } + + @Override + public Predicate d() { + return ItemCrossbow.b; + } + + @Override + public Predicate b() { + return ItemCrossbow.a; + } + + @Override + public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { + ItemStack itemstack = entityhuman.b(enumhand); + + if (d(itemstack)) { + a(world, entityhuman, enumhand, itemstack, l(itemstack), 1.0F); + a(itemstack, false); + return new InteractionResultWrapper<>(EnumInteractionResult.SUCCESS, itemstack); + } else if (!entityhuman.f(itemstack).isEmpty()) { + if (!d(itemstack)) { + this.c = false; + this.d = false; + entityhuman.c(enumhand); + } + + return new InteractionResultWrapper<>(EnumInteractionResult.SUCCESS, itemstack); + } else { + return new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); + } + } + + @Override + public void a(ItemStack itemstack, World world, EntityLiving entityliving, int i) { + int j = this.f_(itemstack) - i; + float f = a(j, itemstack); + + if (f >= 1.0F && !d(itemstack) && a(entityliving, itemstack)) { + a(itemstack, true); + SoundCategory soundcategory = entityliving instanceof EntityHuman ? SoundCategory.PLAYERS : SoundCategory.HOSTILE; + + world.playSound((EntityHuman) null, entityliving.locX, entityliving.locY, entityliving.locZ, SoundEffects.ITEM_CROSSBOW_LOADING_END, soundcategory, 1.0F, 1.0F / (ItemCrossbow.i.nextFloat() * 0.5F + 1.0F) + 0.2F); + } + + } + + private static boolean a(EntityLiving entityliving, ItemStack itemstack) { + int i = EnchantmentManager.getEnchantmentLevel(Enchantments.MULTISHOT, itemstack); + int j = i == 0 ? 1 : 3; + boolean flag = entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.canInstantlyBuild; + ItemStack itemstack1 = entityliving.f(itemstack); + ItemStack itemstack2 = itemstack1.cloneItemStack(); + + for (int k = 0; k < j; ++k) { + if (k > 0) { + itemstack1 = itemstack2.cloneItemStack(); + } + + if (itemstack1.isEmpty() && flag) { + itemstack1 = new ItemStack(Items.ARROW); + itemstack2 = itemstack1.cloneItemStack(); + } + // CraftBukkit start - SPIGOT-4870, MC-150847 + else if (itemstack1.isEmpty()) { + return false; + } + // CraftBukkit end + + if (!a(entityliving, itemstack, itemstack1, k > 0, flag)) { + return false; + } + } + + return true; + } + + private static boolean a(EntityLiving entityliving, ItemStack itemstack, ItemStack itemstack1, boolean flag, boolean flag1) { + if (itemstack1.isEmpty()) { + return false; + } else { + boolean flag2 = flag1 && itemstack1.getItem() instanceof ItemArrow; + ItemStack itemstack2; + + if (!flag2 && !flag1 && !flag) { + itemstack2 = itemstack1.cloneAndSubtract(1); + if (itemstack1.isEmpty() && entityliving instanceof EntityHuman) { + ((EntityHuman) entityliving).inventory.f(itemstack1); + } + } else { + itemstack2 = itemstack1.cloneItemStack(); + } + + b(itemstack, itemstack2); + return true; + } + } + + public static boolean d(ItemStack itemstack) { + NBTTagCompound nbttagcompound = itemstack.getTag(); + + return nbttagcompound != null && nbttagcompound.getBoolean("Charged"); + } + + public static void a(ItemStack itemstack, boolean flag) { + NBTTagCompound nbttagcompound = itemstack.getOrCreateTag(); + + nbttagcompound.setBoolean("Charged", flag); + } + + private static void b(ItemStack itemstack, ItemStack itemstack1) { + NBTTagCompound nbttagcompound = itemstack.getOrCreateTag(); + NBTTagList nbttaglist; + + if (nbttagcompound.hasKeyOfType("ChargedProjectiles", 9)) { + nbttaglist = nbttagcompound.getList("ChargedProjectiles", 10); + } else { + nbttaglist = new NBTTagList(); + } + + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + itemstack1.save(nbttagcompound1); + nbttaglist.add(nbttagcompound1); + nbttagcompound.set("ChargedProjectiles", nbttaglist); + } + + private static List j(ItemStack itemstack) { + List list = Lists.newArrayList(); + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound != null && nbttagcompound.hasKeyOfType("ChargedProjectiles", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("ChargedProjectiles", 10); + + if (nbttaglist != null) { + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); + + list.add(ItemStack.a(nbttagcompound1)); + } + } + } + + return list; + } + + private static void k(ItemStack itemstack) { + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound != null) { + NBTTagList nbttaglist = nbttagcompound.getList("ChargedProjectiles", 9); + + nbttaglist.clear(); + nbttagcompound.set("ChargedProjectiles", nbttaglist); + } + + } + + private static boolean a(ItemStack itemstack, Item item) { + return j(itemstack).stream().anyMatch((itemstack1) -> { + return itemstack1.getItem() == item; + }); + } + + private static void a(World world, EntityLiving entityliving, EnumHand enumhand, ItemStack itemstack, ItemStack itemstack1, float f, boolean flag, float f1, float f2, float f3) { + if (!world.isClientSide) { + boolean flag1 = itemstack1.getItem() == Items.FIREWORK_ROCKET; + Object object; + + if (flag1) { + object = new EntityFireworks(world, itemstack1, entityliving.locX, entityliving.locY + (double) entityliving.getHeadHeight() - 0.15000000596046448D, entityliving.locZ, true); + ((EntityFireworks) object).spawningEntity = entityliving.getUniqueID(); // Paper + } else { + object = a(world, entityliving, itemstack, itemstack1); + if (flag || f3 != 0.0F) { + ((EntityArrow) object).fromPlayer = EntityArrow.PickupStatus.CREATIVE_ONLY; + } + } + + if (entityliving instanceof ICrossbow) { + ICrossbow icrossbow = (ICrossbow) entityliving; + + icrossbow.a(icrossbow.getGoalTarget(), itemstack, (IProjectile) object, f3); + } else { + Vec3D vec3d = entityliving.i(1.0F); + Quaternion quaternion = new Quaternion(new Vector3fa(vec3d), f3, true); + Vec3D vec3d1 = entityliving.f(1.0F); + Vector3fa vector3fa = new Vector3fa(vec3d1); + + vector3fa.a(quaternion); + ((IProjectile) object).shoot((double) vector3fa.a(), (double) vector3fa.b(), (double) vector3fa.c(), f1, f2); + } + // CraftBukkit start + org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(entityliving, itemstack, itemstack1, (IProjectile) object, f); // Paper // TODO: consume?? + if (event.isCancelled()) { + event.getProjectile().remove(); + return; + } + // CraftBukkit end + + itemstack.damage(flag1 ? 3 : 1, entityliving, (entityliving1) -> { + entityliving1.d(enumhand); + }); + // CraftBukkit start + if (event.getProjectile() == ((Entity) object).getBukkitEntity()) { + if (!world.addEntity((Entity) object)) { + if (entityliving instanceof EntityPlayer) { + ((EntityPlayer) entityliving).getBukkitEntity().updateInventory(); + } + return; + } + } + // CraftBukkit end + world.playSound((EntityHuman) null, entityliving.locX, entityliving.locY, entityliving.locZ, SoundEffects.ITEM_CROSSBOW_SHOOT, SoundCategory.PLAYERS, 1.0F, f); + } + } + + private static EntityArrow a(World world, EntityLiving entityliving, ItemStack itemstack, ItemStack itemstack1) { + ItemArrow itemarrow = (ItemArrow) ((ItemArrow) (itemstack1.getItem() instanceof ItemArrow ? itemstack1.getItem() : Items.ARROW)); + EntityArrow entityarrow = itemarrow.a(world, itemstack1, entityliving); + + if (entityliving instanceof EntityHuman) { + entityarrow.setCritical(true); + } + + entityarrow.a(SoundEffects.ITEM_CROSSBOW_HIT); + entityarrow.o(true); + int i = EnchantmentManager.getEnchantmentLevel(Enchantments.PIERCING, itemstack); + + if (i > 0) { + entityarrow.setPierceLevel((byte) i); + } + + return entityarrow; + } + + public static void a(World world, EntityLiving entityliving, EnumHand enumhand, ItemStack itemstack, float f, float f1) { + List list = j(itemstack); + float[] afloat = a(entityliving.getRandom()); + + for (int i = 0; i < list.size(); ++i) { + ItemStack itemstack1 = (ItemStack) list.get(i); + boolean flag = entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.canInstantlyBuild; + + if (!itemstack1.isEmpty()) { + if (i == 0) { + a(world, entityliving, enumhand, itemstack, itemstack1, afloat[i], flag, f, f1, 0.0F); + } else if (i == 1) { + a(world, entityliving, enumhand, itemstack, itemstack1, afloat[i], flag, f, f1, -10.0F); + } else if (i == 2) { + a(world, entityliving, enumhand, itemstack, itemstack1, afloat[i], flag, f, f1, 10.0F); + } + } + } + + a(world, entityliving, itemstack); + } + + private static float[] a(Random random) { + boolean flag = random.nextBoolean(); + + return new float[]{1.0F, a(flag), a(!flag)}; + } + + private static float a(boolean flag) { + float f = flag ? 0.63F : 0.43F; + + return 1.0F / (ItemCrossbow.i.nextFloat() * 0.5F + 1.8F) + f; + } + + private static void a(World world, EntityLiving entityliving, ItemStack itemstack) { + if (entityliving instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entityliving; + + if (!world.isClientSide) { + CriterionTriggers.F.a(entityplayer, itemstack); + } + + entityplayer.b(StatisticList.ITEM_USED.b(itemstack.getItem())); + } + + k(itemstack); + } + + @Override + public void a(World world, EntityLiving entityliving, ItemStack itemstack, int i) { + if (!world.isClientSide) { + int j = EnchantmentManager.getEnchantmentLevel(Enchantments.QUICK_CHARGE, itemstack); + SoundEffect soundeffect = this.a(j); + SoundEffect soundeffect1 = j == 0 ? SoundEffects.ITEM_CROSSBOW_LOADING_MIDDLE : null; + float f = (float) (itemstack.k() - i) / (float) e(itemstack); + + if (f < 0.2F) { + this.c = false; + this.d = false; + } + + if (f >= 0.2F && !this.c) { + this.c = true; + world.playSound((EntityHuman) null, entityliving.locX, entityliving.locY, entityliving.locZ, soundeffect, SoundCategory.PLAYERS, 0.5F, 1.0F); + } + + if (f >= 0.5F && soundeffect1 != null && !this.d) { + this.d = true; + world.playSound((EntityHuman) null, entityliving.locX, entityliving.locY, entityliving.locZ, soundeffect1, SoundCategory.PLAYERS, 0.5F, 1.0F); + } + } + + } + + @Override + public int f_(ItemStack itemstack) { + return e(itemstack) + 3; + } + + public static int e(ItemStack itemstack) { + int i = EnchantmentManager.getEnchantmentLevel(Enchantments.QUICK_CHARGE, itemstack); + + return i == 0 ? 25 : 25 - 5 * i; + } + + @Override + public EnumAnimation e_(ItemStack itemstack) { + return EnumAnimation.CROSSBOW; + } + + private SoundEffect a(int i) { + switch (i) { + case 1: + return SoundEffects.ITEM_CROSSBOW_QUICK_CHARGE_1; + case 2: + return SoundEffects.ITEM_CROSSBOW_QUICK_CHARGE_2; + case 3: + return SoundEffects.ITEM_CROSSBOW_QUICK_CHARGE_3; + default: + return SoundEffects.ITEM_CROSSBOW_LOADING_START; + } + } + + private static float a(int i, ItemStack itemstack) { + float f = (float) i / (float) e(itemstack); + + if (f > 1.0F) { + f = 1.0F; + } + + return f; + } + + private static float l(ItemStack itemstack) { + return itemstack.getItem() == Items.CROSSBOW && a(itemstack, Items.FIREWORK_ROCKET) ? 1.6F : 3.15F; + } +} diff --git a/src/main/java/net/minecraft/server/ItemDebugStick.java b/src/main/java/net/minecraft/server/ItemDebugStick.java index 9095d582e..519617ded 100644 --- a/src/main/java/net/minecraft/server/ItemDebugStick.java +++ b/src/main/java/net/minecraft/server/ItemDebugStick.java @@ -9,6 +9,7 @@ public class ItemDebugStick extends Item { super(item_info); } + @Override public boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman) { if (!world.isClientSide) { this.a(entityhuman, iblockdata, world, blockposition, false, entityhuman.b(EnumHand.MAIN_HAND)); @@ -17,6 +18,7 @@ public class ItemDebugStick extends Item { return false; } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { EntityHuman entityhuman = itemactioncontext.getEntity(); World world = itemactioncontext.getWorld(); @@ -38,7 +40,7 @@ public class ItemDebugStick extends Item { String s = IRegistry.BLOCK.getKey(block).toString(); if (collection.isEmpty()) { - a(entityhuman, (IChatBaseComponent) (new ChatMessage(this.getName() + ".empty", new Object[] { s}))); + a(entityhuman, (IChatBaseComponent) (new ChatMessage(this.getName() + ".empty", new Object[]{s}))); } else { NBTTagCompound nbttagcompound = itemstack.a("DebugProperty"); String s1 = nbttagcompound.getString(s); @@ -52,13 +54,13 @@ public class ItemDebugStick extends Item { IBlockData iblockdata1 = a(iblockdata, iblockstate, entityhuman.isSneaking()); generatoraccess.setTypeAndData(blockposition, iblockdata1, 18); - a(entityhuman, (IChatBaseComponent) (new ChatMessage(this.getName() + ".update", new Object[] { iblockstate.a(), a(iblockdata1, iblockstate)}))); + a(entityhuman, (IChatBaseComponent) (new ChatMessage(this.getName() + ".update", new Object[]{iblockstate.a(), a(iblockdata1, iblockstate)}))); } else { iblockstate = (IBlockState) a((Iterable) collection, (Object) iblockstate, entityhuman.isSneaking()); String s2 = iblockstate.a(); nbttagcompound.setString(s, s2); - a(entityhuman, (IChatBaseComponent) (new ChatMessage(this.getName() + ".select", new Object[] { s2, a(iblockdata, iblockstate)}))); + a(entityhuman, (IChatBaseComponent) (new ChatMessage(this.getName() + ".select", new Object[]{s2, a(iblockdata, iblockstate)}))); } } @@ -66,7 +68,7 @@ public class ItemDebugStick extends Item { } private static > IBlockData a(IBlockData iblockdata, IBlockState iblockstate, boolean flag) { - return (IBlockData) iblockdata.set(iblockstate, a(iblockstate.d(), iblockdata.get(iblockstate), flag)); + return (IBlockData) iblockdata.set(iblockstate, a(iblockstate.getValues(), iblockdata.get(iblockstate), flag)); } private static T a(Iterable iterable, @Nullable T t0, boolean flag) { diff --git a/src/main/java/net/minecraft/server/ItemDye.java b/src/main/java/net/minecraft/server/ItemDye.java index 88f6ee46e..da49f6e5a 100644 --- a/src/main/java/net/minecraft/server/ItemDye.java +++ b/src/main/java/net/minecraft/server/ItemDye.java @@ -16,11 +16,12 @@ public class ItemDye extends Item { ItemDye.a.put(enumcolor, this); } + @Override public boolean a(ItemStack itemstack, EntityHuman entityhuman, EntityLiving entityliving, EnumHand enumhand) { if (entityliving instanceof EntitySheep) { EntitySheep entitysheep = (EntitySheep) entityliving; - if (!entitysheep.isSheared() && entitysheep.getColor() != this.b) { + if (entitysheep.isAlive() && !entitysheep.isSheared() && entitysheep.getColor() != this.b) { // CraftBukkit start byte bColor = (byte) this.b.getColorIndex(); SheepDyeWoolEvent event = new SheepDyeWoolEvent((org.bukkit.entity.Sheep) entitysheep.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData(bColor)); diff --git a/src/main/java/net/minecraft/server/ItemEgg.java b/src/main/java/net/minecraft/server/ItemEgg.java index 5f3926d83..b92d39600 100644 --- a/src/main/java/net/minecraft/server/ItemEgg.java +++ b/src/main/java/net/minecraft/server/ItemEgg.java @@ -6,6 +6,7 @@ public class ItemEgg extends Item { super(item_info); } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -14,11 +15,12 @@ public class ItemEgg extends Item { itemstack.subtract(1); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemEgg.i.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemEgg.i.nextFloat() * 0.4F + 0.8F)); */ // Paper end if (!world.isClientSide) { EntityEgg entityegg = new EntityEgg(world, entityhuman); + entityegg.setItem(itemstack); entityegg.a(entityhuman, entityhuman.pitch, entityhuman.yaw, 0.0F, 1.5F, 1.0F); // Paper start com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityegg.getBukkitEntity()); @@ -29,7 +31,7 @@ public class ItemEgg extends Item { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); } else { if (entityhuman instanceof EntityPlayer) { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); diff --git a/src/main/java/net/minecraft/server/ItemEndCrystal.java b/src/main/java/net/minecraft/server/ItemEndCrystal.java index 4914a40de..544e63558 100644 --- a/src/main/java/net/minecraft/server/ItemEndCrystal.java +++ b/src/main/java/net/minecraft/server/ItemEndCrystal.java @@ -8,6 +8,7 @@ public class ItemEndCrystal extends Item { super(item_info); } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { World world = itemactioncontext.getWorld(); BlockPosition blockposition = itemactioncontext.getClickPosition(); @@ -40,7 +41,7 @@ public class ItemEndCrystal extends Item { // CraftBukkit end world.addEntity(entityendercrystal); if (world.worldProvider instanceof WorldProviderTheEnd) { - EnderDragonBattle enderdragonbattle = ((WorldProviderTheEnd) world.worldProvider).r(); + EnderDragonBattle enderdragonbattle = ((WorldProviderTheEnd) world.worldProvider).q(); enderdragonbattle.e(); } diff --git a/src/main/java/net/minecraft/server/ItemEnderPearl.java b/src/main/java/net/minecraft/server/ItemEnderPearl.java index 719210da1..570abc8b2 100644 --- a/src/main/java/net/minecraft/server/ItemEnderPearl.java +++ b/src/main/java/net/minecraft/server/ItemEnderPearl.java @@ -6,6 +6,7 @@ public class ItemEnderPearl extends Item { super(item_info); } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -13,6 +14,7 @@ public class ItemEnderPearl extends Item { if (!world.isClientSide) { EntityEnderPearl entityenderpearl = new EntityEnderPearl(world, entityhuman); + entityenderpearl.setItem(itemstack); entityenderpearl.a(entityhuman, entityhuman.pitch, entityhuman.yaw, 0.0F, 1.5F, 1.0F); // Paper start com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityenderpearl.getBukkitEntity()); @@ -23,8 +25,8 @@ public class ItemEnderPearl extends Item { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); - entityhuman.getCooldownTracker().a(this, 20); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); + entityhuman.getCooldownTracker().setCooldown(this, 20); } else { // Paper end if (entityhuman instanceof EntityPlayer) { @@ -34,15 +36,15 @@ public class ItemEnderPearl extends Item { } } - // Paper start - moved up - //if (!entityhuman.abilities.canInstantlyBuild) { - // itemstack.subtract(1); - //} - // - //world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.i.nextFloat() * 0.4F + 0.8F)); - //entityhuman.getCooldownTracker().a(this, 20); - // // CraftBukkit end - // Paper end +// // Paper start - moved up +// if (!entityhuman.abilities.canInstantlyBuild) { +// itemstack.subtract(1); +// } +// +// world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.i.nextFloat() * 0.4F + 0.8F)); +// entityhuman.getCooldownTracker().a(this, 20); +// // CraftBukkit end +// // Paper end entityhuman.b(StatisticList.ITEM_USED.b(this)); return new InteractionResultWrapper<>(EnumInteractionResult.SUCCESS, itemstack); diff --git a/src/main/java/net/minecraft/server/ItemExpBottle.java b/src/main/java/net/minecraft/server/ItemExpBottle.java index 23b06169e..2a0aded65 100644 --- a/src/main/java/net/minecraft/server/ItemExpBottle.java +++ b/src/main/java/net/minecraft/server/ItemExpBottle.java @@ -6,6 +6,7 @@ public class ItemExpBottle extends Item { super(item_info); } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); /* // Paper start @@ -13,11 +14,12 @@ public class ItemExpBottle extends Item { itemstack.subtract(1); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.i.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.i.nextFloat() * 0.4F + 0.8F)); */ // Paper end if (!world.isClientSide) { EntityThrownExpBottle entitythrownexpbottle = new EntityThrownExpBottle(world, entityhuman); + entitythrownexpbottle.setItem(itemstack); entitythrownexpbottle.a(entityhuman, entityhuman.pitch, entityhuman.yaw, -20.0F, 0.7F, 1.0F); // Paper start com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitythrownexpbottle.getBukkitEntity()); @@ -28,7 +30,7 @@ public class ItemExpBottle extends Item { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); } else { if (entityhuman instanceof EntityPlayer) { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); diff --git a/src/main/java/net/minecraft/server/ItemFireball.java b/src/main/java/net/minecraft/server/ItemFireball.java index 37a481e1e..8924753be 100644 --- a/src/main/java/net/minecraft/server/ItemFireball.java +++ b/src/main/java/net/minecraft/server/ItemFireball.java @@ -6,29 +6,51 @@ public class ItemFireball extends Item { super(item_info); } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { World world = itemactioncontext.getWorld(); if (world.isClientSide) { return EnumInteractionResult.SUCCESS; } else { - BlockPosition blockposition = itemactioncontext.getClickPosition().shift(itemactioncontext.getClickedFace()); + BlockPosition blockposition = itemactioncontext.getClickPosition(); + IBlockData iblockdata = world.getType(blockposition); - if (world.getType(blockposition).isAir()) { - // CraftBukkit start - fire BlockIgniteEvent - if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, itemactioncontext.getEntity()).isCancelled()) { - if (!itemactioncontext.getEntity().abilities.canInstantlyBuild) { - itemactioncontext.getItemStack().subtract(1); + if (iblockdata.getBlock() == Blocks.CAMPFIRE) { + if (!(Boolean) iblockdata.get(BlockCampfire.b) && !(Boolean) iblockdata.get(BlockCampfire.d)) { + // CraftBukkit start - fire BlockIgniteEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, itemactioncontext.getEntity()).isCancelled()) { + if (!itemactioncontext.getEntity().abilities.canInstantlyBuild) { + itemactioncontext.getItemStack().subtract(1); + } + return EnumInteractionResult.PASS; } - return EnumInteractionResult.PASS; + // CraftBukkit end + this.a(world, blockposition); + world.setTypeUpdate(blockposition, (IBlockData) iblockdata.set(BlockCampfire.b, true)); + } + } else { + blockposition = blockposition.shift(itemactioncontext.getClickedFace()); + if (world.getType(blockposition).isAir()) { + // CraftBukkit start - fire BlockIgniteEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, itemactioncontext.getEntity()).isCancelled()) { + if (!itemactioncontext.getEntity().abilities.canInstantlyBuild) { + itemactioncontext.getItemStack().subtract(1); + } + return EnumInteractionResult.PASS; + } + // CraftBukkit end + this.a(world, blockposition); + world.setTypeUpdate(blockposition, ((BlockFire) Blocks.FIRE).a((IBlockAccess) world, blockposition)); } - // CraftBukkit end - world.a((EntityHuman) null, blockposition, SoundEffects.ITEM_FIRECHARGE_USE, SoundCategory.BLOCKS, 1.0F, (ItemFireball.i.nextFloat() - ItemFireball.i.nextFloat()) * 0.2F + 1.0F); - world.setTypeUpdate(blockposition, ((BlockFire) Blocks.FIRE).a((IBlockAccess) world, blockposition)); } itemactioncontext.getItemStack().subtract(1); return EnumInteractionResult.SUCCESS; } } + + private void a(World world, BlockPosition blockposition) { + world.playSound((EntityHuman) null, blockposition, SoundEffects.ITEM_FIRECHARGE_USE, SoundCategory.BLOCKS, 1.0F, (ItemFireball.i.nextFloat() - ItemFireball.i.nextFloat()) * 0.2F + 1.0F); + } } diff --git a/src/main/java/net/minecraft/server/ItemFireworks.java b/src/main/java/net/minecraft/server/ItemFireworks.java index 13938775b..9e86ef4ce 100644 --- a/src/main/java/net/minecraft/server/ItemFireworks.java +++ b/src/main/java/net/minecraft/server/ItemFireworks.java @@ -9,14 +9,15 @@ public class ItemFireworks extends Item { super(item_info); } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { World world = itemactioncontext.getWorld(); if (!world.isClientSide) { - BlockPosition blockposition = itemactioncontext.getClickPosition(); ItemStack itemstack = itemactioncontext.getItemStack(); - EntityFireworks entityfireworks = new EntityFireworks(world, (double) ((float) blockposition.getX() + itemactioncontext.m()), (double) ((float) blockposition.getY() + itemactioncontext.n()), (double) ((float) blockposition.getZ() + itemactioncontext.o()), itemstack); - entityfireworks.spawningEntity = itemactioncontext.b.getUniqueID(); // Paper + Vec3D vec3d = itemactioncontext.j(); + EntityFireworks entityfireworks = new EntityFireworks(world, vec3d.x, vec3d.y, vec3d.z, itemstack); + entityfireworks.spawningEntity = itemactioncontext.getEntity().getUniqueID(); // Paper world.addEntity(entityfireworks); itemstack.subtract(1); @@ -25,14 +26,15 @@ public class ItemFireworks extends Item { return EnumInteractionResult.SUCCESS; } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { - if (entityhuman.dc()) { + if (entityhuman.isGliding()) { ItemStack itemstack = entityhuman.b(enumhand); if (!world.isClientSide) { - EntityFireworks entityfireworks = new EntityFireworks(world, itemstack, entityhuman); - entityfireworks.spawningEntity = entityhuman.getUniqueID(); // Paper - + // Paper start + final EntityFireworks entityfireworks = new EntityFireworks(world, itemstack, entityhuman); + entityfireworks.spawningEntity = entityhuman.getUniqueID(); // Paper start com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Firework) entityfireworks.getBukkitEntity()); if (event.callEvent() && world.addEntity(entityfireworks)) { @@ -41,8 +43,8 @@ public class ItemFireworks extends Item { } else ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); } else if (entityhuman instanceof EntityPlayer) { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); - // Paper end } + // Paper end } return new InteractionResultWrapper<>(EnumInteractionResult.SUCCESS, entityhuman.b(enumhand)); diff --git a/src/main/java/net/minecraft/server/ItemFish.java b/src/main/java/net/minecraft/server/ItemFish.java deleted file mode 100644 index a43606fb3..000000000 --- a/src/main/java/net/minecraft/server/ItemFish.java +++ /dev/null @@ -1,86 +0,0 @@ -package net.minecraft.server; - -public class ItemFish extends ItemFood { - - private final boolean a; - private final ItemFish.EnumFish b; - - public ItemFish(ItemFish.EnumFish itemfish_enumfish, boolean flag, Item.Info item_info) { - super(0, 0.0F, false, item_info); - this.b = itemfish_enumfish; - this.a = flag; - } - - public int getNutrition(ItemStack itemstack) { - ItemFish.EnumFish itemfish_enumfish = ItemFish.EnumFish.a(itemstack); - - return this.a && itemfish_enumfish.e() ? itemfish_enumfish.c() : itemfish_enumfish.a(); - } - - public float getSaturationModifier(ItemStack itemstack) { - return this.a && this.b.e() ? this.b.d() : this.b.b(); - } - - protected void a(ItemStack itemstack, World world, EntityHuman entityhuman) { - ItemFish.EnumFish itemfish_enumfish = ItemFish.EnumFish.a(itemstack); - - if (itemfish_enumfish == ItemFish.EnumFish.PUFFERFISH) { - // CraftBukkit start - entityhuman.addEffect(new MobEffect(MobEffects.POISON, 1200, 3), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); - entityhuman.addEffect(new MobEffect(MobEffects.HUNGER, 300, 2), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); - entityhuman.addEffect(new MobEffect(MobEffects.CONFUSION, 300, 1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); - // CraftBukkit end - } - - super.a(itemstack, world, entityhuman); - } - - public static enum EnumFish { - - COD(2, 0.1F, 5, 0.6F), SALMON(2, 0.1F, 6, 0.8F), TROPICAL_FISH(1, 0.1F), PUFFERFISH(1, 0.1F); - - private final int e; - private final float f; - private final int g; - private final float h; - private final boolean i; - - private EnumFish(int i, float f, int j, float f1) { - this.e = i; - this.f = f; - this.g = j; - this.h = f1; - this.i = j != 0; - } - - private EnumFish(int i, float f) { - this(i, f, 0, 0.0F); - } - - public int a() { - return this.e; - } - - public float b() { - return this.f; - } - - public int c() { - return this.g; - } - - public float d() { - return this.h; - } - - public boolean e() { - return this.i; - } - - public static ItemFish.EnumFish a(ItemStack itemstack) { - Item item = itemstack.getItem(); - - return item instanceof ItemFish ? ((ItemFish) item).b : ItemFish.EnumFish.COD; - } - } -} diff --git a/src/main/java/net/minecraft/server/ItemFishingRod.java b/src/main/java/net/minecraft/server/ItemFishingRod.java index 0c2305977..37c4707cf 100644 --- a/src/main/java/net/minecraft/server/ItemFishingRod.java +++ b/src/main/java/net/minecraft/server/ItemFishingRod.java @@ -26,32 +26,29 @@ public class ItemFishingRod extends Item { // CraftBukkit end } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); + int i; if (entityhuman.hookedFish != null) { - int i = entityhuman.hookedFish.b(itemstack); - - itemstack.damage(i, entityhuman); - entityhuman.a(enumhand); - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_FISHING_BOBBER_RETRIEVE, SoundCategory.NEUTRAL, 1.0F, 0.4F / (ItemFishingRod.i.nextFloat() * 0.4F + 0.8F)); - } else { - // world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_FISHING_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemFishingRod.i.nextFloat() * 0.4F + 0.8F)); if (!world.isClientSide) { - EntityFishingHook entityfishinghook = new EntityFishingHook(world, entityhuman); - int j = EnchantmentManager.c(itemstack); + i = entityhuman.hookedFish.b(itemstack); + itemstack.damage(i, entityhuman, (entityhuman1) -> { + entityhuman1.d(enumhand); + }); + } - if (j > 0) { - entityfishinghook.a(j); - } - - int k = EnchantmentManager.b(itemstack); - - if (k > 0) { - entityfishinghook.b(k); - } + entityhuman.a(enumhand); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_FISHING_BOBBER_RETRIEVE, SoundCategory.NEUTRAL, 1.0F, 0.4F / (ItemFishingRod.i.nextFloat() * 0.4F + 0.8F)); + } else { + // world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_FISHING_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemFishingRod.i.nextFloat() * 0.4F + 0.8F)); + if (!world.isClientSide) { + i = EnchantmentManager.c(itemstack); + int j = EnchantmentManager.b(itemstack); // CraftBukkit start + EntityFishingHook entityfishinghook = new EntityFishingHook(entityhuman, world, j, i); PlayerFishEvent playerFishEvent = new PlayerFishEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), null, (org.bukkit.entity.FishHook) entityfishinghook.getBukkitEntity(), PlayerFishEvent.State.FISHING); world.getServer().getPluginManager().callEvent(playerFishEvent); @@ -59,10 +56,9 @@ public class ItemFishingRod extends Item { entityhuman.hookedFish = null; return new InteractionResultWrapper(EnumInteractionResult.PASS, itemstack); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_FISHING_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemFishingRod.i.nextFloat() * 0.4F + 0.8F)); - // CraftBukkit end - + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_FISHING_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemFishingRod.i.nextFloat() * 0.4F + 0.8F)); world.addEntity(entityfishinghook); + // CraftBukkit end } entityhuman.a(enumhand); @@ -72,6 +68,7 @@ public class ItemFishingRod extends Item { return new InteractionResultWrapper<>(EnumInteractionResult.SUCCESS, itemstack); } + @Override public int c() { return 1; } diff --git a/src/main/java/net/minecraft/server/ItemFlintAndSteel.java b/src/main/java/net/minecraft/server/ItemFlintAndSteel.java index 3d58bf2d5..298dc620c 100644 --- a/src/main/java/net/minecraft/server/ItemFlintAndSteel.java +++ b/src/main/java/net/minecraft/server/ItemFlintAndSteel.java @@ -8,40 +8,60 @@ public class ItemFlintAndSteel extends Item { super(item_info); } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { EntityHuman entityhuman = itemactioncontext.getEntity(); World world = itemactioncontext.getWorld(); - BlockPosition blockposition = itemactioncontext.getClickPosition().shift(itemactioncontext.getClickedFace()); + BlockPosition blockposition = itemactioncontext.getClickPosition(); + BlockPosition blockposition1 = blockposition.shift(itemactioncontext.getClickedFace()); + IBlockData iblockdata; - if (a((GeneratorAccess) world, blockposition)) { + if (a(world.getType(blockposition1), (GeneratorAccess) world, blockposition1)) { // CraftBukkit start - Store the clicked block - if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, entityhuman).isCancelled()) { - itemactioncontext.getItemStack().damage(1, entityhuman); + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition1, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, entityhuman).isCancelled()) { + itemactioncontext.getItemStack().damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(itemactioncontext.n()); + }); return EnumInteractionResult.PASS; } // CraftBukkit end - world.a(entityhuman, blockposition, SoundEffects.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F, ItemFlintAndSteel.i.nextFloat() * 0.4F + 0.8F); - IBlockData iblockdata = ((BlockFire) Blocks.FIRE).a((IBlockAccess) world, blockposition); - - world.setTypeAndData(blockposition, iblockdata, 11); + world.playSound(entityhuman, blockposition1, SoundEffects.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F, ItemFlintAndSteel.i.nextFloat() * 0.4F + 0.8F); + iblockdata = ((BlockFire) Blocks.FIRE).a((IBlockAccess) world, blockposition1); + world.setTypeAndData(blockposition1, iblockdata, 11); ItemStack itemstack = itemactioncontext.getItemStack(); if (entityhuman instanceof EntityPlayer) { - CriterionTriggers.y.a((EntityPlayer) entityhuman, blockposition, itemstack); - } - - if (entityhuman != null) { - itemstack.damage(1, entityhuman); + CriterionTriggers.y.a((EntityPlayer) entityhuman, blockposition1, itemstack); + itemstack.damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(itemactioncontext.n()); + }); } return EnumInteractionResult.SUCCESS; } else { - return EnumInteractionResult.FAIL; + iblockdata = world.getType(blockposition); + if (a(iblockdata)) { + world.playSound(entityhuman, blockposition, SoundEffects.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F, ItemFlintAndSteel.i.nextFloat() * 0.4F + 0.8F); + world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockProperties.r, true), 11); + if (entityhuman != null) { + itemactioncontext.getItemStack().damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(itemactioncontext.n()); + }); + } + + return EnumInteractionResult.SUCCESS; + } else { + return EnumInteractionResult.FAIL; + } } } - public static boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition) { - IBlockData iblockdata = ((BlockFire) Blocks.FIRE).a((IBlockAccess) generatoraccess, blockposition); + public static boolean a(IBlockData iblockdata) { + return iblockdata.getBlock() == Blocks.CAMPFIRE && !(Boolean) iblockdata.get(BlockProperties.C) && !(Boolean) iblockdata.get(BlockProperties.r); + } + + public static boolean a(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition) { + IBlockData iblockdata1 = ((BlockFire) Blocks.FIRE).a((IBlockAccess) generatoraccess, blockposition); boolean flag = false; Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); @@ -53,6 +73,6 @@ public class ItemFlintAndSteel extends Item { } } - return generatoraccess.isEmpty(blockposition) && (iblockdata.canPlace(generatoraccess, blockposition) || flag); + return iblockdata.isAir() && (iblockdata1.canPlace(generatoraccess, blockposition) || flag); } } diff --git a/src/main/java/net/minecraft/server/ItemFood.java b/src/main/java/net/minecraft/server/ItemFood.java deleted file mode 100644 index 762b6f4a1..000000000 --- a/src/main/java/net/minecraft/server/ItemFood.java +++ /dev/null @@ -1,90 +0,0 @@ -package net.minecraft.server; - -public class ItemFood extends Item { - - private final int a; - private final float b; - private final boolean c; - private boolean d; - private boolean e; - private MobEffect k; - private float l; - - public ItemFood(int i, float f, boolean flag, Item.Info item_info) { - super(item_info); - this.a = i; - this.c = flag; - this.b = f; - } - - public ItemStack a(ItemStack itemstack, World world, EntityLiving entityliving) { - if (entityliving instanceof EntityHuman) { - EntityHuman entityhuman = (EntityHuman) entityliving; - - entityhuman.getFoodData().a(this, itemstack); - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_PLAYER_BURP, SoundCategory.PLAYERS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); - this.a(itemstack, world, entityhuman); - entityhuman.b(StatisticList.ITEM_USED.b(this)); - if (entityhuman instanceof EntityPlayer) { - CriterionTriggers.z.a((EntityPlayer) entityhuman, itemstack); - } - } - - itemstack.subtract(1); - return itemstack; - } - - protected void a(ItemStack itemstack, World world, EntityHuman entityhuman) { - if (!world.isClientSide && this.k != null && world.random.nextFloat() < this.l) { - entityhuman.addEffect(new MobEffect(this.k), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); // CraftBukkit - } - - } - - public int c(ItemStack itemstack) { - return this.e ? 16 : 32; - } - - public EnumAnimation d(ItemStack itemstack) { - return EnumAnimation.EAT; - } - - public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { - ItemStack itemstack = entityhuman.b(enumhand); - - if (entityhuman.q(this.d)) { - entityhuman.c(enumhand); - return new InteractionResultWrapper<>(EnumInteractionResult.SUCCESS, itemstack); - } else { - return new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); - } - } - - public int getNutrition(ItemStack itemstack) { - return this.a; - } - - public float getSaturationModifier(ItemStack itemstack) { - return this.b; - } - - public boolean d() { - return this.c; - } - - public ItemFood a(MobEffect mobeffect, float f) { - this.k = mobeffect; - this.l = f; - return this; - } - - public ItemFood e() { - this.d = true; - return this; - } - - public ItemFood f() { - this.e = true; - return this; - } -} diff --git a/src/main/java/net/minecraft/server/ItemGoldenApple.java b/src/main/java/net/minecraft/server/ItemGoldenApple.java deleted file mode 100644 index e81fa8dfd..000000000 --- a/src/main/java/net/minecraft/server/ItemGoldenApple.java +++ /dev/null @@ -1,18 +0,0 @@ -package net.minecraft.server; - -public class ItemGoldenApple extends ItemFood { - - public ItemGoldenApple(int i, float f, boolean flag, Item.Info item_info) { - super(i, f, flag, item_info); - } - - protected void a(ItemStack itemstack, World world, EntityHuman entityhuman) { - if (!world.isClientSide) { - // CraftBukkit start - entityhuman.addEffect(new MobEffect(MobEffects.REGENERATION, 100, 1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); - entityhuman.addEffect(new MobEffect(MobEffects.ABSORBTION, 2400, 0), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); - // CraftBukkit end - } - - } -} diff --git a/src/main/java/net/minecraft/server/ItemGoldenAppleEnchanted.java b/src/main/java/net/minecraft/server/ItemGoldenAppleEnchanted.java deleted file mode 100644 index 0a572d068..000000000 --- a/src/main/java/net/minecraft/server/ItemGoldenAppleEnchanted.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.minecraft.server; - -public class ItemGoldenAppleEnchanted extends ItemFood { - - public ItemGoldenAppleEnchanted(int i, float f, boolean flag, Item.Info item_info) { - super(i, f, flag, item_info); - } - - protected void a(ItemStack itemstack, World world, EntityHuman entityhuman) { - if (!world.isClientSide) { - // CraftBukkit start - entityhuman.addEffect(new MobEffect(MobEffects.REGENERATION, 400, 1), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); - entityhuman.addEffect(new MobEffect(MobEffects.RESISTANCE, 6000, 0), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); - entityhuman.addEffect(new MobEffect(MobEffects.FIRE_RESISTANCE, 6000, 0), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); - entityhuman.addEffect(new MobEffect(MobEffects.ABSORBTION, 2400, 3), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.FOOD); - // CraftBukkit end - } - - } -} diff --git a/src/main/java/net/minecraft/server/ItemHanging.java b/src/main/java/net/minecraft/server/ItemHanging.java index 82e7b3c56..c49bada2d 100644 --- a/src/main/java/net/minecraft/server/ItemHanging.java +++ b/src/main/java/net/minecraft/server/ItemHanging.java @@ -1,6 +1,5 @@ package net.minecraft.server; -import javax.annotation.Nullable; // CraftBukkit start import org.bukkit.entity.Player; import org.bukkit.event.hanging.HangingPlaceEvent; @@ -8,44 +7,62 @@ import org.bukkit.event.hanging.HangingPlaceEvent; public class ItemHanging extends Item { - private final Class a; + private final EntityTypes a; - public ItemHanging(Class oclass, Item.Info item_info) { + public ItemHanging(EntityTypes entitytypes, Item.Info item_info) { super(item_info); - this.a = oclass; + this.a = entitytypes; } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { BlockPosition blockposition = itemactioncontext.getClickPosition(); EnumDirection enumdirection = itemactioncontext.getClickedFace(); BlockPosition blockposition1 = blockposition.shift(enumdirection); EntityHuman entityhuman = itemactioncontext.getEntity(); + ItemStack itemstack = itemactioncontext.getItemStack(); - if (entityhuman != null && !this.a(entityhuman, enumdirection, itemactioncontext.getItemStack(), blockposition1)) { + if (entityhuman != null && !this.a(entityhuman, enumdirection, itemstack, blockposition1)) { return EnumInteractionResult.FAIL; } else { World world = itemactioncontext.getWorld(); - EntityHanging entityhanging = this.a(world, blockposition1, enumdirection); + Object object; - if (entityhanging != null && entityhanging.survives()) { + if (this.a == EntityTypes.PAINTING) { + object = new EntityPainting(world, blockposition1, enumdirection); + } else { + if (this.a != EntityTypes.ITEM_FRAME) { + return EnumInteractionResult.SUCCESS; + } + + object = new EntityItemFrame(world, blockposition1, enumdirection); + } + + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound != null) { + EntityTypes.a(world, entityhuman, (Entity) object, nbttagcompound); + } + + if (((EntityHanging) object).survives()) { if (!world.isClientSide) { // CraftBukkit start - fire HangingPlaceEvent Player who = (itemactioncontext.getEntity() == null) ? null : (Player) itemactioncontext.getEntity().getBukkitEntity(); - org.bukkit.block.Block blockClicked = world.getWorld().getBlockAt(blockposition); // Akarin + org.bukkit.block.Block blockClicked = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(enumdirection); - HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityhanging.getBukkitEntity(), who, blockClicked, blockFace); + HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) ((EntityHanging) object).getBukkitEntity(), who, blockClicked, blockFace); world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return EnumInteractionResult.FAIL; } // CraftBukkit end - entityhanging.m(); - world.addEntity(entityhanging); + ((EntityHanging) object).playPlaceSound(); + world.addEntity((Entity) object); } - itemactioncontext.getItemStack().subtract(1); + itemstack.subtract(1); } return EnumInteractionResult.SUCCESS; @@ -55,9 +72,4 @@ public class ItemHanging extends Item { protected boolean a(EntityHuman entityhuman, EnumDirection enumdirection, ItemStack itemstack, BlockPosition blockposition) { return !enumdirection.k().b() && entityhuman.a(blockposition, enumdirection, itemstack); } - - @Nullable - private EntityHanging a(World world, BlockPosition blockposition, EnumDirection enumdirection) { - return (EntityHanging) (this.a == EntityPainting.class ? new EntityPainting(world, blockposition, enumdirection) : (this.a == EntityItemFrame.class ? new EntityItemFrame(world, blockposition, enumdirection) : null)); - } } diff --git a/src/main/java/net/minecraft/server/ItemLeash.java b/src/main/java/net/minecraft/server/ItemLeash.java index c0f40c2ff..5bdc466de 100644 --- a/src/main/java/net/minecraft/server/ItemLeash.java +++ b/src/main/java/net/minecraft/server/ItemLeash.java @@ -11,12 +11,13 @@ public class ItemLeash extends Item { super(item_info); } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { World world = itemactioncontext.getWorld(); BlockPosition blockposition = itemactioncontext.getClickPosition(); Block block = world.getType(blockposition).getBlock(); - if (block instanceof BlockFence) { + if (block.a(TagsBlock.FENCES)) { EntityHuman entityhuman = itemactioncontext.getEntity(); if (!world.isClientSide && entityhuman != null) { @@ -30,7 +31,7 @@ public class ItemLeash extends Item { } public static boolean a(EntityHuman entityhuman, World world, BlockPosition blockposition) { - EntityLeash entityleash = EntityLeash.b(world, blockposition); + EntityLeash entityleash = null; boolean flag = false; double d0 = 7.0D; int i = blockposition.getX(); @@ -42,12 +43,12 @@ public class ItemLeash extends Item { while (iterator.hasNext()) { EntityInsentient entityinsentient = (EntityInsentient) iterator.next(); - if (entityinsentient.isLeashed() && entityinsentient.getLeashHolder() == entityhuman) { + if (entityinsentient.getLeashHolder() == entityhuman) { if (entityleash == null) { entityleash = EntityLeash.a(world, blockposition); // CraftBukkit start - fire HangingPlaceEvent - HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityleash.getBukkitEntity(), entityhuman != null ? (org.bukkit.entity.Player) entityhuman.getBukkitEntity() : null, world.getWorld().getBlockAt(blockposition), org.bukkit.block.BlockFace.SELF); // Akarin + HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityleash.getBukkitEntity(), entityhuman != null ? (org.bukkit.entity.Player) entityhuman.getBukkitEntity() : null, world.getWorld().getBlockAt(i, j, k), org.bukkit.block.BlockFace.SELF); world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { diff --git a/src/main/java/net/minecraft/server/ItemLingeringPotion.java b/src/main/java/net/minecraft/server/ItemLingeringPotion.java index 8d882b81b..ca3f9f8cc 100644 --- a/src/main/java/net/minecraft/server/ItemLingeringPotion.java +++ b/src/main/java/net/minecraft/server/ItemLingeringPotion.java @@ -6,22 +6,25 @@ public class ItemLingeringPotion extends ItemPotion { super(item_info); } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); /* // Paper start ItemStack itemstack1 = entityhuman.abilities.canInstantlyBuild ? itemstack.cloneItemStack() : itemstack.cloneAndSubtract(1); - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.i.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.i.nextFloat() * 0.4F + 0.8F)); */ // Paper end if (!world.isClientSide) { + // Paper start - ensure stack count matches vanilla behavior without modifying original stack yet ItemStack itemstack1 = itemstack.cloneItemStack(); if (!entityhuman.abilities.canInstantlyBuild) { itemstack1.setCount(1); } // Paper end - EntityPotion entitypotion = new EntityPotion(world, entityhuman, itemstack1); + EntityPotion entitypotion = new EntityPotion(world, entityhuman); + entitypotion.setItem(itemstack1); entitypotion.a(entityhuman, entityhuman.pitch, entityhuman.yaw, -20.0F, 0.5F, 1.0F); // Paper start com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitypotion.getBukkitEntity()); @@ -32,7 +35,7 @@ public class ItemLingeringPotion extends ItemPotion { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); } else { if (entityhuman instanceof EntityPlayer) { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); diff --git a/src/main/java/net/minecraft/server/ItemMilkBucket.java b/src/main/java/net/minecraft/server/ItemMilkBucket.java index 9bae2c570..a6477d26a 100644 --- a/src/main/java/net/minecraft/server/ItemMilkBucket.java +++ b/src/main/java/net/minecraft/server/ItemMilkBucket.java @@ -6,6 +6,7 @@ public class ItemMilkBucket extends Item { super(item_info); } + @Override public ItemStack a(ItemStack itemstack, World world, EntityLiving entityliving) { if (entityliving instanceof EntityPlayer) { EntityPlayer entityplayer = (EntityPlayer) entityliving; @@ -25,14 +26,17 @@ public class ItemMilkBucket extends Item { return itemstack.isEmpty() ? new ItemStack(Items.BUCKET) : itemstack; } - public int c(ItemStack itemstack) { + @Override + public int f_(ItemStack itemstack) { return 32; } - public EnumAnimation d(ItemStack itemstack) { + @Override + public EnumAnimation e_(ItemStack itemstack) { return EnumAnimation.DRINK; } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { entityhuman.c(enumhand); return new InteractionResultWrapper<>(EnumInteractionResult.SUCCESS, entityhuman.b(enumhand)); diff --git a/src/main/java/net/minecraft/server/ItemMinecart.java b/src/main/java/net/minecraft/server/ItemMinecart.java index 91b79939b..ec96fa0a4 100644 --- a/src/main/java/net/minecraft/server/ItemMinecart.java +++ b/src/main/java/net/minecraft/server/ItemMinecart.java @@ -8,10 +8,11 @@ import org.bukkit.event.block.BlockDispenseEvent; public class ItemMinecart extends Item { private static final IDispenseBehavior a = new DispenseBehaviorItem() { - private final DispenseBehaviorItem a = new DispenseBehaviorItem(); + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + @Override public ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); World world = isourceblock.getWorld(); double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX() * 1.125D; double d1 = Math.floor(isourceblock.getY()) + (double) enumdirection.getAdjacentY(); @@ -29,7 +30,7 @@ public class ItemMinecart extends Item { } } else { if (!iblockdata.isAir() || !world.getType(blockposition.down()).a(TagsBlock.RAILS)) { - return this.a.dispense(isourceblock, itemstack); + return this.b.dispense(isourceblock, itemstack); } IBlockData iblockdata1 = world.getType(blockposition.down()); @@ -45,7 +46,7 @@ public class ItemMinecart extends Item { // CraftBukkit start // EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.a(world, d0, d1 + d3, d2, ((ItemMinecart) itemstack.getItem()).b); ItemStack itemstack1 = itemstack.cloneAndSubtract(1); - org.bukkit.block.Block block2 = world.getWorld().getBlockAt(isourceblock.getBlockPosition()); // Akarin + org.bukkit.block.Block block2 = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); BlockDispenseEvent event = new BlockDispenseEvent(block2, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); @@ -82,6 +83,7 @@ public class ItemMinecart extends Item { return itemstack; } + @Override protected void a(ISourceBlock isourceblock) { isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); } @@ -94,6 +96,7 @@ public class ItemMinecart extends Item { BlockDispenser.a((IMaterial) this, ItemMinecart.a); } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { World world = itemactioncontext.getWorld(); BlockPosition blockposition = itemactioncontext.getClickPosition(); diff --git a/src/main/java/net/minecraft/server/ItemPotion.java b/src/main/java/net/minecraft/server/ItemPotion.java index 6584ee485..d45d990d8 100644 --- a/src/main/java/net/minecraft/server/ItemPotion.java +++ b/src/main/java/net/minecraft/server/ItemPotion.java @@ -9,6 +9,7 @@ public class ItemPotion extends Item { super(item_info); } + @Override public ItemStack a(ItemStack itemstack, World world, EntityLiving entityliving) { EntityHuman entityhuman = entityliving instanceof EntityHuman ? (EntityHuman) entityliving : null; @@ -52,23 +53,28 @@ public class ItemPotion extends Item { return itemstack; } - public int c(ItemStack itemstack) { + @Override + public int f_(ItemStack itemstack) { return 32; } - public EnumAnimation d(ItemStack itemstack) { + @Override + public EnumAnimation e_(ItemStack itemstack) { return EnumAnimation.DRINK; } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { entityhuman.c(enumhand); return new InteractionResultWrapper<>(EnumInteractionResult.SUCCESS, entityhuman.b(enumhand)); } - public String h(ItemStack itemstack) { + @Override + public String f(ItemStack itemstack) { return PotionUtil.d(itemstack).b(this.getName() + ".effect."); } + @Override public void a(CreativeModeTab creativemodetab, NonNullList nonnulllist) { if (this.a(creativemodetab)) { Iterator iterator = IRegistry.POTION.iterator(); diff --git a/src/main/java/net/minecraft/server/ItemRecord.java b/src/main/java/net/minecraft/server/ItemRecord.java index ddae1f516..d9cfdc0d8 100644 --- a/src/main/java/net/minecraft/server/ItemRecord.java +++ b/src/main/java/net/minecraft/server/ItemRecord.java @@ -1,30 +1,22 @@ package net.minecraft.server; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import java.util.List; import java.util.Map; -import java.util.Random; public class ItemRecord extends Item { private static final Map a = Maps.newHashMap(); - private static final List b = Lists.newArrayList(); - private final int c; - private final SoundEffect d; + private final int b; + private final SoundEffect c; protected ItemRecord(int i, SoundEffect soundeffect, Item.Info item_info) { super(item_info); - this.c = i; - this.d = soundeffect; - ItemRecord.a.put(this.d, this); - ItemRecord.b.add(this); - } - - public static ItemRecord a(Random random) { - return (ItemRecord) ItemRecord.b.get(random.nextInt(ItemRecord.b.size())); + this.b = i; + this.c = soundeffect; + ItemRecord.a.put(this.c, this); } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { World world = itemactioncontext.getWorld(); BlockPosition blockposition = itemactioncontext.getClickPosition(); @@ -52,6 +44,6 @@ public class ItemRecord extends Item { } public int d() { - return this.c; + return this.b; } } diff --git a/src/main/java/net/minecraft/server/ItemSign.java b/src/main/java/net/minecraft/server/ItemSign.java index 11045ee1e..d85f56655 100644 --- a/src/main/java/net/minecraft/server/ItemSign.java +++ b/src/main/java/net/minecraft/server/ItemSign.java @@ -4,19 +4,20 @@ import javax.annotation.Nullable; public class ItemSign extends ItemBlockWallable { - public static boolean openSign; // CraftBukkit - - public ItemSign(Item.Info item_info) { - super(Blocks.SIGN, Blocks.WALL_SIGN, item_info); + public static BlockPosition openSign; // CraftBukkit + + public ItemSign(Item.Info item_info, Block block, Block block1) { + super(block, block1, item_info); } + @Override protected boolean a(BlockPosition blockposition, World world, @Nullable EntityHuman entityhuman, ItemStack itemstack, IBlockData iblockdata) { boolean flag = super.a(blockposition, world, entityhuman, itemstack, iblockdata); if (!world.isClientSide && !flag && entityhuman != null) { // CraftBukkit start - SPIGOT-4678 // entityhuman.openSign((TileEntitySign) world.getTileEntity(blockposition)); - ItemSign.openSign = true; + ItemSign.openSign = blockposition; // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/ItemSkullPlayer.java b/src/main/java/net/minecraft/server/ItemSkullPlayer.java index a21ec22a9..4e4162dc4 100644 --- a/src/main/java/net/minecraft/server/ItemSkullPlayer.java +++ b/src/main/java/net/minecraft/server/ItemSkullPlayer.java @@ -10,7 +10,8 @@ public class ItemSkullPlayer extends ItemBlockWallable { super(block, block1, item_info); } - public IChatBaseComponent i(ItemStack itemstack) { + @Override + public IChatBaseComponent g(ItemStack itemstack) { if (itemstack.getItem() == Items.PLAYER_HEAD && itemstack.hasTag()) { String s = null; NBTTagCompound nbttagcompound = itemstack.getTag(); @@ -26,13 +27,14 @@ public class ItemSkullPlayer extends ItemBlockWallable { } if (s != null) { - return new ChatMessage(this.getName() + ".named", new Object[] { s}); + return new ChatMessage(this.getName() + ".named", new Object[]{s}); } } - return super.i(itemstack); + return super.g(itemstack); } + @Override public boolean a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); if (nbttagcompound.hasKeyOfType("SkullOwner", 8) && !StringUtils.isBlank(nbttagcompound.getString("SkullOwner"))) { diff --git a/src/main/java/net/minecraft/server/ItemSnowball.java b/src/main/java/net/minecraft/server/ItemSnowball.java index 95194ccdc..bbd22596e 100644 --- a/src/main/java/net/minecraft/server/ItemSnowball.java +++ b/src/main/java/net/minecraft/server/ItemSnowball.java @@ -6,6 +6,7 @@ public class ItemSnowball extends Item { super(item_info); } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); @@ -15,11 +16,12 @@ public class ItemSnowball extends Item { itemstack.subtract(1); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemSnowball.i.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemSnowball.i.nextFloat() * 0.4F + 0.8F)); */ if (!world.isClientSide) { EntitySnowball entitysnowball = new EntitySnowball(world, entityhuman); + entitysnowball.setItem(itemstack); entitysnowball.a(entityhuman, entityhuman.pitch, entityhuman.yaw, 0.0F, 1.5F, 1.0F); // Paper start com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity()); @@ -30,14 +32,13 @@ public class ItemSnowball extends Item { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); } else { if (entityhuman instanceof EntityPlayer) { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); } - return new InteractionResultWrapper(EnumInteractionResult.FAIL, itemstack); + return new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); } - // Paper end } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/ItemSplashPotion.java b/src/main/java/net/minecraft/server/ItemSplashPotion.java index 2bddefb80..4460ddc6d 100644 --- a/src/main/java/net/minecraft/server/ItemSplashPotion.java +++ b/src/main/java/net/minecraft/server/ItemSplashPotion.java @@ -6,22 +6,24 @@ public class ItemSplashPotion extends ItemPotion { super(item_info); } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); /* // Paper start ItemStack itemstack1 = entityhuman.abilities.canInstantlyBuild ? itemstack.cloneItemStack() : itemstack.cloneAndSubtract(1); - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.i.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.i.nextFloat() * 0.4F + 0.8F)); */ // Paper end if (!world.isClientSide) { + EntityPotion entitypotion = new EntityPotion(world, entityhuman); // Paper start - ensure stack count matches vanilla behavior without modifying original stack yet ItemStack itemstack1 = itemstack.cloneItemStack(); if (!entityhuman.abilities.canInstantlyBuild) { itemstack1.setCount(1); } // Paper end - EntityPotion entitypotion = new EntityPotion(world, entityhuman, itemstack1); + entitypotion.setItem(itemstack1); entitypotion.a(entityhuman, entityhuman.pitch, entityhuman.yaw, -20.0F, 0.5F, 1.0F); // Paper start com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitypotion.getBukkitEntity()); @@ -32,7 +34,7 @@ public class ItemSplashPotion extends ItemPotion { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); + world.playSound((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F)); } else { if (entityhuman instanceof EntityPlayer) { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java index eb130c012..0e164840f 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -12,6 +12,7 @@ import java.util.Comparator; import java.util.Locale; import java.util.Objects; import java.util.Random; +import java.util.function.Consumer; import java.util.function.Predicate; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; @@ -37,9 +38,9 @@ import org.bukkit.event.world.StructureGrowEvent; public final class ItemStack { - private static final Logger c = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public static final ItemStack a = new ItemStack((Item) null);public static final ItemStack NULL_ITEM = a; // Paper - OBFHELPER - public static final DecimalFormat b = D(); + public static final DecimalFormat b = F(); private int count; private int e; // Paper start @@ -61,7 +62,7 @@ public final class ItemStack { private ShapeDetectorBlock l; private boolean m; - private static DecimalFormat D() { + private static DecimalFormat F() { DecimalFormat decimalformat = new DecimalFormat("#.##"); decimalformat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)); @@ -91,26 +92,20 @@ public final class ItemStack { public ItemStack(IMaterial imaterial, int i) { this.item = imaterial == null ? null : imaterial.getItem(); this.count = i; - this.E(); + this.checkEmpty(); } // Called to run this stack through the data converter to handle older storage methods and serialized items - public void convertStack() { - if (false && MinecraftServer.getServer() != null) { // Skip for now, causes more issues than it solves - // Don't convert some things - both the old and new data values are valid - // Conversion would make getting then impossible - if (this.item == Blocks.PUMPKIN.getItem() || this.item == Blocks.GRASS.getItem() || this.item == Blocks.SNOW.getItem()) { - return; - } - + public void convertStack(int version) { + if (0 < version && version < CraftMagicNumbers.INSTANCE.getDataVersion()) { NBTTagCompound savedStack = new NBTTagCompound(); this.save(savedStack); - savedStack = (NBTTagCompound) MinecraftServer.getServer().dataConverterManager.update(DataConverterTypes.ITEM_STACK, new Dynamic(DynamicOpsNBT.a, savedStack), -1, CraftMagicNumbers.INSTANCE.getDataVersion()).getValue(); + savedStack = (NBTTagCompound) MinecraftServer.getServer().dataConverterManager.update(DataConverterTypes.ITEM_STACK, new Dynamic(DynamicOpsNBT.a, savedStack), version, CraftMagicNumbers.INSTANCE.getDataVersion()).getValue(); this.load(savedStack); } } - private void E() { + private void checkEmpty() { if (this.h && this == ItemStack.a) throw new AssertionError("TRAP"); // CraftBukkit this.h = false; this.h = this.isEmpty(); @@ -118,9 +113,7 @@ public final class ItemStack { // CraftBukkit - break into own method private void load(NBTTagCompound nbttagcompound) { - Item item = (Item) IRegistry.ITEM.get(new MinecraftKey(nbttagcompound.getString("id"))); - - this.item = item == null ? Items.AIR : item; + this.item = (Item) IRegistry.ITEM.get(new MinecraftKey(nbttagcompound.getString("id"))); this.count = nbttagcompound.getByte("Count"); if (nbttagcompound.hasKeyOfType("tag", 10)) { // CraftBukkit start - make defensive copy as this data may be coming from the save thread @@ -133,19 +126,20 @@ public final class ItemStack { if (this.getItem().usesDurability()) { this.setDamage(this.getDamage()); } + } private ItemStack(NBTTagCompound nbttagcompound) { this.load(nbttagcompound); // CraftBukkit end - this.E(); + this.checkEmpty(); } public static ItemStack a(NBTTagCompound nbttagcompound) { try { return new ItemStack(nbttagcompound); } catch (RuntimeException runtimeexception) { - ItemStack.c.debug("Tried to load invalid item: {}", nbttagcompound, runtimeexception); + ItemStack.LOGGER.debug("Tried to load invalid item: {}", nbttagcompound, runtimeexception); return ItemStack.a; } } @@ -172,7 +166,7 @@ public final class ItemStack { BlockPosition blockposition = itemactioncontext.getClickPosition(); ShapeDetectorBlock shapedetectorblock = new ShapeDetectorBlock(itemactioncontext.getWorld(), blockposition, false); - if (entityhuman != null && !entityhuman.abilities.mayBuild && !this.b(itemactioncontext.getWorld().F(), shapedetectorblock)) { + if (entityhuman != null && !entityhuman.abilities.mayBuild && !this.b(itemactioncontext.getWorld().t(), shapedetectorblock)) { return EnumInteractionResult.PASS; } else { // CraftBukkit start - handle all block place event logic here @@ -270,7 +264,7 @@ public final class ItemStack { IBlockData block = world.getType(newblockposition); if (!(block.getBlock() instanceof BlockTileEntity)) { // Containers get placed automatically - block.getBlock().onPlace(block, world, newblockposition, oldBlock); + block.getBlock().onPlace(block, world, newblockposition, oldBlock, true); } world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getType(newblockposition), updateFlag); // send null chunk as chunk.k() returns false by this point @@ -303,15 +297,18 @@ public final class ItemStack { } // SPIGOT-4678 - if (this.item instanceof ItemSign && ItemSign.openSign) { - ItemSign.openSign = false; - entityhuman.openSign((TileEntitySign) world.getTileEntity(new BlockActionContext(itemactioncontext).getClickPosition())); + if (this.item instanceof ItemSign && ItemSign.openSign != null) { + try { + entityhuman.openSign((TileEntitySign) world.getTileEntity(ItemSign.openSign)); + } finally { + ItemSign.openSign = null; + } } // SPIGOT-1288 - play sound stripped from ItemBlock if (this.item instanceof ItemBlock) { - SoundEffectType soundeffecttype = ((ItemBlock) this.item).getBlock().getStepSound(); - world.a(entityhuman, blockposition, soundeffecttype.e(), SoundCategory.BLOCKS, (soundeffecttype.a() + 1.0F) / 2.0F, soundeffecttype.b() * 0.8F); + SoundEffectType soundeffecttype = ((ItemBlock) this.item).getBlock().stepSound; + world.playSound(entityhuman, blockposition, soundeffecttype.e(), SoundCategory.BLOCKS, (soundeffecttype.a() + 1.0F) / 2.0F, soundeffecttype.b() * 0.8F); } entityhuman.b(StatisticList.ITEM_USED.b(item)); @@ -376,6 +373,12 @@ public final class ItemStack { } public void setDamage(int i) { + // CraftBukkit start - remove Damage tag if 0 + if (i <= 0) { + this.removeTag("Damage"); + return; + } + // CraftBukkit end this.getOrCreateTag().setInt("Damage", Math.max(0, i)); } @@ -430,21 +433,21 @@ public final class ItemStack { } } - public void damage(int i, EntityLiving entityliving) { - if (!(entityliving instanceof EntityHuman) || !((EntityHuman) entityliving).abilities.canInstantlyBuild) { + public void damage(int i, T t0, Consumer consumer) { + if (!t0.world.isClientSide && (!(t0 instanceof EntityHuman) || !((EntityHuman) t0).abilities.canInstantlyBuild)) { if (this.e()) { - if (this.isDamaged(i, entityliving.getRandom(), entityliving instanceof EntityPlayer ? (EntityPlayer) entityliving : null)) { - entityliving.c(this); + if (this.isDamaged(i, t0.getRandom(), t0 instanceof EntityPlayer ? (EntityPlayer) t0 : null)) { + consumer.accept(t0); Item item = this.getItem(); // CraftBukkit start - Check for item breaking - if (this.count == 1 && entityliving instanceof EntityHuman) { - org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((EntityHuman) entityliving, this); + if (this.count == 1 && t0 instanceof EntityHuman) { + org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((EntityHuman) t0, this); } // CraftBukkit end this.subtract(1); - if (entityliving instanceof EntityHuman) { - ((EntityHuman) entityliving).b(StatisticList.ITEM_BROKEN.b(item)); + if (t0 instanceof EntityHuman) { + ((EntityHuman) t0).b(StatisticList.ITEM_BROKEN.b(item)); } this.setDamage(0); @@ -484,7 +487,7 @@ public final class ItemStack { public ItemStack cloneItemStack(boolean origItem) { // Paper ItemStack itemstack = new ItemStack(origItem ? this.item : this.getItem(), this.count); // Paper - itemstack.d(this.B()); + itemstack.d(this.C()); if (this.tag != null) { itemstack.tag = this.tag.clone(); } @@ -521,11 +524,11 @@ public final class ItemStack { } public String j() { - return this.getItem().h(this); + return this.getItem().f(this); } public String toString() { - return this.count + "x" + this.getItem().getName(); + return this.count + " " + this.getItem(); } public void a(World world, Entity entity, int i, boolean flag) { @@ -546,17 +549,21 @@ public final class ItemStack { public int getItemUseMaxDuration() { return k(); } // Paper - OBFHELPER public int k() { - return this.getItem().c(this); + return this.getItem().f_(this); } public EnumAnimation l() { - return this.getItem().d(this); + return this.getItem().e_(this); } public void a(World world, EntityLiving entityliving, int i) { this.getItem().a(this, world, entityliving, i); } + public boolean m() { + return this.getItem().i(this); + } + public boolean hasTag() { return !this.h && this.tag != null && !this.tag.isEmpty(); } @@ -601,7 +608,7 @@ public final class ItemStack { return this.tag != null && this.tag.hasKeyOfType(s, 10) ? this.tag.getCompound(s) : null; } - public void c(String s) { + public void removeTag(String s) { if (this.tag != null && this.tag.hasKey(s)) { this.tag.remove(s); if (this.tag.isEmpty()) { @@ -648,7 +655,7 @@ public final class ItemStack { } } - return this.getItem().i(this); + return this.getItem().g(this); } public ItemStack a(@Nullable IChatBaseComponent ichatbasecomponent) { @@ -663,13 +670,13 @@ public final class ItemStack { return this; } - public void r() { + public void s() { NBTTagCompound nbttagcompound = this.b("display"); if (nbttagcompound != null) { nbttagcompound.remove("Name"); if (nbttagcompound.isEmpty()) { - this.c("display"); + this.removeTag("display"); } } @@ -685,12 +692,12 @@ public final class ItemStack { return nbttagcompound != null && nbttagcompound.hasKeyOfType("Name", 8); } - public EnumItemRarity u() { - return this.getItem().j(this); + public EnumItemRarity v() { + return this.getItem().h(this); } public boolean canEnchant() { - return !this.getItem().a(this) ? false : !this.hasEnchantments(); + return !this.getItem().g_(this) ? false : !this.hasEnchantments(); } public void addEnchantment(Enchantment enchantment, int i) { @@ -704,7 +711,7 @@ public final class ItemStack { nbttagcompound.setString("id", String.valueOf(IRegistry.ENCHANTMENT.getKey(enchantment))); nbttagcompound.setShort("lvl", (short) ((byte) i)); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); processEnchantOrder(nbttagcompound); // Paper } @@ -717,7 +724,7 @@ public final class ItemStack { this.getOrCreateTag().set(s, nbtbase); } - public boolean x() { + public boolean y() { return this.i != null; } @@ -726,7 +733,7 @@ public final class ItemStack { } @Nullable - public EntityItemFrame y() { + public EntityItemFrame z() { return this.h ? null : this.i; } @@ -737,9 +744,7 @@ public final class ItemStack { public void setRepairCost(int i) { // CraftBukkit start - remove RepairCost tag when 0 (SPIGOT-3945) if (i == 0) { - if (this.hasTag()) { - this.tag.remove("RepairCost"); - } + this.removeTag("RepairCost"); return; } // CraftBukkit end @@ -757,7 +762,7 @@ public final class ItemStack { NBTTagCompound nbttagcompound = nbttaglist.getCompound(i); AttributeModifier attributemodifier = GenericAttributes.a(nbttagcompound); - if (attributemodifier != null && (!nbttagcompound.hasKeyOfType("Slot", 8) || nbttagcompound.getString("Slot").equals(enumitemslot.getSlotName())) && attributemodifier.a().getLeastSignificantBits() != 0L && attributemodifier.a().getMostSignificantBits() != 0L) { + if (attributemodifier != null && (!nbttagcompound.hasKeyOfType("Slot", 8) || nbttagcompound.getString("Slot").equals(enumitemslot.getSlotName())) && attributemodifier.getUniqueId().getLeastSignificantBits() != 0L && attributemodifier.getUniqueId().getMostSignificantBits() != 0L) { ((Multimap) object).put(nbttagcompound.getString("AttributeName"), attributemodifier); } } @@ -782,7 +787,7 @@ public final class ItemStack { nbttagcompound.setString("Slot", enumitemslot.getSlotName()); } - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); } // CraftBukkit start @@ -793,7 +798,7 @@ public final class ItemStack { } // CraftBukkit end - public IChatBaseComponent A() { + public IChatBaseComponent B() { IChatBaseComponent ichatbasecomponent = (new ChatComponentText("")).addSibling(this.getName()); if (this.hasName()) { @@ -805,7 +810,7 @@ public final class ItemStack { if (!this.h) { NBTTagCompound nbttagcompound = this.save(new NBTTagCompound()); - ichatbasecomponent1.a(this.u().e).a((chatmodifier) -> { + ichatbasecomponent1.a(this.v().e).a((chatmodifier) -> { chatmodifier.setChatHoverable(new ChatHoverable(ChatHoverable.EnumHoverAction.SHOW_ITEM, new ChatComponentText(nbttagcompound.toString()))); }); } @@ -875,7 +880,7 @@ public final class ItemStack { } } - public int B() { + public int C() { return this.e; } @@ -889,7 +894,7 @@ public final class ItemStack { public void setCount(int i) { this.count = i; - this.E(); + this.checkEmpty(); } public void add(int i) { @@ -899,4 +904,12 @@ public final class ItemStack { public void subtract(int i) { this.add(-i); } + + public void b(World world, EntityLiving entityliving, int i) { + this.getItem().a(world, entityliving, this, i); + } + + public boolean E() { + return this.getItem().isFood(); + } } diff --git a/src/main/java/net/minecraft/server/ItemTrident.java b/src/main/java/net/minecraft/server/ItemTrident.java index 40b8eb203..c40815736 100644 --- a/src/main/java/net/minecraft/server/ItemTrident.java +++ b/src/main/java/net/minecraft/server/ItemTrident.java @@ -9,35 +9,44 @@ public class ItemTrident extends Item { // CraftBukkit start - obfuscator went a little crazy /* this.a(new MinecraftKey("throwing"), (itemstack, world, entityliving) -> { - return entityliving != null && entityliving.isHandRaised() && entityliving.cW() == itemstack ? 1.0F : 0.0F; + return entityliving != null && entityliving.isHandRaised() && entityliving.dl() == itemstack ? 1.0F : 0.0F; }); */ // CraftBukkit end } + @Override public boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman) { - return !entityhuman.u(); + return !entityhuman.isCreative(); } - public EnumAnimation d(ItemStack itemstack) { + @Override + public EnumAnimation e_(ItemStack itemstack) { return EnumAnimation.SPEAR; } - public int c(ItemStack itemstack) { + @Override + public int f_(ItemStack itemstack) { return 72000; } + @Override public void a(ItemStack itemstack, World world, EntityLiving entityliving, int i) { if (entityliving instanceof EntityHuman) { EntityHuman entityhuman = (EntityHuman) entityliving; - int j = this.c(itemstack) - i; + int j = this.f_(itemstack) - i; if (j >= 10) { int k = EnchantmentManager.g(itemstack); - if (k <= 0 || entityhuman.ao()) { + if (k <= 0 || entityhuman.isInWaterOrRain()) { if (!world.isClientSide) { - // itemstack.damage(1, entityhuman); // CraftBukkit - moved down + // CraftBukkit - moved down + /* + itemstack.damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(entityliving.getRaisedHand()); + }); + */ if (k == 0) { EntityThrownTrident entitythrowntrident = new EntityThrownTrident(world, entityhuman, itemstack); @@ -54,10 +63,13 @@ public class ItemTrident extends Item { return; } - itemstack.damage(1, entityhuman); + itemstack.damage(1, entityhuman, (entityhuman1) -> { + entityhuman1.d(entityliving.getRaisedHand()); + }); entitythrowntrident.trident = itemstack.cloneItemStack(); // SPIGOT-4511 update since damage call moved // CraftBukkit end + world.playSound((EntityHuman) null, (Entity) entitythrowntrident, SoundEffects.ITEM_TRIDENT_THROW, SoundCategory.PLAYERS, 1.0F, 1.0F); if (!entityhuman.abilities.canInstantlyBuild) { entityhuman.inventory.f(itemstack); } @@ -65,8 +77,6 @@ public class ItemTrident extends Item { } entityhuman.b(StatisticList.ITEM_USED.b(this)); - SoundEffect soundeffect = SoundEffects.ITEM_TRIDENT_THROW; - if (k > 0) { // CraftBukkit start org.bukkit.event.player.PlayerRiptideEvent event = new org.bukkit.event.player.PlayerRiptideEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); @@ -84,6 +94,15 @@ public class ItemTrident extends Item { f3 *= f6 / f5; f4 *= f6 / f5; entityhuman.f((double) f2, (double) f3, (double) f4); + entityhuman.q(20); + if (entityhuman.onGround) { + float f7 = 1.1999999F; + + entityhuman.move(EnumMoveType.SELF, new Vec3D(0.0D, 1.1999999284744263D, 0.0D)); + } + + SoundEffect soundeffect; + if (k >= 3) { soundeffect = SoundEffects.ITEM_TRIDENT_RIPTIDE_3; } else if (k == 2) { @@ -92,26 +111,21 @@ public class ItemTrident extends Item { soundeffect = SoundEffects.ITEM_TRIDENT_RIPTIDE_1; } - entityhuman.o(20); - if (entityhuman.onGround) { - float f7 = 1.1999999F; - - entityhuman.move(EnumMoveType.SELF, 0.0D, 1.1999999284744263D, 0.0D); - } + world.playSound((EntityHuman) null, (Entity) entityhuman, soundeffect, SoundCategory.PLAYERS, 1.0F, 1.0F); } - world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, soundeffect, SoundCategory.PLAYERS, 1.0F, 1.0F); } } } } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); if (itemstack.getDamage() >= itemstack.h()) { return new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); - } else if (EnchantmentManager.g(itemstack) > 0 && !entityhuman.ao()) { + } else if (EnchantmentManager.g(itemstack) > 0 && !entityhuman.isInWaterOrRain()) { return new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); } else { entityhuman.c(enumhand); @@ -119,30 +133,38 @@ public class ItemTrident extends Item { } } + @Override public boolean a(ItemStack itemstack, EntityLiving entityliving, EntityLiving entityliving1) { - itemstack.damage(1, entityliving1); + itemstack.damage(1, entityliving1, (entityliving2) -> { + entityliving2.c(EnumItemSlot.MAINHAND); + }); return true; } + @Override public boolean a(ItemStack itemstack, World world, IBlockData iblockdata, BlockPosition blockposition, EntityLiving entityliving) { - if ((double) iblockdata.e(world, blockposition) != 0.0D) { - itemstack.damage(2, entityliving); + if ((double) iblockdata.f(world, blockposition) != 0.0D) { + itemstack.damage(2, entityliving, (entityliving1) -> { + entityliving1.c(EnumItemSlot.MAINHAND); + }); } return true; } + @Override public Multimap a(EnumItemSlot enumitemslot) { Multimap multimap = super.a(enumitemslot); if (enumitemslot == EnumItemSlot.MAINHAND) { - multimap.put(GenericAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ItemTrident.g, "Tool modifier", 8.0D, 0)); - multimap.put(GenericAttributes.g.getName(), new AttributeModifier(ItemTrident.h, "Tool modifier", -2.9000000953674316D, 0)); + multimap.put(GenericAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ItemTrident.g, "Tool modifier", 8.0D, AttributeModifier.Operation.ADDITION)); + multimap.put(GenericAttributes.ATTACK_SPEED.getName(), new AttributeModifier(ItemTrident.h, "Tool modifier", -2.9000000953674316D, AttributeModifier.Operation.ADDITION)); } return multimap; } + @Override public int c() { return 1; } diff --git a/src/main/java/net/minecraft/server/ItemWaterLily.java b/src/main/java/net/minecraft/server/ItemWaterLily.java index fdeb5411d..694a3a70e 100644 --- a/src/main/java/net/minecraft/server/ItemWaterLily.java +++ b/src/main/java/net/minecraft/server/ItemWaterLily.java @@ -6,21 +6,25 @@ public class ItemWaterLily extends ItemBlock { super(block, item_info); } + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { return EnumInteractionResult.PASS; } + @Override public InteractionResultWrapper a(World world, EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.b(enumhand); - MovingObjectPosition movingobjectposition = this.a(world, entityhuman, true); + MovingObjectPosition movingobjectposition = a(world, entityhuman, RayTrace.FluidCollisionOption.SOURCE_ONLY); - if (movingobjectposition == null) { + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.MISS) { return new InteractionResultWrapper<>(EnumInteractionResult.PASS, itemstack); } else { - if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { - BlockPosition blockposition = movingobjectposition.getBlockPosition(); + if (movingobjectposition.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + MovingObjectPositionBlock movingobjectpositionblock = (MovingObjectPositionBlock) movingobjectposition; + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition(); + EnumDirection enumdirection = movingobjectpositionblock.getDirection(); - if (!world.a(entityhuman, blockposition) || !entityhuman.a(blockposition.shift(movingobjectposition.direction), movingobjectposition.direction, itemstack)) { + if (!world.a(entityhuman, blockposition) || !entityhuman.a(blockposition.shift(enumdirection), enumdirection, itemstack)) { return new InteractionResultWrapper<>(EnumInteractionResult.FAIL, itemstack); } @@ -29,7 +33,7 @@ public class ItemWaterLily extends ItemBlock { Material material = iblockdata.getMaterial(); Fluid fluid = world.getFluid(blockposition); - if ((fluid.c() == FluidTypes.WATER || material == Material.ICE) && world.isEmpty(blockposition1)) { + if ((fluid.getType() == FluidTypes.WATER || material == Material.ICE) && world.isEmpty(blockposition1)) { // CraftBukkit start - special case for handling block placement with water lilies org.bukkit.block.BlockState blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(world, blockposition1); world.setTypeAndData(blockposition1, Blocks.LILY_PAD.getBlockData(), 11); @@ -48,7 +52,7 @@ public class ItemWaterLily extends ItemBlock { } entityhuman.b(StatisticList.ITEM_USED.b(this)); - world.a(entityhuman, blockposition, SoundEffects.BLOCK_LILY_PAD_PLACE, SoundCategory.BLOCKS, 1.0F, 1.0F); + world.playSound(entityhuman, blockposition, SoundEffects.BLOCK_LILY_PAD_PLACE, SoundCategory.BLOCKS, 1.0F, 1.0F); return new InteractionResultWrapper<>(EnumInteractionResult.SUCCESS, itemstack); } } diff --git a/src/main/java/net/minecraft/server/ItemWorldMap.java b/src/main/java/net/minecraft/server/ItemWorldMap.java index c0540ca9b..cf9efcf11 100644 --- a/src/main/java/net/minecraft/server/ItemWorldMap.java +++ b/src/main/java/net/minecraft/server/ItemWorldMap.java @@ -20,16 +20,21 @@ public class ItemWorldMap extends ItemWorldMapBase { public static ItemStack createFilledMapView(World world, int i, int j, byte b0, boolean flag, boolean flag1) { ItemStack itemstack = new ItemStack(Items.FILLED_MAP); - a(itemstack, world, i, j, b0, flag, flag1, ((WorldServer) world).dimension); // CraftBukkit - fixes Bukkit multiworld maps + a(itemstack, world, i, j, b0, flag, flag1, world.worldProvider.getDimensionManager()); return itemstack; } + @Nullable + public static WorldMap a(ItemStack itemstack, World world) { + return world.a(a(e(itemstack))); + } + @Nullable public static WorldMap getSavedMap(ItemStack itemstack, World world) { - WorldMap worldmap = a((GeneratorAccess) world, "map_" + e(itemstack)); + WorldMap worldmap = a(itemstack, world); if (worldmap == null && !world.isClientSide) { - worldmap = a(itemstack, world, world.getWorldData().b(), world.getWorldData().d(), 3, false, false, ((WorldServer) world).dimension); // CraftBukkit - fixes Bukkit multiworld maps + worldmap = a(itemstack, world, world.getWorldData().b(), world.getWorldData().d(), 3, false, false, world.worldProvider.getDimensionManager()); } return worldmap; @@ -42,12 +47,11 @@ public class ItemWorldMap extends ItemWorldMapBase { } private static WorldMap a(ItemStack itemstack, World world, int i, int j, int k, boolean flag, boolean flag1, DimensionManager dimensionmanager) { - World worldMain = world.getServer().getServer().getWorldServer(DimensionManager.OVERWORLD); // CraftBukkit - store reference to primary world - int l = worldMain.a(DimensionManager.OVERWORLD, "map"); // CraftBukkit - use primary world for maps - WorldMap worldmap = new WorldMap("map_" + l); + int l = world.getWorldMapCount(); + WorldMap worldmap = new WorldMap(a(l)); worldmap.a(i, j, k, flag, flag1, dimensionmanager); - worldMain.a(DimensionManager.OVERWORLD, worldmap.getId(), (PersistentBase) worldmap); // CraftBukkit - use primary world for maps + world.a(worldmap); itemstack.getOrCreateTag().setInt("map", l); // CraftBukkit start @@ -57,23 +61,12 @@ public class ItemWorldMap extends ItemWorldMapBase { return worldmap; } - @Nullable - public static WorldMap a(GeneratorAccess generatoraccess, String s) { - // CraftBukkit start - use primary world for maps and call event - WorldMap worldmap = (WorldMap) MinecraftServer.getServer().getWorldServer(DimensionManager.OVERWORLD).a(DimensionManager.OVERWORLD, (id) -> { - // We only get here when the data file exists, but is not a valid map - WorldMap newMap = new WorldMap(id); - MapInitializeEvent event = new MapInitializeEvent(newMap.mapView); - Bukkit.getServer().getPluginManager().callEvent(event); - return newMap; - }, s); - return worldmap; - // CraftBukkit end + public static String a(int i) { + return "map_" + i; } public void a(World world, Entity entity, WorldMap worldmap) { - // CraftBukkit - world.worldProvider -> ((WorldServer) world) - if (((WorldServer) world).dimension == worldmap.map && entity instanceof EntityHuman) { + if (world.worldProvider.getDimensionManager() == worldmap.map && entity instanceof EntityHuman) { int i = 1 << worldmap.scale; int j = worldmap.centerX; int k = worldmap.centerZ; @@ -106,6 +99,7 @@ public class ItemWorldMap extends ItemWorldMapBase { Chunk chunk = world.getChunkAtWorldCoords(new BlockPosition(k2, 0, l2)); if (!chunk.isEmpty()) { + ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); int i3 = k2 & 15; int j3 = l2 & 15; int k3 = 0; @@ -116,14 +110,15 @@ public class ItemWorldMap extends ItemWorldMapBase { l3 = l3 * l3 * 31287121 + l3 * 11; if ((l3 >> 20 & 1) == 0) { - multiset.add(Blocks.DIRT.getBlockData().d(world, BlockPosition.ZERO), 10); + multiset.add(Blocks.DIRT.getBlockData().c((IBlockAccess) world, BlockPosition.ZERO), 10); } else { - multiset.add(Blocks.STONE.getBlockData().d(world, BlockPosition.ZERO), 100); + multiset.add(Blocks.STONE.getBlockData().c((IBlockAccess) world, BlockPosition.ZERO), 100); } d1 = 100.0D; } else { BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition1 = new BlockPosition.MutableBlockPosition(); for (int i4 = 0; i4 < i; ++i4) { for (int j4 = 0; j4 < i; ++j4) { @@ -133,19 +128,22 @@ public class ItemWorldMap extends ItemWorldMapBase { if (k4 > 1) { do { --k4; - iblockdata = chunk.getBlockData(i4 + i3, k4, j4 + j3); - blockposition_mutableblockposition.c((chunk.locX << 4) + i4 + i3, k4, (chunk.locZ << 4) + j4 + j3); - } while (iblockdata.d(world, blockposition_mutableblockposition) == MaterialMapColor.b && k4 > 0); + blockposition_mutableblockposition.d(chunkcoordintpair.d() + i4 + i3, k4, chunkcoordintpair.e() + j4 + j3); + iblockdata = chunk.getType(blockposition_mutableblockposition); + } while (iblockdata.c((IBlockAccess) world, (BlockPosition) blockposition_mutableblockposition) == MaterialMapColor.b && k4 > 0); - if (k4 > 0 && !iblockdata.s().e()) { + if (k4 > 0 && !iblockdata.p().isEmpty()) { int l4 = k4 - 1; + blockposition_mutableblockposition1.g(blockposition_mutableblockposition); + IBlockData iblockdata1; do { - iblockdata1 = chunk.getBlockData(i4 + i3, l4--, j4 + j3); + blockposition_mutableblockposition1.p(l4--); + iblockdata1 = chunk.getType(blockposition_mutableblockposition1); ++k3; - } while (l4 > 0 && !iblockdata1.s().e()); + } while (l4 > 0 && !iblockdata1.p().isEmpty()); iblockdata = this.a(world, iblockdata, (BlockPosition) blockposition_mutableblockposition); } @@ -153,9 +151,9 @@ public class ItemWorldMap extends ItemWorldMapBase { iblockdata = Blocks.BEDROCK.getBlockData(); } - worldmap.a(world, (chunk.locX << 4) + i4 + i3, (chunk.locZ << 4) + j4 + j3); + worldmap.a(world, chunkcoordintpair.d() + i4 + i3, chunkcoordintpair.e() + j4 + j3); d1 += (double) k4 / (double) (i * i); - multiset.add(iblockdata.d(world, blockposition_mutableblockposition)); + multiset.add(iblockdata.c((IBlockAccess) world, (BlockPosition) blockposition_mutableblockposition)); } } } @@ -207,21 +205,20 @@ public class ItemWorldMap extends ItemWorldMapBase { } private IBlockData a(World world, IBlockData iblockdata, BlockPosition blockposition) { - Fluid fluid = iblockdata.s(); + Fluid fluid = iblockdata.p(); - return !fluid.e() && !Block.a(iblockdata.getCollisionShape(world, blockposition), EnumDirection.UP) ? fluid.i() : iblockdata; + return !fluid.isEmpty() && !iblockdata.d(world, blockposition, EnumDirection.UP) ? fluid.getBlockData() : iblockdata; } private static boolean a(BiomeBase[] abiomebase, int i, int j, int k) { - return abiomebase[j * i + k * i * 128 * i].h() >= 0.0F; + return abiomebase[j * i + k * i * 128 * i].g() >= 0.0F; } public static void applySepiaFilter(World world, ItemStack itemstack) { WorldMap worldmap = getSavedMap(itemstack, world); if (worldmap != null) { - // CraftBukkit - world.worldProvider -> ((WorldServer) world) - if (((WorldServer) world).dimension == worldmap.map) { + if (world.worldProvider.getDimensionManager() == worldmap.map) { int i = 1 << worldmap.scale; int j = worldmap.centerX; int k = worldmap.centerZ; @@ -268,7 +265,7 @@ public class ItemWorldMap extends ItemWorldMapBase { int k1 = 3; MaterialMapColor materialmapcolor = MaterialMapColor.b; - if (biomebase.h() < 0.0F) { + if (biomebase.g() < 0.0F) { materialmapcolor = MaterialMapColor.q; if (j1 > 7 && i1 % 2 == 0) { k1 = (l + (int) (MathHelper.sin((float) i1 + 0.0F) * 7.0F)) / 8 % 5; @@ -307,28 +304,33 @@ public class ItemWorldMap extends ItemWorldMapBase { } } + @Override public void a(ItemStack itemstack, World world, Entity entity, int i, boolean flag) { if (!world.isClientSide) { WorldMap worldmap = getSavedMap(itemstack, world); - if (entity instanceof EntityHuman) { - EntityHuman entityhuman = (EntityHuman) entity; + if (worldmap != null) { + if (entity instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) entity; + + worldmap.a(entityhuman, itemstack); + } + + if (!worldmap.locked && (flag || entity instanceof EntityHuman && ((EntityHuman) entity).getItemInOffHand() == itemstack)) { + this.a(world, entity, worldmap); + } - worldmap.a(entityhuman, itemstack); } - - if (flag || entity instanceof EntityHuman && ((EntityHuman) entity).getItemInOffHand() == itemstack) { - this.a(world, entity, worldmap); - } - } } @Nullable + @Override public Packet a(ItemStack itemstack, World world, EntityHuman entityhuman) { return getSavedMap(itemstack, world).a(itemstack, world, entityhuman); } + @Override public void b(ItemStack itemstack, World world, EntityHuman entityhuman) { NBTTagCompound nbttagcompound = itemstack.getTag(); @@ -348,11 +350,27 @@ public class ItemWorldMap extends ItemWorldMapBase { } + @Nullable + public static ItemStack b(World world, ItemStack itemstack) { + WorldMap worldmap = getSavedMap(itemstack, world); + + if (worldmap != null) { + ItemStack itemstack1 = itemstack.cloneItemStack(); + WorldMap worldmap1 = a(itemstack1, world, 0, 0, worldmap.scale, worldmap.track, worldmap.unlimitedTracking, worldmap.map); + + worldmap1.a(worldmap); + return itemstack1; + } else { + return null; + } + } + + @Override public EnumInteractionResult a(ItemActionContext itemactioncontext) { IBlockData iblockdata = itemactioncontext.getWorld().getType(itemactioncontext.getClickPosition()); if (iblockdata.a(TagsBlock.BANNERS)) { - if (!itemactioncontext.g.isClientSide) { + if (!itemactioncontext.e.isClientSide) { WorldMap worldmap = getSavedMap(itemactioncontext.getItemStack(), itemactioncontext.getWorld()); worldmap.a((GeneratorAccess) itemactioncontext.getWorld(), itemactioncontext.getClickPosition()); diff --git a/src/main/java/net/minecraft/server/JsonList.java b/src/main/java/net/minecraft/server/JsonList.java index 56f8d3649..c97be42dd 100644 --- a/src/main/java/net/minecraft/server/JsonList.java +++ b/src/main/java/net/minecraft/server/JsonList.java @@ -12,11 +12,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; -import com.mojang.authlib.GameProfile; - -import io.akarin.server.core.AkarinAsyncExecutor; -import io.akarin.server.misc.CopyOnWriteHashMap; - import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -29,29 +24,23 @@ import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.Iterator; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.logging.Level; - import javax.annotation.Nullable; import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; public class JsonList> { - protected static final Logger a = LogManager.getLogger(); + protected static final Logger LOGGER = LogManager.getLogger(); protected final Gson b; private final File c; // Paper - replace HashMap is ConcurrentHashMap - protected final Map d = new CopyOnWriteHashMap(); private final Map getBackingMap() { return this.d; } // Paper - OBFHELPER // Akarin + private final Map d = Maps.newConcurrentMap(); private final Map getBackingMap() { return this.d; } // Paper - OBFHELPER private boolean e = true; private static final ParameterizedType f = new ParameterizedType() { public Type[] getActualTypeArguments() { - return new Type[] { JsonListEntry.class}; + return new Type[]{JsonListEntry.class}; } public Type getRawType() { @@ -75,7 +64,7 @@ public class JsonList> { return this.e; } - public void setEnabled(boolean flag) { a(flag); } // Paper - OBFHeLPER + public void setEnabled(boolean flag) { this.a(flag); } // Paper - OBFHeLPER public void a(boolean flag) { this.e = flag; } @@ -90,7 +79,7 @@ public class JsonList> { try { this.save(); } catch (IOException ioexception) { - JsonList.a.warn("Could not save the list after adding a user.", ioexception); + JsonList.LOGGER.warn("Could not save the list after adding a user.", ioexception); } } @@ -112,7 +101,7 @@ public class JsonList> { try { this.save(); } catch (IOException ioexception) { - JsonList.a.warn("Could not save the list after removing a user.", ioexception); + JsonList.LOGGER.warn("Could not save the list after removing a user.", ioexception); } } @@ -179,7 +168,6 @@ public class JsonList> { } public void save() throws IOException { - Runnable runnable = () -> { // Akarin this.removeStaleEntries(); // Paper - remove expired values before saving Collection collection = this.d.values(); String s = this.b.toJson(collection); @@ -188,13 +176,9 @@ public class JsonList> { try { bufferedwriter = Files.newWriter(this.c, StandardCharsets.UTF_8); bufferedwriter.write(s); - } catch (IOException e) { // Akarin - Bukkit.getLogger().log(Level.SEVERE, "Failed to save {0}, {1}", new Object[] {this.c.getName(), e.getMessage()}); // Akarin } finally { IOUtils.closeQuietly(bufferedwriter); } - }; // Akarin - AkarinAsyncExecutor.scheduleSingleAsyncTask(runnable); // Akarin } diff --git a/src/main/java/net/minecraft/server/LegacyPingHandler.java b/src/main/java/net/minecraft/server/LegacyPingHandler.java index 2a30af7de..4a49fe4cc 100644 --- a/src/main/java/net/minecraft/server/LegacyPingHandler.java +++ b/src/main/java/net/minecraft/server/LegacyPingHandler.java @@ -14,7 +14,7 @@ import org.apache.logging.log4j.Logger; public class LegacyPingHandler extends ChannelInboundHandlerAdapter { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private final ServerConnection b; private ByteBuf buf; // Paper @@ -51,8 +51,8 @@ public class LegacyPingHandler extends ChannelInboundHandlerAdapter { com.destroystokyo.paper.event.server.PaperServerListPingEvent event; // Paper switch (i) { - case 0: - LegacyPingHandler.a.debug("Ping: (<1.3.x) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort()); + case 0: + LegacyPingHandler.LOGGER.debug("Ping: (<1.3.x) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort()); // Paper start - Call PaperServerListPingEvent and use results event = PaperLegacyStatusClient.processRequest(minecraftserver, inetsocketaddress, 39, null); if (event == null) { @@ -60,14 +60,14 @@ public class LegacyPingHandler extends ChannelInboundHandlerAdapter { break; } s = String.format("%s\u00a7%d\u00a7%d", PaperLegacyStatusClient.getUnformattedMotd(event), event.getNumPlayers(), event.getMaxPlayers()); - this.a(channelhandlercontext, this.a(s)); - break; - case 1: - if (bytebuf.readUnsignedByte() != 1) { - return; - } + this.a(channelhandlercontext, this.a(s)); + break; + case 1: + if (bytebuf.readUnsignedByte() != 1) { + return; + } - LegacyPingHandler.a.debug("Ping: (1.4-1.5.x) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort()); + LegacyPingHandler.LOGGER.debug("Ping: (1.4-1.5.x) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort()); // Paper start - Call PaperServerListPingEvent and use results event = PaperLegacyStatusClient.processRequest(minecraftserver, inetsocketaddress, 127, null); // Paper if (event == null) { @@ -76,36 +76,36 @@ public class LegacyPingHandler extends ChannelInboundHandlerAdapter { } s = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", new Object[] { event.getProtocolVersion(), minecraftserver.getVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()}); // CraftBukkit // Paper end - this.a(channelhandlercontext, this.a(s)); - break; - default: + this.a(channelhandlercontext, this.a(s)); + break; + default: // Paper start - Replace with improved version below if (bytebuf.readUnsignedByte() != 0x01 || bytebuf.readUnsignedByte() != 0xFA) return; readLegacy1_6(channelhandlercontext, bytebuf); /* - boolean flag1 = bytebuf.readUnsignedByte() == 1; + boolean flag1 = bytebuf.readUnsignedByte() == 1; - flag1 &= bytebuf.readUnsignedByte() == 250; - flag1 &= "MC|PingHost".equals(new String(bytebuf.readBytes(bytebuf.readShort() * 2).array(), StandardCharsets.UTF_16BE)); - int j = bytebuf.readUnsignedShort(); + flag1 &= bytebuf.readUnsignedByte() == 250; + flag1 &= "MC|PingHost".equals(new String(bytebuf.readBytes(bytebuf.readShort() * 2).array(), StandardCharsets.UTF_16BE)); + int j = bytebuf.readUnsignedShort(); - flag1 &= bytebuf.readUnsignedByte() >= 73; - flag1 &= 3 + bytebuf.readBytes(bytebuf.readShort() * 2).array().length + 4 == j; - flag1 &= bytebuf.readInt() <= 65535; - flag1 &= bytebuf.readableBytes() == 0; - if (!flag1) { - return; - } + flag1 &= bytebuf.readUnsignedByte() >= 73; + flag1 &= 3 + bytebuf.readBytes(bytebuf.readShort() * 2).array().length + 4 == j; + flag1 &= bytebuf.readInt() <= 65535; + flag1 &= bytebuf.readableBytes() == 0; + if (!flag1) { + return; + } - LegacyPingHandler.a.debug("Ping: (1.6) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort()); - String s1 = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", 127, minecraftserver.getVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit - ByteBuf bytebuf1 = this.a(s1); + LegacyPingHandler.LOGGER.debug("Ping: (1.6) from {}:{}", inetsocketaddress.getAddress(), inetsocketaddress.getPort()); + String s1 = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", 127, minecraftserver.getVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); // CraftBukkit + ByteBuf bytebuf1 = this.a(s1); - try { - this.a(channelhandlercontext, bytebuf1); - } finally { - bytebuf1.release(); - } + try { + this.a(channelhandlercontext, bytebuf1); + } finally { + bytebuf1.release(); + } */ // Paper end - Replace with improved version below } @@ -183,7 +183,7 @@ public class LegacyPingHandler extends ChannelInboundHandlerAdapter { buf.release(); this.buf = null; - a.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress()); + LOGGER.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress()); InetSocketAddress virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(host, port); com.destroystokyo.paper.event.server.PaperServerListPingEvent event = PaperLegacyStatusClient.processRequest( diff --git a/src/main/java/net/minecraft/server/LocaleLanguage.java b/src/main/java/net/minecraft/server/LocaleLanguage.java index 4c5556a09..601273933 100644 --- a/src/main/java/net/minecraft/server/LocaleLanguage.java +++ b/src/main/java/net/minecraft/server/LocaleLanguage.java @@ -5,6 +5,7 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; @@ -17,7 +18,7 @@ import org.apache.logging.log4j.Logger; public class LocaleLanguage { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final Pattern b = Pattern.compile("%(\\d+\\$)?[\\d\\.]*[df]"); private static final LocaleLanguage c = new LocaleLanguage(); private final Map d = Maps.newHashMap(); @@ -26,20 +27,40 @@ public class LocaleLanguage { public LocaleLanguage() { try { InputStream inputstream = LocaleLanguage.class.getResourceAsStream("/assets/minecraft/lang/en_us.json"); - JsonElement jsonelement = (JsonElement) (new Gson()).fromJson(new InputStreamReader(inputstream, StandardCharsets.UTF_8), JsonElement.class); - JsonObject jsonobject = ChatDeserializer.m(jsonelement, "strings"); - Iterator iterator = jsonobject.entrySet().iterator(); + Throwable throwable = null; - while (iterator.hasNext()) { - Entry entry = (Entry) iterator.next(); - String s = LocaleLanguage.b.matcher(ChatDeserializer.a((JsonElement) entry.getValue(), (String) entry.getKey())).replaceAll("%$1s"); + try { + JsonElement jsonelement = (JsonElement) (new Gson()).fromJson(new InputStreamReader(inputstream, StandardCharsets.UTF_8), JsonElement.class); + JsonObject jsonobject = ChatDeserializer.m(jsonelement, "strings"); + Iterator iterator = jsonobject.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + String s = LocaleLanguage.b.matcher(ChatDeserializer.a((JsonElement) entry.getValue(), (String) entry.getKey())).replaceAll("%$1s"); + + this.d.put(entry.getKey(), s); + } + + this.e = SystemUtils.getMonotonicMillis(); + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (inputstream != null) { + if (throwable != null) { + try { + inputstream.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + inputstream.close(); + } + } - this.d.put(entry.getKey(), s); } - - this.e = SystemUtils.getMonotonicMillis(); - } catch (JsonParseException jsonparseexception) { - LocaleLanguage.a.error("Couldn't read strings from /assets/minecraft/lang/en_us.json", jsonparseexception); + } catch (JsonParseException | IOException ioexception) { + LocaleLanguage.LOGGER.error("Couldn't read strings from /assets/minecraft/lang/en_us.json", ioexception); } } diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java index 93e67cbcf..a8773037e 100644 --- a/src/main/java/net/minecraft/server/LoginListener.java +++ b/src/main/java/net/minecraft/server/LoginListener.java @@ -4,8 +4,6 @@ import com.destroystokyo.paper.profile.CraftPlayerProfile; import com.destroystokyo.paper.profile.PlayerProfile; import com.mojang.authlib.GameProfile; import com.mojang.authlib.exceptions.AuthenticationUnavailableException; - -import co.aikar.timings.ThreadAssertion; import io.netty.channel.ChannelFuture; import java.math.BigInteger; import java.net.InetAddress; @@ -29,17 +27,17 @@ import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.event.player.PlayerPreLoginEvent; // CraftBukkit end -public class LoginListener implements PacketLoginInListener, ITickable { +public class LoginListener implements PacketLoginInListener { private static final AtomicInteger b = new AtomicInteger(0); - private static final Logger c = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final Random random = new Random(); private final byte[] e = new byte[4]; private final MinecraftServer server; public final NetworkManager networkManager; private LoginListener.EnumProtocolState g; public final LoginListener.EnumProtocolState getLoginState() { return this.g; }; // Paper - OBFHELPER private int h; - private GameProfile i; private void setGameProfile(GameProfile profile) { i = profile; } public final GameProfile getGameProfile() { return i; } // Paper - OBFHELPER + private GameProfile i; private void setGameProfile(final GameProfile profile) { this.i = profile; } public GameProfile getGameProfile() { return this.i; } // Paper - OBFHELPER private final String j; private SecretKey loginKey; private EntityPlayer l; @@ -64,7 +62,7 @@ public class LoginListener implements PacketLoginInListener, ITickable { if (this.g == LoginListener.EnumProtocolState.READY_TO_ACCEPT) { // Paper start - prevent logins to be processed even though disconnect was called if (networkManager.isConnected()) { - this.b(); + this.c(); } // Paper end } else if (this.g == LoginListener.EnumProtocolState.DELAY_ACCEPT) { @@ -88,22 +86,27 @@ public class LoginListener implements PacketLoginInListener, ITickable { public void disconnect(String s) { try { IChatBaseComponent ichatbasecomponent = new ChatComponentText(s); - LoginListener.c.info("Disconnecting {}: {}", this.c(), s); + LoginListener.LOGGER.info("Disconnecting {}: {}", this.d(), s); this.networkManager.sendPacket(new PacketLoginOutDisconnect(ichatbasecomponent)); this.networkManager.close(ichatbasecomponent); } catch (Exception exception) { - LoginListener.c.error("Error whilst disconnecting player", exception); + LoginListener.LOGGER.error("Error whilst disconnecting player", exception); } } // CraftBukkit end + @Override + public NetworkManager a() { + return this.networkManager; + } + public void disconnect(IChatBaseComponent ichatbasecomponent) { try { - LoginListener.c.info("Disconnecting {}: {}", this.c(), ichatbasecomponent.getString()); + LoginListener.LOGGER.info("Disconnecting {}: {}", this.d(), ichatbasecomponent.getString()); this.networkManager.sendPacket(new PacketLoginOutDisconnect(ichatbasecomponent)); this.networkManager.close(ichatbasecomponent); } catch (Exception exception) { - LoginListener.c.error("Error whilst disconnecting player", exception); + LoginListener.LOGGER.error("Error whilst disconnecting player", exception); } } @@ -138,7 +141,7 @@ public class LoginListener implements PacketLoginInListener, ITickable { } // Spigot end - public void b() { + public void c() { // Spigot start - Moved to initUUID /* if (!this.i.isComplete()) { @@ -155,9 +158,9 @@ public class LoginListener implements PacketLoginInListener, ITickable { // CraftBukkit end } else { this.g = LoginListener.EnumProtocolState.ACCEPTED; - if (this.server.aw() >= 0 && !this.networkManager.isLocal()) { - this.networkManager.sendPacket(new PacketLoginOutSetCompression(this.server.aw()), (channelfuture) -> { - this.networkManager.setCompressionLevel(this.server.aw()); + if (this.server.az() >= 0 && !this.networkManager.isLocal()) { + this.networkManager.sendPacket(new PacketLoginOutSetCompression(this.server.az()), (channelfuture) -> { + this.networkManager.setCompressionLevel(this.server.az()); }); } @@ -174,20 +177,22 @@ public class LoginListener implements PacketLoginInListener, ITickable { } + @Override public void a(IChatBaseComponent ichatbasecomponent) { - LoginListener.c.info("{} lost connection: {}", this.c(), ichatbasecomponent.getString()); + LoginListener.LOGGER.info("{} lost connection: {}", this.d(), ichatbasecomponent.getString()); } - public String c() { + public String d() { return this.i != null ? this.i + " (" + this.networkManager.getSocketAddress() + ")" : String.valueOf(this.networkManager.getSocketAddress()); } + @Override public void a(PacketLoginInStart packetlogininstart) { Validate.validState(this.g == LoginListener.EnumProtocolState.HELLO, "Unexpected hello packet", new Object[0]); this.i = packetlogininstart.b(); if (this.server.getOnlineMode() && !this.networkManager.isLocal()) { this.g = LoginListener.EnumProtocolState.KEY; - this.networkManager.sendPacket(new PacketLoginOutEncryptionBegin("", this.server.E().getPublic(), this.e)); + this.networkManager.sendPacket(new PacketLoginOutEncryptionBegin("", this.server.getKeyPair().getPublic(), this.e)); } else { // Paper start - Velocity support if (com.destroystokyo.paper.PaperConfig.velocitySupport) { @@ -202,7 +207,6 @@ public class LoginListener implements PacketLoginInListener, ITickable { authenticatorPool.execute(new Runnable() { @Override public void run() { - ThreadAssertion.close(); // Akarin try { initUUID(); new LoginHandler().fireEvents(); @@ -218,9 +222,10 @@ public class LoginListener implements PacketLoginInListener, ITickable { } + @Override public void a(PacketLoginInEncryptionBegin packetlogininencryptionbegin) { Validate.validState(this.g == LoginListener.EnumProtocolState.KEY, "Unexpected key packet", new Object[0]); - PrivateKey privatekey = this.server.E().getPrivate(); + PrivateKey privatekey = this.server.getKeyPair().getPrivate(); if (!Arrays.equals(this.e, packetlogininencryptionbegin.b(privatekey))) { throw new IllegalStateException("Invalid nonce!"); @@ -231,13 +236,12 @@ public class LoginListener implements PacketLoginInListener, ITickable { // Paper start - Cache authenticator threads authenticatorPool.execute(new Runnable() { public void run() { - ThreadAssertion.close(); // Akarin GameProfile gameprofile = LoginListener.this.i; try { - String s = (new BigInteger(MinecraftEncryption.a("", LoginListener.this.server.E().getPublic(), LoginListener.this.loginKey))).toString(16); + String s = (new BigInteger(MinecraftEncryption.a("", LoginListener.this.server.getKeyPair().getPublic(), LoginListener.this.loginKey))).toString(16); - LoginListener.this.i = LoginListener.this.server.ap().hasJoinedServer(new GameProfile((UUID) null, gameprofile.getName()), s, this.a()); + LoginListener.this.i = LoginListener.this.server.getMinecraftSessionService().hasJoinedServer(new GameProfile((UUID) null, gameprofile.getName()), s, this.a()); if (LoginListener.this.i != null) { // CraftBukkit start - fire PlayerPreLoginEvent if (!networkManager.isConnected()) { @@ -245,17 +249,17 @@ public class LoginListener implements PacketLoginInListener, ITickable { } new LoginHandler().fireEvents(); - } else if (LoginListener.this.server.H()) { - LoginListener.c.warn("Failed to verify username but will let them in anyway!"); + } else if (LoginListener.this.server.isEmbeddedServer()) { + LoginListener.LOGGER.warn("Failed to verify username but will let them in anyway!"); LoginListener.this.i = LoginListener.this.a(gameprofile); LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; } else { LoginListener.this.disconnect(new ChatMessage("multiplayer.disconnect.unverified_username", new Object[0])); - LoginListener.c.error("Username '{}' tried to join with an invalid session", gameprofile.getName()); + LoginListener.LOGGER.error("Username '{}' tried to join with an invalid session", gameprofile.getName()); } } catch (AuthenticationUnavailableException authenticationunavailableexception) { - if (LoginListener.this.server.H()) { - LoginListener.c.warn("Authentication servers are down but will let them in anyway!"); + if (LoginListener.this.server.isEmbeddedServer()) { + LoginListener.LOGGER.warn("Authentication servers are down but will let them in anyway!"); LoginListener.this.i = LoginListener.this.a(gameprofile); LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; } else { @@ -264,7 +268,7 @@ public class LoginListener implements PacketLoginInListener, ITickable { LoginListener.this.disconnect(new ChatComponentText(com.destroystokyo.paper.PaperConfig.authenticationServersDownKickMessage)); } else // Paper end LoginListener.this.disconnect(new ChatMessage("multiplayer.disconnect.authservers_down", new Object[0])); - LoginListener.c.error("Couldn't verify username because servers are unavailable"); + LoginListener.LOGGER.error("Couldn't verify username because servers are unavailable"); } // CraftBukkit start - catch all exceptions } catch (Exception exception) { @@ -279,43 +283,13 @@ public class LoginListener implements PacketLoginInListener, ITickable { private InetAddress a() { SocketAddress socketaddress = LoginListener.this.networkManager.getSocketAddress(); - return LoginListener.this.server.S() && socketaddress instanceof InetSocketAddress ? ((InetSocketAddress) socketaddress).getAddress() : null; + return LoginListener.this.server.U() && socketaddress instanceof InetSocketAddress ? ((InetSocketAddress) socketaddress).getAddress() : null; } }); // Paper end } } - // Paper start - Delay async prelogin until plugins are ready - private static volatile Object blockingLogins = new Object(); - - public static void checkStartupAndBlock() { - final Object lock = LoginListener.blockingLogins; - if (lock != null) { - synchronized (lock) { - for (;;) { - if (LoginListener.blockingLogins == null) { - return; - } - try { - lock.wait(); - } catch (final InterruptedException ignore) {// handled by the if statement above - Thread.currentThread().interrupt(); - } - } - } - } - } - - public static void allowLogins() { - final Object lock = LoginListener.blockingLogins; - synchronized (lock) { - LoginListener.blockingLogins = null; - lock.notifyAll(); - } - } - // Paper end - // Spigot start public class LoginHandler { @@ -326,7 +300,6 @@ public class LoginListener implements PacketLoginInListener, ITickable { return; } // Paper end - LoginListener.checkStartupAndBlock(); // Paper - Delay async login events until plugins are ready String playerName = i.getName(); java.net.InetAddress address = ((java.net.InetSocketAddress) networkManager.getSocketAddress()).getAddress(); java.util.UUID uniqueId = i.getId(); @@ -367,7 +340,7 @@ public class LoginListener implements PacketLoginInListener, ITickable { } } // CraftBukkit end - LoginListener.c.info("UUID of player {} is {}", LoginListener.this.i.getName(), LoginListener.this.i.getId()); + LoginListener.LOGGER.info("UUID of player {} is {}", LoginListener.this.i.getName(), LoginListener.this.i.getId()); LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; } } @@ -393,7 +366,6 @@ public class LoginListener implements PacketLoginInListener, ITickable { // Proceed with login authenticatorPool.execute(() -> { - ThreadAssertion.close(); // Akarin try { new LoginHandler().fireEvents(); } catch (Exception ex) { diff --git a/src/main/java/net/minecraft/server/LootContextParameters.java b/src/main/java/net/minecraft/server/LootContextParameters.java new file mode 100644 index 000000000..1dcbe2b9d --- /dev/null +++ b/src/main/java/net/minecraft/server/LootContextParameters.java @@ -0,0 +1,20 @@ +package net.minecraft.server; + +public class LootContextParameters { + + public static final LootContextParameter THIS_ENTITY = a("this_entity"); + public static final LootContextParameter LAST_DAMAGE_PLAYER = a("last_damage_player"); + public static final LootContextParameter DAMAGE_SOURCE = a("damage_source"); + public static final LootContextParameter KILLER_ENTITY = a("killer_entity"); + public static final LootContextParameter DIRECT_KILLER_ENTITY = a("direct_killer_entity"); + public static final LootContextParameter POSITION = a("position"); + public static final LootContextParameter BLOCK_STATE = a("block_state"); + public static final LootContextParameter BLOCK_ENTITY = a("block_entity"); + public static final LootContextParameter TOOL = a("tool"); + public static final LootContextParameter EXPLOSION_RADIUS = a("explosion_radius"); + public static final LootContextParameter LOOTING_MOD = new LootContextParameter<>(new MinecraftKey("bukkit:looting_mod")); // CraftBukkit + + private static LootContextParameter a(String s) { + return new LootContextParameter<>(new MinecraftKey(s)); + } +} diff --git a/src/main/java/net/minecraft/server/LootEnchantFunction.java b/src/main/java/net/minecraft/server/LootEnchantFunction.java index 23028f0e3..542538c4f 100644 --- a/src/main/java/net/minecraft/server/LootEnchantFunction.java +++ b/src/main/java/net/minecraft/server/LootEnchantFunction.java @@ -1,29 +1,40 @@ package net.minecraft.server; +import com.google.common.collect.ImmutableSet; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonObject; import com.google.gson.JsonSerializationContext; -import java.util.Random; +import java.util.Set; -public class LootEnchantFunction extends LootItemFunction { +public class LootEnchantFunction extends LootItemFunctionConditional { private final LootValueBounds a; - private final int b; + private final int c; - public LootEnchantFunction(LootItemCondition[] alootitemcondition, LootValueBounds lootvaluebounds, int i) { + private LootEnchantFunction(LootItemCondition[] alootitemcondition, LootValueBounds lootvaluebounds, int i) { super(alootitemcondition); this.a = lootvaluebounds; - this.b = i; + this.c = i; } - public ItemStack a(ItemStack itemstack, Random random, LootTableInfo loottableinfo) { - Entity entity = loottableinfo.c(); + @Override + public Set> a() { + return ImmutableSet.of(LootContextParameters.KILLER_ENTITY); + } + + private boolean b() { + return this.c > 0; + } + + @Override + public ItemStack a(ItemStack itemstack, LootTableInfo loottableinfo) { + Entity entity = (Entity) loottableinfo.getContextParameter(LootContextParameters.KILLER_ENTITY); if (entity instanceof EntityLiving) { int i = EnchantmentManager.g((EntityLiving) entity); // CraftBukkit start - use lootingModifier if set by plugin - if (loottableinfo.lootingMod > org.bukkit.loot.LootContext.DEFAULT_LOOT_MODIFIER) { - i = loottableinfo.lootingMod; + if (loottableinfo.hasContextParameter(LootContextParameters.LOOTING_MOD)) { + i = loottableinfo.getContextParameter(LootContextParameters.LOOTING_MOD); } // CraftBukkit end @@ -31,35 +42,66 @@ public class LootEnchantFunction extends LootItemFunction { return itemstack; } - float f = (float) i * this.a.b(random); + float f = (float) i * this.a.b(loottableinfo.b()); itemstack.add(Math.round(f)); - if (this.b != 0 && itemstack.getCount() > this.b) { - itemstack.setCount(this.b); + if (this.b() && itemstack.getCount() > this.c) { + itemstack.setCount(this.c); } } return itemstack; } - public static class a extends LootItemFunction.a { + public static LootEnchantFunction.a a(LootValueBounds lootvaluebounds) { + return new LootEnchantFunction.a(lootvaluebounds); + } - protected a() { + public static class b extends LootItemFunctionConditional.c { + + protected b() { super(new MinecraftKey("looting_enchant"), LootEnchantFunction.class); } public void a(JsonObject jsonobject, LootEnchantFunction lootenchantfunction, JsonSerializationContext jsonserializationcontext) { + super.a(jsonobject, lootenchantfunction, jsonserializationcontext); // CraftBukkit - decompile error jsonobject.add("count", jsonserializationcontext.serialize(lootenchantfunction.a)); - if (lootenchantfunction.b > 0) { - jsonobject.add("limit", jsonserializationcontext.serialize(lootenchantfunction.b)); + if (lootenchantfunction.b()) { + jsonobject.add("limit", jsonserializationcontext.serialize(lootenchantfunction.c)); } } + @Override public LootEnchantFunction b(JsonObject jsonobject, JsonDeserializationContext jsondeserializationcontext, LootItemCondition[] alootitemcondition) { - int i = ChatDeserializer.a(jsonobject, "limit", 0); + int i = ChatDeserializer.a(jsonobject, "limit", (int) 0); return new LootEnchantFunction(alootitemcondition, (LootValueBounds) ChatDeserializer.a(jsonobject, "count", jsondeserializationcontext, LootValueBounds.class), i); } } + + public static class a extends LootItemFunctionConditional.a { + + private final LootValueBounds a; + private int b = 0; + + public a(LootValueBounds lootvaluebounds) { + this.a = lootvaluebounds; + } + + @Override + protected LootEnchantFunction.a d() { + return this; + } + + public LootEnchantFunction.a a(int i) { + this.b = i; + return this; + } + + @Override + public LootItemFunction b() { + return new LootEnchantFunction(this.g(), this.a, this.b); + } + } } diff --git a/src/main/java/net/minecraft/server/LootItemConditionRandomChanceWithLooting.java b/src/main/java/net/minecraft/server/LootItemConditionRandomChanceWithLooting.java index 5e42d668b..1f801ae58 100644 --- a/src/main/java/net/minecraft/server/LootItemConditionRandomChanceWithLooting.java +++ b/src/main/java/net/minecraft/server/LootItemConditionRandomChanceWithLooting.java @@ -1,36 +1,49 @@ package net.minecraft.server; +import com.google.common.collect.ImmutableSet; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonObject; import com.google.gson.JsonSerializationContext; -import java.util.Random; +import java.util.Set; public class LootItemConditionRandomChanceWithLooting implements LootItemCondition { private final float a; private final float b; - public LootItemConditionRandomChanceWithLooting(float f, float f1) { + private LootItemConditionRandomChanceWithLooting(float f, float f1) { this.a = f; this.b = f1; } - public boolean a(Random random, LootTableInfo loottableinfo) { + @Override + public Set> a() { + return ImmutableSet.of(LootContextParameters.KILLER_ENTITY); + } + + public boolean test(LootTableInfo loottableinfo) { + Entity entity = (Entity) loottableinfo.getContextParameter(LootContextParameters.KILLER_ENTITY); int i = 0; - if (loottableinfo.c() instanceof EntityLiving) { - i = EnchantmentManager.g((EntityLiving) loottableinfo.c()); + if (entity instanceof EntityLiving) { + i = EnchantmentManager.g((EntityLiving) entity); } // CraftBukkit start - only use lootingModifier if set by Bukkit - if (loottableinfo.lootingMod > org.bukkit.loot.LootContext.DEFAULT_LOOT_MODIFIER) { - i = loottableinfo.lootingMod; + if (loottableinfo.hasContextParameter(LootContextParameters.LOOTING_MOD)) { + i = loottableinfo.getContextParameter(LootContextParameters.LOOTING_MOD); } // CraftBukkit end - return random.nextFloat() < this.a + (float) i * this.b; + return loottableinfo.b().nextFloat() < this.a + (float) i * this.b; } - public static class a extends LootItemCondition.a { + public static LootItemCondition.a a(float f, float f1) { + return () -> { + return new LootItemConditionRandomChanceWithLooting(f, f1); + }; + } + + public static class a extends LootItemCondition.b { protected a() { super(new MinecraftKey("random_chance_with_looting"), LootItemConditionRandomChanceWithLooting.class); @@ -41,6 +54,7 @@ public class LootItemConditionRandomChanceWithLooting implements LootItemConditi jsonobject.addProperty("looting_multiplier", lootitemconditionrandomchancewithlooting.b); } + @Override public LootItemConditionRandomChanceWithLooting b(JsonObject jsonobject, JsonDeserializationContext jsondeserializationcontext) { return new LootItemConditionRandomChanceWithLooting(ChatDeserializer.l(jsonobject, "chance"), ChatDeserializer.l(jsonobject, "looting_multiplier")); } diff --git a/src/main/java/net/minecraft/server/LootItemConditionSurvivesExplosion.java b/src/main/java/net/minecraft/server/LootItemConditionSurvivesExplosion.java new file mode 100644 index 000000000..67f3a78d1 --- /dev/null +++ b/src/main/java/net/minecraft/server/LootItemConditionSurvivesExplosion.java @@ -0,0 +1,54 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableSet; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import java.util.Random; +import java.util.Set; + +public class LootItemConditionSurvivesExplosion implements LootItemCondition { + + private static final LootItemConditionSurvivesExplosion a = new LootItemConditionSurvivesExplosion(); + + private LootItemConditionSurvivesExplosion() {} + + @Override + public Set> a() { + return ImmutableSet.of(LootContextParameters.EXPLOSION_RADIUS); + } + + public boolean test(LootTableInfo loottableinfo) { + Float ofloat = (Float) loottableinfo.getContextParameter(LootContextParameters.EXPLOSION_RADIUS); + + if (ofloat != null) { + Random random = loottableinfo.b(); + float f = 1.0F / ofloat; + + // CraftBukkit - <= to < to allow for plugins to completely disable block drops from explosions + return random.nextFloat() < f; + } else { + return true; + } + } + + public static LootItemCondition.a b() { + return () -> { + return LootItemConditionSurvivesExplosion.a; + }; + } + + public static class a extends LootItemCondition.b { + + protected a() { + super(new MinecraftKey("survives_explosion"), LootItemConditionSurvivesExplosion.class); + } + + public void a(JsonObject jsonobject, LootItemConditionSurvivesExplosion lootitemconditionsurvivesexplosion, JsonSerializationContext jsonserializationcontext) {} + + @Override + public LootItemConditionSurvivesExplosion b(JsonObject jsonobject, JsonDeserializationContext jsondeserializationcontext) { + return LootItemConditionSurvivesExplosion.a; + } + } +} diff --git a/src/main/java/net/minecraft/server/LootSelectorEntry.java b/src/main/java/net/minecraft/server/LootSelectorEntry.java index 80f9f9a25..2c979e0b7 100644 --- a/src/main/java/net/minecraft/server/LootSelectorEntry.java +++ b/src/main/java/net/minecraft/server/LootSelectorEntry.java @@ -1,114 +1,184 @@ package net.minecraft.server; +import com.google.common.collect.Lists; import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; -import com.google.gson.JsonSyntaxException; -import java.lang.reflect.Type; -import java.util.Collection; -import java.util.Random; +import java.util.List; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import org.apache.commons.lang3.ArrayUtils; -public abstract class LootSelectorEntry { +public abstract class LootSelectorEntry extends LootEntryAbstract { - protected final int c; public int getWeight() { return c; } // Paper - OBFHELPER - protected final int d; public int getQuality() { return d; } // Paper - OBFHELPER - protected final LootItemCondition[] e; + protected final int e; public int getWeight() { return e; } // Paper - OBFHELPER + protected final int f; public int getQuality() { return f; } // Paper - OBFHELPER + protected final LootItemFunction[] g; + private final BiFunction c; + private final LootEntry h = new LootSelectorEntry.c() { + @Override + public void a(Consumer consumer, LootTableInfo loottableinfo) { + LootSelectorEntry.this.a(LootItemFunction.a(LootSelectorEntry.this.c, consumer, loottableinfo), loottableinfo); + } + }; - protected LootSelectorEntry(int i, int j, LootItemCondition[] alootitemcondition) { - this.c = i; - this.d = j; - this.e = alootitemcondition; + protected LootSelectorEntry(int i, int j, LootItemCondition[] alootitemcondition, LootItemFunction[] alootitemfunction) { + super(alootitemcondition); + this.e = i; + this.f = j; + this.g = alootitemfunction; + this.c = LootItemFunctions.a((BiFunction[]) alootitemfunction); } - public int a(float f) { - // Paper start - Offer an alternative loot formula to refactor how luck bonus applies - // SEE: https://luckformula.emc.gs for details and data - if (lastLuck != null && lastLuck == f) { - return lastWeight; + @Override + public void a(LootCollector lootcollector, Function function, Set set, LootContextParameterSet lootcontextparameterset) { + super.a(lootcollector, function, set, lootcontextparameterset); + + for (int i = 0; i < this.g.length; ++i) { + this.g[i].a(lootcollector.b(".functions[" + i + "]"), function, set, lootcontextparameterset); } - // This is vanilla - float qualityModifer = (float) this.getQuality() * f; - double baseWeight = (this.getWeight() + qualityModifer); - if (com.destroystokyo.paper.PaperConfig.useAlternativeLuckFormula) { - // Random boost to avoid losing precision in the final int cast on return - final int weightBoost = 100; - baseWeight *= weightBoost; - // If we have vanilla 1, bump that down to 0 so nothing is is impacted - // vanilla 3 = 300, 200 basis = impact 2% - // =($B2*(($B2-100)/100/100)) - double impacted = baseWeight * ((baseWeight - weightBoost) / weightBoost / 100); - // =($B$7/100) - float luckModifier = Math.min(100, f * 10) / 100; - // =B2 - (C2 *($B$7/100)) - baseWeight = Math.ceil(baseWeight - (impacted * luckModifier)); - } - lastLuck = f; - lastWeight = (int) Math.max(0, Math.floor(baseWeight)); - return lastWeight; + } - private Float lastLuck = null; - private int lastWeight = 0; - // Paper end - public abstract void a(Collection collection, Random random, LootTableInfo loottableinfo); + protected abstract void a(Consumer consumer, LootTableInfo loottableinfo); - protected abstract void a(JsonObject jsonobject, JsonSerializationContext jsonserializationcontext); + @Override + public boolean expand(LootTableInfo loottableinfo, Consumer consumer) { + if (this.a(loottableinfo)) { + consumer.accept(this.h); + return true; + } else { + return false; + } + } - public static class a implements JsonDeserializer, JsonSerializer { + public static LootSelectorEntry.a a(LootSelectorEntry.d lootselectorentry_d) { + return new LootSelectorEntry.b(lootselectorentry_d); + } + + public abstract static class e extends LootEntryAbstract.b { + + public e(MinecraftKey minecraftkey, Class oclass) { + super(minecraftkey, oclass); + } + + public void a(JsonObject jsonobject, T t0, JsonSerializationContext jsonserializationcontext) { + if (t0.e != 1) { + jsonobject.addProperty("weight", t0.e); + } + + if (t0.f != 0) { + jsonobject.addProperty("quality", t0.f); + } + + if (!ArrayUtils.isEmpty(t0.g)) { + jsonobject.add("functions", jsonserializationcontext.serialize(t0.g)); + } + + } + + @Override + public final T b(JsonObject jsonobject, JsonDeserializationContext jsondeserializationcontext, LootItemCondition[] alootitemcondition) { + int i = ChatDeserializer.a(jsonobject, "weight", (int) 1); + int j = ChatDeserializer.a(jsonobject, "quality", (int) 0); + LootItemFunction[] alootitemfunction = (LootItemFunction[]) ChatDeserializer.a(jsonobject, "functions", new LootItemFunction[0], jsondeserializationcontext, LootItemFunction[].class); + + return this.b(jsonobject, jsondeserializationcontext, i, j, alootitemcondition, alootitemfunction); + } + + protected abstract T b(JsonObject jsonobject, JsonDeserializationContext jsondeserializationcontext, int i, int j, LootItemCondition[] alootitemcondition, LootItemFunction[] alootitemfunction); + } + + static class b extends LootSelectorEntry.a { + + private final LootSelectorEntry.d c; + + public b(LootSelectorEntry.d lootselectorentry_d) { + this.c = lootselectorentry_d; + } + + @Override + protected LootSelectorEntry.b d() { + return this; + } + + @Override + public LootEntryAbstract b() { + return this.c.build(this.a, this.b, this.f(), this.a()); + } + } + + @FunctionalInterface + public interface d { + + LootSelectorEntry build(int i, int j, LootItemCondition[] alootitemcondition, LootItemFunction[] alootitemfunction); + } + + public abstract static class a> extends LootEntryAbstract.a implements LootItemFunctionUser { + + protected int a = 1; + protected int b = 0; + private final List c = Lists.newArrayList(); public a() {} - public LootSelectorEntry deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { - JsonObject jsonobject = ChatDeserializer.m(jsonelement, "loot item"); - String s = ChatDeserializer.h(jsonobject, "type"); - int i = ChatDeserializer.a(jsonobject, "weight", 1); - int j = ChatDeserializer.a(jsonobject, "quality", 0); - LootItemCondition[] alootitemcondition; - - if (jsonobject.has("conditions")) { - alootitemcondition = (LootItemCondition[]) ChatDeserializer.a(jsonobject, "conditions", jsondeserializationcontext, LootItemCondition[].class); - } else { - alootitemcondition = new LootItemCondition[0]; - } - - if ("item".equals(s)) { - return LootItem.a(jsonobject, jsondeserializationcontext, i, j, alootitemcondition); - } else if ("loot_table".equals(s)) { - return LootSelectorLootTable.a(jsonobject, jsondeserializationcontext, i, j, alootitemcondition); - } else if ("empty".equals(s)) { - return LootSelectorEmpty.a(jsonobject, jsondeserializationcontext, i, j, alootitemcondition); - } else { - throw new JsonSyntaxException("Unknown loot entry type '" + s + "'"); - } + @Override + public T b(LootItemFunction.a lootitemfunction_a) { + this.c.add(lootitemfunction_a.b()); + return this.d(); // Paper - decompile fix } - public JsonElement serialize(LootSelectorEntry lootselectorentry, Type type, JsonSerializationContext jsonserializationcontext) { - JsonObject jsonobject = new JsonObject(); + protected LootItemFunction[] a() { + return (LootItemFunction[]) this.c.toArray(new LootItemFunction[0]); + } - jsonobject.addProperty("weight", lootselectorentry.c); - jsonobject.addProperty("quality", lootselectorentry.d); - if (lootselectorentry.e.length > 0) { - jsonobject.add("conditions", jsonserializationcontext.serialize(lootselectorentry.e)); - } + public T a(int i) { + this.a = i; + return this.d(); // Paper - decompile fix + } - if (lootselectorentry instanceof LootItem) { - jsonobject.addProperty("type", "item"); - } else if (lootselectorentry instanceof LootSelectorLootTable) { - jsonobject.addProperty("type", "loot_table"); - } else { - if (!(lootselectorentry instanceof LootSelectorEmpty)) { - throw new IllegalArgumentException("Don't know how to serialize " + lootselectorentry); - } - - jsonobject.addProperty("type", "empty"); - } - - lootselectorentry.a(jsonobject, jsonserializationcontext); - return jsonobject; + public T b(int i) { + this.b = i; + return this.d(); // Paper - decompile fix } } + + public abstract class c implements LootEntry { + + protected c() { + } + + @Override + public int a(float f) { + // Paper start - Offer an alternative loot formula to refactor how luck bonus applies + // SEE: https://luckformula.emc.gs for details and data + if (lastLuck != null && lastLuck == f) { + return lastWeight; + } + // This is vanilla + float qualityModifer = (float) getQuality() * f; + double baseWeight = (getWeight() + qualityModifer); + if (com.destroystokyo.paper.PaperConfig.useAlternativeLuckFormula) { + // Random boost to avoid losing precision in the final int cast on return + final int weightBoost = 100; + baseWeight *= weightBoost; + // If we have vanilla 1, bump that down to 0 so nothing is is impacted + // vanilla 3 = 300, 200 basis = impact 2% + // =($B2*(($B2-100)/100/100)) + double impacted = baseWeight * ((baseWeight - weightBoost) / weightBoost / 100); + // =($B$7/100) + float luckModifier = Math.min(100, f * 10) / 100; + // =B2 - (C2 *($B$7/100)) + baseWeight = Math.ceil(baseWeight - (impacted * luckModifier)); + } + lastLuck = f; + lastWeight = (int) Math.max(0, Math.floor(baseWeight)); + return lastWeight; + } + } + private Float lastLuck = null; + private int lastWeight = 0; + // Paper end } diff --git a/src/main/java/net/minecraft/server/LootTableInfo.java b/src/main/java/net/minecraft/server/LootTableInfo.java deleted file mode 100644 index 5230a2540..000000000 --- a/src/main/java/net/minecraft/server/LootTableInfo.java +++ /dev/null @@ -1,182 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Sets; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Set; -import javax.annotation.Nullable; - -public class LootTableInfo { - - private final float a; - public final int lootingMod; // CraftBukkit - add field - private final WorldServer b; - private final LootTableRegistry c; - @Nullable - private final Entity d; - @Nullable - private final EntityHuman e; - @Nullable - private final DamageSource f; - @Nullable - private final BlockPosition g; - private final Set h = Sets.newLinkedHashSet(); - - // CraftBukkit - add looting modifier to constructor - public LootTableInfo(float f, WorldServer worldserver, LootTableRegistry loottableregistry, @Nullable Entity entity, @Nullable EntityHuman entityhuman, @Nullable DamageSource damagesource, @Nullable BlockPosition blockposition, int lootingModifier) { - this.a = f; - this.b = worldserver; - this.c = loottableregistry; - this.d = entity; - this.e = entityhuman; - this.f = damagesource; - this.g = blockposition; - this.lootingMod = lootingModifier; // CraftBukkit - } - - @Nullable - public Entity a() { - return this.d; - } - - @Nullable - public Entity b() { - return this.e; - } - - @Nullable - public Entity c() { - return this.f == null ? null : this.f.getEntity(); - } - - @Nullable - public BlockPosition e() { - return this.g; - } - - public boolean a(LootTable loottable) { - return this.h.add(loottable); - } - - public void b(LootTable loottable) { - this.h.remove(loottable); - } - - public LootTableRegistry f() { - return this.c; - } - - public float g() { - return this.a; - } - - public WorldServer h() { - return this.b; - } - - @Nullable - public Entity a(LootTableInfo.EntityTarget loottableinfo_entitytarget) { - switch (loottableinfo_entitytarget) { - case THIS: - return this.a(); - case KILLER: - return this.c(); - case KILLER_PLAYER: - return this.b(); - default: - return null; - } - } - - public static enum EntityTarget { - - THIS("this"), KILLER("killer"), KILLER_PLAYER("killer_player"); - - private final String d; - - private EntityTarget(String s) { - this.d = s; - } - - public static LootTableInfo.EntityTarget a(String s) { - LootTableInfo.EntityTarget[] aloottableinfo_entitytarget = values(); - int i = aloottableinfo_entitytarget.length; - - for (int j = 0; j < i; ++j) { - LootTableInfo.EntityTarget loottableinfo_entitytarget = aloottableinfo_entitytarget[j]; - - if (loottableinfo_entitytarget.d.equals(s)) { - return loottableinfo_entitytarget; - } - } - - throw new IllegalArgumentException("Invalid entity target " + s); - } - - public static class a extends TypeAdapter { - - public a() {} - - public void write(JsonWriter jsonwriter, LootTableInfo.EntityTarget loottableinfo_entitytarget) throws IOException { - jsonwriter.value(loottableinfo_entitytarget.d); - } - - public LootTableInfo.EntityTarget read(JsonReader jsonreader) throws IOException { - return LootTableInfo.EntityTarget.a(jsonreader.nextString()); - } - } - } - - public static class Builder { - - private final WorldServer a; - private float b; - private int lootingMod = org.bukkit.loot.LootContext.DEFAULT_LOOT_MODIFIER; // CraftBukkit - private Entity c; - private EntityHuman d; - private DamageSource e; - private BlockPosition f; - - public Builder(WorldServer worldserver) { - this.a = worldserver; - } - - public LootTableInfo.Builder luck(float f) { - this.b = f; - return this; - } - - public LootTableInfo.Builder entity(Entity entity) { - this.c = entity; - return this; - } - - public LootTableInfo.Builder killer(EntityHuman entityhuman) { - this.d = entityhuman; - return this; - } - - public LootTableInfo.Builder damageSource(DamageSource damagesource) { - this.e = damagesource; - return this; - } - - public LootTableInfo.Builder position(BlockPosition blockposition) { - this.f = blockposition; - return this; - } - - // CraftBukkit start - add looting modifier - public LootTableInfo.Builder lootingModifier(int modifier) { - this.lootingMod = modifier; - return this; - } - // CraftBukkit end - - public LootTableInfo build() { - return new LootTableInfo(this.b, this.a, this.a.getMinecraftServer().getLootTableRegistry(), this.c, this.d, this.e, this.f, this.lootingMod); // CraftBukkit add looting modifier - } - } -} diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java index b0e45f9f7..14f8b6104 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java +++ b/src/main/java/net/minecraft/server/MCUtil.java @@ -4,10 +4,13 @@ import com.destroystokyo.paper.block.TargetBlockInfo; import com.destroystokyo.paper.profile.CraftPlayerProfile; import com.destroystokyo.paper.profile.PlayerProfile; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.internal.Streams; +import com.google.gson.stream.JsonWriter; import com.mojang.authlib.GameProfile; - -import co.aikar.timings.ThreadAssertion; - +import com.mojang.datafixers.util.Either; +import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import org.apache.commons.lang.exception.ExceptionUtils; import org.bukkit.Location; import org.bukkit.block.BlockFace; @@ -17,7 +20,11 @@ import org.spigotmc.AsyncCatcher; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.io.*; +import java.util.ArrayList; +import java.util.List; import java.util.Queue; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; @@ -51,7 +58,7 @@ public final class MCUtil { } public static boolean isMainThread() { - return ThreadAssertion.is() && MinecraftServer.getServer().isMainThread(); // Akarin + return MinecraftServer.getServer().isMainThread(); } private static class DelayedRunnable implements Runnable { @@ -77,7 +84,7 @@ public final class MCUtil { public static void scheduleTask(int ticks, Runnable runnable) { // We use post to main instead of process queue as we don't want to process these mid tick if // Someone uses processQueueWhileWaiting - MinecraftServer.getServer().postToMainThread(new DelayedRunnable(ticks, runnable)); + MinecraftServer.getServer().scheduleOnMain(new DelayedRunnable(ticks, runnable)); } public static void processQueue() { @@ -118,7 +125,7 @@ public final class MCUtil { * @return */ public static void ensureMain(String reason, Runnable run) { - if (/*AsyncCatcher.enabled &&*/ !ThreadAssertion.is() && Thread.currentThread() != MinecraftServer.getServer().primaryThread) { // Akarin + if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread) { if (reason != null) { new IllegalStateException("Asynchronous " + reason + "!").printStackTrace(); } @@ -143,7 +150,7 @@ public final class MCUtil { * @return */ public static T ensureMain(String reason, Supplier run) { - if (/*AsyncCatcher.enabled &&*/ !ThreadAssertion.is() && Thread.currentThread() != MinecraftServer.getServer().primaryThread) { // Akarin + if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread) { if (reason != null) { new IllegalStateException("Asynchronous " + reason + "! Blocking thread until it returns ").printStackTrace(); } @@ -269,7 +276,7 @@ public final class MCUtil { } public static org.bukkit.block.Block toBukkitBlock(World world, BlockPosition pos) { - return world.getWorld().getBlockAt(pos); // Akarin + return world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); } public static BlockPosition toBlockPosition(Location loc) { @@ -287,14 +294,13 @@ public final class MCUtil { * @param run */ public static void scheduleAsyncTask(Runnable run) { - ThreadAssertion.close(); // Akarin asyncExecutor.execute(run); } @Nullable public static TileEntityHopper getHopper(World world, BlockPosition pos) { Chunk chunk = world.getChunkIfLoaded(pos.getX() >> 4, pos.getZ() >> 4); - if (chunk != null && chunk.getBlockData(pos.getX(), pos.getY(), pos.getZ()).getBlock() == Blocks.HOPPER) { + if (chunk != null && chunk.getType(new BlockPosition(pos.getX(), pos.getY(), pos.getZ())).getBlock() == Blocks.HOPPER) { TileEntity tileEntity = chunk.getTileEntityImmediately(pos); if (tileEntity instanceof TileEntityHopper) { return (TileEntityHopper) tileEntity; @@ -312,15 +318,15 @@ public final class MCUtil { return getNMSWorld(entity.getWorld()); } - public static FluidCollisionOption getNMSFluidCollisionOption(TargetBlockInfo.FluidMode fluidMode) { + public static RayTrace.FluidCollisionOption getNMSFluidCollisionOption(TargetBlockInfo.FluidMode fluidMode) { if (fluidMode == TargetBlockInfo.FluidMode.NEVER) { - return FluidCollisionOption.NEVER; + return RayTrace.FluidCollisionOption.NONE; } if (fluidMode == TargetBlockInfo.FluidMode.SOURCE_ONLY) { - return FluidCollisionOption.SOURCE_ONLY; + return RayTrace.FluidCollisionOption.SOURCE_ONLY; } if (fluidMode == TargetBlockInfo.FluidMode.ALWAYS) { - return FluidCollisionOption.ALWAYS; + return RayTrace.FluidCollisionOption.ANY; } return null; } @@ -358,4 +364,175 @@ public final class MCUtil { return null; } + + public static ChunkStatus getChunkStatus(PlayerChunk chunk) { + List statuses = ChunkProviderServer.getPossibleChunkStatuses(); + for (int i = statuses.size() - 1; i >= 0; --i) { + ChunkStatus curr = statuses.get(i); + CompletableFuture> future = chunk.getStatusFutureUnchecked(curr); + if (future != PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE) { + return curr; + } + } + return null; // unloaded + } + + public static void dumpChunks(File file) throws IOException { + file.getParentFile().mkdirs(); + file.createNewFile(); + /* + * Json format: + * + * Main data format: + * -server-version: + * -data-version: + * -worlds: + * -name: + * -view-distance: + * -keep-spawn-loaded: + * -keep-spawn-loaded-range: + * -visible-chunk-count: + * -loaded-chunk-count: + * -verified-fully-loaded-chunks: + * -players: + * -chunk-data: + * + * Player format: + * -name: + * -x: + * -y: + * -z: + * + * Chunk Format: + * -x: + * -z: + * -ticket-level: + * -state: + * -queued-for-unload: + * -status: + * -tickets: + * + * + * Ticket format: + * -ticket-type: + * -ticket-level: + * -add-tick: + * -object-reason: // This depends on the type of ticket. ie POST_TELEPORT -> entity id + */ + List worlds = org.bukkit.Bukkit.getWorlds(); + JsonObject data = new JsonObject(); + + data.addProperty("server-version", org.bukkit.Bukkit.getVersion()); + data.addProperty("data-version", 0); + + JsonArray worldsData = new JsonArray(); + + for (org.bukkit.World bukkitWorld : worlds) { + JsonObject worldData = new JsonObject(); + + WorldServer world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle(); + PlayerChunkMap chunkMap = world.getChunkProvider().playerChunkMap; + Long2ObjectLinkedOpenHashMap visibleChunks = chunkMap.visibleChunks; + ChunkMapDistance chunkMapDistance = chunkMap.getChunkMapDistanceManager(); + List allChunks = new ArrayList<>(visibleChunks.values()); + List players = world.players; + + int fullLoadedChunks = 0; + + for (PlayerChunk chunk : allChunks) { + if (chunk.getFullChunkIfCached() != null) { + ++fullLoadedChunks; + } + } + + // sorting by coordinate makes the log easier to read + allChunks.sort((PlayerChunk v1, PlayerChunk v2) -> { + if (v1.location.x != v2.location.x) { + return Integer.compare(v1.location.x, v2.location.x); + } + return Integer.compare(v1.location.z, v2.location.z); + }); + + worldData.addProperty("name", world.getWorldData().getName()); + worldData.addProperty("view-distance", world.spigotConfig.viewDistance); + worldData.addProperty("keep-spawn-loaded", world.keepSpawnInMemory); + worldData.addProperty("keep-spawn-loaded-range", world.paperConfig.keepLoadedRange); + worldData.addProperty("visible-chunk-count", visibleChunks.size()); + worldData.addProperty("loaded-chunk-count", chunkMap.loadedChunks.size()); + worldData.addProperty("verified-fully-loaded-chunks", fullLoadedChunks); + + JsonArray playersData = new JsonArray(); + + for (EntityPlayer player : players) { + JsonObject playerData = new JsonObject(); + + playerData.addProperty("name", player.getName()); + playerData.addProperty("x", player.locX); + playerData.addProperty("y", player.locY); + playerData.addProperty("z", player.locZ); + + playersData.add(playerData); + + } + + worldData.add("players", playersData); + + JsonArray chunksData = new JsonArray(); + + for (PlayerChunk playerChunk : allChunks) { + JsonObject chunkData = new JsonObject(); + + Set> tickets = chunkMapDistance.tickets.get(playerChunk.location.pair()); + ChunkStatus status = getChunkStatus(playerChunk); + + chunkData.addProperty("x", playerChunk.location.x); + chunkData.addProperty("z", playerChunk.location.z); + chunkData.addProperty("ticket-level", playerChunk.getTicketLevel()); + chunkData.addProperty("state", PlayerChunk.getChunkState(playerChunk.getTicketLevel()).toString()); + chunkData.addProperty("queued-for-unload", chunkMap.unloadQueue.contains(playerChunk.location.pair())); + chunkData.addProperty("status", status == null ? "unloaded" : status.toString()); + + JsonArray ticketsData = new JsonArray(); + + if (tickets != null) { + for (Ticket ticket : tickets) { + JsonObject ticketData = new JsonObject(); + + ticketData.addProperty("ticket-type", ticket.getTicketType().toString()); + ticketData.addProperty("ticket-level", ticket.getTicketLevel()); + ticketData.addProperty("object-reason", String.valueOf(ticket.getObjectReason())); + ticketData.addProperty("add-tick", ticket.getCreationTick()); + + ticketsData.add(ticketData); + } + } + + chunkData.add("tickets", ticketsData); + chunksData.add(chunkData); + } + + + worldData.add("chunk-data", chunksData); + worldsData.add(worldData); + } + + data.add("worlds", worldsData); + + StringWriter stringWriter = new StringWriter(); + JsonWriter jsonWriter = new JsonWriter(stringWriter); + jsonWriter.setIndent(" "); + jsonWriter.setLenient(false); + Streams.write(data, jsonWriter); + + String fileData = stringWriter.toString(); + + try (PrintStream out = new PrintStream(new FileOutputStream(file), false, "UTF-8")) { + out.print(fileData); + } + } + + public static int getTicketLevelFor(ChunkStatus status) { + // TODO make sure the constant `33` is correct on future updates. See getChunkAt(int, int, ChunkStatus, boolean) + return 33 + ChunkStatus.getTicketLevelOffset(status); + } } diff --git a/src/main/java/net/minecraft/server/MathHelper.java b/src/main/java/net/minecraft/server/MathHelper.java deleted file mode 100644 index 67bb28954..000000000 --- a/src/main/java/net/minecraft/server/MathHelper.java +++ /dev/null @@ -1,353 +0,0 @@ -package net.minecraft.server; - -import java.util.Random; -import java.util.UUID; -import java.util.function.IntPredicate; - -public class MathHelper { - - public static final float a = c(2.0F); - private static final float[] b = (float[]) SystemUtils.a((new float[65536]), (afloat) -> { // Paper - Decompile fix - for (int i = 0; i < afloat.length; ++i) { - afloat[i] = (float) Math.sin((double) i * 3.141592653589793D * 2.0D / 65536.0D); - } - - }); - private static final Random c = new Random(); - private static final int[] d = new int[] { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; - private static final double e = Double.longBitsToDouble(4805340802404319232L); - private static final double[] f = new double[257]; - private static final double[] g = new double[257]; - - public static float sin(float f) { - return MathHelper.b[(int) (f * 10430.378F) & '\uffff']; - } - - public static float cos(float f) { - return MathHelper.b[(int) (f * 10430.378F + 16384.0F) & '\uffff']; - } - - public static float c(float f) { - return (float) Math.sqrt((double) f); - } - - public static float sqrt(double d0) { - return (float) Math.sqrt(d0); - } - - public static int d(float f) { - int i = (int) f; - - return f < (float) i ? i - 1 : i; - } - - public static int floor(double d0) { - int i = (int) d0; - - return d0 < (double) i ? i - 1 : i; - } - - public static long d(double d0) { - long i = (long) d0; - - return d0 < (double) i ? i - 1L : i; - } - - public static float e(float f) { - return f >= 0.0F ? f : -f; - } - - public static int a(int i) { - return i >= 0 ? i : -i; - } - - public static int f(float f) { - int i = (int) f; - - return f > (float) i ? i + 1 : i; - } - - public static int f(double d0) { - int i = (int) d0; - - return d0 > (double) i ? i + 1 : i; - } - - public static int clamp(int i, int j, int k) { - return i < j ? j : (i > k ? k : i); - } - - public static float a(float f, float f1, float f2) { - return f < f1 ? f1 : (f > f2 ? f2 : f); - } - - public static double clamp(double d0, double d1, double d2) { return a(d0, d1, d2); } // Paper - OBFHELPER - public static double a(double d0, double d1, double d2) { - return d0 < d1 ? d1 : (d0 > d2 ? d2 : d0); - } - - public static double b(double d0, double d1, double d2) { - return d2 < 0.0D ? d0 : (d2 > 1.0D ? d1 : d0 + (d1 - d0) * d2); - } - - public static double a(double d0, double d1) { - if (d0 < 0.0D) { - d0 = -d0; - } - - if (d1 < 0.0D) { - d1 = -d1; - } - - return d0 > d1 ? d0 : d1; - } - - public static int a(int i, int j) { - return Math.floorDiv(i, j); - } - - public static int nextInt(Random random, int i, int j) { - return i >= j ? i : random.nextInt(j - i + 1) + i; - } - - public static float a(Random random, float f, float f1) { - return f >= f1 ? f : random.nextFloat() * (f1 - f) + f; - } - - public static double a(Random random, double d0, double d1) { - return d0 >= d1 ? d0 : random.nextDouble() * (d1 - d0) + d0; - } - - public static double a(long[] along) { - long i = 0L; - long[] along1 = along; - int j = along.length; - - for (int k = 0; k < j; ++k) { - long l = along1[k]; - - i += l; - } - - return (double) i / (double) along.length; - } - - public static int b(int i, int j) { - return Math.floorMod(i, j); - } - - public static float normalizeYaw(float fx) { return g(fx); } // Paper - OBFHELPER - public static float g(float f) { - f %= 360.0F; - if (f >= 180.0F) { - f -= 360.0F; - } - - if (f < -180.0F) { - f += 360.0F; - } - - return f; - } - - public static double g(double d0) { - d0 %= 360.0D; - if (d0 >= 180.0D) { - d0 -= 360.0D; - } - - if (d0 < -180.0D) { - d0 += 360.0D; - } - - return d0; - } - - public static float c(float f, float f1) { - float f2 = g(f - f1); - - return f2 < 180.0F ? f2 : f2 - 360.0F; - } - - public static float d(float f, float f1) { - float f2 = g(f - f1); - - return f2 < 180.0F ? e(f2) : e(f2 - 360.0F); - } - - public static float b(float f, float f1, float f2) { - f2 = e(f2); - return f < f1 ? a(f + f2, f, f1) : a(f - f2, f1, f); - } - - public static float c(float f, float f1, float f2) { - float f3 = c(f1, f); - - return b(f, f + f3, f2); - } - - public static int c(int i) { - int j = i - 1; - - j |= j >> 1; - j |= j >> 2; - j |= j >> 4; - j |= j >> 8; - j |= j >> 16; - return j + 1; - } - - private static boolean g(int i) { - return i != 0 && (i & i - 1) == 0; - } - - public static int d(int i) { - i = g(i) ? i : c(i); - return MathHelper.d[(int) ((long) i * 125613361L >> 27) & 31]; - } - - public static int e(int i) { - return d(i) - (g(i) ? 0 : 1); - } - - public static int c(int i, int j) { - if (j == 0) { - return 0; - } else if (i == 0) { - return j; - } else { - if (i < 0) { - j *= -1; - } - - int k = i % j; - - return k == 0 ? i : i + j - k; - } - } - - public static long c(int i, int j, int k) { - long l = (long) (i * 3129871) ^ (long) k * 116129781L ^ (long) j; - - l = l * l * 42317861L + l * 11L; - return l >> 16; - } - - public static UUID a(Random random) { - long i = random.nextLong() & -61441L | 16384L; - long j = random.nextLong() & 4611686018427387903L | Long.MIN_VALUE; - - return new UUID(i, j); - } - - public static UUID a() { - return a(MathHelper.c); - } - - public static double c(double d0, double d1, double d2) { - return (d0 - d1) / (d2 - d1); - } - - public static double c(double d0, double d1) { - double d2 = d1 * d1 + d0 * d0; - - if (Double.isNaN(d2)) { - return Double.NaN; - } else { - boolean flag = d0 < 0.0D; - - if (flag) { - d0 = -d0; - } - - boolean flag1 = d1 < 0.0D; - - if (flag1) { - d1 = -d1; - } - - boolean flag2 = d0 > d1; - double d3; - - if (flag2) { - d3 = d1; - d1 = d0; - d0 = d3; - } - - d3 = i(d2); - d1 *= d3; - d0 *= d3; - double d4 = MathHelper.e + d0; - int i = (int) Double.doubleToRawLongBits(d4); - double d5 = MathHelper.f[i]; - double d6 = MathHelper.g[i]; - double d7 = d4 - MathHelper.e; - double d8 = d0 * d6 - d1 * d7; - double d9 = (6.0D + d8 * d8) * d8 * 0.16666666666666666D; - double d10 = d5 + d9; - - if (flag2) { - d10 = 1.5707963267948966D - d10; - } - - if (flag1) { - d10 = 3.141592653589793D - d10; - } - - if (flag) { - d10 = -d10; - } - - return d10; - } - } - - public static double i(double d0) { - double d1 = 0.5D * d0; - long i = Double.doubleToRawLongBits(d0); - - i = 6910469410427058090L - (i >> 1); - d0 = Double.longBitsToDouble(i); - d0 *= 1.5D - d1 * d0 * d0; - return d0; - } - - public static int f(int i) { - i ^= i >>> 16; - i *= -2048144789; - i ^= i >>> 13; - i *= -1028477387; - i ^= i >>> 16; - return i; - } - - public static int a(int i, int j, IntPredicate intpredicate) { - int k = j - i; - - while (k > 0) { - int l = k / 2; - int i1 = i + l; - - if (intpredicate.test(i1)) { - k = l; - } else { - i = i1 + 1; - k -= l + 1; - } - } - - return i; - } - - static { - for (int i = 0; i < 257; ++i) { - double d0 = (double) i / 256.0D; - double d1 = Math.asin(d0); - - MathHelper.g[i] = Math.cos(d1); - MathHelper.f[i] = d1; - } - - } -} diff --git a/src/main/java/net/minecraft/server/MerchantRecipe.java b/src/main/java/net/minecraft/server/MerchantRecipe.java index 21666d2d5..b5ec1f1bb 100644 --- a/src/main/java/net/minecraft/server/MerchantRecipe.java +++ b/src/main/java/net/minecraft/server/MerchantRecipe.java @@ -6,10 +6,14 @@ public class MerchantRecipe { public ItemStack buyingItem1; public ItemStack buyingItem2; - public ItemStack sellingItem; + public final ItemStack sellingItem; public int uses; public int maxUses; public boolean rewardExp; + private int specialPrice; + private int demand; + public float priceMultiplier; + public int xp; // CraftBukkit start private CraftMerchantRecipe bukkitHandle; @@ -17,64 +21,104 @@ public class MerchantRecipe { return (bukkitHandle == null) ? bukkitHandle = new CraftMerchantRecipe(this) : bukkitHandle; } - public MerchantRecipe(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int i, int j, CraftMerchantRecipe bukkit) { - this(itemstack, itemstack1, itemstack2, i, j); + public MerchantRecipe(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, CraftMerchantRecipe bukkit) { + this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier); this.bukkitHandle = bukkit; } // CraftBukkit end public MerchantRecipe(NBTTagCompound nbttagcompound) { - this.buyingItem1 = ItemStack.a; - this.buyingItem2 = ItemStack.a; - this.sellingItem = ItemStack.a; - this.a(nbttagcompound); + this.rewardExp = true; + this.xp = 1; + this.buyingItem1 = ItemStack.a(nbttagcompound.getCompound("buy")); + this.buyingItem2 = ItemStack.a(nbttagcompound.getCompound("buyB")); + this.sellingItem = ItemStack.a(nbttagcompound.getCompound("sell")); + this.uses = nbttagcompound.getInt("uses"); + if (nbttagcompound.hasKeyOfType("maxUses", 99)) { + this.maxUses = nbttagcompound.getInt("maxUses"); + } else { + this.maxUses = 4; + } + + if (nbttagcompound.hasKeyOfType("rewardExp", 1)) { + this.rewardExp = nbttagcompound.getBoolean("rewardExp"); + } + + if (nbttagcompound.hasKeyOfType("xp", 3)) { + this.xp = nbttagcompound.getInt("xp"); + } + + if (nbttagcompound.hasKeyOfType("priceMultiplier", 5)) { + this.priceMultiplier = nbttagcompound.getFloat("priceMultiplier"); + } + + this.specialPrice = nbttagcompound.getInt("specialPrice"); + this.demand = nbttagcompound.getInt("demand"); } - public MerchantRecipe(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2) { - this(itemstack, itemstack1, itemstack2, 0, 7); + public MerchantRecipe(ItemStack itemstack, ItemStack itemstack1, int i, int j, float f) { + this(itemstack, ItemStack.a, itemstack1, i, j, f); } - public MerchantRecipe(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int i, int j) { - this.buyingItem1 = ItemStack.a; - this.buyingItem2 = ItemStack.a; - this.sellingItem = ItemStack.a; + public MerchantRecipe(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int i, int j, float f) { + this(itemstack, itemstack1, itemstack2, 0, i, j, f); + } + + public MerchantRecipe(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int i, int j, int k, float f) { + this(itemstack, itemstack1, itemstack2, i, j, k, f, 0); + } + + public MerchantRecipe(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int i, int j, int k, float f, int l) { + this.rewardExp = true; + this.xp = 1; this.buyingItem1 = itemstack; this.buyingItem2 = itemstack1; this.sellingItem = itemstack2; this.uses = i; this.maxUses = j; - this.rewardExp = true; + this.xp = k; + this.priceMultiplier = f; + this.demand = l; } - public MerchantRecipe(ItemStack itemstack, ItemStack itemstack1) { - this(itemstack, ItemStack.a, itemstack1); - } - - public MerchantRecipe(ItemStack itemstack, Item item) { - this(itemstack, new ItemStack(item)); + public ItemStack a() { + return this.buyingItem1; } public ItemStack getBuyItem1() { - return this.buyingItem1; + int i = this.buyingItem1.getCount(); + ItemStack itemstack = this.buyingItem1.cloneItemStack(); + int j = Math.max(0, MathHelper.d((float) (i * this.demand) * this.priceMultiplier)); + + itemstack.setCount(MathHelper.clamp(i + j + this.specialPrice, 1, this.buyingItem1.getItem().getMaxStackSize())); + return itemstack; } public ItemStack getBuyItem2() { return this.buyingItem2; } - public boolean hasSecondItem() { - return !this.buyingItem2.isEmpty(); - } - - public ItemStack getBuyItem3() { + public ItemStack getSellingItem() { return this.sellingItem; } - public int e() { + public void e() { + this.demand = this.demand + this.uses - (this.maxUses - this.uses); + } + + public ItemStack f() { + return this.sellingItem.cloneItemStack(); + } + + public int getUses() { return this.uses; } - public int f() { + public void resetUses() { + this.uses = 0; + } + + public int getMaxUses() { return this.maxUses; } @@ -82,59 +126,90 @@ public class MerchantRecipe { ++this.uses; } - public void a(int i) { - this.maxUses += i; + public int k() { + return this.demand; } - public boolean h() { + public void increaseSpecialPrice(int i) { + this.specialPrice += i; + } + + public void setSpecialPrice() { + this.specialPrice = 0; + } + + public int getSpecialPrice() { + return this.specialPrice; + } + + public void setSpecialPrice(int i) { + this.specialPrice = i; + } + + public float getPriceMultiplier() { + return this.priceMultiplier; + } + + public int getXp() { + return this.xp; + } + + public boolean isFullyUsed() { return this.uses >= this.maxUses; } - public boolean j() { + public void q() { + this.uses = this.maxUses; + } + + public boolean isRewardExp() { return this.rewardExp; } - public void a(NBTTagCompound nbttagcompound) { - NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("buy"); - - this.buyingItem1 = ItemStack.a(nbttagcompound1); - NBTTagCompound nbttagcompound2 = nbttagcompound.getCompound("sell"); - - this.sellingItem = ItemStack.a(nbttagcompound2); - if (nbttagcompound.hasKeyOfType("buyB", 10)) { - this.buyingItem2 = ItemStack.a(nbttagcompound.getCompound("buyB")); - } - - if (nbttagcompound.hasKeyOfType("uses", 99)) { - this.uses = nbttagcompound.getInt("uses"); - } - - if (nbttagcompound.hasKeyOfType("maxUses", 99)) { - this.maxUses = nbttagcompound.getInt("maxUses"); - } else { - this.maxUses = 7; - } - - if (nbttagcompound.hasKeyOfType("rewardExp", 1)) { - this.rewardExp = nbttagcompound.getBoolean("rewardExp"); - } else { - this.rewardExp = true; - } - - } - - public NBTTagCompound k() { + public NBTTagCompound s() { NBTTagCompound nbttagcompound = new NBTTagCompound(); nbttagcompound.set("buy", this.buyingItem1.save(new NBTTagCompound())); nbttagcompound.set("sell", this.sellingItem.save(new NBTTagCompound())); - if (!this.buyingItem2.isEmpty()) { - nbttagcompound.set("buyB", this.buyingItem2.save(new NBTTagCompound())); - } - + nbttagcompound.set("buyB", this.buyingItem2.save(new NBTTagCompound())); nbttagcompound.setInt("uses", this.uses); nbttagcompound.setInt("maxUses", this.maxUses); nbttagcompound.setBoolean("rewardExp", this.rewardExp); + nbttagcompound.setInt("xp", this.xp); + nbttagcompound.setFloat("priceMultiplier", this.priceMultiplier); + nbttagcompound.setInt("specialPrice", this.specialPrice); + nbttagcompound.setInt("demand", this.demand); return nbttagcompound; } + + public boolean a(ItemStack itemstack, ItemStack itemstack1) { + return this.c(itemstack, this.getBuyItem1()) && itemstack.getCount() >= this.getBuyItem1().getCount() && this.c(itemstack1, this.buyingItem2) && itemstack1.getCount() >= this.buyingItem2.getCount(); + } + + private boolean c(ItemStack itemstack, ItemStack itemstack1) { + if (itemstack1.isEmpty() && itemstack.isEmpty()) { + return true; + } else { + ItemStack itemstack2 = itemstack.cloneItemStack(); + + if (itemstack2.getItem().usesDurability()) { + itemstack2.setDamage(itemstack2.getDamage()); + } + + return ItemStack.c(itemstack2, itemstack1) && (!itemstack1.hasTag() || itemstack2.hasTag() && GameProfileSerializer.a(itemstack1.getTag(), itemstack2.getTag(), false)); + } + } + + public boolean b(ItemStack itemstack, ItemStack itemstack1) { + if (!this.a(itemstack, itemstack1)) { + return false; + } else { + itemstack.subtract(this.getBuyItem1().getCount()); + if (!this.getBuyItem2().isEmpty()) { + itemstack1.subtract(this.getBuyItem2().getCount()); + } + + return true; + } + } } diff --git a/src/main/java/net/minecraft/server/MethodProfiler.java b/src/main/java/net/minecraft/server/MethodProfiler.java deleted file mode 100644 index ac3a51372..000000000 --- a/src/main/java/net/minecraft/server/MethodProfiler.java +++ /dev/null @@ -1,188 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class MethodProfiler { - - public static final boolean ENABLED = Boolean.getBoolean("enableDebugMethodProfiler"); // CraftBukkit - disable unless specified in JVM arguments - private static final Logger a = LogManager.getLogger(); - private final List b = Lists.newArrayList(); - private final List c = Lists.newArrayList(); - private boolean d; - private String e = ""; - private final Map f = Maps.newHashMap(); - private long g; - private int h; - - public MethodProfiler() {} - - public boolean a() { - return this.d; - } - - public void b() { - this.d = false; - } - - public long c() { - return this.g; - } - - public int d() { - return this.h; - } - - public void a(int i) { - if (!ENABLED) return; // CraftBukkit - if (!this.d) { - this.d = true; - this.f.clear(); - this.e = ""; - this.b.clear(); - this.h = i; - this.g = SystemUtils.getMonotonicNanos(); - } - } - - public void enter(String s) { - if (!ENABLED) return; // CraftBukkit - if (this.d) { - if (!this.e.isEmpty()) { - this.e = this.e + "."; - } - - this.e = this.e + s; - this.b.add(this.e); - this.c.add(SystemUtils.getMonotonicNanos()); - } - } - - public void a(Supplier supplier) { - if (!ENABLED) return; // CraftBukkit - if (this.d) { - this.enter((String) supplier.get()); - } - } - - public void exit() { - if (!ENABLED) return; // CraftBukkit - if (this.d && !this.c.isEmpty()) { - long i = SystemUtils.getMonotonicNanos(); - long j = (Long) this.c.remove(this.c.size() - 1); - - this.b.remove(this.b.size() - 1); - long k = i - j; - - if (this.f.containsKey(this.e)) { - this.f.put(this.e, (Long) this.f.get(this.e) + k); - } else { - this.f.put(this.e, k); - } - - if (k > 100000000L) { - MethodProfiler.a.warn("Something's taking too long! '{}' took aprox {} ms", this.e, (double) k / 1000000.0D); - } - - this.e = this.b.isEmpty() ? "" : (String) this.b.get(this.b.size() - 1); - } - } - - public List b(String s) { - if (!ENABLED) return Collections.emptyList(); // CraftBukkit - long i = this.f.containsKey("root") ? (Long) this.f.get("root") : 0L; - long j = this.f.containsKey(s) ? (Long) this.f.get(s) : -1L; - List list = Lists.newArrayList(); - - if (!s.isEmpty()) { - s = s + "."; - } - - long k = 0L; - Iterator iterator = this.f.keySet().iterator(); - - while (iterator.hasNext()) { - String s1 = (String) iterator.next(); - - if (s1.length() > s.length() && s1.startsWith(s) && s1.indexOf(".", s.length() + 1) < 0) { - k += (Long) this.f.get(s1); - } - } - - float f = (float) k; - - if (k < j) { - k = j; - } - - if (i < k) { - i = k; - } - - Iterator iterator1 = this.f.keySet().iterator(); - - String s2; - - while (iterator1.hasNext()) { - s2 = (String) iterator1.next(); - if (s2.length() > s.length() && s2.startsWith(s) && s2.indexOf(".", s.length() + 1) < 0) { - long l = (Long) this.f.get(s2); - double d0 = (double) l * 100.0D / (double) k; - double d1 = (double) l * 100.0D / (double) i; - String s3 = s2.substring(s.length()); - - list.add(new MethodProfiler.ProfilerInfo(s3, d0, d1)); - } - } - - iterator1 = this.f.keySet().iterator(); - - while (iterator1.hasNext()) { - s2 = (String) iterator1.next(); - this.f.put(s2, (Long) this.f.get(s2) * 999L / 1000L); - } - - if ((float) k > f) { - list.add(new MethodProfiler.ProfilerInfo("unspecified", (double) ((float) k - f) * 100.0D / (double) k, (double) ((float) k - f) * 100.0D / (double) i)); - } - - Collections.sort(list); - list.add(0, new MethodProfiler.ProfilerInfo(s, 100.0D, (double) k * 100.0D / (double) i)); - return list; - } - - public void exitEnter(String s) { - if (!ENABLED) return; // CraftBukkit - this.exit(); - this.enter(s); - } - - public String f() { - if (!ENABLED) return "[DISABLED]"; // CraftBukkit - return this.b.isEmpty() ? "[UNKNOWN]" : (String) this.b.get(this.b.size() - 1); - } - - public static final class ProfilerInfo implements Comparable { - - public double a; - public double b; - public String c; - - public ProfilerInfo(String s, double d0, double d1) { - this.c = s; - this.a = d0; - this.b = d1; - } - - public int compareTo(MethodProfiler.ProfilerInfo methodprofiler_profilerinfo) { - return methodprofiler_profilerinfo.a < this.a ? -1 : (methodprofiler_profilerinfo.a > this.a ? 1 : methodprofiler_profilerinfo.c.compareTo(this.c)); - } - } -} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 64777c881..0b0058138 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1,60 +1,61 @@ package net.minecraft.server; +import com.google.common.base.Splitter; import co.aikar.timings.Timings; import com.destroystokyo.paper.event.server.PaperServerListPingEvent; import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Queues; -import com.google.common.collect.Sets; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListenableFutureTask; import com.google.gson.JsonElement; import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfileRepository; import com.mojang.authlib.minecraft.MinecraftSessionService; import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; import com.mojang.datafixers.DataFixer; - -import io.akarin.server.core.AkarinGlobalConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.longs.LongIterator; import java.awt.GraphicsEnvironment; import java.awt.image.BufferedImage; +import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import java.net.Proxy; import java.net.URLEncoder; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; import java.security.KeyPair; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Queue; +import java.util.Optional; import java.util.Random; -import java.util.Set; import java.util.UUID; -import java.util.concurrent.Callable; +import java.util.Map.Entry; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.concurrent.Executor; import java.util.function.BooleanSupplier; import javax.annotation.Nullable; import javax.imageio.ImageIO; +import joptsimple.NonOptionArgumentSpec; +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import joptsimple.OptionSpec; import org.apache.commons.lang3.Validate; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -65,80 +66,95 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.Main; import org.bukkit.event.server.ServerLoadEvent; // CraftBukkit end -import org.spigotmc.SlackActivityAccountant; // Spigot import co.aikar.timings.MinecraftTimings; // Paper -import co.aikar.timings.ThreadAssertion; +import org.spigotmc.SlackActivityAccountant; // Spigot -public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStatistics, ICommandListener, Runnable { +public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant implements IMojangStatistics, ICommandListener, AutoCloseable, Runnable { private static MinecraftServer SERVER; // Paper public static final Logger LOGGER = LogManager.getLogger(); - public static final File a = new File("usercache.json"); + public static final File b = new File("usercache.json"); + private static final CompletableFuture i = CompletableFuture.completedFuture(Unit.INSTANCE); + public static final WorldSettings c = (new WorldSettings((long) "North Carolina".hashCode(), EnumGamemode.SURVIVAL, true, false, WorldType.NORMAL)).a(); public Convertable convertable; private final MojangStatisticsGenerator snooper = new MojangStatisticsGenerator("server", this, SystemUtils.getMonotonicMillis()); public File universe; - private final List k = Lists.newArrayList(); - public final MethodProfiler methodProfiler = new MethodProfiler(); - private ServerConnection serverConnection; // Spigot - private final ServerPing m = new ServerPing(); - private final Random n = new Random(); + private final List tickables = Lists.newArrayList(); + private final GameProfiler methodProfiler = new GameProfiler(this::aj); + private ServerConnection serverConnection; + public final WorldLoadListenerFactory worldLoadListenerFactory; + private final ServerPing serverPing = new ServerPing(); + private final Random q = new Random(); public final DataFixer dataConverterManager; private String serverIp; - private int q = -1; + private int serverPort = -1; public final Map worldServer = new com.destroystokyo.paper.PaperWorldMap(); // Paper; private PlayerList playerList; - private boolean isRunning = true; - private boolean isRestarting = false; // Paper - flag to signify we're attempting to restart + private volatile boolean isRunning = true; + private volatile boolean isRestarting = false; // Paper - flag to signify we're attempting to restart private boolean isStopped; - private int ticks; public int currentTick() { return this.ticks; } // Akarin - OBFHELPER - protected final Proxy c; - private IChatBaseComponent w; - private int x; + private int ticks; + protected final Proxy proxy; private boolean onlineMode; - private boolean z; + private boolean A; private boolean spawnAnimals; private boolean spawnNPCs; private boolean pvpMode; private boolean allowFlight; + @Nullable private String motd; - private int F; private int G; - public final long[] d = new long[100]; - protected final Map e = com.koloboke.collect.map.hash.HashObjObjMaps.getDefaultFactory().withNullKeyAllowed(true).withKeyEquivalence(com.koloboke.collect.Equivalence.identity()).newUpdatableMap(); // Akarin - koloboke - private KeyPair H; - private String I; + private int H; + public final long[] f = new long[100]; + @Nullable + private KeyPair I; + @Nullable private String J; + private final String K; private boolean demoMode; - private boolean M; - private String N = ""; + private boolean bonusChest; private String O = ""; - private boolean P; + private String P = ""; + private volatile boolean hasTicked; private long lastOverloadTime; - private IChatBaseComponent R; - private boolean S; + @Nullable + private IChatBaseComponent S; private boolean T; - private final YggdrasilAuthenticationService U; - private final MinecraftSessionService V; - private final GameProfileRepository W; - private final UserCache X; - private long Y; - protected final Queue> f = Queues.newConcurrentLinkedQueue(); - private Thread serverThread; + private boolean U; + @Nullable + private final YggdrasilAuthenticationService yggdrasilAuthenticationService; + private final MinecraftSessionService minecraftSessionService; + private final GameProfileRepository gameProfileRepository; + private final UserCache userCache; + private long Z; + public final Thread serverThread = (Thread) SystemUtils.a((new Thread(this, "Server thread")), (thread) -> { // CraftBukkit - decompile error + thread.setUncaughtExceptionHandler((thread1, throwable) -> { + MinecraftServer.LOGGER.error(throwable); + }); + }); private long nextTick = SystemUtils.getMonotonicMillis(); - private final IReloadableResourceManager ac; + private long ab; final long getTickOversleepMaxTime() { return this.ab; } // Paper - OBFHELPER + private boolean ac; final boolean hasExecutedTask() { return this.ac; } // Paper - OBFHELPER + private final IReloadableResourceManager ae; private final ResourcePackRepository resourcePackRepository; + @Nullable private ResourcePackSourceFolder resourcePackFolder; public CommandDispatcher commandDispatcher; - private final CraftingManager ag; - private final TagRegistry ah; - private final ScoreboardServer ai; - private final BossBattleCustomData aj; - private final LootTableRegistry ak; - private final AdvancementDataWorld al; - private final CustomFunctionData am; - private boolean an; + private final CraftingManager ai; + private final TagRegistry aj; + private final ScoreboardServer ak; + private final BossBattleCustomData al; + private final LootTableRegistry am; + private final AdvancementDataWorld an; + private final CustomFunctionData ao; + private final CircularTimer ap; + private boolean aq; private boolean forceUpgrade; - private float ap; + private boolean eraseCache; + private float at; + public final Executor executorService; + @Nullable + private String av; // CraftBukkit start public org.bukkit.craftbukkit.CraftServer server; @@ -147,13 +163,12 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati public org.bukkit.command.RemoteConsoleCommandSender remoteConsole; //public ConsoleReader reader; // Paper public static int currentTick = 0; // Paper - Further improve tick loop - public boolean serverAutoSave = false; // Paper - public final Thread primaryThread; public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); public int autosavePeriod; + public boolean serverAutoSave = false; // Paper public File bukkitDataPackFolder; public CommandDispatcher vanillaCommandDispatcher; - public List expiringMaps = java.util.Collections.synchronizedList(new java.util.ArrayList<>()); // Paper + private boolean forceTicks; // CraftBukkit end // Spigot start public static final int TPS = 20; @@ -163,34 +178,37 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati public final SlackActivityAccountant slackActivityAccountant = new SlackActivityAccountant(); // Spigot end - public MinecraftServer(OptionSet options, Proxy proxy, DataFixer datafixer, CommandDispatcher commanddispatcher, YggdrasilAuthenticationService yggdrasilauthenticationservice, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache) { + public MinecraftServer(OptionSet options, Proxy proxy, DataFixer datafixer, CommandDispatcher commanddispatcher, YggdrasilAuthenticationService yggdrasilauthenticationservice, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache, WorldLoadListenerFactory worldloadlistenerfactory, String s) { + super("Server"); + this.ae = new ResourceManager(EnumResourcePackType.SERVER_DATA, this.serverThread); SERVER = this; // Paper - better singleton - this.commandDispatcher = commanddispatcher; // CraftBukkit - this.ac = new ResourceManager(EnumResourcePackType.SERVER_DATA); this.resourcePackRepository = new ResourcePackRepository<>(ResourcePackLoader::new); - this.ag = new CraftingManager(); - this.ah = new TagRegistry(); - this.ai = new ScoreboardServer(this); - this.aj = new BossBattleCustomData(this); - this.ak = new LootTableRegistry(); - this.al = new AdvancementDataWorld(); - this.am = new CustomFunctionData(this); - this.c = proxy; + this.ai = new CraftingManager(); + this.aj = new TagRegistry(); + this.ak = new ScoreboardServer(this); + this.al = new BossBattleCustomData(this); + this.am = new LootTableRegistry(); + this.an = new AdvancementDataWorld(); + this.ao = new CustomFunctionData(this); + this.ap = new CircularTimer(); + this.proxy = proxy; this.commandDispatcher = this.vanillaCommandDispatcher = commanddispatcher; // CraftBukkit - this.U = yggdrasilauthenticationservice; - this.V = minecraftsessionservice; - this.W = gameprofilerepository; - this.X = usercache; - this.userCache = new AkarinUserCache(gameprofilerepository, usercache.file(), usercache.gson()); // Akarin + this.yggdrasilAuthenticationService = yggdrasilauthenticationservice; + this.minecraftSessionService = minecraftsessionservice; + this.gameProfileRepository = gameprofilerepository; + this.userCache = usercache; // this.universe = file; // CraftBukkit // this.serverConnection = new ServerConnection(this); // CraftBukkit // Spigot - // this.convertable = file == null ? null : new WorldLoaderServer(file.toPath(), file.toPath().resolve("../backups"), datafixer); // CraftBukkit - moved to DedicatedServer.init + this.worldLoadListenerFactory = worldloadlistenerfactory; + // this.convertable = new Convertable(file.toPath(), file.toPath().resolve("../backups"), datafixer); // CraftBukkit - moved to DedicatedServer.init this.dataConverterManager = datafixer; - this.ac.a((IResourcePackListener) this.ah); - this.ac.a((IResourcePackListener) this.ag); - this.ac.a((IResourcePackListener) this.ak); - this.ac.a((IResourcePackListener) this.am); - this.ac.a((IResourcePackListener) this.al); + this.ae.a((IReloadListener) this.aj); + this.ae.a((IReloadListener) this.ai); + this.ae.a((IReloadListener) this.am); + this.ae.a((IReloadListener) this.ao); + this.ae.a((IReloadListener) this.an); + this.executorService = SystemUtils.e(); + this.K = s; // CraftBukkit start this.options = options; // Paper start - Handled by TerminalConsoleAppender @@ -219,14 +237,17 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati */ // Paper end Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this)); - - this.serverThread = primaryThread = new Thread(this, "Server thread"); // Moved from main } - - public abstract PropertyManager getPropertyManager(); // CraftBukkit end - public abstract boolean init() throws IOException; + private void initializeScoreboards(WorldPersistentData worldpersistentdata) { + PersistentScoreboard persistentscoreboard = (PersistentScoreboard) worldpersistentdata.a(PersistentScoreboard::new, "scoreboard"); + + persistentscoreboard.a((Scoreboard) this.getScoreboard()); + this.getScoreboard().a((Runnable) (new RunnableSaveScoreboard(persistentscoreboard))); + } + + protected abstract boolean init() throws IOException; public void convertWorld(String s) { if (this.getConvertable().isConvertable(s)) { @@ -235,8 +256,10 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati this.getConvertable().convert(s, new IProgressUpdate() { private long b = SystemUtils.getMonotonicMillis(); + @Override public void a(IChatBaseComponent ichatbasecomponent) {} + @Override public void a(int i) { if (SystemUtils.getMonotonicMillis() - this.b >= 1000L) { this.b = SystemUtils.getMonotonicMillis(); @@ -245,16 +268,17 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } + @Override public void c(IChatBaseComponent ichatbasecomponent) {} }); } if (this.forceUpgrade) { MinecraftServer.LOGGER.info("Forcing world upgrade! {}", s); // CraftBukkit - WorldData worlddata = this.getConvertable().c(s); // CraftBukkit + WorldData worlddata = this.getConvertable().b(s); // CraftBukkit if (worlddata != null) { - WorldUpgrader worldupgrader = new WorldUpgrader(s, this.getConvertable(), worlddata); // CraftBukkit + WorldUpgrader worldupgrader = new WorldUpgrader(s, this.getConvertable(), worlddata, this.eraseCache); // CraftBukkit IChatBaseComponent ichatbasecomponent = null; while (!worldupgrader.b()) { @@ -289,37 +313,37 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } protected synchronized void b(IChatBaseComponent ichatbasecomponent) { - this.R = ichatbasecomponent; + this.S = ichatbasecomponent; } - public void a(String s, String s1, long i, WorldType worldtype, JsonElement jsonelement) { + protected void a(String s, String s1, long i, WorldType worldtype, JsonElement jsonelement) { // this.convertWorld(s); // CraftBukkit - moved down this.b((IChatBaseComponent) (new ChatMessage("menu.loadingLevel", new Object[0]))); /* CraftBukkit start - Remove ticktime arrays and worldsettings - IDataManager idatamanager = this.getConvertable().a(s, this); + WorldNBTStorage worldnbtstorage = this.getConvertable().a(s, this); - this.a(this.getWorld(), idatamanager); - WorldData worlddata = idatamanager.getWorldData(); + this.a(this.getWorld(), worldnbtstorage); + WorldData worlddata = worldnbtstorage.getWorldData(); WorldSettings worldsettings; if (worlddata == null) { - if (this.L()) { - worldsettings = DemoWorldServer.a; + if (this.isDemoMode()) { + worldsettings = MinecraftServer.c; } else { worldsettings = new WorldSettings(i, this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype); worldsettings.setGeneratorSettings(jsonelement); - if (this.M) { + if (this.bonusChest) { worldsettings.a(); } } worlddata = new WorldData(worldsettings, s1); } else { - worlddata.a(s1); + worlddata.setName(s1); worldsettings = new WorldSettings(worlddata); } - this.a(idatamanager.getDirectory(), worlddata); + this.a(worldnbtstorage.getDirectory(), worlddata); */ int worldCount = 3; @@ -353,22 +377,21 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati worldsettings.setGeneratorSettings(jsonelement); if (j == 0) { - IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), s1, this, this.dataConverterManager); - worlddata = idatamanager.getWorldData(); + WorldNBTStorage worldnbtstorage = new WorldNBTStorage(server.getWorldContainer(), s1, this, this.dataConverterManager); + worlddata = worldnbtstorage.getWorldData(); if (worlddata == null) { worlddata = new WorldData(worldsettings, s1); } worlddata.checkName(s1); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) - this.a(idatamanager.getDirectory(), worlddata); - PersistentCollection persistentcollection = new PersistentCollection(idatamanager); + this.a(worldnbtstorage.getDirectory(), worlddata); + WorldLoadListener worldloadlistener = this.worldLoadListenerFactory.create(11); - if (this.L()) { - world = (WorldServer) (new DemoWorldServer(this, idatamanager, persistentcollection, worlddata, DimensionManager.OVERWORLD, this.methodProfiler)).i_(); - } else { - world = (WorldServer) (new WorldServer(this, idatamanager, persistentcollection, worlddata, DimensionManager.OVERWORLD, this.methodProfiler, org.bukkit.World.Environment.getEnvironment(dimension), gen)).i_(); + if (this.isDemoMode()) { + worlddata.a(MinecraftServer.c); } + world = new WorldServer(this, this.executorService, worldnbtstorage, worlddata, DimensionManager.OVERWORLD, this.methodProfiler, worldloadlistener, org.bukkit.World.Environment.getEnvironment(dimension), gen); - world.a(worldsettings); + this.initializeScoreboards(world.getWorldPersistentData()); this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard()); } else { String dim = "DIM" + dimension; @@ -407,33 +430,32 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } } - IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), name, this, this.dataConverterManager); + WorldNBTStorage worldnbtstorage = new WorldNBTStorage(server.getWorldContainer(), name, this, this.dataConverterManager); // world =, b0 to dimension, s1 to name, added Environment and gen - worlddata = idatamanager.getWorldData(); + worlddata = worldnbtstorage.getWorldData(); if (worlddata == null) { worlddata = new WorldData(worldsettings, name); } worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) - world = (WorldServer) new SecondaryWorldServer(this, idatamanager, DimensionManager.a(dimension), this.getWorldServer(DimensionManager.OVERWORLD), this.methodProfiler, worlddata, org.bukkit.World.Environment.getEnvironment(dimension), gen).i_(); + WorldLoadListener worldloadlistener = this.worldLoadListenerFactory.create(11); + world = new SecondaryWorldServer(this.getWorldServer(DimensionManager.OVERWORLD), this, this.executorService, worldnbtstorage, DimensionManager.a(dimension), this.methodProfiler, worldloadlistener, worlddata, org.bukkit.World.Environment.getEnvironment(dimension), gen); } + this.initWorld(world, worlddata, worldsettings); this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld())); - world.addIWorldAccess(new WorldManager(this, world)); - if (!this.H()) { - world.getWorldData().setGameType(this.getGamemode()); - } - - this.worldServer.put(world.dimension, world); + this.worldServer.put(world.getWorldProvider().getDimensionManager(), world); this.getPlayerList().setPlayerFileData(world); - if (worlddata.P() != null) { - this.getBossBattleCustomData().a(worlddata.P()); + if (worlddata.getCustomBossEvents() != null) { + this.getBossBattleCustomData().a(worlddata.getCustomBossEvents()); } } - this.a(this.getDifficulty()); - this.a(this.getWorldServer(DimensionManager.OVERWORLD).worldMaps); - // CraftBukkit end + this.a(this.getDifficulty(), true); + for (WorldServer worldserver : com.google.common.collect.Lists.newArrayList(this.getWorlds())) { // Paper - avoid como if 1 world triggers another world + this.loadSpawn(worldserver.getChunkProvider().playerChunkMap.worldLoadListener, worldserver); + this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(worldserver.getWorld())); + } // Paper start - Handle collideRule team for player collision toggle final Scoreboard scoreboard = this.getScoreboard(); @@ -448,6 +470,61 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati collideTeam.setCanSeeFriendlyInvisibles(false); // Because we want to mimic them not being on a team at all } // Paper end + + this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); + this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP)); + this.serverConnection.acceptConnections(); + // CraftBukkit end + + } + + // CraftBukkit start + public void initWorld(WorldServer worldserver1, WorldData worlddata, WorldSettings worldsettings) { + worldserver1.getWorldBorder().b(worlddata); + + // CraftBukkit start + if (worldserver1.generator != null) { + worldserver1.getWorld().getPopulators().addAll(worldserver1.generator.getDefaultPopulators(worldserver1.getWorld())); + } + // CraftBukkit end + + if (!worlddata.u()) { + try { + worldserver1.a(worldsettings); + if (worlddata.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { + this.a(worlddata); + } + + worlddata.d(true); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Exception initializing level"); + + try { + worldserver1.a(crashreport); + } catch (Throwable throwable1) { + ; + } + + throw new ReportedException(crashreport); + } + + worlddata.d(true); + } + } + // CraftBukkit end + + private void a(WorldData worlddata) { + worlddata.f(false); + worlddata.c(true); + worlddata.setStorm(false); + worlddata.setThundering(false); + worlddata.g(1000000000); + worlddata.setDayTime(6000L); + worlddata.setGameType(EnumGamemode.SPECTATOR); + worlddata.g(false); + worlddata.setDifficulty(EnumDifficulty.PEACEFUL); + worlddata.e(true); + ((GameRules.GameRuleBoolean) worlddata.v().get(GameRules.DO_DAYLIGHT_CYCLE)).a(false, this); } protected void a(File file, WorldData worlddata) { @@ -459,17 +536,15 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati bukkitDataPackFolder.mkdirs(); } File mcMeta = new File(bukkitDataPackFolder, "pack.mcmeta"); - if (!mcMeta.exists()) { - try { - com.google.common.io.Files.write("{\n" - + " \"pack\": {\n" - + " \"description\": \"Data pack for resources provided by Bukkit plugins\",\n" - + " \"pack_format\": 1\n" - + " }\n" - + "}", mcMeta, com.google.common.base.Charsets.UTF_8); - } catch (IOException ex) { - throw new RuntimeException("Could not initialize Bukkit datapack", ex); - } + try { + com.google.common.io.Files.write("{\n" + + " \"pack\": {\n" + + " \"description\": \"Data pack for resources provided by Bukkit plugins\",\n" + + " \"pack_format\": " + SharedConstants.a().getPackVersion() + "\n" + + " }\n" + + "}\n", mcMeta, com.google.common.base.Charsets.UTF_8); + } catch (IOException ex) { + throw new RuntimeException("Could not initialize Bukkit datapack", ex); } // CraftBukkit end this.resourcePackRepository.a((ResourcePackSource) this.resourcePackFolder); @@ -489,93 +564,91 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } this.resourcePackRepository.a((Collection) list); - this.a(worlddata); + this.b(worlddata); } - protected void a(PersistentCollection persistentcollection) { - boolean flag = true; - boolean flag1 = true; - boolean flag2 = true; - boolean flag3 = true; - boolean flag4 = true; + // CraftBukkit start + public void loadSpawn(WorldLoadListener worldloadlistener, WorldServer worldserver) { + if (!worldserver.getWorld().getKeepSpawnInMemory()) { + return; + } this.b((IChatBaseComponent) (new ChatMessage("menu.generatingTerrain", new Object[0]))); - - // CraftBukkit start - fire WorldLoadEvent and handle whether or not to keep the spawn in memory - Stopwatch stopwatch = Stopwatch.createStarted(); - boolean waitForChunks = Boolean.getBoolean("paper.waitforchunks"); // Paper - for (WorldServer worldserver : this.getWorlds()) { - MinecraftServer.LOGGER.info("Preparing start region for level " + worldserver.dimension + " (Seed: " + worldserver.getSeed() + ")"); - if (!worldserver.getWorld().getKeepSpawnInMemory()) { - continue; - } - - BlockPosition blockposition = worldserver.getSpawn(); - List list = worldserver.getChunkProvider().getSpiralOutChunks(blockposition, worldserver.paperConfig.keepLoadedRange >> 4); // Paper - Set set = Sets.newConcurrentHashSet(); - - // Paper - remove arraylist creation, call spiral above - if (this.isRunning()) { // Paper - int expected = list.size(); // Paper - - CompletableFuture completablefuture = worldserver.getChunkProvider().loadAllChunks(list, (chunk) -> { // Paper - set.add(chunk.getPos()); - if (waitForChunks && (set.size() == expected || (set.size() < expected && set.size() % (set.size() / 10) == 0))) { - this.a(new ChatMessage("menu.preparingSpawn", new Object[0]), set.size() * 100 / expected); // Paper - } - }); - - while (waitForChunks && !completablefuture.isDone() && isRunning()) { // Paper - try { - PaperAsyncChunkProvider.processMainThreadQueue(this); // Paper - completablefuture.get(50L, TimeUnit.MILLISECONDS); // Paper - } catch (InterruptedException interruptedexception) { - throw new RuntimeException(interruptedexception); - } catch (ExecutionException executionexception) { - if (executionexception.getCause() instanceof RuntimeException) { - throw (RuntimeException) executionexception.getCause(); - } - - throw new RuntimeException(executionexception.getCause()); - } catch (TimeoutException timeoutexception) { - //this.a(new ChatMessage("menu.preparingSpawn", new Object[0]), set.size() * 100 / expected); // Paper - } - } - - if (waitForChunks) this.a(new ChatMessage("menu.preparingSpawn", new Object[0]), set.size() * 100 / expected); // Paper - } - } - - for (WorldServer world : com.google.common.collect.Lists.newArrayList(this.getWorlds())) { // Paper - avoid como if 1 world triggers another world - this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(world.getWorld())); - } + // WorldServer worldserver = this.getWorldServer(DimensionManager.OVERWORLD); + this.forceTicks = true; // CraftBukkit end - MinecraftServer.LOGGER.info("Time elapsed: {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS)); - Iterator iterator = DimensionManager.b().iterator(); - while (iterator.hasNext()) { - DimensionManager dimensionmanager = (DimensionManager) iterator.next(); - ForcedChunk forcedchunk = (ForcedChunk) persistentcollection.get(dimensionmanager, ForcedChunk::new, "chunks"); + // Paper start - configurable spawn reason + int radiusBlocks = worldserver.paperConfig.keepLoadedRange; + int radiusChunks = radiusBlocks / 16 + ((radiusBlocks & 15) != 0 ? 1 : 0); + int totalChunks = ((radiusChunks) * 2 + 1); + totalChunks *= totalChunks; + worldloadlistener.setChunkRadius(radiusBlocks / 16); + // Paper end + + MinecraftServer.LOGGER.info("Preparing start region for dimension '{}'/{}", worldserver.getWorldData().getName(), DimensionManager.a(worldserver.worldProvider.getDimensionManager().getType())); // CraftBukkit + BlockPosition blockposition = worldserver.getSpawn(); + + worldloadlistener.a(new ChunkCoordIntPair(blockposition)); + ChunkProviderServer chunkproviderserver = worldserver.getChunkProvider(); + + chunkproviderserver.getLightEngine().a(500); + this.nextTick = SystemUtils.getMonotonicMillis(); + // Paper start - Configurable spawn radius + if (worldserver.keepSpawnInMemory) { + worldserver.addTicketsForSpawn(radiusBlocks, blockposition); + + // we use a getChunk loop since we don't need to worry about what some plugin does to keepSpawnInMemory + // or the spawn radius while we are loading + // just keep in mind too that executeModerately will handle player network queue (i.e commands) + int centerX = blockposition.getX() >> 4; + int centerZ = blockposition.getZ() >> 4; + radiusChunks += 2; // we need to load radius +2 to get the chunks in ticking level + for (int xoff = -radiusChunks; xoff <= radiusChunks; ++xoff) { + for (int zoff = -radiusChunks; zoff <= radiusChunks; ++zoff) { + worldserver.getChunkAt(centerX + xoff, centerZ + zoff); + } + } + } + // Paper end + LOGGER.info("Loaded " + chunkproviderserver.b() + " spawn chunks for world " + worldserver.getWorldData().getName()); // Paper + + // CraftBukkit start + // this.nextTick = SystemUtils.getMonotonicMillis() + 10L; + this.executeModerately(); + // Iterator iterator = DimensionManager.a().iterator(); + if (true) { + DimensionManager dimensionmanager = worldserver.worldProvider.getDimensionManager(); + ForcedChunk forcedchunk = (ForcedChunk) worldserver.getWorldPersistentData().b(ForcedChunk::new, "chunks"); + // CraftBukkit end if (forcedchunk != null) { WorldServer worldserver1 = this.getWorldServer(dimensionmanager); LongIterator longiterator = forcedchunk.a().iterator(); while (longiterator.hasNext()) { - this.a(new ChatMessage("menu.loadingForcedChunks", new Object[] { dimensionmanager}), forcedchunk.a().size() * 100 / 625); - long k = longiterator.nextLong(); - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(k); + long i = longiterator.nextLong(); + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i); - worldserver1.getChunkProvider().getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, true, true); + worldserver1.getChunkProvider().a(chunkcoordintpair, true); } } } - this.l(); + // CraftBukkit start + // this.nextTick = SystemUtils.getMonotonicMillis() + 10L; + this.executeModerately(); + // CraftBukkit end + worldloadlistener.b(); + chunkproviderserver.getLightEngine().a(5); + + // CraftBukkit start + this.forceTicks = false; + // CraftBukkit end } - protected void a(String s, IDataManager idatamanager) { - File file = new File(idatamanager.getDirectory(), "resources.zip"); + protected void a(String s, WorldNBTStorage worldnbtstorage) { + File file = new File(worldnbtstorage.getDirectory(), "resources.zip"); if (file.isFile()) { try { @@ -597,57 +670,61 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati public abstract int j(); - public abstract boolean k(); + public abstract int k(); - protected void a(IChatBaseComponent ichatbasecomponent, int i) { - this.w = ichatbasecomponent; - this.x = i; - MinecraftServer.LOGGER.info("{}: {}%", ichatbasecomponent.getString(), i); - } + public abstract boolean l(); - protected void l() { - this.w = null; - this.x = 0; - // CraftBukkit Start - this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); - LoginListener.allowLogins(); // Paper - Allow logins once postworld - this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP)); - // CraftBukkit end - } + public boolean saveChunks(boolean flag, boolean flag1, boolean flag2) { + boolean flag3 = false; - protected void saveChunks(boolean flag) { - Iterator iterator = this.getWorlds().iterator(); - - while (iterator.hasNext()) { + for (Iterator iterator = this.getWorlds().iterator(); iterator.hasNext(); flag3 = true) { WorldServer worldserver = (WorldServer) iterator.next(); - if (worldserver != null) { - if (!flag) { - MinecraftServer.LOGGER.info("Saving chunks for level '{}'/{}", worldserver.getWorldData().getName(), DimensionManager.a(worldserver.worldProvider.getDimensionManager())); - } + if (!flag) { + MinecraftServer.LOGGER.info("Saving chunks for level '{}'/{}", worldserver.getWorldData().getName(), DimensionManager.a(worldserver.worldProvider.getDimensionManager())); + } - try { - worldserver.save(true, (IProgressUpdate) null); - } catch (ExceptionWorldConflict exceptionworldconflict) { - MinecraftServer.LOGGER.warn(exceptionworldconflict.getMessage()); - } + try { + worldserver.save((IProgressUpdate) null, flag1, worldserver.savingDisabled && !flag2); + } catch (ExceptionWorldConflict exceptionworldconflict) { + MinecraftServer.LOGGER.warn(exceptionworldconflict.getMessage()); } } + // CraftBukkit start - moved to WorldServer.save + /* + WorldServer worldserver1 = this.getWorldServer(DimensionManager.OVERWORLD); + WorldData worlddata = worldserver1.getWorldData(); + + worldserver1.getWorldBorder().a(worlddata); + worlddata.c(this.getBossBattleCustomData().c()); + worldserver1.getDataManager().saveWorldData(worlddata, this.getPlayerList().r()); + */ + // CraftBukkit end + return flag3; + } + + @Override + public void close() { + this.stop(); } // CraftBukkit start private boolean hasStopped = false; private final Object stopLock = new Object(); + public final boolean hasStopped() { + synchronized (stopLock) { + return hasStopped; + } + } // CraftBukkit end - public void stop() throws ExceptionWorldConflict { // CraftBukkit - added throws + protected void stop() { // CraftBukkit start - prevent double stopping on multiple threads synchronized(stopLock) { if (hasStopped) return; hasStopped = true; } - PaperAsyncChunkProvider.stop(this); // Paper // CraftBukkit end MinecraftServer.LOGGER.info("Stopping server"); MinecraftTimings.stopServer(); // Paper @@ -663,7 +740,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati if (this.playerList != null) { MinecraftServer.LOGGER.info("Saving players"); this.playerList.savePlayers(); - this.playerList.u(isRestarting); // Paper + this.playerList.shutdown(this.isRestarting); // Paper try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets } @@ -679,13 +756,17 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } } - this.saveChunks(false); + this.saveChunks(false, true, false); iterator = this.getWorlds().iterator(); while (iterator.hasNext()) { worldserver = (WorldServer) iterator.next(); if (worldserver != null) { - worldserver.close(); + try { + worldserver.close(); + } catch (IOException ioexception) { + MinecraftServer.LOGGER.error("Exception closing the level", ioexception); + } } } @@ -696,9 +777,10 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati // Spigot start if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { LOGGER.info("Saving usercache.json"); - this.getModernUserCache().save(); // Paper // Akarin - force to single thread to ensure safety + this.getUserCache().c(false); // Paper } // Spigot end + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper } public String getServerIp() { @@ -714,20 +796,23 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } // Paper start - allow passing of the intent to restart - public void safeShutdown() { - safeShutdown(false); + public void safeShutdown(boolean flag) { + this.safeShutdown(flag, false); } - - public void safeShutdown(boolean isRestarting) { + public void safeShutdown(boolean flag, boolean isRestarting) { this.isRunning = false; this.isRestarting = isRestarting; + if (flag) { + try { + this.serverThread.join(); + } catch (InterruptedException interruptedexception) { + MinecraftServer.LOGGER.error("Error while shutting down", interruptedexception); + } + } + } // Paper end - private boolean canSleepForTick() { - return System.nanoTime() - lastTick + catchupTime < TICK_TIME; // Paper - improved "are we lagging" check to match our own - } - // Spigot Start private static double calcTps(double avg, double exp, double tps) { @@ -790,46 +875,27 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati try { if (this.init()) { this.nextTick = SystemUtils.getMonotonicMillis(); - this.m.setMOTD(new ChatComponentText(this.motd)); - this.m.setServerInfo(new ServerPing.ServerData("1.13.2", 404)); - this.a(this.m); + this.serverPing.setMOTD(new ChatComponentText(this.motd)); + this.serverPing.setServerInfo(new ServerPing.ServerData(SharedConstants.a().getName(), SharedConstants.a().getProtocolVersion())); + this.a(this.serverPing); // Spigot start org.spigotmc.WatchdogThread.hasStarted = true; // Paper - io.akarin.server.core.AkarinAsyncScheduler.initalise(); // Akarin - Thread.currentThread().setPriority(Thread.MAX_PRIORITY); // Akarin Arrays.fill( recentTps, 20 ); - long start = System.nanoTime(), curTime, wait, tickSection = start; // Paper - Further improve server tick loop + long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop lastTick = start - TICK_TIME; // Paper while (this.isRunning) { - curTime = System.nanoTime(); - // Paper start - Further improve server tick loop - wait = TICK_TIME - (curTime - lastTick); - if (wait > 0) { - if (catchupTime < 2E6) { - wait += Math.abs(catchupTime); - } else if (wait < catchupTime) { - catchupTime -= wait; - wait = 0; - } else { - wait -= catchupTime; - catchupTime = 0; - } - } - if (wait > 0) { - // Akarin start - if (AkarinGlobalConfig.spinningAwaitTicking) { - long park = System.nanoTime(); - while ((System.nanoTime() - park) < wait); - } else { - Thread.sleep(wait / 1000000); - } - // Akarin end - curTime = System.nanoTime(); - wait = TICK_TIME - (curTime - lastTick); + long i = ((curTime = System.nanoTime()) / (1000L * 1000L)) - this.nextTick; // Paper + + if (i > 5000L && this.nextTick - this.lastOverloadTime >= 30000L) { // CraftBukkit + long j = i / 50L; + + if (server.getWarnOnOverload()) // CraftBukkit + MinecraftServer.LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", i, j); + this.nextTick += j * 50L; + this.lastOverloadTime = this.nextTick; } - catchupTime = Math.min(MAX_CATCHUP_BUFFER, catchupTime - wait); if ( ++MinecraftServer.currentTick % SAMPLE_INTERVAL == 0 ) { final long diff = curTime - tickSection; @@ -844,13 +910,26 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati // Paper end tickSection = curTime; } - lastTick = curTime; + // Spigot end //MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit // Paper - don't overwrite current tick time - this.a(this::canSleepForTick); + lastTick = curTime; this.nextTick += 50L; - // Spigot end - this.P = true; + if (this.T) { + this.T = false; + this.methodProfiler.d().d(); + } + + this.methodProfiler.a(); + this.methodProfiler.enter("tick"); + this.a(this::canSleepForTick); + this.methodProfiler.exitEnter("nextTickWait"); + this.ac = true; + this.ab = Math.max(SystemUtils.getMonotonicMillis() + 50L, this.nextTick); + this.sleepForTick(); + this.methodProfiler.exit(); + this.methodProfiler.b(); + this.hasTicked = true; } } else { this.a((CrashReport) null); @@ -871,7 +950,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati crashreport = this.b(new CrashReport("Exception in server tick loop", throwable)); } - File file = new File(new File(this.s(), "crash-reports"), "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt"); + File file = new File(new File(this.t(), "crash-reports"), "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt"); if (crashreport.a(file)) { MinecraftServer.LOGGER.error("This crash report has been saved to: {}", file.getAbsolutePath()); @@ -894,15 +973,80 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } catch (Exception ignored) { } // CraftBukkit end - this.t(); + this.exit(); } } } + private boolean canSleepForTick() { + // CraftBukkit start + return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < (this.ac ? this.ab : this.nextTick); + } + + // Paper start + private boolean canOversleep() { + return this.hasExecutedTask() && SystemUtils.getMonotonicMillis() < this.getTickOversleepMaxTime(); + } + + private boolean canSleepForTickNoOversleep() { + return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < this.nextTick; + } + // Paper end + + private void executeModerately() { + this.executeAll(); + java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L); + } + // CraftBukkit end + + protected void sleepForTick() { + //this.executeAll(); // Paper - move this into the tick method for timings + this.awaitTasks(() -> { + return !this.canSleepForTickNoOversleep(); // Paper - move oversleep into full server tick + }); + } + + @Override + protected TickTask postToMainThread(Runnable runnable) { + return new TickTask(this.ticks, runnable); + } + + protected boolean canExecute(TickTask ticktask) { + return ticktask.a() + 3 < this.ticks || this.canSleepForTick(); + } + + @Override + public boolean executeNext() { + boolean flag = this.aX(); + + this.ac = flag; + return flag; + } + + private boolean aX() { + if (super.executeNext()) { + return true; + } else { + if (this.canSleepForTick()) { + Iterator iterator = this.getWorlds().iterator(); + + while (iterator.hasNext()) { + WorldServer worldserver = (WorldServer) iterator.next(); + + if (worldserver.getChunkProvider().runTasks()) { + return true; + } + } + } + + return false; + } + } + public void a(ServerPing serverping) { - File file = this.c("server-icon.png"); + File file = this.d("server-icon.png"); if (!file.exists()) { file = this.getConvertable().b(this.getWorld(), "icon.png"); @@ -929,87 +1073,91 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } - public File s() { + public File t() { return new File("."); } protected void a(CrashReport crashreport) {} - public void t() {} + protected void exit() {} protected void a(BooleanSupplier booleansupplier) { - co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper // Akarin + co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper + // Paper start - move oversleep into full server tick + MinecraftTimings.serverOversleep.startTiming(); + this.awaitTasks(() -> { + return !this.canOversleep(); + }); + MinecraftTimings.serverOversleep.stopTiming(); + // Paper end this.slackActivityAccountant.tickStarted(); // Spigot - long i = SystemUtils.getMonotonicNanos(); long startTime = i; // Paper + long i = SystemUtils.getMonotonicNanos(); new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.ticks+1).callEvent(); // Paper ++this.ticks; - if (this.S) { - this.S = false; - //this.methodProfiler.a(this.ticks); // Akarin - remove caller - } - - //this.methodProfiler.enter(* // Akarin - remove caller this.b(booleansupplier); - if (i - this.Y >= 5000000000L) { - this.Y = i; - this.m.setPlayerSample(new ServerPing.ServerPingPlayerSample(this.getMaxPlayers(), this.getPlayerCount())); + if (i - this.Z >= 5000000000L) { + this.Z = i; + this.serverPing.setPlayerSample(new ServerPing.ServerPingPlayerSample(this.getMaxPlayers(), this.getPlayerCount())); GameProfile[] agameprofile = new GameProfile[Math.min(this.getPlayerCount(), org.spigotmc.SpigotConfig.playerSample)]; // Paper - int j = MathHelper.nextInt(this.n, 0, this.getPlayerCount() - agameprofile.length); + int j = MathHelper.nextInt(this.q, 0, this.getPlayerCount() - agameprofile.length); for (int k = 0; k < agameprofile.length; ++k) { - agameprofile[k] = ((EntityPlayer) this.playerList.v().get(j + k)).getProfile(); + agameprofile[k] = ((EntityPlayer) this.playerList.getPlayers().get(j + k)).getProfile(); } Collections.shuffle(Arrays.asList(agameprofile)); - this.m.b().a(agameprofile); + this.serverPing.b().a(agameprofile); } - //this.methodProfiler.enter(* // Akarin - remove caller - - serverAutoSave = (autosavePeriod > 0 && this.ticks % autosavePeriod == 0); // Paper - int playerSaveInterval = com.destroystokyo.paper.PaperConfig.playerAutoSaveRate; - if (playerSaveInterval < 0) { - playerSaveInterval = autosavePeriod; - } - if (playerSaveInterval > 0) { // CraftBukkit // Paper - this.playerList.savePlayers(playerSaveInterval); - // Spigot Start - } // Paper - Incremental Auto Saving - - // We replace this with saving each individual world as this.saveChunks(...) is broken, - // and causes the main thread to sleep for random amounts of time depending on chunk activity - // Also pass flag to only save modified chunks - server.playerCommandState = true; - for (World world : getWorlds()) { - if (world.paperConfig.autoSavePeriod > 0) world.getWorld().save(false); // Paper - Incremental / Configurable Auto Saving + //if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit // Paper - move down + //MinecraftServer.LOGGER.debug("Autosave started"); // Paper + serverAutoSave = (autosavePeriod > 0 && this.ticks % autosavePeriod == 0); // Paper + this.methodProfiler.enter("save"); + if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // Paper + this.playerList.savePlayers(); + }// Paper + // Paper start + for (WorldServer world : getWorlds()) { + if (world.paperConfig.autoSavePeriod > 0) { + try { + world.saveIncrementally(serverAutoSave); + } catch (ExceptionWorldConflict exceptionWorldConflict) { + MinecraftServer.LOGGER.warn(exceptionWorldConflict.getMessage()); + } + } } - server.playerCommandState = false; - // this.saveChunks(true); - // Spigot End - ////this.methodProfiler.exit(); // Akarin // Akarin - remove caller - //} // Paper - Incremental Auto Saving + // Paper end - //this.methodProfiler.enter(* // Akarin - remove caller - if (getSnooperEnabled() && !this.snooper.d() && this.ticks > 100) { // Spigot + this.methodProfiler.exit(); + //MinecraftServer.LOGGER.debug("Autosave finished"); // Paper + //} // Paper + + this.methodProfiler.enter("snooper"); + if (((DedicatedServer) this).getDedicatedServerProperties().snooperEnabled && !this.snooper.d() && this.ticks > 100) { // Spigot this.snooper.a(); } - if (getSnooperEnabled() && this.ticks % 6000 == 0) { // Spigot + if (((DedicatedServer) this).getDedicatedServerProperties().snooperEnabled && this.ticks % 6000 == 0) { // Spigot this.snooper.b(); } - //this.methodProfiler.exit(); // Akarin - //this.methodProfiler.enter(* // Akarin - remove caller - long l = this.d[this.ticks % 100] = SystemUtils.getMonotonicNanos() - i; + this.methodProfiler.exit(); + this.methodProfiler.enter("tallying"); + long l = this.f[this.ticks % 100] = SystemUtils.getMonotonicNanos() - i; - this.ap = this.ap * 0.8F + (float) l / 1000000.0F * 0.19999999F; - //this.methodProfiler.exit(); // Akarin - //this.methodProfiler.exit(); // Akarin + this.at = this.at * 0.8F + (float) l / 1000000.0F * 0.19999999F; + long i1 = SystemUtils.getMonotonicNanos(); + + this.ap.a(i1 - i); + this.methodProfiler.exit(); org.spigotmc.WatchdogThread.tick(); // Spigot - PaperLightingQueue.processQueue(startTime); // Paper - expiringMaps.removeIf(ExpiringMap::clean); // Paper this.slackActivityAccountant.tickEnded(l); // Spigot + // Paper start - move executeAll() into full server tick timing + try (co.aikar.timings.Timing ignored = MinecraftTimings.processTasksTimer.startTiming()) { + this.executeAll(); + } + // Paper end // Paper start long endTime = System.nanoTime(); long remaining = (TICK_TIME - (endTime - lastTick)) - catchupTime; @@ -1018,50 +1166,34 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper } - public void b(BooleanSupplier booleansupplier) { - MinecraftTimings.bukkitSchedulerTimer.startTimingUnsafe(); // Paper // Akarin + protected void b(BooleanSupplier booleansupplier) { + MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper this.server.getScheduler().mainThreadHeartbeat(this.ticks); // CraftBukkit - MinecraftTimings.bukkitSchedulerTimer.stopTimingUnsafe(); // Paper // Akarin - MinecraftTimings.minecraftSchedulerTimer.startTimingUnsafe(); // Paper // Akarin - //this.methodProfiler.enter(* // Akarin - remove caller - - FutureTask futuretask; - - while ((futuretask = (FutureTask) this.f.poll()) != null) { - SystemUtils.a(futuretask, MinecraftServer.LOGGER); - } - PaperAsyncChunkProvider.processMainThreadQueue(this); // Paper - MinecraftTimings.minecraftSchedulerTimer.stopTimingUnsafe(); // Paper // Akarin - - //this.methodProfiler.exitEnter("commandFunctions"); // Akarin - MinecraftTimings.commandFunctionsTimer.startTimingUnsafe(); // Spigot // Akarin + MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper + this.methodProfiler.enter("commandFunctions"); + MinecraftTimings.commandFunctionsTimer.startTiming(); // Spigot // Paper this.getFunctionData().tick(); - MinecraftTimings.commandFunctionsTimer.stopTimingUnsafe(); // Spigot // Akarin - //this.methodProfiler.exitEnter("levels"); // Akarin + MinecraftTimings.commandFunctionsTimer.stopTiming(); // Spigot // Paper + this.methodProfiler.exitEnter("levels"); + Iterator iterator = this.getWorlds().iterator(); // CraftBukkit start // Run tasks that are waiting on processing - MinecraftTimings.processQueueTimer.startTimingUnsafe(); // Spigot // Akarin + MinecraftTimings.processQueueTimer.startTiming(); // Spigot while (!processQueue.isEmpty()) { processQueue.remove().run(); } - MinecraftTimings.processQueueTimer.stopTimingUnsafe(); // Spigot // Akarin + MinecraftTimings.processQueueTimer.stopTiming(); // Spigot - MinecraftTimings.chunkIOTickTimer.startTimingUnsafe(); // Spigot // Akarin - org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick(); - MinecraftTimings.chunkIOTickTimer.stopTimingUnsafe(); // Spigot // Akarin - - // Akarin start - /* - MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot + MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot // Paper // Send time updates to everyone, it will get the right time from the world the player is in. // Paper start - optimize time updates for (final WorldServer world : this.getWorlds()) { - final boolean doDaylight = world.getGameRules().getBoolean("doDaylightCycle"); + final boolean doDaylight = world.getGameRules().getBoolean(GameRules.DO_DAYLIGHT_CYCLE); final long dayTime = world.getDayTime(); long worldTime = world.getTime(); final PacketPlayOutUpdateTime worldPacket = new PacketPlayOutUpdateTime(worldTime, dayTime, doDaylight); - for (EntityHuman entityhuman : world.players) { + for (EntityHuman entityhuman : world.getPlayers()) { if (!(entityhuman instanceof EntityPlayer) || (ticks + entityhuman.getId()) % 20 != 0) { continue; } @@ -1073,206 +1205,159 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } } // Paper end - MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot - */ - // Akarin end + MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper - // WorldServer worldserver; // CraftBukkit - dropped down - long i; + while (iterator.hasNext()) { + WorldServer worldserver = (WorldServer) iterator.next(); - // CraftBukkit - dropTickTime - for (Iterator iterator = this.getWorlds().iterator(); iterator.hasNext();) { - WorldServer worldserver = (WorldServer) iterator.next(); - PaperAsyncChunkProvider.processMainThreadQueue(worldserver); // Paper worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper TileEntityHopper.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - i = SystemUtils.getMonotonicNanos(); if (true || worldserver.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD || this.getAllowNether()) { // CraftBukkit - // Akarin start - /* this.methodProfiler.a(() -> { - return "dim-" + worldserver.worldProvider.getDimensionManager().getDimensionID(); + return worldserver.getWorldData().getName() + " " + IRegistry.DIMENSION_TYPE.getKey(worldserver.worldProvider.getDimensionManager()); }); - */ - // Akarin end /* Drop global time updates if (this.ticks % 20 == 0) { - //this.methodProfiler.enter(* // Akarin - remove caller - this.playerList.a((Packet) (new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle"))), worldserver.worldProvider.getDimensionManager()); - //this.methodProfiler.exit(); // Akarin + this.methodProfiler.enter("timeSync"); + this.playerList.a((Packet) (new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean(GameRules.DO_DAYLIGHT_CYCLE))), worldserver.worldProvider.getDimensionManager()); + this.methodProfiler.exit(); } // CraftBukkit end */ - //this.methodProfiler.enter(* // Akarin - remove caller - - CrashReport crashreport; + this.methodProfiler.enter("tick"); try { - worldserver.timings.doTick.startTimingUnsafe(); // Spigot // Akarin + worldserver.timings.doTick.startTiming(); // Spigot worldserver.doTick(booleansupplier); - worldserver.timings.doTick.stopTimingUnsafe(); // Spigot // Akarin + worldserver.timings.doTick.stopTiming(); // Spigot } catch (Throwable throwable) { // Spigot Start + CrashReport crashreport; try { - crashreport = CrashReport.a(throwable, "Exception ticking world"); - } catch (Throwable t){ + crashreport = CrashReport.a(throwable, "Exception ticking world"); + } catch (Throwable t) { throw new RuntimeException("Error generating crash report", t); } // Spigot End + worldserver.a(crashreport); throw new ReportedException(crashreport); } - try { - worldserver.timings.tickEntities.startTimingUnsafe(); // Spigot // Akarin - worldserver.tickEntities(); - worldserver.timings.tickEntities.stopTimingUnsafe(); // Spigot // Akarin - } catch (Throwable throwable1) { - // Spigot Start - try { - crashreport = CrashReport.a(throwable1, "Exception ticking world entities"); - } catch (Throwable t){ - throw new RuntimeException("Error generating crash report", t); - } - // Spigot End - worldserver.a(crashreport); - throw new ReportedException(crashreport); - } - - //this.methodProfiler.exit(); // Akarin - //this.methodProfiler.enter(* // Akarin - remove caller - if (playerList.players.size() > 0) worldserver.getTracker().updatePlayers(); // Paper - No players, why spend time tracking them? (See patch) - //this.methodProfiler.exit(); // Akarin - //this.methodProfiler.exit(); // Akarin + this.methodProfiler.exit(); + this.methodProfiler.exit(); worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions } } - //this.methodProfiler.exitEnter("connection"); // Akarin - MinecraftTimings.connectionTimer.startTimingUnsafe(); // Spigot // Akarin + this.methodProfiler.exitEnter("connection"); + MinecraftTimings.connectionTimer.startTiming(); // Spigot this.getServerConnection().c(); - MinecraftTimings.connectionTimer.stopTimingUnsafe(); // Spigot // Akarin - //this.methodProfiler.exitEnter("players"); // Akarin - // Akarin start - /* - MinecraftTimings.playerListTimer.startTiming(); // Spigot + MinecraftTimings.connectionTimer.stopTiming(); // Spigot + this.methodProfiler.exitEnter("players"); + MinecraftTimings.playerListTimer.startTiming(); // Spigot // Paper this.playerList.tick(); - MinecraftTimings.playerListTimer.stopTiming(); // Spigot - */ - // Akarin end - //this.methodProfiler.exitEnter("tickables"); // Akarin + MinecraftTimings.playerListTimer.stopTiming(); // Spigot // Paper + this.methodProfiler.exitEnter("server gui refresh"); - MinecraftTimings.tickablesTimer.startTimingUnsafe(); // Spigot // Akarin - for (int j = 0; j < this.k.size(); ++j) { - ((ITickable) this.k.get(j)).tick(); + MinecraftTimings.tickablesTimer.startTiming(); // Spigot // Paper + for (int i = 0; i < this.tickables.size(); ++i) { + ((Runnable) this.tickables.get(i)).run(); } - MinecraftTimings.tickablesTimer.stopTimingUnsafe(); // Spigot // Akarin + MinecraftTimings.tickablesTimer.stopTiming(); // Spigot // Paper - //this.methodProfiler.exit(); // Akarin + this.methodProfiler.exit(); } public boolean getAllowNether() { return true; } - public void a(ITickable itickable) { - this.k.add(itickable); + public void b(Runnable runnable) { + this.tickables.add(runnable); } - public static void main(final OptionSet options) { // CraftBukkit - replaces main(String[] astring) - DispenserRegistry.c(); + public static void main(final OptionSet optionset) { // CraftBukkit - replaces main(String[] astring) + /* CraftBukkit start - Replace everything + OptionParser optionparser = new OptionParser(); + OptionSpec optionspec = optionparser.accepts("nogui"); + OptionSpec optionspec1 = optionparser.accepts("initSettings", "Initializes 'server.properties' and 'eula.txt', then quits"); + OptionSpec optionspec2 = optionparser.accepts("demo"); + OptionSpec optionspec3 = optionparser.accepts("bonusChest"); + OptionSpec optionspec4 = optionparser.accepts("forceUpgrade"); + OptionSpec optionspec5 = optionparser.accepts("eraseCache"); + OptionSpec optionspec6 = optionparser.accepts("help").forHelp(); + OptionSpec optionspec7 = optionparser.accepts("singleplayer").withRequiredArg(); + OptionSpec optionspec8 = optionparser.accepts("universe").withRequiredArg().defaultsTo(".", new String[0]); + OptionSpec optionspec9 = optionparser.accepts("world").withRequiredArg(); + OptionSpec optionspec10 = optionparser.accepts("port").withRequiredArg().ofType(Integer.class).defaultsTo(-1, new Integer[0]); + OptionSpec optionspec11 = optionparser.accepts("serverId").withRequiredArg(); + NonOptionArgumentSpec nonoptionargumentspec = optionparser.nonOptions(); try { - /* CraftBukkit start - Replace everything - boolean flag = true; - String s = null; - String s1 = "."; - String s2 = null; - boolean flag1 = false; - boolean flag2 = false; - boolean flag3 = false; - int i = -1; + OptionSet optionset = optionparser.parse(astring); - for (int j = 0; j < astring.length; ++j) { - String s3 = astring[j]; - String s4 = j == astring.length - 1 ? null : astring[j + 1]; - boolean flag4 = false; - - if (!"nogui".equals(s3) && !"--nogui".equals(s3)) { - if ("--port".equals(s3) && s4 != null) { - flag4 = true; - - try { - i = Integer.parseInt(s4); - } catch (NumberFormatException numberformatexception) { - ; - } - } else if ("--singleplayer".equals(s3) && s4 != null) { - flag4 = true; - s = s4; - } else if ("--universe".equals(s3) && s4 != null) { - flag4 = true; - s1 = s4; - } else if ("--world".equals(s3) && s4 != null) { - flag4 = true; - s2 = s4; - } else if ("--demo".equals(s3)) { - flag1 = true; - } else if ("--bonusChest".equals(s3)) { - flag2 = true; - } else if ("--forceUpgrade".equals(s3)) { - flag3 = true; - } - } else { - flag = false; - } - - if (flag4) { - ++j; - } + if (optionset.has(optionspec6)) { + optionparser.printHelpOn(System.err); + return; } */ // CraftBukkit end - String s1 = "."; // PAIL? + try { + java.nio.file.Path java_nio_file_path = Paths.get("server.properties"); + DedicatedServerSettings dedicatedserversettings = new DedicatedServerSettings(optionset); // CraftBukkit - CLI argument support + + dedicatedserversettings.save(); + java.nio.file.Path java_nio_file_path1 = Paths.get("eula.txt"); + EULA eula = new EULA(java_nio_file_path1); + + if (optionset.has("initSettings")) { // CraftBukkit + MinecraftServer.LOGGER.info("Initialized '" + java_nio_file_path.toAbsolutePath().toString() + "' and '" + java_nio_file_path1.toAbsolutePath().toString() + "'"); + return; + } + + // Spigot Start + boolean eulaAgreed = Boolean.getBoolean( "com.mojang.eula.agree" ); + if ( eulaAgreed ) + { + System.err.println( "You have used the Spigot command line EULA agreement flag." ); + System.err.println( "By using this setting you are indicating your agreement to Mojang's EULA (https://account.mojang.com/documents/minecraft_eula)." ); + System.err.println( "If you do not agree to the above EULA please stop your server and remove this flag immediately." ); + } + // Spigot End + if (!eula.a() && !eulaAgreed) { // Spigot + MinecraftServer.LOGGER.info("You need to agree to the EULA in order to run the server. Go to eula.txt for more info."); + return; + } + + DispenserRegistry.init(); + DispenserRegistry.c(); + String s = "."; // PAIL? YggdrasilAuthenticationService yggdrasilauthenticationservice = new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()); // Paper MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService(); GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository(); - UserCache usercache = new UserCache(gameprofilerepository, new File(s1, MinecraftServer.a.getName())); - final DedicatedServer dedicatedserver = new DedicatedServer(options, DataConverterRegistry.a(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, usercache); + UserCache usercache = new UserCache(gameprofilerepository, new File(s, MinecraftServer.b.getName())); + String s1 = (String) Optional.ofNullable(optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName); + final DedicatedServer dedicatedserver = new DedicatedServer(optionset, dedicatedserversettings, DataConverterRegistry.a(), yggdrasilauthenticationservice, minecraftsessionservice, gameprofilerepository, usercache, WorldLoadListenerLogger::new, s1); /* CraftBukkit start - if (s != null) { - dedicatedserver.h(s); - } - - if (s2 != null) { - dedicatedserver.setWorld(s2); - } - - if (i >= 0) { - dedicatedserver.setPort(i); - } - - if (flag1) { - dedicatedserver.c(true); - } - - if (flag2) { - dedicatedserver.d(true); - } + dedicatedserver.i((String) optionset.valueOf(optionspec7)); + dedicatedserver.setPort((Integer) optionset.valueOf(optionspec10)); + dedicatedserver.e(optionset.has(optionspec2)); + dedicatedserver.f(optionset.has(optionspec3)); + dedicatedserver.setForceUpgrade(optionset.has(optionspec4)); + dedicatedserver.setEraseCache(optionset.has(optionspec5)); + dedicatedserver.c((String) optionset.valueOf(optionspec11)); + boolean flag = !optionset.has(optionspec) && !optionset.valuesOf(nonoptionargumentspec).contains("nogui"); if (flag && !GraphicsEnvironment.isHeadless()) { - dedicatedserver.aW(); + dedicatedserver.aZ(); } - if (flag3) { - dedicatedserver.setForceUpgrade(true); - } - - dedicatedserver.v(); + dedicatedserver.startServerThread(); Thread thread = new Thread("Server Shutdown Thread") { public void run() { - dedicatedserver.stop(); + dedicatedserver.safeShutdown(true); } }; @@ -1280,26 +1365,26 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati Runtime.getRuntime().addShutdownHook(thread); */ - if (options.has("port")) { - int port = (Integer) options.valueOf("port"); + if (optionset.has("port")) { + int port = (Integer) optionset.valueOf("port"); if (port > 0) { dedicatedserver.setPort(port); } } - if (options.has("universe")) { - dedicatedserver.universe = (File) options.valueOf("universe"); + if (optionset.has("universe")) { + dedicatedserver.universe = (File) optionset.valueOf("universe"); } - if (options.has("world")) { - dedicatedserver.setWorld((String) options.valueOf("world")); - } - - if (options.has("forceUpgrade")) { + if (optionset.has("forceUpgrade")) { dedicatedserver.setForceUpgrade(true); } - dedicatedserver.primaryThread.start(); + if (optionset.has("eraseCache")) { + dedicatedserver.setEraseCache(true); + } + + dedicatedserver.serverThread.start(); // CraftBukkit end } catch (Exception exception) { MinecraftServer.LOGGER.fatal("Failed to start the minecraft server", exception); @@ -1307,22 +1392,26 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } + protected void c(String s) { + this.av = s; + } + protected void setForceUpgrade(boolean flag) { this.forceUpgrade = flag; } - public void v() { + protected void setEraseCache(boolean flag) { + this.eraseCache = flag; + } + + public void startServerThread() { /* CraftBukkit start - prevent abuse - this.serverThread = new Thread(this, "Server thread"); - this.serverThread.setUncaughtExceptionHandler((thread, throwable) -> { - MinecraftServer.LOGGER.error(throwable); - }); this.serverThread.start(); // CraftBukkit end */ } - public File c(String s) { - return new File(this.s(), s); + public File d(String s) { + return new File(this.t(), s); } public void info(String s) { @@ -1342,7 +1431,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } public String getVersion() { - return "1.13.2"; + return SharedConstants.a().getName(); } public int getPlayerCount() { @@ -1354,18 +1443,18 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } public String[] getPlayers() { - return this.playerList.f(); + return this.playerList.e(); } public boolean isDebugging() { - return this.getPropertyManager().getBoolean("debug", false); // CraftBukkit - don't hardcode - } - - public void f(String s) { - MinecraftServer.LOGGER.error(s); + return false; } public void g(String s) { + MinecraftServer.LOGGER.error(s); + } + + public void h(String s) { if (this.isDebugging()) { MinecraftServer.LOGGER.info(s); } @@ -1377,12 +1466,9 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } public CrashReport b(CrashReport crashreport) { - crashreport.g().a("Profiler Position", () -> { - return this.methodProfiler.a() ? this.methodProfiler.f() : "N/A (disabled)"; - }); if (this.playerList != null) { crashreport.g().a("Player Count", () -> { - return this.playerList.getPlayerCount() + " / " + this.playerList.getMaxPlayers() + "; " + this.playerList.v(); + return this.playerList.getPlayerCount() + " / " + this.playerList.getMaxPlayers() + "; " + this.playerList.getPlayers(); }); } @@ -1405,87 +1491,113 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati return stringbuilder.toString(); }); + if (this.av != null) { + crashreport.g().a("Server Id", () -> { + return this.av; + }); + } + return crashreport; } - public boolean D() { + public boolean F() { return true; // CraftBukkit } + @Override public void sendMessage(IChatBaseComponent ichatbasecomponent) { MinecraftServer.LOGGER.info(org.bukkit.craftbukkit.util.CraftChatMessage.fromComponent(ichatbasecomponent, net.minecraft.server.EnumChatFormat.WHITE));// Paper - Log message with colors } - public KeyPair E() { - return this.H; - } - - public int getPort() { - return this.q; - } - - public void setPort(int i) { - this.q = i; - } - - public String G() { + public KeyPair getKeyPair() { return this.I; } - public void h(String s) { - this.I = s; + public int getPort() { + return this.serverPort; } - public boolean H() { - return this.I != null; + public void setPort(int i) { + this.serverPort = i; } - public String getWorld() { + public String getSinglePlayerName() { return this.J; } - public void setWorld(String s) { + public void i(String s) { this.J = s; } - public void a(KeyPair keypair) { - this.H = keypair; + public boolean isEmbeddedServer() { + return this.J != null; } - public void a(EnumDifficulty enumdifficulty) { + public String getWorld() { + return this.K; + } + + public void a(KeyPair keypair) { + this.I = keypair; + } + + public void a(EnumDifficulty enumdifficulty, boolean flag) { Iterator iterator = this.getWorlds().iterator(); while (iterator.hasNext()) { WorldServer worldserver = (WorldServer) iterator.next(); + WorldData worlddata = worldserver.getWorldData(); - if (worldserver.getWorldData().isHardcore()) { - worldserver.getWorldData().setDifficulty(EnumDifficulty.HARD); - worldserver.setSpawnFlags(true, true); - } else if (this.H()) { - worldserver.getWorldData().setDifficulty(enumdifficulty); - worldserver.setSpawnFlags(worldserver.getDifficulty() != EnumDifficulty.PEACEFUL, true); - } else { - worldserver.getWorldData().setDifficulty(enumdifficulty); - worldserver.setSpawnFlags(this.getSpawnMonsters(), this.spawnAnimals); + if (flag || !worlddata.isDifficultyLocked()) { + if (worlddata.isHardcore()) { + worlddata.setDifficulty(EnumDifficulty.HARD); + worldserver.setSpawnFlags(true, true); + } else if (this.isEmbeddedServer()) { + worlddata.setDifficulty(enumdifficulty); + worldserver.setSpawnFlags(worldserver.getDifficulty() != EnumDifficulty.PEACEFUL, true); + } else { + worlddata.setDifficulty(enumdifficulty); + worldserver.setSpawnFlags(this.getSpawnMonsters(), this.spawnAnimals); + } } } - } - - public boolean getSpawnMonsters() { - return true; - } - - public boolean L() { - return this.demoMode; - } - - public void c(boolean flag) { - this.demoMode = flag; + this.getPlayerList().getPlayers().forEach(this::a); } public void d(boolean flag) { - this.M = flag; + Iterator iterator = this.getWorlds().iterator(); + + while (iterator.hasNext()) { + WorldServer worldserver = (WorldServer) iterator.next(); + WorldData worlddata = worldserver.getWorldData(); + + worlddata.e(flag); + } + + this.getPlayerList().getPlayers().forEach(this::a); + } + + private void a(EntityPlayer entityplayer) { + WorldData worlddata = entityplayer.getWorldServer().getWorldData(); + + entityplayer.playerConnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); + } + + protected boolean getSpawnMonsters() { + return true; + } + + public boolean isDemoMode() { + return this.demoMode; + } + + public void e(boolean flag) { + this.demoMode = flag; + } + + public void f(boolean flag) { + this.bonusChest = flag; } public Convertable getConvertable() { @@ -1493,31 +1605,32 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } public String getResourcePack() { - return this.N; - } - - public String getResourcePackHash() { return this.O; } - public void setResourcePack(String s, String s1) { - this.N = s; - this.O = s1; + public String getResourcePackHash() { + return this.P; } + public void setResourcePack(String s, String s1) { + this.O = s; + this.P = s1; + } + + @Override public void a(MojangStatisticsGenerator mojangstatisticsgenerator) { mojangstatisticsgenerator.a("whitelist_enabled", false); mojangstatisticsgenerator.a("whitelist_count", 0); if (this.playerList != null) { mojangstatisticsgenerator.a("players_current", this.getPlayerCount()); mojangstatisticsgenerator.a("players_max", this.getMaxPlayers()); - mojangstatisticsgenerator.a("players_seen", this.playerList.getSeenPlayers().length); + mojangstatisticsgenerator.a("players_seen", this.getWorldServer(DimensionManager.OVERWORLD).getDataManager().getSeenPlayers().length); } mojangstatisticsgenerator.a("uses_auth", this.onlineMode); - mojangstatisticsgenerator.a("gui_state", this.ag() ? "enabled" : "disabled"); + mojangstatisticsgenerator.a("gui_state", this.ai() ? "enabled" : "disabled"); mojangstatisticsgenerator.a("run_time", (SystemUtils.getMonotonicMillis() - mojangstatisticsgenerator.g()) / 60L * 1000L); - mojangstatisticsgenerator.a("avg_tick_ms", (int) (MathHelper.a(this.d) * 1.0E-6D)); + mojangstatisticsgenerator.a("avg_tick_ms", (int) (MathHelper.a(this.f) * 1.0E-6D)); int i = 0; Iterator iterator = this.getWorlds().iterator(); @@ -1533,8 +1646,8 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati mojangstatisticsgenerator.a("world[" + i + "][hardcore]", worlddata.isHardcore()); mojangstatisticsgenerator.a("world[" + i + "][generator_name]", worlddata.getType().name()); mojangstatisticsgenerator.a("world[" + i + "][generator_version]", worlddata.getType().getVersion()); - mojangstatisticsgenerator.a("world[" + i + "][height]", this.F); - mojangstatisticsgenerator.a("world[" + i + "][chunks_loaded]", worldserver.getChunkProvider().g()); + mojangstatisticsgenerator.a("world[" + i + "][height]", this.G); + mojangstatisticsgenerator.a("world[" + i + "][chunks_loaded]", worldserver.getChunkProvider().h()); ++i; } } @@ -1542,26 +1655,22 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati mojangstatisticsgenerator.a("worlds", i); } - public boolean getSnooperEnabled() { - return true; - } - - public abstract boolean Q(); + public abstract boolean S(); public boolean getOnlineMode() { - return server.getOnlineMode(); // CraftBukkit + return this.onlineMode; } public void setOnlineMode(boolean flag) { this.onlineMode = flag; } - public boolean S() { - return this.z; + public boolean U() { + return this.A; } - public void f(boolean flag) { - this.z = flag; + public void h(boolean flag) { + this.A = flag; } public boolean getSpawnAnimals() { @@ -1576,7 +1685,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati return this.spawnNPCs; } - public abstract boolean V(); + public abstract boolean X(); public void setSpawnNPCs(boolean flag) { this.spawnNPCs = flag; @@ -1609,11 +1718,11 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } public int getMaxBuildHeight() { - return this.F; + return this.G; } public void b(int i) { - this.F = i; + this.G = i; } public boolean isStopped() { @@ -1628,7 +1737,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati this.playerList = playerlist; } - public abstract boolean ad(); + public abstract boolean af(); public void setGamemode(EnumGamemode enumgamemode) { Iterator iterator = this.getWorlds().iterator(); @@ -1641,22 +1750,23 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } + @Nullable public ServerConnection getServerConnection() { return this.serverConnection == null ? this.serverConnection = new ServerConnection(this) : this.serverConnection; // Spigot } - public boolean ag() { + public boolean ai() { return false; } public abstract boolean a(EnumGamemode enumgamemode, boolean flag, int i); - public int ah() { + public int aj() { return this.ticks; } - public void ai() { - this.S = true; + public void ak() { + this.T = true; } public int getSpawnProtection() { @@ -1668,124 +1778,92 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } public void setForceGamemode(boolean flag) { - this.T = flag; + this.U = flag; } public boolean getForceGamemode() { - return this.T; + return this.U; } public int getIdleTimeout() { - return this.G; + return this.H; } public void setIdleTimeout(int i) { - this.G = i; + this.H = i; } - public MinecraftSessionService getSessionService() { return ap(); } // Paper - OBFHELPER - public MinecraftSessionService ap() { - return this.V; + public final MinecraftSessionService getSessionService() { return this.getMinecraftSessionService(); } // Paper - OBFHELPER + public MinecraftSessionService getMinecraftSessionService() { + return this.minecraftSessionService; } public GameProfileRepository getGameProfileRepository() { - return this.W; + return this.gameProfileRepository; } public UserCache getUserCache() { - return this.X; + return this.userCache; } - // Akarin start - private final AkarinUserCache userCache; - - public AkarinUserCache getModernUserCache() { - return userCache; - } - // Akarin end public ServerPing getServerPing() { - return this.m; + return this.serverPing; } - public void at() { - this.Y = 0L; - } - - public int au() { - return 29999984; - } - - public ListenableFuture a(Callable callable) { - Validate.notNull(callable); - if (!this.isMainThread()) { // CraftBukkit && !this.isStopped()) { - ListenableFutureTask listenablefuturetask = ListenableFutureTask.create(callable); - - this.f.offer(listenablefuturetask); // Akarin - add -> offer - return listenablefuturetask; - } else { - try { - return Futures.immediateFuture(callable.call()); - } catch (Exception exception) { - return Futures.immediateFailedCheckedFuture(exception); - } - } - } - // Akarin start - @Override - public void ensuresMainThread(Runnable runnable) { - this.f.offer(ListenableFutureTask.create(runnable, null)); - } - // Akarin end - - public ListenableFuture postToMainThread(Runnable runnable) { - Validate.notNull(runnable); - return this.a(Executors.callable(runnable)); - } - - public boolean isMainThread() { - return ThreadAssertion.is() || Thread.currentThread() == this.serverThread; // Akarin + public void invalidatePingSample() { + this.Z = 0L; } public int aw() { - return 256; + return 29999984; } - public long ax() { - return this.nextTick; + @Override + public boolean isNotMainThread() { + return super.isNotMainThread() && !this.isStopped(); } - public Thread ay() { + @Override + public Thread getThread() { return this.serverThread; } - public DataFixer az() { + public int az() { + return 256; + } + + public long aA() { + return this.nextTick; + } + + public DataFixer aB() { return this.dataConverterManager; } public int a(@Nullable WorldServer worldserver) { - return worldserver != null ? worldserver.getGameRules().c("spawnRadius") : 10; + return worldserver != null ? worldserver.getGameRules().getInt(GameRules.SPAWN_RADIUS) : 10; } public AdvancementDataWorld getAdvancementData() { - return this.al; + return this.an; } public CustomFunctionData getFunctionData() { - return this.am; + return this.ao; } public void reload() { if (!this.isMainThread()) { - this.postToMainThread(this::reload); + this.execute(this::reload); } else { this.getPlayerList().savePlayers(); this.resourcePackRepository.a(); - this.a(this.getWorldServer(DimensionManager.OVERWORLD).getWorldData()); + this.b(this.getWorldServer(DimensionManager.OVERWORLD).getWorldData()); this.getPlayerList().reload(); } } - private void a(WorldData worlddata) { + private void b(WorldData worlddata) { List list = Lists.newArrayList(this.resourcePackRepository.d()); Iterator iterator = this.resourcePackRepository.b().iterator(); @@ -1806,7 +1884,16 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati this.resourcePackRepository.d().forEach((resourcepackloader1) -> { list1.add(resourcepackloader1.d()); }); - this.ac.a((List) list1); + CompletableFuture completablefuture = this.ae.a(this.executorService, this, list1, MinecraftServer.i); + + this.awaitTasks(completablefuture::isDone); + + try { + completablefuture.get(); + } catch (Exception exception) { + MinecraftServer.LOGGER.error("Failed to reload data packs", exception); + } + worlddata.O().clear(); worlddata.N().clear(); this.resourcePackRepository.d().forEach((resourcepackloader1) -> { @@ -1826,7 +1913,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati WhiteList whitelist = playerlist.getWhitelist(); if (whitelist.isEnabled()) { - List list = Lists.newArrayList(playerlist.v()); + List list = Lists.newArrayList(playerlist.getPlayers()); Iterator iterator = list.iterator(); while (iterator.hasNext()) { @@ -1842,7 +1929,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati } public IReloadableResourceManager getResourceManager() { - return this.ac; + return this.ae; } public ResourcePackRepository getResourcePackRepository() { @@ -1857,60 +1944,273 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati return new CommandListenerWrapper(this, this.getWorldServer(DimensionManager.OVERWORLD) == null ? Vec3D.a : new Vec3D(this.getWorldServer(DimensionManager.OVERWORLD).getSpawn()), Vec2F.a, this.getWorldServer(DimensionManager.OVERWORLD), 4, "Server", new ChatComponentText("Server"), this, (Entity) null); } - public boolean a() { + @Override + public boolean shouldSendSuccess() { return true; } - public boolean b() { + @Override + public boolean shouldSendFailure() { return true; } public CraftingManager getCraftingManager() { - return this.ag; - } - - public TagRegistry getTagRegistry() { - return this.ah; - } - - public ScoreboardServer getScoreboard() { return this.ai; } - public LootTableRegistry getLootTableRegistry() { + public TagRegistry getTagRegistry() { + return this.aj; + } + + public ScoreboardServer getScoreboard() { return this.ak; } + public LootTableRegistry getLootTableRegistry() { + return this.am; + } + public GameRules getGameRules() { return this.getWorldServer(DimensionManager.OVERWORLD).getGameRules(); } public BossBattleCustomData getBossBattleCustomData() { - return this.aj; + return this.al; } public boolean aQ() { - return this.an; + return this.aq; } - public void l(boolean flag) { - this.an = flag; + public void n(boolean flag) { + this.aq = flag; + } + + public float aR() { + return this.at; } public int a(GameProfile gameprofile) { if (this.getPlayerList().isOp(gameprofile)) { OpListEntry oplistentry = (OpListEntry) this.getPlayerList().getOPs().get(gameprofile); - return oplistentry != null ? oplistentry.a() : (this.H() ? (this.G().equals(gameprofile.getName()) ? 4 : (this.getPlayerList().x() ? 4 : 0)) : this.j()); + return oplistentry != null ? oplistentry.a() : (this.b(gameprofile) ? 4 : (this.isEmbeddedServer() ? (this.getPlayerList().v() ? 4 : 0) : this.j())); } else { return 0; } } + public GameProfiler getMethodProfiler() { + return this.methodProfiler; + } + + public Executor aU() { + return this.executorService; + } + + public abstract boolean b(GameProfile gameprofile); + + public void a(java.nio.file.Path java_nio_file_path) throws IOException { + java.nio.file.Path java_nio_file_path1 = java_nio_file_path.resolve("levels"); + Iterator iterator = this.worldServer.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + MinecraftKey minecraftkey = DimensionManager.a((DimensionManager) entry.getKey()); + java.nio.file.Path java_nio_file_path2 = java_nio_file_path1.resolve(minecraftkey.getNamespace()).resolve(minecraftkey.getKey()); + + Files.createDirectories(java_nio_file_path2); + ((WorldServer) entry.getValue()).a(java_nio_file_path2); + } + + this.d(java_nio_file_path.resolve("gamerules.txt")); + this.e(java_nio_file_path.resolve("classpath.txt")); + this.c(java_nio_file_path.resolve("example_crash.txt")); + this.b(java_nio_file_path.resolve("stats.txt")); + this.f(java_nio_file_path.resolve("threads.txt")); + } + + private void b(java.nio.file.Path java_nio_file_path) throws IOException { + BufferedWriter bufferedwriter = Files.newBufferedWriter(java_nio_file_path); + Throwable throwable = null; + + try { + bufferedwriter.write(String.format("pending_tasks: %d\n", this.be())); + bufferedwriter.write(String.format("average_tick_time: %f\n", this.aR())); + bufferedwriter.write(String.format("tick_times: %s\n", Arrays.toString(this.f))); + bufferedwriter.write(String.format("queue: %s\n", SystemUtils.e())); + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (bufferedwriter != null) { + if (throwable != null) { + try { + bufferedwriter.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + bufferedwriter.close(); + } + } + + } + + } + + private void c(java.nio.file.Path java_nio_file_path) throws IOException { + CrashReport crashreport = new CrashReport("Server dump", new Exception("dummy")); + + this.b(crashreport); + BufferedWriter bufferedwriter = Files.newBufferedWriter(java_nio_file_path); + Throwable throwable = null; + + try { + bufferedwriter.write(crashreport.e()); + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (bufferedwriter != null) { + if (throwable != null) { + try { + bufferedwriter.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + bufferedwriter.close(); + } + } + + } + + } + + private void d(java.nio.file.Path java_nio_file_path) throws IOException { + BufferedWriter bufferedwriter = Files.newBufferedWriter(java_nio_file_path); + Throwable throwable = null; + + try { + final List list = Lists.newArrayList(); + final GameRules gamerules = this.getGameRules(); + + GameRules.a(new GameRules.GameRuleVisitor() { + @Override + public > void a(GameRules.GameRuleKey gamerules_gamerulekey, GameRules.GameRuleDefinition gamerules_gameruledefinition) { + list.add(String.format("%s=%s\n", gamerules_gamerulekey.a(), gamerules.get(gamerules_gamerulekey).toString())); + } + }); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + + bufferedwriter.write(s); + } + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (bufferedwriter != null) { + if (throwable != null) { + try { + bufferedwriter.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + bufferedwriter.close(); + } + } + + } + + } + + private void e(java.nio.file.Path java_nio_file_path) throws IOException { + BufferedWriter bufferedwriter = Files.newBufferedWriter(java_nio_file_path); + Throwable throwable = null; + + try { + String s = System.getProperty("java.class.path"); + String s1 = System.getProperty("path.separator"); + Iterator iterator = Splitter.on(s1).split(s).iterator(); + + while (iterator.hasNext()) { + String s2 = (String) iterator.next(); + + bufferedwriter.write(s2); + bufferedwriter.write("\n"); + } + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (bufferedwriter != null) { + if (throwable != null) { + try { + bufferedwriter.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + bufferedwriter.close(); + } + } + + } + + } + + private void f(java.nio.file.Path java_nio_file_path) throws IOException { + ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean(); + ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true); + + Arrays.sort(athreadinfo, Comparator.comparing(ThreadInfo::getThreadName)); + BufferedWriter bufferedwriter = Files.newBufferedWriter(java_nio_file_path); + Throwable throwable = null; + + try { + ThreadInfo[] athreadinfo1 = athreadinfo; + int i = athreadinfo.length; + + for (int j = 0; j < i; ++j) { + ThreadInfo threadinfo = athreadinfo1[j]; + + bufferedwriter.write(threadinfo.toString()); + bufferedwriter.write(10); + } + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (bufferedwriter != null) { + if (throwable != null) { + try { + bufferedwriter.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + bufferedwriter.close(); + } + } + + } + + } + // CraftBukkit start - //@Deprecated // Akarin - remove deprecated + @Override + public boolean isMainThread() { + return super.isMainThread() /*|| this.isStopped()*/; // CraftBukkit - MC-142590 // Paper - causes issues elsewhere + } + + @Deprecated public static MinecraftServer getServer() { - return SERVER; + return SERVER; // Paper } // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/MobEffectList.java b/src/main/java/net/minecraft/server/MobEffectList.java index a9a6e5c2f..233eaf677 100644 --- a/src/main/java/net/minecraft/server/MobEffectList.java +++ b/src/main/java/net/minecraft/server/MobEffectList.java @@ -15,13 +15,10 @@ import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; public class MobEffectList { private final Map a = Maps.newHashMap(); - private final boolean b; + private final MobEffectInfo b; private final int c; @Nullable private String d; - private int e = -1; - public double durationModifier; - private boolean g; @Nullable public static MobEffectList fromId(int i) { @@ -32,22 +29,11 @@ public class MobEffectList { return IRegistry.MOB_EFFECT.a(mobeffectlist); // CraftBukkit - decompile error } - protected MobEffectList(boolean flag, int i) { - this.b = flag; - if (flag) { - this.durationModifier = 0.5D; - } else { - this.durationModifier = 1.0D; - } - + protected MobEffectList(MobEffectInfo mobeffectinfo, int i) { + this.b = mobeffectinfo; this.c = i; } - protected MobEffectList b(int i, int j) { - this.e = i + j * 12; - return this; - } - public void tick(EntityLiving entityliving, int i) { if (this == MobEffects.REGENERATION) { if (entityliving.getHealth() < entityliving.getMaxHealth()) { @@ -76,8 +62,8 @@ public class MobEffectList { ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel)); // CraftBukkit end } - } else if ((this != MobEffects.HEAL || entityliving.cp()) && (this != MobEffects.HARM || !entityliving.cp())) { - if (this == MobEffects.HARM && !entityliving.cp() || this == MobEffects.HEAL && entityliving.cp()) { + } else if ((this != MobEffects.HEAL || entityliving.cC()) && (this != MobEffects.HARM || !entityliving.cC())) { + if (this == MobEffects.HARM && !entityliving.cC() || this == MobEffects.HEAL && entityliving.cC()) { entityliving.damageEntity(DamageSource.MAGIC, (float) (6 << i)); } } else { @@ -89,8 +75,8 @@ public class MobEffectList { public void applyInstantEffect(@Nullable Entity entity, @Nullable Entity entity1, EntityLiving entityliving, int i, double d0) { int j; - if ((this != MobEffects.HEAL || entityliving.cp()) && (this != MobEffects.HARM || !entityliving.cp())) { - if ((this != MobEffects.HARM || entityliving.cp()) && (this != MobEffects.HEAL || !entityliving.cp())) { + if ((this != MobEffects.HEAL || entityliving.cC()) && (this != MobEffects.HARM || !entityliving.cC())) { + if ((this != MobEffects.HARM || entityliving.cC()) && (this != MobEffects.HEAL || !entityliving.cC())) { this.tick(entityliving, i); } else { j = (int) (d0 * (double) (6 << i) + 0.5D); @@ -144,17 +130,12 @@ public class MobEffectList { return new ChatMessage(this.c(), new Object[0]); } - protected MobEffectList a(double d0) { - this.durationModifier = d0; - return this; - } - public int getColor() { return this.c; } - public MobEffectList a(IAttribute iattribute, String s, double d0, int i) { - AttributeModifier attributemodifier = new AttributeModifier(UUID.fromString(s), this::c, d0, i); + public MobEffectList a(IAttribute iattribute, String s, double d0, AttributeModifier.Operation attributemodifier_operation) { + AttributeModifier attributemodifier = new AttributeModifier(UUID.fromString(s), this::c, d0, attributemodifier_operation); this.a.put(iattribute, attributemodifier); return this; @@ -168,7 +149,7 @@ public class MobEffectList { AttributeInstance attributeinstance = attributemapbase.a((IAttribute) entry.getKey()); if (attributeinstance != null) { - attributeinstance.c((AttributeModifier) entry.getValue()); + attributeinstance.removeModifier((AttributeModifier) entry.getValue()); } } @@ -184,61 +165,14 @@ public class MobEffectList { if (attributeinstance != null) { AttributeModifier attributemodifier = (AttributeModifier) entry.getValue(); - attributeinstance.c(attributemodifier); - attributeinstance.b(new AttributeModifier(attributemodifier.a(), this.c() + " " + i, this.a(i, attributemodifier), attributemodifier.c())); + attributeinstance.removeModifier(attributemodifier); + attributeinstance.addModifier(new AttributeModifier(attributemodifier.getUniqueId(), this.c() + " " + i, this.a(i, attributemodifier), attributemodifier.getOperation())); } } } public double a(int i, AttributeModifier attributemodifier) { - return attributemodifier.d() * (double) (i + 1); - } - - public MobEffectList l() { - this.g = true; - return this; - } - - public static void m() { - a(1, "speed", (new MobEffectList(false, 8171462)).b(0, 0).a(GenericAttributes.MOVEMENT_SPEED, "91AEAA56-376B-4498-935B-2F7F68070635", 0.20000000298023224D, 2).l()); - a(2, "slowness", (new MobEffectList(true, 5926017)).b(1, 0).a(GenericAttributes.MOVEMENT_SPEED, "7107DE5E-7CE8-4030-940E-514C1F160890", -0.15000000596046448D, 2)); - a(3, "haste", (new MobEffectList(false, 14270531)).b(2, 0).a(1.5D).l().a(GenericAttributes.g, "AF8B6E3F-3328-4C0A-AA36-5BA2BB9DBEF3", 0.10000000149011612D, 2)); - a(4, "mining_fatigue", (new MobEffectList(true, 4866583)).b(3, 0).a(GenericAttributes.g, "55FCED67-E92A-486E-9800-B47F202C4386", -0.10000000149011612D, 2)); - a(5, "strength", (new MobEffectAttackDamage(false, 9643043, 3.0D)).b(4, 0).a(GenericAttributes.ATTACK_DAMAGE, "648D7064-6A60-4F59-8ABE-C2C23A6DD7A9", 0.0D, 0).l()); - a(6, "instant_health", (new InstantMobEffect(false, 16262179)).l()); - a(7, "instant_damage", (new InstantMobEffect(true, 4393481)).l()); - a(8, "jump_boost", (new MobEffectList(false, 2293580)).b(2, 1).l()); - a(9, "nausea", (new MobEffectList(true, 5578058)).b(3, 1).a(0.25D)); - a(10, "regeneration", (new MobEffectList(false, 13458603)).b(7, 0).a(0.25D).l()); - a(11, "resistance", (new MobEffectList(false, 10044730)).b(6, 1).l()); - a(12, "fire_resistance", (new MobEffectList(false, 14981690)).b(7, 1).l()); - a(13, "water_breathing", (new MobEffectList(false, 3035801)).b(0, 2).l()); - a(14, "invisibility", (new MobEffectList(false, 8356754)).b(0, 1).l()); - a(15, "blindness", (new MobEffectList(true, 2039587)).b(5, 1).a(0.25D)); - a(16, "night_vision", (new MobEffectList(false, 2039713)).b(4, 1).l()); - a(17, "hunger", (new MobEffectList(true, 5797459)).b(1, 1)); - a(18, "weakness", (new MobEffectAttackDamage(true, 4738376, -4.0D)).b(5, 0).a(GenericAttributes.ATTACK_DAMAGE, "22653B89-116E-49DC-9B6B-9971489B5BE5", 0.0D, 0)); - a(19, "poison", (new MobEffectList(true, 5149489)).b(6, 0).a(0.25D)); - a(20, "wither", (new MobEffectList(true, 3484199)).b(1, 2).a(0.25D)); - a(21, "health_boost", (new MobEffectHealthBoost(false, 16284963)).b(7, 2).a(GenericAttributes.maxHealth, "5D6F0BA2-1186-46AC-B896-C61C5CEE99CC", 4.0D, 0).l()); - a(22, "absorption", (new MobEffectAbsorption(false, 2445989)).b(2, 2).l()); - a(23, "saturation", (new InstantMobEffect(false, 16262179)).l()); - a(24, "glowing", (new MobEffectList(false, 9740385)).b(4, 2)); - a(25, "levitation", (new MobEffectList(true, 13565951)).b(3, 2)); - a(26, "luck", (new MobEffectList(false, 3381504)).b(5, 2).l().a(GenericAttributes.j, "03C3C89D-7037-4B42-869F-B146BCB64D2E", 1.0D, 0)); - a(27, "unluck", (new MobEffectList(true, 12624973)).b(6, 2).a(GenericAttributes.j, "CC5AF142-2BD2-4215-B636-2605AED11727", -1.0D, 0)); - a(28, "slow_falling", (new MobEffectList(false, 16773073)).b(8, 0).l()); - a(29, "conduit_power", (new MobEffectList(false, 1950417)).b(9, 0).l()); - a(30, "dolphins_grace", (new MobEffectList(false, 8954814)).b(10, 0).l()); - // CraftBukkit start - for (Object effect : IRegistry.MOB_EFFECT) { - org.bukkit.potion.PotionEffectType.registerPotionEffectType(new org.bukkit.craftbukkit.potion.CraftPotionEffectType((MobEffectList) effect)); - } - // CraftBukkit end - } - - private static void a(int i, String s, MobEffectList mobeffectlist) { - IRegistry.MOB_EFFECT.a(i, new MinecraftKey(s), mobeffectlist); + return attributemodifier.getAmount() * (double) (i + 1); } } diff --git a/src/main/java/net/minecraft/server/MobEffects.java b/src/main/java/net/minecraft/server/MobEffects.java new file mode 100644 index 000000000..f5492b08c --- /dev/null +++ b/src/main/java/net/minecraft/server/MobEffects.java @@ -0,0 +1,71 @@ +package net.minecraft.server; + +public class MobEffects { + + public static final MobEffectList FASTER_MOVEMENT = a(1, "speed", (new MobEffectList(MobEffectInfo.BENEFICIAL, 8171462)).a(GenericAttributes.MOVEMENT_SPEED, "91AEAA56-376B-4498-935B-2F7F68070635", 0.20000000298023224D, AttributeModifier.Operation.MULTIPLY_TOTAL)); + public static final MobEffectList SLOWER_MOVEMENT = a(2, "slowness", (new MobEffectList(MobEffectInfo.HARMFUL, 5926017)).a(GenericAttributes.MOVEMENT_SPEED, "7107DE5E-7CE8-4030-940E-514C1F160890", -0.15000000596046448D, AttributeModifier.Operation.MULTIPLY_TOTAL)); + public static final MobEffectList FASTER_DIG = a(3, "haste", (new MobEffectList(MobEffectInfo.BENEFICIAL, 14270531)).a(GenericAttributes.ATTACK_SPEED, "AF8B6E3F-3328-4C0A-AA36-5BA2BB9DBEF3", 0.10000000149011612D, AttributeModifier.Operation.MULTIPLY_TOTAL)); + public static final MobEffectList SLOWER_DIG = a(4, "mining_fatigue", (new MobEffectList(MobEffectInfo.HARMFUL, 4866583)).a(GenericAttributes.ATTACK_SPEED, "55FCED67-E92A-486E-9800-B47F202C4386", -0.10000000149011612D, AttributeModifier.Operation.MULTIPLY_TOTAL)); + public static final MobEffectList INCREASE_DAMAGE = a(5, "strength", (new MobEffectAttackDamage(MobEffectInfo.BENEFICIAL, 9643043, 3.0D)).a(GenericAttributes.ATTACK_DAMAGE, "648D7064-6A60-4F59-8ABE-C2C23A6DD7A9", 0.0D, AttributeModifier.Operation.ADDITION)); + public static final MobEffectList HEAL = a(6, "instant_health", new InstantMobEffect(MobEffectInfo.BENEFICIAL, 16262179)); + public static final MobEffectList HARM = a(7, "instant_damage", new InstantMobEffect(MobEffectInfo.HARMFUL, 4393481)); + public static final MobEffectList JUMP = a(8, "jump_boost", new MobEffectList(MobEffectInfo.BENEFICIAL, 2293580)); + public static final MobEffectList CONFUSION = a(9, "nausea", new MobEffectList(MobEffectInfo.HARMFUL, 5578058)); + public static final MobEffectList REGENERATION = a(10, "regeneration", new MobEffectList(MobEffectInfo.BENEFICIAL, 13458603)); + public static final MobEffectList RESISTANCE = a(11, "resistance", new MobEffectList(MobEffectInfo.BENEFICIAL, 10044730)); + public static final MobEffectList FIRE_RESISTANCE = a(12, "fire_resistance", new MobEffectList(MobEffectInfo.BENEFICIAL, 14981690)); + public static final MobEffectList WATER_BREATHING = a(13, "water_breathing", new MobEffectList(MobEffectInfo.BENEFICIAL, 3035801)); + public static final MobEffectList INVISIBILITY = a(14, "invisibility", new MobEffectList(MobEffectInfo.BENEFICIAL, 8356754)); + public static final MobEffectList BLINDNESS = a(15, "blindness", new MobEffectList(MobEffectInfo.HARMFUL, 2039587)); + public static final MobEffectList NIGHT_VISION = a(16, "night_vision", new MobEffectList(MobEffectInfo.BENEFICIAL, 2039713)); + public static final MobEffectList HUNGER = a(17, "hunger", new MobEffectList(MobEffectInfo.HARMFUL, 5797459)); + public static final MobEffectList WEAKNESS = a(18, "weakness", (new MobEffectAttackDamage(MobEffectInfo.HARMFUL, 4738376, -4.0D)).a(GenericAttributes.ATTACK_DAMAGE, "22653B89-116E-49DC-9B6B-9971489B5BE5", 0.0D, AttributeModifier.Operation.ADDITION)); + public static final MobEffectList POISON = a(19, "poison", new MobEffectList(MobEffectInfo.HARMFUL, 5149489)); + public static final MobEffectList WITHER = a(20, "wither", new MobEffectList(MobEffectInfo.HARMFUL, 3484199)); + public static final MobEffectList HEALTH_BOOST = a(21, "health_boost", (new MobEffectHealthBoost(MobEffectInfo.BENEFICIAL, 16284963)).a(GenericAttributes.MAX_HEALTH, "5D6F0BA2-1186-46AC-B896-C61C5CEE99CC", 4.0D, AttributeModifier.Operation.ADDITION)); + public static final MobEffectList ABSORBTION = a(22, "absorption", new MobEffectAbsorption(MobEffectInfo.BENEFICIAL, 2445989)); + public static final MobEffectList SATURATION = a(23, "saturation", new InstantMobEffect(MobEffectInfo.BENEFICIAL, 16262179)); + public static final MobEffectList GLOWING = a(24, "glowing", new MobEffectList(MobEffectInfo.NEUTRAL, 9740385)); + public static final MobEffectList LEVITATION = a(25, "levitation", new MobEffectList(MobEffectInfo.HARMFUL, 13565951)); + public static final MobEffectList LUCK = a(26, "luck", (new MobEffectList(MobEffectInfo.BENEFICIAL, 3381504)).a(GenericAttributes.LUCK, "03C3C89D-7037-4B42-869F-B146BCB64D2E", 1.0D, AttributeModifier.Operation.ADDITION)); + public static final MobEffectList UNLUCK = a(27, "unluck", (new MobEffectList(MobEffectInfo.HARMFUL, 12624973)).a(GenericAttributes.LUCK, "CC5AF142-2BD2-4215-B636-2605AED11727", -1.0D, AttributeModifier.Operation.ADDITION)); + public static final MobEffectList SLOW_FALLING = a(28, "slow_falling", new MobEffectList(MobEffectInfo.BENEFICIAL, 16773073)); + public static final MobEffectList CONDUIT_POWER = a(29, "conduit_power", new MobEffectList(MobEffectInfo.BENEFICIAL, 1950417)); + public static final MobEffectList DOLPHINS_GRACE = a(30, "dolphins_grace", new MobEffectList(MobEffectInfo.BENEFICIAL, 8954814)); + public static final MobEffectList BAD_OMEN = a(31, "bad_omen", new MobEffectList(MobEffectInfo.NEUTRAL, 745784) { + @Override + public boolean a(int i, int j) { + return true; + } + + @Override + public void tick(EntityLiving entityliving, int i) { + if (entityliving instanceof EntityPlayer && !entityliving.isSpectator()) { + EntityPlayer entityplayer = (EntityPlayer) entityliving; + WorldServer worldserver = entityplayer.getWorldServer(); + + if (worldserver.getDifficulty() == EnumDifficulty.PEACEFUL) { + return; + } + + if (worldserver.b_(new BlockPosition(entityliving))) { + worldserver.C().a(entityplayer); + } + } + + } + }); + public static final MobEffectList HERO_OF_THE_VILLAGE = a(32, "hero_of_the_village", new MobEffectList(MobEffectInfo.BENEFICIAL, 4521796)); + + // CraftBukkit start + static { + for (Object effect : IRegistry.MOB_EFFECT) { + org.bukkit.potion.PotionEffectType.registerPotionEffectType(new org.bukkit.craftbukkit.potion.CraftPotionEffectType((MobEffectList) effect)); + } + } + // CraftBukkit end + + private static MobEffectList a(int i, String s, MobEffectList mobeffectlist) { + return (MobEffectList) IRegistry.a(IRegistry.MOB_EFFECT, i, s, mobeffectlist); + } +} diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java index e1861d80b..a4e6be549 100644 --- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java +++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java @@ -1,19 +1,19 @@ package net.minecraft.server; import com.google.common.collect.Lists; - import java.util.Iterator; import java.util.List; +import java.util.Optional; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public abstract class MobSpawnerAbstract { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public int spawnDelay = 20; - private final List mobs = Lists.newArrayList(); - private MobSpawnerData spawnData = new MobSpawnerData(); + public final List mobs = Lists.newArrayList(); + public MobSpawnerData spawnData = new MobSpawnerData(); private double e; private double f; public int minSpawnDelay = 200; @@ -29,27 +29,28 @@ public abstract class MobSpawnerAbstract { @Nullable public MinecraftKey getMobName() { - String s = this.spawnData.b().getString("id"); + String s = this.spawnData.getEntity().getString("id"); try { return UtilColor.b(s) ? null : new MinecraftKey(s); } catch (ResourceKeyInvalidException resourcekeyinvalidexception) { BlockPosition blockposition = this.b(); - MobSpawnerAbstract.a.warn("Invalid entity id '{}' at spawner {}:[{},{},{}]", s, this.a().worldProvider.getDimensionManager(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); + MobSpawnerAbstract.LOGGER.warn("Invalid entity id '{}' at spawner {}:[{},{},{}]", s, this.a().worldProvider.getDimensionManager(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); return null; } } public void setMobName(EntityTypes entitytypes) { - this.spawnData.b().setString("id", IRegistry.ENTITY_TYPE.getKey(entitytypes).toString()); + this.spawnData.getEntity().setString("id", IRegistry.ENTITY_TYPE.getKey(entitytypes).toString()); this.mobs.clear(); // CraftBukkit - SPIGOT-3496, MC-92282 } + public boolean isActivated() { return h(); } // Paper - OBFHELPER private boolean h() { BlockPosition blockposition = this.b(); - return this.a().b((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, (double) this.requiredPlayerRange); + return this.a().isPlayerNearby((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, (double) this.requiredPlayerRange); } public void c() { @@ -60,19 +61,16 @@ public abstract class MobSpawnerAbstract { if (!this.h()) { this.f = this.e; } else { + World world = this.a(); BlockPosition blockposition = this.b(); - if (this.a().isClientSide) { - // Akarin start - this handle by client - /* - double d0 = (double) ((float) blockposition.getX() + this.a().random.nextFloat()); - double d1 = (double) ((float) blockposition.getY() + this.a().random.nextFloat()); - double d2 = (double) ((float) blockposition.getZ() + this.a().random.nextFloat()); + if (world.isClientSide) { + double d0 = (double) ((float) blockposition.getX() + world.random.nextFloat()); + double d1 = (double) ((float) blockposition.getY() + world.random.nextFloat()); + double d2 = (double) ((float) blockposition.getZ() + world.random.nextFloat()); - this.a().addParticle(Particles.M, d0, d1, d2, 0.0D, 0.0D, 0.0D); - this.a().addParticle(Particles.y, d0, d1, d2, 0.0D, 0.0D, 0.0D); - */ - // Akarin end + world.addParticle(Particles.SMOKE, d0, d1, d2, 0.0D, 0.0D, 0.0D); + world.addParticle(Particles.FLAME, d0, d1, d2, 0.0D, 0.0D, 0.0D); if (this.spawnDelay > 0) { this.spawnDelay -= tickDelay; // Paper } @@ -92,25 +90,32 @@ public abstract class MobSpawnerAbstract { boolean flag = false; for (int i = 0; i < this.spawnCount; ++i) { - NBTTagCompound nbttagcompound = this.spawnData.b(); - NBTTagList nbttaglist = nbttagcompound.getList("Pos", 6); - World world = this.a(); - int j = nbttaglist.size(); - double d3 = j >= 1 ? nbttaglist.k(0) : (double) blockposition.getX() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D; - double d4 = j >= 2 ? nbttaglist.k(1) : (double) (blockposition.getY() + world.random.nextInt(3) - 1); - double d5 = j >= 3 ? nbttaglist.k(2) : (double) blockposition.getZ() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D; - // Paper start - if (this.getMobName() == null) { + NBTTagCompound nbttagcompound = this.spawnData.getEntity(); + Optional> optional = EntityTypes.a(nbttagcompound); + + if (!optional.isPresent()) { + this.i(); return; } - String key = this.getMobName().getKey(); + + NBTTagList nbttaglist = nbttagcompound.getList("Pos", 6); + int j = nbttaglist.size(); + double d3 = j >= 1 ? nbttaglist.h(0) : (double) blockposition.getX() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D; + double d4 = j >= 2 ? nbttaglist.h(1) : (double) (blockposition.getY() + world.random.nextInt(3) - 1); + double d5 = j >= 3 ? nbttaglist.h(2) : (double) blockposition.getZ() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D; + + if (world.c(((EntityTypes) optional.get()).a(d3, d4, d5)) && EntityPositionTypes.a((EntityTypes) optional.get(), world.getMinecraftWorld(), EnumMobSpawn.SPAWNER, new BlockPosition(d3, d4, d5), world.getRandom())) { + // Paper start + EntityTypes entityType = optional.get(); + String key = EntityTypes.getName(entityType).getKey(); + org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key); if (type != null) { com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event; event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent( - MCUtil.toLocation(world, d3, d4, d5), - type, - MCUtil.toLocation(world, blockposition) + MCUtil.toLocation(world, d3, d4, d5), + type, + MCUtil.toLocation(world, blockposition) ); if (!event.callEvent()) { flag = true; @@ -121,26 +126,35 @@ public abstract class MobSpawnerAbstract { } } // Paper end - Entity entity = ChunkRegionLoader.spawnEntity(nbttagcompound, world, d3, d4, d5, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER); // Paper - if (entity == null) { - this.i(); - return; - } + Entity entity = EntityTypes.a(nbttagcompound, world, (entity1) -> { + entity1.setPositionRotation(d3, d4, d5, entity1.yaw, entity1.pitch); + return entity1; + }); - int k = world.a(entity.getClass(), (new AxisAlignedBB((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), (double) (blockposition.getX() + 1), (double) (blockposition.getY() + 1), (double) (blockposition.getZ() + 1))).g((double) this.spawnRange)).size(); + if (entity == null) { + this.i(); + return; + } - if (k >= this.maxNearbyEntities) { - this.i(); - return; - } + int k = world.a(entity.getClass(), (new AxisAlignedBB((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), (double) (blockposition.getX() + 1), (double) (blockposition.getY() + 1), (double) (blockposition.getZ() + 1))).g((double) this.spawnRange)).size(); - EntityInsentient entityinsentient = entity instanceof EntityInsentient ? (EntityInsentient) entity : null; + if (k >= this.maxNearbyEntities) { + this.i(); + return; + } - entity.setPositionRotation(entity.locX, entity.locY, entity.locZ, world.random.nextFloat() * 360.0F, 0.0F); - if (entityinsentient == null || entityinsentient.a((GeneratorAccess) world, true) && entityinsentient.canSpawn()) { - if (this.spawnData.b().d() == 1 && this.spawnData.b().hasKeyOfType("id", 8) && entity instanceof EntityInsentient) { - ((EntityInsentient) entity).prepare(world.getDamageScaler(new BlockPosition(entity)), (GroupDataEntity) null, (NBTTagCompound) null); + entity.setPositionRotation(entity.locX, entity.locY, entity.locZ, world.random.nextFloat() * 360.0F, 0.0F); + if (entity instanceof EntityInsentient) { + EntityInsentient entityinsentient = (EntityInsentient) entity; + + if (!entityinsentient.a((GeneratorAccess) world, EnumMobSpawn.SPAWNER) || !entityinsentient.a((IWorldReader) world)) { + continue; + } + + if (this.spawnData.getEntity().d() == 1 && this.spawnData.getEntity().hasKeyOfType("id", 8)) { + ((EntityInsentient) entity).prepare(world, world.getDamageScaler(new BlockPosition(entity)), EnumMobSpawn.SPAWNER, (GroupDataEntity) null, (NBTTagCompound) null); + } } entity.spawnedViaMobSpawner = true; // Paper // Spigot Start @@ -162,10 +176,10 @@ public abstract class MobSpawnerAbstract { continue; } // Spigot End - ChunkRegionLoader.a(entity, (GeneratorAccess) world, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit + this.a(entity); world.triggerEffect(2004, blockposition, 0); - if (entityinsentient != null) { - entityinsentient.doSpawnEffect(); + if (entity instanceof EntityInsentient) { + ((EntityInsentient) entity).doSpawnEffect(); } /*flag = true;*/ // Paper - moved up above cancellable event @@ -180,6 +194,20 @@ public abstract class MobSpawnerAbstract { } } + private void a(Entity entity) { + if (entity.valid || this.a().addEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER)) { // CraftBukkit // Paper + Iterator iterator = entity.getPassengers().iterator(); + + while (iterator.hasNext()) { + Entity entity1 = (Entity) iterator.next(); + + this.a(entity1); + } + + } + } + + public void resetTimer() { i(); } // Paper - OBFHELPER private void i() { if (this.maxSpawnDelay <= this.minSpawnDelay) { this.spawnDelay = this.minSpawnDelay; @@ -190,14 +218,20 @@ public abstract class MobSpawnerAbstract { } if (!this.mobs.isEmpty()) { - this.a((MobSpawnerData) WeightedRandom.a(this.a().random, this.mobs)); + this.setSpawnData((MobSpawnerData) WeightedRandom.a(this.a().random, this.mobs)); } this.a(1); } public void a(NBTTagCompound nbttagcompound) { + // Paper start - use larger int if set + if (nbttagcompound.hasKey("Paper.Delay")) { + this.spawnDelay = nbttagcompound.getInt("Paper.Delay"); + } else { this.spawnDelay = nbttagcompound.getShort("Delay"); + } + // Paper end this.mobs.clear(); if (nbttagcompound.hasKeyOfType("SpawnPotentials", 9)) { NBTTagList nbttaglist = nbttagcompound.getList("SpawnPotentials", 10); @@ -208,14 +242,19 @@ public abstract class MobSpawnerAbstract { } if (nbttagcompound.hasKeyOfType("SpawnData", 10)) { - this.a(new MobSpawnerData(1, nbttagcompound.getCompound("SpawnData"))); + this.setSpawnData(new MobSpawnerData(1, nbttagcompound.getCompound("SpawnData"))); } else if (!this.mobs.isEmpty()) { - this.a((MobSpawnerData) WeightedRandom.a(this.a().random, this.mobs)); + this.setSpawnData((MobSpawnerData) WeightedRandom.a(this.a().random, this.mobs)); } - + // Paper start - use ints if set + if (nbttagcompound.hasKeyOfType("Paper.MinSpawnDelay", 99)) { + this.minSpawnDelay = nbttagcompound.getInt("Paper.MinSpawnDelay"); + this.maxSpawnDelay = nbttagcompound.getInt("Paper.MaxSpawnDelay"); + this.spawnCount = nbttagcompound.getShort("SpawnCount"); + } else // Paper end if (nbttagcompound.hasKeyOfType("MinSpawnDelay", 99)) { - this.minSpawnDelay = nbttagcompound.getShort("MinSpawnDelay"); - this.maxSpawnDelay = nbttagcompound.getShort("MaxSpawnDelay"); + this.minSpawnDelay = nbttagcompound.getInt("MinSpawnDelay"); + this.maxSpawnDelay = nbttagcompound.getInt("MaxSpawnDelay"); this.spawnCount = nbttagcompound.getShort("SpawnCount"); } @@ -240,25 +279,36 @@ public abstract class MobSpawnerAbstract { if (minecraftkey == null) { return nbttagcompound; } else { - nbttagcompound.setShort("Delay", (short) this.spawnDelay); - nbttagcompound.setShort("MinSpawnDelay", (short) this.minSpawnDelay); - nbttagcompound.setShort("MaxSpawnDelay", (short) this.maxSpawnDelay); + // Paper start + if (spawnDelay > Short.MAX_VALUE) { + nbttagcompound.setInt("Paper.Delay", this.spawnDelay); + } + nbttagcompound.setShort("Delay", (short) Math.min(Short.MAX_VALUE, this.spawnDelay)); + + if (minSpawnDelay > Short.MAX_VALUE || maxSpawnDelay > Short.MAX_VALUE) { + nbttagcompound.setInt("Paper.MinSpawnDelay", this.minSpawnDelay); + nbttagcompound.setInt("Paper.MaxSpawnDelay", this.maxSpawnDelay); + } + + nbttagcompound.setShort("MinSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.minSpawnDelay)); + nbttagcompound.setShort("MaxSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.maxSpawnDelay)); + // Paper end nbttagcompound.setShort("SpawnCount", (short) this.spawnCount); nbttagcompound.setShort("MaxNearbyEntities", (short) this.maxNearbyEntities); nbttagcompound.setShort("RequiredPlayerRange", (short) this.requiredPlayerRange); nbttagcompound.setShort("SpawnRange", (short) this.spawnRange); - nbttagcompound.set("SpawnData", this.spawnData.b().clone()); + nbttagcompound.set("SpawnData", this.spawnData.getEntity().clone()); NBTTagList nbttaglist = new NBTTagList(); if (this.mobs.isEmpty()) { - nbttaglist.add((NBTBase) this.spawnData.a()); + nbttaglist.add(this.spawnData.a()); } else { Iterator iterator = this.mobs.iterator(); while (iterator.hasNext()) { MobSpawnerData mobspawnerdata = (MobSpawnerData) iterator.next(); - nbttaglist.add((NBTBase) mobspawnerdata.a()); + nbttaglist.add(mobspawnerdata.a()); } } @@ -276,7 +326,7 @@ public abstract class MobSpawnerAbstract { } } - public void a(MobSpawnerData mobspawnerdata) { + public void setSpawnData(MobSpawnerData mobspawnerdata) { this.spawnData = mobspawnerdata; } diff --git a/src/main/java/net/minecraft/server/MobSpawnerPatrol.java b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java new file mode 100644 index 000000000..a9d32ebdf --- /dev/null +++ b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java @@ -0,0 +1,106 @@ +package net.minecraft.server; + +import java.util.Random; + +public class MobSpawnerPatrol { + + private int a; + + public MobSpawnerPatrol() {} + + public int a(WorldServer worldserver, boolean flag, boolean flag1) { + if (!flag) { + return 0; + } else { + Random random = worldserver.random; + + --this.a; + if (this.a > 0) { + return 0; + } else { + this.a += 12000 + random.nextInt(1200); + long i = worldserver.getDayTime() / 24000L; + + if (i >= 5L && worldserver.J()) { + if (random.nextInt(5) != 0) { + return 0; + } else { + int j = worldserver.getPlayers().size(); + + if (j < 1) { + return 0; + } else { + EntityHuman entityhuman = (EntityHuman) worldserver.getPlayers().get(random.nextInt(j)); + + if (entityhuman.isSpectator()) { + return 0; + } else if (worldserver.b_(entityhuman.getChunkCoordinates())) { + return 0; + } else { + int k = (24 + random.nextInt(24)) * (random.nextBoolean() ? -1 : 1); + int l = (24 + random.nextInt(24)) * (random.nextBoolean() ? -1 : 1); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + blockposition_mutableblockposition.c(entityhuman.locX, entityhuman.locY, entityhuman.locZ).e(k, 0, l); + if (!worldserver.isAreaLoaded(blockposition_mutableblockposition.getX() - 10, blockposition_mutableblockposition.getY() - 10, blockposition_mutableblockposition.getZ() - 10, blockposition_mutableblockposition.getX() + 10, blockposition_mutableblockposition.getY() + 10, blockposition_mutableblockposition.getZ() + 10)) { + return 0; + } else { + BiomeBase biomebase = worldserver.getBiome(blockposition_mutableblockposition); + BiomeBase.Geography biomebase_geography = biomebase.o(); + + if (biomebase_geography == BiomeBase.Geography.MUSHROOM) { + return 0; + } else { + int i1 = 0; + int j1 = (int) Math.ceil((double) worldserver.getDamageScaler(blockposition_mutableblockposition).b()) + 1; + + for (int k1 = 0; k1 < j1; ++k1) { + ++i1; + blockposition_mutableblockposition.p(worldserver.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, blockposition_mutableblockposition).getY()); + if (k1 == 0) { + if (!this.a(worldserver, blockposition_mutableblockposition, random, true)) { + break; + } + } else { + this.a(worldserver, blockposition_mutableblockposition, random, false); + } + + blockposition_mutableblockposition.o(blockposition_mutableblockposition.getX() + random.nextInt(5) - random.nextInt(5)); + blockposition_mutableblockposition.q(blockposition_mutableblockposition.getZ() + random.nextInt(5) - random.nextInt(5)); + } + + return i1; + } + } + } + } + } + } else { + return 0; + } + } + } + } + + private boolean a(World world, BlockPosition blockposition, Random random, boolean flag) { + if (!EntityMonsterPatrolling.b(EntityTypes.PILLAGER, world, EnumMobSpawn.PATROL, blockposition, random)) { + return false; + } else { + EntityMonsterPatrolling entitymonsterpatrolling = (EntityMonsterPatrolling) EntityTypes.PILLAGER.a(world); + + if (entitymonsterpatrolling != null) { + if (flag) { + entitymonsterpatrolling.setPatrolLeader(true); + entitymonsterpatrolling.ed(); + } + + entitymonsterpatrolling.setPosition((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); + entitymonsterpatrolling.prepare(world, world.getDamageScaler(blockposition), EnumMobSpawn.PATROL, (GroupDataEntity) null, (NBTTagCompound) null); + world.addEntity(entitymonsterpatrolling, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.PATROL); // CraftBukkit + return true; + } else { + return false; + } + } + } +} diff --git a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java index 7deba4eab..1818e7c38 100644 --- a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java +++ b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java @@ -9,31 +9,31 @@ public class MobSpawnerPhantom { public MobSpawnerPhantom() {} - public int a(World world, boolean flag, boolean flag1) { + public int a(WorldServer worldserver, boolean flag, boolean flag1) { if (!flag) { return 0; } else { - Random random = world.random; + Random random = worldserver.random; --this.a; if (this.a > 0) { return 0; } else { this.a += (60 + random.nextInt(60)) * 20; - if (world.c() < 5 && world.worldProvider.g()) { + if (worldserver.c() < 5 && worldserver.worldProvider.g()) { return 0; } else { int i = 0; - Iterator iterator = world.players.iterator(); + Iterator iterator = worldserver.getPlayers().iterator(); while (iterator.hasNext()) { EntityHuman entityhuman = (EntityHuman) iterator.next(); - if (!entityhuman.isSpectator() && !((EntityPlayer) entityhuman).playerInteractManager.isCreative()) { // Akarin - ignore creative mode + if (!entityhuman.isSpectator()) { BlockPosition blockposition = new BlockPosition(entityhuman); - if (!world.worldProvider.g() || blockposition.getY() >= world.getSeaLevel() && world.e(blockposition)) { - DifficultyDamageScaler difficultydamagescaler = world.getDamageScaler(blockposition); + if (!worldserver.worldProvider.g() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.f(blockposition)) { + DifficultyDamageScaler difficultydamagescaler = worldserver.getDamageScaler(blockposition); if (difficultydamagescaler.a(random.nextFloat() * 3.0F)) { ServerStatisticManager serverstatisticmanager = ((EntityPlayer) entityhuman).getStatisticManager(); @@ -42,16 +42,16 @@ public class MobSpawnerPhantom { if (random.nextInt(j) >= 72000) { BlockPosition blockposition1 = blockposition.up(20 + random.nextInt(15)).east(-10 + random.nextInt(21)).south(-10 + random.nextInt(21)); - IBlockData iblockdata = world.getType(blockposition1); - Fluid fluid = world.getFluid(blockposition1); + IBlockData iblockdata = worldserver.getType(blockposition1); + Fluid fluid = worldserver.getFluid(blockposition1); - if (SpawnerCreature.a(iblockdata, fluid)) { + if (SpawnerCreature.a((IBlockAccess) worldserver, blockposition1, iblockdata, fluid)) { GroupDataEntity groupdataentity = null; int k = 1 + random.nextInt(difficultydamagescaler.a().a() + 1); for (int l = 0; l < k; ++l) { // Paper start - com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(MCUtil.toLocation(world, blockposition1), ((EntityPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); + com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(MCUtil.toLocation(worldserver, blockposition1), ((EntityPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); if (!event.callEvent()) { if (event.shouldAbortSpawn()) { break; @@ -59,11 +59,11 @@ public class MobSpawnerPhantom { continue; } // Paper end - EntityPhantom entityphantom = EntityTypes.PHANTOM.create(world); // Paper + EntityPhantom entityphantom = (EntityPhantom) EntityTypes.PHANTOM.a((World) worldserver); entityphantom.spawningEntity = entityhuman.uniqueID; // Paper entityphantom.setPositionRotation(blockposition1, 0.0F, 0.0F); - groupdataentity = entityphantom.prepare(difficultydamagescaler, groupdataentity, (NBTTagCompound) null); - world.addEntity(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit + groupdataentity = entityphantom.prepare(worldserver, difficultydamagescaler, EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null); + worldserver.addEntity(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit } i += k; diff --git a/src/main/java/net/minecraft/server/NBTBase.java b/src/main/java/net/minecraft/server/NBTBase.java index b2757aad8..7a987c6be 100644 --- a/src/main/java/net/minecraft/server/NBTBase.java +++ b/src/main/java/net/minecraft/server/NBTBase.java @@ -6,7 +6,7 @@ import java.io.IOException; public interface NBTBase { - String[] a = new String[] { "END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]", "LONG[]"}; + String[] a = new String[]{"END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]", "LONG[]"}; EnumChatFormat b = EnumChatFormat.AQUA; EnumChatFormat c = EnumChatFormat.GREEN; EnumChatFormat d = EnumChatFormat.GOLD; @@ -22,69 +22,69 @@ public interface NBTBase { static NBTBase createTag(byte b0) { switch (b0) { - case 0: - return new NBTTagEnd(); - case 1: - return new NBTTagByte(); - case 2: - return new NBTTagShort(); - case 3: - return new NBTTagInt(); - case 4: - return new NBTTagLong(); - case 5: - return new NBTTagFloat(); - case 6: - return new NBTTagDouble(); - case 7: - return new NBTTagByteArray(); - case 8: - return new NBTTagString(); - case 9: - return new NBTTagList(); - case 10: - return new NBTTagCompound(); - case 11: - return new NBTTagIntArray(); - case 12: - return new NBTTagLongArray(); - default: - return null; + case 0: + return new NBTTagEnd(); + case 1: + return new NBTTagByte(); + case 2: + return new NBTTagShort(); + case 3: + return new NBTTagInt(); + case 4: + return new NBTTagLong(); + case 5: + return new NBTTagFloat(); + case 6: + return new NBTTagDouble(); + case 7: + return new NBTTagByteArray(); + case 8: + return new NBTTagString(); + case 9: + return new NBTTagList(); + case 10: + return new NBTTagCompound(); + case 11: + return new NBTTagIntArray(); + case 12: + return new NBTTagLongArray(); + default: + return null; } } - static String n(int i) { + static String l(int i) { switch (i) { - case 0: - return "TAG_End"; - case 1: - return "TAG_Byte"; - case 2: - return "TAG_Short"; - case 3: - return "TAG_Int"; - case 4: - return "TAG_Long"; - case 5: - return "TAG_Float"; - case 6: - return "TAG_Double"; - case 7: - return "TAG_Byte_Array"; - case 8: - return "TAG_String"; - case 9: - return "TAG_List"; - case 10: - return "TAG_Compound"; - case 11: - return "TAG_Int_Array"; - case 12: - return "TAG_Long_Array"; - case 99: - return "Any Numeric Tag"; - default: - return "UNKNOWN"; + case 0: + return "TAG_End"; + case 1: + return "TAG_Byte"; + case 2: + return "TAG_Short"; + case 3: + return "TAG_Int"; + case 4: + return "TAG_Long"; + case 5: + return "TAG_Float"; + case 6: + return "TAG_Double"; + case 7: + return "TAG_Byte_Array"; + case 8: + return "TAG_String"; + case 9: + return "TAG_List"; + case 10: + return "TAG_Compound"; + case 11: + return "TAG_Int_Array"; + case 12: + return "TAG_Long_Array"; + case 99: + return "Any Numeric Tag"; + default: + return "UNKNOWN"; } } diff --git a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java index e1f7e06ab..d49afd622 100644 --- a/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java +++ b/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java @@ -16,13 +16,28 @@ public class NBTCompressedStreamTools { public static NBTTagCompound a(InputStream inputstream) throws IOException { DataInputStream datainputstream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(inputstream))); + Throwable throwable = null; NBTTagCompound nbttagcompound; try { nbttagcompound = a((DataInput) datainputstream, NBTReadLimiter.a); + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; } finally { - datainputstream.close(); + if (datainputstream != null) { + if (throwable != null) { + try { + datainputstream.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + datainputstream.close(); + } + } + } return nbttagcompound; @@ -30,11 +45,26 @@ public class NBTCompressedStreamTools { public static void a(NBTTagCompound nbttagcompound, OutputStream outputstream) throws IOException { DataOutputStream dataoutputstream = new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(outputstream))); + Throwable throwable = null; try { a(nbttagcompound, (DataOutput) dataoutputstream); + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; } finally { - dataoutputstream.close(); + if (dataoutputstream != null) { + if (throwable != null) { + try { + dataoutputstream.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + dataoutputstream.close(); + } + } + } } diff --git a/src/main/java/net/minecraft/server/NBTTagByteArray.java b/src/main/java/net/minecraft/server/NBTTagByteArray.java index e0fb6fb49..1110b277f 100644 --- a/src/main/java/net/minecraft/server/NBTTagByteArray.java +++ b/src/main/java/net/minecraft/server/NBTTagByteArray.java @@ -33,11 +33,13 @@ public class NBTTagByteArray extends NBTList { return abyte; } + @Override public void write(DataOutput dataoutput) throws IOException { dataoutput.writeInt(this.data.length); dataoutput.write(this.data); } + @Override public void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException { nbtreadlimiter.a(192L); int j = datainput.readInt(); @@ -48,10 +50,12 @@ public class NBTTagByteArray extends NBTList { datainput.readFully(this.data); } + @Override public byte getTypeId() { return 7; } + @Override public String toString() { StringBuilder stringbuilder = new StringBuilder("[B;"); @@ -67,7 +71,7 @@ public class NBTTagByteArray extends NBTList { } @Override - public NBTTagByteArray clone() { // Paper - decompile fix + public NBTBase clone() { byte[] abyte = new byte[this.data.length]; System.arraycopy(this.data, 0, abyte, 0, this.data.length); @@ -82,6 +86,7 @@ public class NBTTagByteArray extends NBTList { return Arrays.hashCode(this.data); } + @Override public IChatBaseComponent a(String s, int i) { IChatBaseComponent ichatbasecomponent = (new ChatComponentText("B")).a(NBTTagByteArray.e); IChatBaseComponent ichatbasecomponent1 = (new ChatComponentText("[")).addSibling(ichatbasecomponent).a(";"); @@ -99,7 +104,7 @@ public class NBTTagByteArray extends NBTList { return ichatbasecomponent1; } - public byte[] c() { + public byte[] getBytes() { return this.data; } @@ -107,15 +112,50 @@ public class NBTTagByteArray extends NBTList { return this.data.length; } - public NBTTagByte c(int i) { + public NBTTagByte get(int i) { return new NBTTagByte(this.data[i]); } - public void a(int i, NBTBase nbtbase) { - this.data[i] = ((NBTNumber) nbtbase).asByte(); + public NBTTagByte set(int i, NBTTagByte nbttagbyte) { + byte b0 = this.data[i]; + + this.data[i] = nbttagbyte.asByte(); + return new NBTTagByte(b0); } - public void b(int i) { + public void add(int i, NBTTagByte nbttagbyte) { + this.data = ArrayUtils.add(this.data, i, nbttagbyte.asByte()); + } + + @Override + public boolean a(int i, NBTBase nbtbase) { + if (nbtbase instanceof NBTNumber) { + this.data[i] = ((NBTNumber) nbtbase).asByte(); + return true; + } else { + return false; + } + } + + @Override + public boolean b(int i, NBTBase nbtbase) { + if (nbtbase instanceof NBTNumber) { + this.data = ArrayUtils.add(this.data, i, ((NBTNumber) nbtbase).asByte()); + return true; + } else { + return false; + } + } + + @Override + public NBTTagByte remove(int i) { + byte b0 = this.data[i]; + this.data = ArrayUtils.remove(this.data, i); + return new NBTTagByte(b0); + } + + public void clear() { + this.data = new byte[0]; } } diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/java/net/minecraft/server/NBTTagCompound.java index d4165f7e4..b1fd18151 100644 --- a/src/main/java/net/minecraft/server/NBTTagCompound.java +++ b/src/main/java/net/minecraft/server/NBTTagCompound.java @@ -21,12 +21,13 @@ import org.apache.logging.log4j.Logger; public class NBTTagCompound implements NBTBase { - private static final Logger f = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final Pattern g = Pattern.compile("[A-Za-z0-9._+-]+"); public final Map map = Maps.newHashMap(); // Paper public NBTTagCompound() {} + @Override public void write(DataOutput dataoutput) throws IOException { Iterator iterator = this.map.keySet().iterator(); @@ -40,6 +41,7 @@ public class NBTTagCompound implements NBTBase { dataoutput.writeByte(0); } + @Override public void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException { nbtreadlimiter.a(384L); if (i > 512) { @@ -67,6 +69,7 @@ public class NBTTagCompound implements NBTBase { return this.map.keySet(); } + @Override public byte getTypeId() { return 10; } @@ -75,8 +78,9 @@ public class NBTTagCompound implements NBTBase { return this.map.size(); } - public void set(String s, NBTBase nbtbase) { - this.map.put(s, nbtbase); + @Nullable + public NBTBase set(String s, NBTBase nbtbase) { + return (NBTBase) this.map.put(s, nbtbase); } public void setByte(String s, byte b0) { @@ -101,13 +105,14 @@ public class NBTTagCompound implements NBTBase { this.setLong(s + "Least", uuid.getLeastSignificantBits()); } - public UUID getUUID(String prefix) { return a(prefix); } // Paper - OBFHELPER + + @Nullable public UUID getUUID(String prefix) { return a(prefix); } // Paper - OBFHELPER @Nullable public UUID a(String s) { return new UUID(this.getLong(s + "Most"), this.getLong(s + "Least")); } - public boolean hasUUID(String s) { return b(s); } public boolean b(String s) { // Paper - OBFHELPER + public final boolean hasUUID(String s) { return this.b(s); } public boolean b(String s) { // Paper - OBFHELPER return this.hasKeyOfType(s + "Most", 99) && this.hasKeyOfType(s + "Least", 99); } @@ -147,6 +152,7 @@ public class NBTTagCompound implements NBTBase { this.setByte(s, (byte) (flag ? 1 : 0)); } + @Nullable public NBTBase get(String s) { return (NBTBase) this.map.get(s); } @@ -254,7 +260,7 @@ public class NBTTagCompound implements NBTBase { public byte[] getByteArray(String s) { try { if (this.hasKeyOfType(s, 7)) { - return ((NBTTagByteArray) this.map.get(s)).c(); + return ((NBTTagByteArray) this.map.get(s)).getBytes(); } } catch (ClassCastException classcastexception) { throw new ReportedException(this.a(s, 7, classcastexception)); @@ -266,7 +272,7 @@ public class NBTTagCompound implements NBTBase { public int[] getIntArray(String s) { try { if (this.hasKeyOfType(s, 11)) { - return ((NBTTagIntArray) this.map.get(s)).d(); + return ((NBTTagIntArray) this.map.get(s)).getInts(); } } catch (ClassCastException classcastexception) { throw new ReportedException(this.a(s, 11, classcastexception)); @@ -275,10 +281,10 @@ public class NBTTagCompound implements NBTBase { return new int[0]; } - public long[] o(String s) { + public long[] getLongArray(String s) { try { if (this.hasKeyOfType(s, 12)) { - return ((NBTTagLongArray) this.map.get(s)).d(); + return ((NBTTagLongArray) this.map.get(s)).getLongs(); } } catch (ClassCastException classcastexception) { throw new ReportedException(this.a(s, 12, classcastexception)); @@ -304,7 +310,7 @@ public class NBTTagCompound implements NBTBase { if (this.d(s) == 9) { NBTTagList nbttaglist = (NBTTagList) this.map.get(s); - if (!nbttaglist.isEmpty() && nbttaglist.d() != i) { + if (!nbttaglist.isEmpty() && nbttaglist.a_() != i) { return new NBTTagList(); } @@ -325,11 +331,12 @@ public class NBTTagCompound implements NBTBase { this.map.remove(s); } + @Override public String toString() { StringBuilder stringbuilder = new StringBuilder("{"); Collection collection = this.map.keySet(); - if (NBTTagCompound.f.isDebugEnabled()) { + if (NBTTagCompound.LOGGER.isDebugEnabled()) { List list = Lists.newArrayList(this.map.keySet()); Collections.sort(list); @@ -366,6 +373,7 @@ public class NBTTagCompound implements NBTBase { return crashreport; } + @Override public NBTTagCompound clone() { NBTTagCompound nbttagcompound = new NBTTagCompound(); Iterator iterator = this.map.keySet().iterator(); @@ -443,19 +451,22 @@ public class NBTTagCompound implements NBTBase { } protected static String s(String s) { - return NBTTagCompound.g.matcher(s).matches() ? s : NBTTagString.a(s, true); + return NBTTagCompound.g.matcher(s).matches() ? s : NBTTagString.a(s); } protected static IChatBaseComponent t(String s) { if (NBTTagCompound.g.matcher(s).matches()) { return (new ChatComponentText(s)).a(NBTTagCompound.b); } else { - IChatBaseComponent ichatbasecomponent = (new ChatComponentText(NBTTagString.a(s, false))).a(NBTTagCompound.b); + String s1 = NBTTagString.a(s); + String s2 = s1.substring(0, 1); + IChatBaseComponent ichatbasecomponent = (new ChatComponentText(s1.substring(1, s1.length() - 1))).a(NBTTagCompound.b); - return (new ChatComponentText("\"")).addSibling(ichatbasecomponent).a("\""); + return (new ChatComponentText(s2)).addSibling(ichatbasecomponent).a(s2); } } + @Override public IChatBaseComponent a(String s, int i) { if (this.map.isEmpty()) { return new ChatComponentText("{}"); @@ -463,7 +474,7 @@ public class NBTTagCompound implements NBTBase { ChatComponentText chatcomponenttext = new ChatComponentText("{"); Collection collection = this.map.keySet(); - if (NBTTagCompound.f.isDebugEnabled()) { + if (NBTTagCompound.LOGGER.isDebugEnabled()) { List list = Lists.newArrayList(this.map.keySet()); Collections.sort(list); diff --git a/src/main/java/net/minecraft/server/NBTTagIntArray.java b/src/main/java/net/minecraft/server/NBTTagIntArray.java index 2652a28e1..e3ed32aa7 100644 --- a/src/main/java/net/minecraft/server/NBTTagIntArray.java +++ b/src/main/java/net/minecraft/server/NBTTagIntArray.java @@ -33,6 +33,7 @@ public class NBTTagIntArray extends NBTList { return aint; } + @Override public void write(DataOutput dataoutput) throws IOException { dataoutput.writeInt(this.data.length); int[] aint = this.data; @@ -46,6 +47,7 @@ public class NBTTagIntArray extends NBTList { } + @Override public void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException { nbtreadlimiter.a(192L); int j = datainput.readInt(); @@ -60,10 +62,12 @@ public class NBTTagIntArray extends NBTList { } + @Override public byte getTypeId() { return 11; } + @Override public String toString() { StringBuilder stringbuilder = new StringBuilder("[I;"); @@ -78,6 +82,7 @@ public class NBTTagIntArray extends NBTList { return stringbuilder.append(']').toString(); } + @Override public NBTTagIntArray clone() { int[] aint = new int[this.data.length]; @@ -93,10 +98,11 @@ public class NBTTagIntArray extends NBTList { return Arrays.hashCode(this.data); } - public int[] d() { + public int[] getInts() { return this.data; } + @Override public IChatBaseComponent a(String s, int i) { IChatBaseComponent ichatbasecomponent = (new ChatComponentText("I")).a(NBTTagIntArray.e); IChatBaseComponent ichatbasecomponent1 = (new ChatComponentText("[")).addSibling(ichatbasecomponent).a(";"); @@ -116,15 +122,50 @@ public class NBTTagIntArray extends NBTList { return this.data.length; } - public NBTTagInt c(int i) { + public NBTTagInt get(int i) { return new NBTTagInt(this.data[i]); } - public void a(int i, NBTBase nbtbase) { - this.data[i] = ((NBTNumber) nbtbase).asInt(); + public NBTTagInt set(int i, NBTTagInt nbttagint) { + int j = this.data[i]; + + this.data[i] = nbttagint.asInt(); + return new NBTTagInt(j); } - public void b(int i) { + public void add(int i, NBTTagInt nbttagint) { + this.data = ArrayUtils.add(this.data, i, nbttagint.asInt()); + } + + @Override + public boolean a(int i, NBTBase nbtbase) { + if (nbtbase instanceof NBTNumber) { + this.data[i] = ((NBTNumber) nbtbase).asInt(); + return true; + } else { + return false; + } + } + + @Override + public boolean b(int i, NBTBase nbtbase) { + if (nbtbase instanceof NBTNumber) { + this.data = ArrayUtils.add(this.data, i, ((NBTNumber) nbtbase).asInt()); + return true; + } else { + return false; + } + } + + @Override + public NBTTagInt remove(int i) { + int j = this.data[i]; + this.data = ArrayUtils.remove(this.data, i); + return new NBTTagInt(j); + } + + public void clear() { + this.data = new int[0]; } } diff --git a/src/main/java/net/minecraft/server/NBTTagList.java b/src/main/java/net/minecraft/server/NBTTagList.java index 22027321b..80eea5dfb 100644 --- a/src/main/java/net/minecraft/server/NBTTagList.java +++ b/src/main/java/net/minecraft/server/NBTTagList.java @@ -8,17 +8,15 @@ import java.io.IOException; import java.util.Iterator; import java.util.List; import java.util.Objects; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; public class NBTTagList extends NBTList { - private static final Logger f = LogManager.getLogger(); - public List list = Lists.newArrayList(); // Paper + List list = Lists.newArrayList(); // Paper - private -> package private byte type = 0; public NBTTagList() {} + @Override public void write(DataOutput dataoutput) throws IOException { if (this.list.isEmpty()) { this.type = 0; @@ -28,13 +26,17 @@ public class NBTTagList extends NBTList { dataoutput.writeByte(this.type); dataoutput.writeInt(this.list.size()); + Iterator iterator = this.list.iterator(); - for (int i = 0; i < this.list.size(); ++i) { - ((NBTBase) this.list.get(i)).write(dataoutput); + while (iterator.hasNext()) { + NBTBase nbtbase = (NBTBase) iterator.next(); + + nbtbase.write(dataoutput); } } + @Override public void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException { nbtreadlimiter.a(296L); if (i > 512) { @@ -60,10 +62,12 @@ public class NBTTagList extends NBTList { } } + @Override public byte getTypeId() { return 9; } + @Override public String toString() { StringBuilder stringbuilder = new StringBuilder("["); @@ -78,44 +82,19 @@ public class NBTTagList extends NBTList { return stringbuilder.append(']').toString(); } - public boolean add(NBTBase nbtbase) { - if (nbtbase.getTypeId() == 0) { - NBTTagList.f.warn("Invalid TagEnd added to ListTag"); - return false; - } else { - if (this.type == 0) { - this.type = nbtbase.getTypeId(); - } else if (this.type != nbtbase.getTypeId()) { - NBTTagList.f.warn("Adding mismatching tag types to tag list"); - return false; - } - - this.list.add(nbtbase); - return true; - } - } - - public NBTBase set(int i, NBTBase nbtbase) { - if (nbtbase.getTypeId() == 0) { - NBTTagList.f.warn("Invalid TagEnd added to ListTag"); - return (NBTBase) this.list.get(i); - } else if (i >= 0 && i < this.list.size()) { - if (this.type == 0) { - this.type = nbtbase.getTypeId(); - } else if (this.type != nbtbase.getTypeId()) { - NBTTagList.f.warn("Adding mismatching tag types to tag list"); - return (NBTBase) this.list.get(i); - } - - return (NBTBase) this.list.set(i, nbtbase); - } else { - NBTTagList.f.warn("index out of bounds to set tag in tag list"); - return null; + private void f() { + if (this.list.isEmpty()) { + this.type = 0; } + } + @Override public NBTBase remove(int i) { - return (NBTBase) this.list.remove(i); + NBTBase nbtbase = (NBTBase) this.list.remove(i); + + this.f(); + return nbtbase; } public boolean isEmpty() { @@ -134,7 +113,7 @@ public class NBTTagList extends NBTList { return new NBTTagCompound(); } - public NBTTagList f(int i) { + public NBTTagList b(int i) { if (i >= 0 && i < this.list.size()) { NBTBase nbtbase = (NBTBase) this.list.get(i); @@ -146,7 +125,7 @@ public class NBTTagList extends NBTList { return new NBTTagList(); } - public short g(int i) { + public short d(int i) { if (i >= 0 && i < this.list.size()) { NBTBase nbtbase = (NBTBase) this.list.get(i); @@ -158,7 +137,7 @@ public class NBTTagList extends NBTList { return 0; } - public int h(int i) { + public int e(int i) { if (i >= 0 && i < this.list.size()) { NBTBase nbtbase = (NBTBase) this.list.get(i); @@ -170,20 +149,20 @@ public class NBTTagList extends NBTList { return 0; } - public int[] i(int i) { + public int[] f(int i) { if (i >= 0 && i < this.list.size()) { NBTBase nbtbase = (NBTBase) this.list.get(i); if (nbtbase.getTypeId() == 11) { - return ((NBTTagIntArray) nbtbase).d(); + return ((NBTTagIntArray) nbtbase).getInts(); } } return new int[0]; } - public final double getDoubleAt(int i) { return this.k(i); } // Paper - OBFHELPER - public double k(int i) { + public final double getDoubleAt(int i) { return this.h(i); } // Paper - OBFHELPER + public double h(int i) { if (i >= 0 && i < this.list.size()) { NBTBase nbtbase = (NBTBase) this.list.get(i); @@ -195,7 +174,7 @@ public class NBTTagList extends NBTList { return 0.0D; } - public float l(int i) { + public float i(int i) { if (i >= 0 && i < this.list.size()) { NBTBase nbtbase = (NBTBase) this.list.get(i); @@ -217,26 +196,64 @@ public class NBTTagList extends NBTList { } } - public NBTBase get(int i) { - return (NBTBase) (i >= 0 && i < this.list.size() ? (NBTBase) this.list.get(i) : new NBTTagEnd()); - } - public int size() { return this.list.size(); } - public NBTBase c(int i) { + public NBTBase get(int i) { return (NBTBase) this.list.get(i); } - public void a(int i, NBTBase nbtbase) { - this.list.set(i, nbtbase); + @Override + public NBTBase set(int i, NBTBase nbtbase) { + NBTBase nbtbase1 = this.get(i); + + if (!this.a(i, nbtbase)) { + throw new UnsupportedOperationException(String.format("Trying to add tag of type %d to list of %d", nbtbase.getTypeId(), this.type)); + } else { + return nbtbase1; + } } - public void b(int i) { - this.list.remove(i); + @Override + public void add(int i, NBTBase nbtbase) { + if (!this.b(i, nbtbase)) { + throw new UnsupportedOperationException(String.format("Trying to add tag of type %d to list of %d", nbtbase.getTypeId(), this.type)); + } } + @Override + public boolean a(int i, NBTBase nbtbase) { + if (this.a(nbtbase)) { + this.list.set(i, nbtbase); + return true; + } else { + return false; + } + } + + @Override + public boolean b(int i, NBTBase nbtbase) { + if (this.a(nbtbase)) { + this.list.add(i, nbtbase); + return true; + } else { + return false; + } + } + + private boolean a(NBTBase nbtbase) { + if (nbtbase.getTypeId() == 0) { + return false; + } else if (this.type == 0) { + this.type = nbtbase.getTypeId(); + return true; + } else { + return this.type == nbtbase.getTypeId(); + } + } + + @Override public NBTTagList clone() { NBTTagList nbttaglist = new NBTTagList(); @@ -261,6 +278,7 @@ public class NBTTagList extends NBTList { return this.list.hashCode(); } + @Override public IChatBaseComponent a(String s, int i) { if (this.isEmpty()) { return new ChatComponentText("[]"); @@ -291,7 +309,12 @@ public class NBTTagList extends NBTList { } } - public int d() { + public int a_() { return this.type; } + + public void clear() { + this.list.clear(); + this.type = 0; + } } diff --git a/src/main/java/net/minecraft/server/NameReferencingFileConverter.java b/src/main/java/net/minecraft/server/NameReferencingFileConverter.java index 76a57d3a3..0794aff5b 100644 --- a/src/main/java/net/minecraft/server/NameReferencingFileConverter.java +++ b/src/main/java/net/minecraft/server/NameReferencingFileConverter.java @@ -27,7 +27,7 @@ import org.apache.logging.log4j.Logger; public class NameReferencingFileConverter { - private static final Logger e = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public static final File a = new File("banned-ips.txt"); public static final File b = new File("banned-players.txt"); public static final File c = new File("ops.txt"); @@ -85,7 +85,7 @@ public class NameReferencingFileConverter { gameprofilebanlist.load(); // CraftBukkit start - FileNotFoundException -> IOException, don't print stacktrace } catch (IOException filenotfoundexception) { - NameReferencingFileConverter.e.warn("Could not load existing file {}", gameprofilebanlist.c().getName()); + NameReferencingFileConverter.LOGGER.warn("Could not load existing file {}", gameprofilebanlist.c().getName()); } } @@ -95,11 +95,11 @@ public class NameReferencingFileConverter { a(NameReferencingFileConverter.b, (Map) map); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { public void onProfileLookupSucceeded(GameProfile gameprofile) { - minecraftserver.getModernUserCache().offer(gameprofile); // Akarin + minecraftserver.getUserCache().a(gameprofile); String[] astring = (String[]) map.get(gameprofile.getName().toLowerCase(Locale.ROOT)); if (astring == null) { - NameReferencingFileConverter.e.warn("Could not convert user banlist entry for {}", gameprofile.getName()); + NameReferencingFileConverter.LOGGER.warn("Could not convert user banlist entry for {}", gameprofile.getName()); throw new NameReferencingFileConverter.FileConversionException("Profile not in the conversionlist"); } else { Date date = astring.length > 1 ? NameReferencingFileConverter.b(astring[1], (Date) null) : null; @@ -112,7 +112,7 @@ public class NameReferencingFileConverter { } public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { - NameReferencingFileConverter.e.warn("Could not lookup user banlist entry for {}", gameprofile.getName(), exception); + NameReferencingFileConverter.LOGGER.warn("Could not lookup user banlist entry for {}", gameprofile.getName(), exception); if (!(exception instanceof ProfileNotFoundException)) { throw new NameReferencingFileConverter.FileConversionException("Could not request user " + gameprofile.getName() + " from backend systems", exception); } @@ -124,10 +124,10 @@ public class NameReferencingFileConverter { c(NameReferencingFileConverter.b); return true; } catch (IOException ioexception) { - NameReferencingFileConverter.e.warn("Could not read old user banlist to convert it!", ioexception); + NameReferencingFileConverter.LOGGER.warn("Could not read old user banlist to convert it!", ioexception); return false; } catch (NameReferencingFileConverter.FileConversionException namereferencingfileconverter_fileconversionexception) { - NameReferencingFileConverter.e.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); + NameReferencingFileConverter.LOGGER.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); return false; } } else { @@ -144,7 +144,7 @@ public class NameReferencingFileConverter { ipbanlist.load(); // CraftBukkit start - FileNotFoundException -> IOException, don't print stacktrace } catch (IOException filenotfoundexception) { - NameReferencingFileConverter.e.warn("Could not load existing file {}", ipbanlist.c().getName()); + NameReferencingFileConverter.LOGGER.warn("Could not load existing file {}", ipbanlist.c().getName()); } } @@ -169,7 +169,7 @@ public class NameReferencingFileConverter { c(NameReferencingFileConverter.a); return true; } catch (IOException ioexception) { - NameReferencingFileConverter.e.warn("Could not parse old ip banlist to convert it!", ioexception); + NameReferencingFileConverter.LOGGER.warn("Could not parse old ip banlist to convert it!", ioexception); return false; } } else { @@ -186,7 +186,7 @@ public class NameReferencingFileConverter { oplist.load(); // CraftBukkit start - FileNotFoundException -> IOException, don't print stacktrace } catch (IOException filenotfoundexception) { - NameReferencingFileConverter.e.warn("Could not load existing file {}", oplist.c().getName()); + NameReferencingFileConverter.LOGGER.warn("Could not load existing file {}", oplist.c().getName()); } } @@ -194,12 +194,12 @@ public class NameReferencingFileConverter { List list = Files.readLines(NameReferencingFileConverter.c, StandardCharsets.UTF_8); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { public void onProfileLookupSucceeded(GameProfile gameprofile) { - minecraftserver.getModernUserCache().offer(gameprofile); // Akarin + minecraftserver.getUserCache().a(gameprofile); oplist.add(new OpListEntry(gameprofile, minecraftserver.j(), false)); } public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { - NameReferencingFileConverter.e.warn("Could not lookup oplist entry for {}", gameprofile.getName(), exception); + NameReferencingFileConverter.LOGGER.warn("Could not lookup oplist entry for {}", gameprofile.getName(), exception); if (!(exception instanceof ProfileNotFoundException)) { throw new NameReferencingFileConverter.FileConversionException("Could not request user " + gameprofile.getName() + " from backend systems", exception); } @@ -211,10 +211,10 @@ public class NameReferencingFileConverter { c(NameReferencingFileConverter.c); return true; } catch (IOException ioexception) { - NameReferencingFileConverter.e.warn("Could not read old oplist to convert it!", ioexception); + NameReferencingFileConverter.LOGGER.warn("Could not read old oplist to convert it!", ioexception); return false; } catch (NameReferencingFileConverter.FileConversionException namereferencingfileconverter_fileconversionexception) { - NameReferencingFileConverter.e.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); + NameReferencingFileConverter.LOGGER.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); return false; } } else { @@ -231,7 +231,7 @@ public class NameReferencingFileConverter { whitelist.load(); // CraftBukkit start - FileNotFoundException -> IOException, don't print stacktrace } catch (IOException filenotfoundexception) { - NameReferencingFileConverter.e.warn("Could not load existing file {}", whitelist.c().getName()); + NameReferencingFileConverter.LOGGER.warn("Could not load existing file {}", whitelist.c().getName()); } } @@ -239,12 +239,12 @@ public class NameReferencingFileConverter { List list = Files.readLines(NameReferencingFileConverter.d, StandardCharsets.UTF_8); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { public void onProfileLookupSucceeded(GameProfile gameprofile) { - minecraftserver.getModernUserCache().offer(gameprofile); // Akarin + minecraftserver.getUserCache().a(gameprofile); whitelist.add(new WhiteListEntry(gameprofile)); } public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { - NameReferencingFileConverter.e.warn("Could not lookup user whitelist entry for {}", gameprofile.getName(), exception); + NameReferencingFileConverter.LOGGER.warn("Could not lookup user whitelist entry for {}", gameprofile.getName(), exception); if (!(exception instanceof ProfileNotFoundException)) { throw new NameReferencingFileConverter.FileConversionException("Could not request user " + gameprofile.getName() + " from backend systems", exception); } @@ -256,10 +256,10 @@ public class NameReferencingFileConverter { c(NameReferencingFileConverter.d); return true; } catch (IOException ioexception) { - NameReferencingFileConverter.e.warn("Could not read old whitelist to convert it!", ioexception); + NameReferencingFileConverter.LOGGER.warn("Could not read old whitelist to convert it!", ioexception); return false; } catch (NameReferencingFileConverter.FileConversionException namereferencingfileconverter_fileconversionexception) { - NameReferencingFileConverter.e.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); + NameReferencingFileConverter.LOGGER.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); return false; } } else { @@ -269,24 +269,24 @@ public class NameReferencingFileConverter { public static String a(final MinecraftServer minecraftserver, String s) { if (!UtilColor.b(s) && s.length() <= 16) { - GameProfile gameprofile = minecraftserver.getModernUserCache().peek(s); // Akarin + GameProfile gameprofile = minecraftserver.getUserCache().getProfile(s); if (gameprofile != null && gameprofile.getId() != null) { return gameprofile.getId().toString(); - } else if (!minecraftserver.H() && minecraftserver.getOnlineMode()) { + } else if (!minecraftserver.isEmbeddedServer() && minecraftserver.getOnlineMode()) { final List list = Lists.newArrayList(); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { public void onProfileLookupSucceeded(GameProfile gameprofile1) { - minecraftserver.getModernUserCache().offer(gameprofile1); // Akarin + minecraftserver.getUserCache().a(gameprofile1); list.add(gameprofile1); } public void onProfileLookupFailed(GameProfile gameprofile1, Exception exception) { - NameReferencingFileConverter.e.warn("Could not lookup user whitelist entry for {}", gameprofile1.getName(), exception); + NameReferencingFileConverter.LOGGER.warn("Could not lookup user whitelist entry for {}", gameprofile1.getName(), exception); } }; - a(minecraftserver, Lists.newArrayList(new String[] { s}), profilelookupcallback); + a(minecraftserver, Lists.newArrayList(new String[]{s}), profilelookupcallback); return !list.isEmpty() && ((GameProfile) list.get(0)).getId() != null ? ((GameProfile) list.get(0)).getId().toString() : ""; } else { return EntityHuman.a(new GameProfile((UUID) null, s)).toString(); @@ -296,8 +296,8 @@ public class NameReferencingFileConverter { } } - public static boolean a(final DedicatedServer dedicatedserver, PropertyManager propertymanager) { - final File file = d(propertymanager); + public static boolean a(final DedicatedServer dedicatedserver) { + final File file = getPlayersFolder(dedicatedserver); final File file1 = new File(file.getParentFile(), "playerdata"); final File file2 = new File(file.getParentFile(), "unknownplayers"); @@ -324,7 +324,7 @@ public class NameReferencingFileConverter { final String[] astring = (String[]) list.toArray(new String[list.size()]); ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { public void onProfileLookupSucceeded(GameProfile gameprofile) { - dedicatedserver.getModernUserCache().offer(gameprofile); // Akarin + dedicatedserver.getUserCache().a(gameprofile); UUID uuid = gameprofile.getId(); if (uuid == null) { @@ -335,7 +335,7 @@ public class NameReferencingFileConverter { } public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { - NameReferencingFileConverter.e.warn("Could not lookup user uuid for {}", gameprofile.getName(), exception); + NameReferencingFileConverter.LOGGER.warn("Could not lookup user uuid for {}", gameprofile.getName(), exception); if (exception instanceof ProfileNotFoundException) { String s2 = this.a(gameprofile); @@ -406,7 +406,7 @@ public class NameReferencingFileConverter { a(dedicatedserver, Lists.newArrayList(astring), profilelookupcallback); return true; } catch (NameReferencingFileConverter.FileConversionException namereferencingfileconverter_fileconversionexception) { - NameReferencingFileConverter.e.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); + NameReferencingFileConverter.LOGGER.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); return false; } } else { @@ -424,14 +424,14 @@ public class NameReferencingFileConverter { } } - public static boolean a(PropertyManager propertymanager) { - boolean flag = b(propertymanager); + public static boolean e(MinecraftServer minecraftserver) { + boolean flag = b(); - flag = flag && c(propertymanager); + flag = flag && f(minecraftserver); return flag; } - private static boolean b(PropertyManager propertymanager) { + private static boolean b() { boolean flag = false; if (NameReferencingFileConverter.b.exists() && NameReferencingFileConverter.b.isFile()) { @@ -459,43 +459,43 @@ public class NameReferencingFileConverter { if (!flag && !flag1 && !flag2 && !flag3) { return true; } else { - NameReferencingFileConverter.e.warn("**** FAILED TO START THE SERVER AFTER ACCOUNT CONVERSION!"); - NameReferencingFileConverter.e.warn("** please remove the following files and restart the server:"); + NameReferencingFileConverter.LOGGER.warn("**** FAILED TO START THE SERVER AFTER ACCOUNT CONVERSION!"); + NameReferencingFileConverter.LOGGER.warn("** please remove the following files and restart the server:"); if (flag) { - NameReferencingFileConverter.e.warn("* {}", NameReferencingFileConverter.b.getName()); + NameReferencingFileConverter.LOGGER.warn("* {}", NameReferencingFileConverter.b.getName()); } if (flag1) { - NameReferencingFileConverter.e.warn("* {}", NameReferencingFileConverter.a.getName()); + NameReferencingFileConverter.LOGGER.warn("* {}", NameReferencingFileConverter.a.getName()); } if (flag2) { - NameReferencingFileConverter.e.warn("* {}", NameReferencingFileConverter.c.getName()); + NameReferencingFileConverter.LOGGER.warn("* {}", NameReferencingFileConverter.c.getName()); } if (flag3) { - NameReferencingFileConverter.e.warn("* {}", NameReferencingFileConverter.d.getName()); + NameReferencingFileConverter.LOGGER.warn("* {}", NameReferencingFileConverter.d.getName()); } return false; } } - private static boolean c(PropertyManager propertymanager) { - File file = d(propertymanager); + private static boolean f(MinecraftServer minecraftserver) { + File file = getPlayersFolder(minecraftserver); if (file.exists() && file.isDirectory() && (file.list().length > 0 || !file.delete())) { - NameReferencingFileConverter.e.warn("**** DETECTED OLD PLAYER DIRECTORY IN THE WORLD SAVE"); - NameReferencingFileConverter.e.warn("**** THIS USUALLY HAPPENS WHEN THE AUTOMATIC CONVERSION FAILED IN SOME WAY"); - NameReferencingFileConverter.e.warn("** please restart the server and if the problem persists, remove the directory '{}'", file.getPath()); + NameReferencingFileConverter.LOGGER.warn("**** DETECTED OLD PLAYER DIRECTORY IN THE WORLD SAVE"); + NameReferencingFileConverter.LOGGER.warn("**** THIS USUALLY HAPPENS WHEN THE AUTOMATIC CONVERSION FAILED IN SOME WAY"); + NameReferencingFileConverter.LOGGER.warn("** please restart the server and if the problem persists, remove the directory '{}'", file.getPath()); return false; } else { return true; } } - private static File d(PropertyManager propertymanager) { - String s = propertymanager.getString("level-name", "world"); + private static File getPlayersFolder(MinecraftServer minecraftserver) { + String s = minecraftserver.getWorld(); File file = new File(MinecraftServer.getServer().server.getWorldContainer(), s); // CraftBukkit - Respect container setting return new File(file, "players"); diff --git a/src/main/java/net/minecraft/server/Navigation.java b/src/main/java/net/minecraft/server/Navigation.java new file mode 100644 index 000000000..fd1dbb108 --- /dev/null +++ b/src/main/java/net/minecraft/server/Navigation.java @@ -0,0 +1,249 @@ +package net.minecraft.server; + +import java.util.Iterator; + +public class Navigation extends NavigationAbstract { + + private boolean p; + + public Navigation(EntityInsentient entityinsentient, World world) { + super(entityinsentient, world); + } + + @Override + protected Pathfinder a(int i) { + this.o = new PathfinderNormal(); + this.o.a(true); + return new Pathfinder(this.o, i); + } + + @Override + protected boolean a() { + return this.a.onGround || this.p() || this.a.isPassenger(); + } + + @Override + protected Vec3D b() { + return new Vec3D(this.a.locX, (double) this.t(), this.a.locZ); + } + + @Override + public PathEntity a(BlockPosition blockposition, int i) { + BlockPosition blockposition1; + + if (this.b.getType(blockposition).isAir()) { + for (blockposition1 = blockposition.down(); blockposition1.getY() > 0 && this.b.getType(blockposition1).isAir(); blockposition1 = blockposition1.down()) { + ; + } + + if (blockposition1.getY() > 0) { + return super.a(blockposition1.up(), i); + } + + while (blockposition1.getY() < this.b.getBuildHeight() && this.b.getType(blockposition1).isAir()) { + blockposition1 = blockposition1.up(); + } + + blockposition = blockposition1; + } + + if (!this.b.getType(blockposition).getMaterial().isBuildable()) { + return super.a(blockposition, i); + } else { + for (blockposition1 = blockposition.up(); blockposition1.getY() < this.b.getBuildHeight() && this.b.getType(blockposition1).getMaterial().isBuildable(); blockposition1 = blockposition1.up()) { + ; + } + + return super.a(blockposition1, i); + } + } + + @Override + public PathEntity a(Entity entity, int i) { + return this.a(new BlockPosition(entity), entity, i); // Paper - Forward target entity + } + + private int t() { + if (this.a.isInWater() && this.r()) { + int i = MathHelper.floor(this.a.getBoundingBox().minY); + Block block = this.b.getType(new BlockPosition(this.a.locX, (double) i, this.a.locZ)).getBlock(); + int j = 0; + + do { + if (block != Blocks.WATER) { + return i; + } + + ++i; + block = this.b.getType(new BlockPosition(this.a.locX, (double) i, this.a.locZ)).getBlock(); + ++j; + } while (j <= 16); + + return MathHelper.floor(this.a.getBoundingBox().minY); + } else { + return MathHelper.floor(this.a.getBoundingBox().minY + 0.5D); + } + } + + @Override + protected void D_() { + super.D_(); + if (this.p) { + if (this.b.f(new BlockPosition(this.a.locX, this.a.getBoundingBox().minY + 0.5D, this.a.locZ))) { + return; + } + + for (int i = 0; i < this.c.e(); ++i) { + PathPoint pathpoint = this.c.a(i); + + if (this.b.f(new BlockPosition(pathpoint.a, pathpoint.b, pathpoint.c))) { + this.c.b(i); + return; + } + } + } + + } + + @Override + protected boolean a(Vec3D vec3d, Vec3D vec3d1, int i, int j, int k) { + int l = MathHelper.floor(vec3d.x); + int i1 = MathHelper.floor(vec3d.z); + double d0 = vec3d1.x - vec3d.x; + double d1 = vec3d1.z - vec3d.z; + double d2 = d0 * d0 + d1 * d1; + + if (d2 < 1.0E-8D) { + return false; + } else { + double d3 = 1.0D / Math.sqrt(d2); + + d0 *= d3; + d1 *= d3; + i += 2; + k += 2; + if (!this.a(l, MathHelper.floor(vec3d.y), i1, i, j, k, vec3d, d0, d1)) { + return false; + } else { + i -= 2; + k -= 2; + double d4 = 1.0D / Math.abs(d0); + double d5 = 1.0D / Math.abs(d1); + double d6 = (double) l - vec3d.x; + double d7 = (double) i1 - vec3d.z; + + if (d0 >= 0.0D) { + ++d6; + } + + if (d1 >= 0.0D) { + ++d7; + } + + d6 /= d0; + d7 /= d1; + int j1 = d0 < 0.0D ? -1 : 1; + int k1 = d1 < 0.0D ? -1 : 1; + int l1 = MathHelper.floor(vec3d1.x); + int i2 = MathHelper.floor(vec3d1.z); + int j2 = l1 - l; + int k2 = i2 - i1; + + do { + if (j2 * j1 <= 0 && k2 * k1 <= 0) { + return true; + } + + if (d6 < d7) { + d6 += d4; + l += j1; + j2 = l1 - l; + } else { + d7 += d5; + i1 += k1; + k2 = i2 - i1; + } + } while (this.a(l, MathHelper.floor(vec3d.y), i1, i, j, k, vec3d, d0, d1)); + + return false; + } + } + } + + private boolean a(int i, int j, int k, int l, int i1, int j1, Vec3D vec3d, double d0, double d1) { + int k1 = i - l / 2; + int l1 = k - j1 / 2; + + if (!this.b(k1, j, l1, l, i1, j1, vec3d, d0, d1)) { + return false; + } else { + for (int i2 = k1; i2 < k1 + l; ++i2) { + for (int j2 = l1; j2 < l1 + j1; ++j2) { + double d2 = (double) i2 + 0.5D - vec3d.x; + double d3 = (double) j2 + 0.5D - vec3d.z; + + if (d2 * d0 + d3 * d1 >= 0.0D) { + PathType pathtype = this.o.a(this.b, i2, j - 1, j2, this.a, l, i1, j1, true, true); + + if (pathtype == PathType.WATER) { + return false; + } + + if (pathtype == PathType.LAVA) { + return false; + } + + if (pathtype == PathType.OPEN) { + return false; + } + + pathtype = this.o.a(this.b, i2, j, j2, this.a, l, i1, j1, true, true); + float f = this.a.a(pathtype); + + if (f < 0.0F || f >= 8.0F) { + return false; + } + + if (pathtype == PathType.DAMAGE_FIRE || pathtype == PathType.DANGER_FIRE || pathtype == PathType.DAMAGE_OTHER) { + return false; + } + } + } + } + + return true; + } + } + + private boolean b(int i, int j, int k, int l, int i1, int j1, Vec3D vec3d, double d0, double d1) { + Iterator iterator = BlockPosition.a(new BlockPosition(i, j, k), new BlockPosition(i + l - 1, j + i1 - 1, k + j1 - 1)).iterator(); + + BlockPosition blockposition; + double d2; + double d3; + + do { + if (!iterator.hasNext()) { + return true; + } + + blockposition = (BlockPosition) iterator.next(); + d2 = (double) blockposition.getX() + 0.5D - vec3d.x; + d3 = (double) blockposition.getZ() + 0.5D - vec3d.z; + } while (d2 * d0 + d3 * d1 < 0.0D || this.b.getType(blockposition).a((IBlockAccess) this.b, blockposition, PathMode.LAND)); + + return false; + } + + public void a(boolean flag) { + this.o.b(flag); + } + + public boolean f() { + return this.o.c(); + } + + public void c(boolean flag) { + this.p = flag; + } +} diff --git a/src/main/java/net/minecraft/server/NavigationAbstract.java b/src/main/java/net/minecraft/server/NavigationAbstract.java index 659ad7dca..66e10108d 100644 --- a/src/main/java/net/minecraft/server/NavigationAbstract.java +++ b/src/main/java/net/minecraft/server/NavigationAbstract.java @@ -1,11 +1,15 @@ package net.minecraft.server; +import com.google.common.collect.ImmutableSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nullable; public abstract class NavigationAbstract { - protected EntityInsentient a; public Entity getEntity() { return a; } // Paper - OBFHELPER - protected World b; + protected final EntityInsentient a; public Entity getEntity() { return a; } // Paper - OBFHELPER + protected final World b; @Nullable protected PathEntity c; protected double d; @@ -22,9 +26,9 @@ public abstract class NavigationAbstract { protected long n; protected PathfinderAbstract o; private BlockPosition q; - private Pathfinder r; public Pathfinder getPathfinder() { return r; } // Paper - OBFHELPER + private int r; + private Pathfinder s; public Pathfinder getPathfinder() { return this.s; } // Paper - OBFHELPER - private void setWorld() { if (getPathfinder() != null && getPathfinder().getPathfinder() != null) getPathfinder().getPathfinder().world = getEntity().world; } // Paper public NavigationAbstract(EntityInsentient entityinsentient, World world) { this.g = Vec3D.a; this.h = Vec3D.a; @@ -32,33 +36,32 @@ public abstract class NavigationAbstract { this.a = entityinsentient; this.b = world; this.p = entityinsentient.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); - this.r = this.a(); - setWorld(); // Paper + this.s = this.a(MathHelper.floor(this.p.getValue() * 16.0D)); } - public BlockPosition i() { + public BlockPosition h() { return this.q; } - protected abstract Pathfinder a(); + protected abstract Pathfinder a(int i); public void a(double d0) { this.d = d0; } - public float j() { + public float i() { return (float) this.p.getValue(); } - public boolean k() { + public boolean j() { return this.m; } - public void l() { + public void k() { if (this.b.getTime() - this.n > 20L) { if (this.q != null) { this.c = null; - this.c = this.b(this.q); + this.c = this.a(this.q, this.r); this.n = this.b.getTime(); this.m = false; } @@ -69,84 +72,89 @@ public abstract class NavigationAbstract { } @Nullable - public final PathEntity calculateDestination(double d0, double d1, double d2) { return a(d0, d1, d2); } @Nullable public final PathEntity a(double d0, double d1, double d2) { // Paper - OBFHELPER - return this.b(new BlockPosition(d0, d1, d2)); + public final PathEntity calculateDestination(double d0, double d1, double d2) { return a(d0, d1, d2, 0); } public final PathEntity a(double d0, double d1, double d2, int i) { // Paper - OBFHELPER + return this.a(new BlockPosition(d0, d1, d2), i); } @Nullable - public PathEntity b(BlockPosition blockposition) { - if (!getEntity().getWorld().getWorldBorder().isInBounds(blockposition)) return null; // Paper - don't path out of world border - if (!this.b()) { + public PathEntity a(Stream stream, int i) { + return this.a((Set) stream.collect(Collectors.toSet()), 8, false, i); + } + + @Nullable + public PathEntity a(BlockPosition blockposition, int i) { + // Paper start - add target parameter + return this.a(blockposition, null, i); + } + @Nullable public PathEntity a(BlockPosition blockposition, Entity target, int i) { + return this.a(ImmutableSet.of(blockposition), target, 8, false, i); + // Paper end + } + + @Nullable + public final PathEntity calculateDestination(Entity entity) { return a(entity, 0); } public PathEntity a(Entity entity, int i) { + return this.a(ImmutableSet.of(new BlockPosition(entity)), entity, 16, true, i); // Paper + } + + @Nullable + // Paper start - Add target + protected PathEntity a(Set set, int i, boolean flag, int j) { + return this.a(set, null, i, flag, j); + } + @Nullable protected PathEntity a(Set set, Entity target, int i, boolean flag, int j) { + // Paper end + if (set.isEmpty()) { return null; - } else if (this.c != null && !this.c.b() && blockposition.equals(this.q)) { + } else if (this.a.locY < 0.0D) { + return null; + } else if (!this.a()) { + return null; + } else if (this.c != null && !this.c.b() && set.contains(this.q)) { return this.c; } else { - if (!new com.destroystokyo.paper.event.entity.EntityPathfindEvent(getEntity().getBukkitEntity(), MCUtil.toLocation(getEntity().world, blockposition), null).callEvent()) { return null; } // Paper - this.q = blockposition; - float f = this.j(); + // Paper start - Pathfind event + boolean copiedSet = false; + for (BlockPosition possibleTarget : set) { + if (!getEntity().getWorld().getWorldBorder().isInBounds(possibleTarget) || !new com.destroystokyo.paper.event.entity.EntityPathfindEvent(getEntity().getBukkitEntity(), // Paper - don't path out of world border + MCUtil.toLocation(getEntity().world, possibleTarget), target == null ? null : target.getBukkitEntity()).callEvent()) { + if (!copiedSet) { + copiedSet = true; + set = new java.util.HashSet<>(set); + } + // note: since we copy the set this remove call is safe, since we're iterating over the old copy + set.remove(possibleTarget); + if (set.isEmpty()) { + return null; + } + } + } + // Paper end + this.b.getMethodProfiler().enter("pathfind"); + float f = this.i(); + BlockPosition blockposition = flag ? (new BlockPosition(this.a)).up() : new BlockPosition(this.a); + int k = (int) (f + (float) i); + ChunkCache chunkcache = new ChunkCache(this.b, blockposition.b(-k, -k, -k), blockposition.b(k, k, k)); + PathEntity pathentity = this.s.a(chunkcache, this.a, set, f, j); - //this.b.methodProfiler.enter("pathfind"); // Akarin - BlockPosition blockposition1 = new BlockPosition(this.a); - int i = (int) (f + 8.0F); - ChunkCache chunkcache = new ChunkCache(this.b, blockposition1.a(-i, -i, -i), blockposition1.a(i, i, i), 0); - PathEntity pathentity = this.r.a(chunkcache, this.a, this.q, f); + this.b.getMethodProfiler().exit(); + if (pathentity != null && pathentity.k() != null) { + this.q = pathentity.k(); + this.r = j; + } - //this.b.methodProfiler.exit(); // Akarin return pathentity; } } - @Nullable - public PathEntity calculateDestination(Entity entity) { return a(entity); } @Nullable public PathEntity a(Entity entity) { // Paper - OBFHELPER - if (!this.b()) { - return null; - } else { - BlockPosition blockposition = new BlockPosition(entity); - if (!getEntity().getWorld().getWorldBorder().isInBounds(blockposition)) return null; // Paper - don't path out of world border - if (this.c != null && !this.c.b() && blockposition.equals(this.q)) { - return this.c; - } else { - if (!new com.destroystokyo.paper.event.entity.EntityPathfindEvent(getEntity().getBukkitEntity(), MCUtil.toLocation(entity.world, blockposition), entity.getBukkitEntity()).callEvent()) { return null; } // Paper - this.q = blockposition; - float f = this.j(); - - //this.b.methodProfiler.enter("pathfind"); // Akarin - BlockPosition blockposition1 = (new BlockPosition(this.a)).up(); - int i = (int) (f + 16.0F); - ChunkCache chunkcache = new ChunkCache(this.b, blockposition1.a(-i, -i, -i), blockposition1.a(i, i, i), 0); - PathEntity pathentity = this.r.a(chunkcache, this.a, entity, f); - - //this.b.methodProfiler.exit(); // Akarin - return pathentity; - } - } - } - public boolean a(double d0, double d1, double d2, double d3) { - return this.a(this.a(d0, d1, d2), d3); + return this.a(this.a(d0, d1, d2, 1), d3); } public boolean a(Entity entity, double d0) { - // Paper start - Pathfinding optimizations - if (this.pathfindFailures > 10 && this.c == null && MinecraftServer.currentTick < this.lastFailure + 40) { - return false; - } + PathEntity pathentity = this.a(entity, 1); - PathEntity pathentity = this.a(entity); - - if (pathentity != null && this.a(pathentity, d0)) { - this.lastFailure = 0; - this.pathfindFailures = 0; - return true; - } else { - this.pathfindFailures++; - this.lastFailure = MinecraftServer.currentTick; - return false; - } + return pathentity != null && this.a(pathentity, d0); } - private int lastFailure = 0; - private int pathfindFailures = 0; - // Paper end public boolean setDestination(@Nullable PathEntity pathentity, double speed) { return a(pathentity, speed); } // Paper - OBFHELPER public boolean a(@Nullable PathEntity pathentity, double d0) { @@ -158,12 +166,12 @@ public abstract class NavigationAbstract { this.c = pathentity; } - this.E_(); - if (this.c.d() <= 0) { + this.D_(); + if (this.c.e() <= 0) { return false; } else { this.d = d0; - Vec3D vec3d = this.c(); + Vec3D vec3d = this.b(); this.f = this.e; this.g = vec3d; @@ -171,34 +179,34 @@ public abstract class NavigationAbstract { } } } - @Nullable public PathEntity getPathEntity() { return m(); } @Nullable // Paper - OBFHELPER - public PathEntity m() { + + @Nullable public PathEntity getPathEntity() { return l(); } @Nullable // Paper - OBFHELPER + public PathEntity l() { return this.c; } - public void d() { - setWorld(); // Paper + public void c() { ++this.e; if (this.m) { - this.l(); + this.k(); } - if (!this.p()) { + if (!this.n()) { Vec3D vec3d; - if (this.b()) { - this.o(); - } else if (this.c != null && this.c.e() < this.c.d()) { - vec3d = this.c(); - Vec3D vec3d1 = this.c.a(this.a, this.c.e()); + if (this.a()) { + this.m(); + } else if (this.c != null && this.c.f() < this.c.e()) { + vec3d = this.b(); + Vec3D vec3d1 = this.c.a(this.a, this.c.f()); if (vec3d.y > vec3d1.y && !this.a.onGround && MathHelper.floor(vec3d.x) == MathHelper.floor(vec3d1.x) && MathHelper.floor(vec3d.z) == MathHelper.floor(vec3d1.z)) { - this.c.c(this.c.e() + 1); + this.c.c(this.c.f() + 1); } } - this.n(); - if (!this.p()) { + PacketDebug.a(this.b, this.a, this.c, this.l); + if (!this.n()) { vec3d = this.c.a((Entity) this.a); BlockPosition blockposition = new BlockPosition(vec3d); @@ -207,35 +215,14 @@ public abstract class NavigationAbstract { } } - protected void n() {} + protected void m() { + Vec3D vec3d = this.b(); - protected void o() { - Vec3D vec3d = this.c(); - int i = this.c.d(); + this.l = this.a.getWidth() > 0.75F ? this.a.getWidth() / 2.0F : 0.75F - this.a.getWidth() / 2.0F; + Vec3D vec3d1 = this.c.g(); - for (int j = this.c.e(); j < this.c.d(); ++j) { - if ((double) this.c.a(j).b != Math.floor(vec3d.y)) { - i = j; - break; - } - } - - this.l = this.a.width > 0.75F ? this.a.width / 2.0F : 0.75F - this.a.width / 2.0F; - Vec3D vec3d1 = this.c.f(); - - if (MathHelper.e((float) (this.a.locX - (vec3d1.x + 0.5D))) < this.l && MathHelper.e((float) (this.a.locZ - (vec3d1.z + 0.5D))) < this.l && Math.abs(this.a.locY - vec3d1.y) < 1.0D) { - this.c.c(this.c.e() + 1); - } - - int k = MathHelper.f(this.a.width); - int l = MathHelper.f(this.a.length); - int i1 = k; - - for (int j1 = i - 1; j1 >= this.c.e(); --j1) { - if (this.a(vec3d, this.c.a(this.a, j1), k, l, i1)) { - this.c.c(j1); - break; - } + if (Math.abs(this.a.locX - (vec3d1.x + 0.5D)) < (double) this.l && Math.abs(this.a.locZ - (vec3d1.z + 0.5D)) < (double) this.l && Math.abs(this.a.locY - vec3d1.y) < 1.0D) { + this.c.c(this.c.f() + 1); } this.a(vec3d); @@ -244,7 +231,7 @@ public abstract class NavigationAbstract { protected void a(Vec3D vec3d) { if (this.e - this.f > 100) { if (vec3d.distanceSquared(this.g) < 2.25D) { - this.q(); + this.o(); } this.f = this.e; @@ -252,7 +239,7 @@ public abstract class NavigationAbstract { } if (this.c != null && !this.c.b()) { - Vec3D vec3d1 = this.c.f(); + Vec3D vec3d1 = this.c.g(); if (vec3d1.equals(this.h)) { this.i += SystemUtils.getMonotonicMillis() - this.j; @@ -260,14 +247,14 @@ public abstract class NavigationAbstract { this.h = vec3d1; double d0 = vec3d.f(this.h); - this.k = this.a.cK() > 0.0F ? d0 / (double) this.a.cK() * 1000.0D : 0.0D; + this.k = this.a.db() > 0.0F ? d0 / (double) this.a.db() * 1000.0D : 0.0D; } if (this.k > 0.0D && (double) this.i > this.k * 3.0D) { this.h = Vec3D.a; this.i = 0L; this.k = 0.0D; - this.q(); + this.o(); } this.j = SystemUtils.getMonotonicMillis(); @@ -275,29 +262,28 @@ public abstract class NavigationAbstract { } - public boolean p() { + public boolean n() { return this.c == null || this.c.b(); } - public void stopPathfinding() { q(); } // Paper - OBFHELPER - public void q() { - this.pathfindFailures = 0; this.lastFailure = 0; // Paper - Pathfinding optimizations + public void stopPathfinding() { o(); } // Paper - OBFHELPER + public void o() { this.c = null; } - protected abstract Vec3D c(); + protected abstract Vec3D b(); - protected abstract boolean b(); + protected abstract boolean a(); - protected boolean r() { - return this.a.aq() || this.a.ax(); + protected boolean p() { + return this.a.av() || this.a.aD(); } - protected void E_() { + protected void D_() { if (this.c != null) { - for (int i = 0; i < this.c.d(); ++i) { + for (int i = 0; i < this.c.e(); ++i) { PathPoint pathpoint = this.c.a(i); - PathPoint pathpoint1 = i + 1 < this.c.d() ? this.c.a(i + 1) : null; + PathPoint pathpoint1 = i + 1 < this.c.e() ? this.c.a(i + 1) : null; IBlockData iblockdata = this.b.getType(new BlockPosition(pathpoint.a, pathpoint.b, pathpoint.c)); Block block = iblockdata.getBlock(); @@ -317,10 +303,10 @@ public abstract class NavigationAbstract { public boolean a(BlockPosition blockposition) { BlockPosition blockposition1 = blockposition.down(); - return this.b.getType(blockposition1).f(this.b, blockposition1); + return this.b.getType(blockposition1).g(this.b, blockposition1); } - public PathfinderAbstract s() { + public PathfinderAbstract q() { return this.o; } @@ -328,7 +314,19 @@ public abstract class NavigationAbstract { this.o.c(flag); } - public boolean t() { + public boolean r() { return this.o.e(); } + + public void b(BlockPosition blockposition) { + if (this.c != null && !this.c.b() && this.c.e() != 0) { + PathPoint pathpoint = this.c.c(); + Vec3D vec3d = new Vec3D(((double) pathpoint.a + this.a.locX) / 2.0D, ((double) pathpoint.b + this.a.locY) / 2.0D, ((double) pathpoint.c + this.a.locZ) / 2.0D); + + if (blockposition.a((IPosition) vec3d, (double) (this.c.e() - this.c.f()))) { + this.k(); + } + + } + } } diff --git a/src/main/java/net/minecraft/server/NavigationFlying.java b/src/main/java/net/minecraft/server/NavigationFlying.java new file mode 100644 index 000000000..fbf5752aa --- /dev/null +++ b/src/main/java/net/minecraft/server/NavigationFlying.java @@ -0,0 +1,140 @@ +package net.minecraft.server; + +public class NavigationFlying extends NavigationAbstract { + + public NavigationFlying(EntityInsentient entityinsentient, World world) { + super(entityinsentient, world); + } + + @Override + protected Pathfinder a(int i) { + this.o = new PathfinderFlying(); + this.o.a(true); + return new Pathfinder(this.o, i); + } + + @Override + protected boolean a() { + return this.r() && this.p() || !this.a.isPassenger(); + } + + @Override + protected Vec3D b() { + return new Vec3D(this.a.locX, this.a.locY, this.a.locZ); + } + + @Override + public PathEntity a(Entity entity, int i) { + return this.a(new BlockPosition(entity), entity, i); // Paper - Forward target entity + } + + @Override + public void c() { + ++this.e; + if (this.m) { + this.k(); + } + + if (!this.n()) { + Vec3D vec3d; + + if (this.a()) { + this.m(); + } else if (this.c != null && this.c.f() < this.c.e()) { + vec3d = this.c.a(this.a, this.c.f()); + if (MathHelper.floor(this.a.locX) == MathHelper.floor(vec3d.x) && MathHelper.floor(this.a.locY) == MathHelper.floor(vec3d.y) && MathHelper.floor(this.a.locZ) == MathHelper.floor(vec3d.z)) { + this.c.c(this.c.f() + 1); + } + } + + PacketDebug.a(this.b, this.a, this.c, this.l); + if (!this.n()) { + vec3d = this.c.a((Entity) this.a); + this.a.getControllerMove().a(vec3d.x, vec3d.y, vec3d.z, this.d); + } + } + } + + @Override + protected boolean a(Vec3D vec3d, Vec3D vec3d1, int i, int j, int k) { + int l = MathHelper.floor(vec3d.x); + int i1 = MathHelper.floor(vec3d.y); + int j1 = MathHelper.floor(vec3d.z); + double d0 = vec3d1.x - vec3d.x; + double d1 = vec3d1.y - vec3d.y; + double d2 = vec3d1.z - vec3d.z; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + + if (d3 < 1.0E-8D) { + return false; + } else { + double d4 = 1.0D / Math.sqrt(d3); + + d0 *= d4; + d1 *= d4; + d2 *= d4; + double d5 = 1.0D / Math.abs(d0); + double d6 = 1.0D / Math.abs(d1); + double d7 = 1.0D / Math.abs(d2); + double d8 = (double) l - vec3d.x; + double d9 = (double) i1 - vec3d.y; + double d10 = (double) j1 - vec3d.z; + + if (d0 >= 0.0D) { + ++d8; + } + + if (d1 >= 0.0D) { + ++d9; + } + + if (d2 >= 0.0D) { + ++d10; + } + + d8 /= d0; + d9 /= d1; + d10 /= d2; + int k1 = d0 < 0.0D ? -1 : 1; + int l1 = d1 < 0.0D ? -1 : 1; + int i2 = d2 < 0.0D ? -1 : 1; + int j2 = MathHelper.floor(vec3d1.x); + int k2 = MathHelper.floor(vec3d1.y); + int l2 = MathHelper.floor(vec3d1.z); + int i3 = j2 - l; + int j3 = k2 - i1; + int k3 = l2 - j1; + + while (i3 * k1 > 0 || j3 * l1 > 0 || k3 * i2 > 0) { + if (d8 < d10 && d8 <= d9) { + d8 += d5; + l += k1; + i3 = j2 - l; + } else if (d9 < d8 && d9 <= d10) { + d9 += d6; + i1 += l1; + j3 = k2 - i1; + } else { + d10 += d7; + j1 += i2; + k3 = l2 - j1; + } + } + + return true; + } + } + + public void a(boolean flag) { + this.o.b(flag); + } + + public void b(boolean flag) { + this.o.a(flag); + } + + @Override + public boolean a(BlockPosition blockposition) { + return this.b.getType(blockposition).a((IBlockAccess) this.b, blockposition, (Entity) this.a); + } +} diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java index 7b0a6e32a..96a785af2 100644 --- a/src/main/java/net/minecraft/server/NetworkManager.java +++ b/src/main/java/net/minecraft/server/NetworkManager.java @@ -1,17 +1,11 @@ package net.minecraft.server; -import com.google.common.collect.Lists; import com.google.common.collect.Queues; -import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ThreadFactoryBuilder; - -import io.akarin.server.core.AkarinGlobalConfig; -import io.akarin.server.core.PacketType; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelPromise; import io.netty.channel.DefaultEventLoopGroup; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.epoll.EpollEventLoopGroup; @@ -22,15 +16,8 @@ import io.netty.handler.timeout.TimeoutException; import io.netty.util.AttributeKey; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; -import io.netty.util.concurrent.PromiseNotifier; - import java.net.SocketAddress; -import java.nio.channels.Channels; -import java.util.Iterator; import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.annotation.Nullable; import javax.crypto.SecretKey; import org.apache.commons.lang3.Validate; @@ -41,7 +28,7 @@ import org.apache.logging.log4j.MarkerManager; public class NetworkManager extends SimpleChannelInboundHandler> { - private static final Logger g = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public static final Marker a = MarkerManager.getMarker("NETWORK"); public static final Marker b = MarkerManager.getMarker("NETWORK_PACKETS", NetworkManager.a); public static final AttributeKey c = AttributeKey.valueOf("protocol"); @@ -55,9 +42,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { return new DefaultEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).build()); }); private final EnumProtocolDirection h; - private final ConcurrentLinkedQueue packetQueue = new ConcurrentLinkedQueue(); private final Queue getPacketQueue() { return this.packetQueue; } // Paper - OBFHELPER // Akarin - private final Queue pendingChunkQueue = Queues.newConcurrentLinkedQueue(); // Akarin - remove packet queue - private final ReentrantReadWriteLock j = new ReentrantReadWriteLock(); + private final Queue packetQueue = Queues.newConcurrentLinkedQueue(); private final Queue getPacketQueue() { return this.packetQueue; } // Paper - OBFHELPER public Channel channel; public SocketAddress socketAddress; public void setSpoofedRemoteAddress(SocketAddress address) { this.socketAddress = address; } // Paper - OBFHELPER // Spigot Start @@ -66,15 +51,15 @@ public class NetworkManager extends SimpleChannelInboundHandler> { public boolean preparing = true; // Spigot End private PacketListener packetListener; - private IChatBaseComponent n; + private IChatBaseComponent m; + private boolean n; private boolean o; - private AtomicBoolean p = new AtomicBoolean(false); // Akarin - atomic + private int p; private int q; - private int r; + private float r; private float s; - private float t; - private int u; - private boolean v; + private int t; + private boolean u; // Paper start - NetworkClient implementation public int protocolVersion; public java.net.InetSocketAddress virtualHost; @@ -96,7 +81,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { try { this.setProtocol(EnumProtocol.HANDSHAKING); } catch (Throwable throwable) { - NetworkManager.g.fatal(throwable); + NetworkManager.LOGGER.fatal(throwable); } } @@ -104,7 +89,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { public void setProtocol(EnumProtocol enumprotocol) { this.channel.attr(NetworkManager.c).set(enumprotocol); this.channel.config().setAutoRead(true); - NetworkManager.g.debug("Enabled auto read"); + NetworkManager.LOGGER.debug("Enabled auto read"); } public void channelInactive(ChannelHandlerContext channelhandlercontext) throws Exception { @@ -122,26 +107,26 @@ public class NetworkManager extends SimpleChannelInboundHandler> { } // Paper end if (throwable instanceof SkipEncodeException) { - NetworkManager.g.debug("Skipping packet due to errors", throwable.getCause()); + NetworkManager.LOGGER.debug("Skipping packet due to errors", throwable.getCause()); } else { - boolean flag = !this.v; + boolean flag = !this.u; - this.v = true; + this.u = true; if (this.channel.isOpen()) { if (throwable instanceof TimeoutException) { - NetworkManager.g.debug("Timeout", throwable); + NetworkManager.LOGGER.debug("Timeout", throwable); this.close(new ChatMessage("disconnect.timeout", new Object[0])); } else { - ChatMessage chatmessage = new ChatMessage("disconnect.genericReason", new Object[] { "Internal Exception: " + throwable}); + ChatMessage chatmessage = new ChatMessage("disconnect.genericReason", new Object[]{"Internal Exception: " + throwable}); if (flag) { - NetworkManager.g.debug("Failed to sent packet", throwable); + NetworkManager.LOGGER.debug("Failed to sent packet", throwable); this.sendPacket(new PacketPlayOutKickDisconnect(chatmessage), (future) -> { this.close(chatmessage); }); this.stopReading(); } else { - NetworkManager.g.debug("Double fault", throwable); + NetworkManager.LOGGER.debug("Double fault", throwable); this.close(chatmessage); } } @@ -159,7 +144,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { ; } - ++this.q; + ++this.p; } } @@ -170,7 +155,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { public void setPacketListener(PacketListener packetlistener) { Validate.notNull(packetlistener, "packetListener", new Object[0]); - NetworkManager.g.debug("Set listener of {} to {}", this, packetlistener); + NetworkManager.LOGGER.debug("Set listener of {} to {}", this, packetlistener); this.packetListener = packetlistener; } @@ -178,88 +163,24 @@ public class NetworkManager extends SimpleChannelInboundHandler> { this.sendPacket(packet, (GenericFutureListener) null); } - // Akarin start - public final void sendPackets(Packet packet0, Packet packet1) { - if (this.isConnected() && this.channel.isRegistered()) { // why send packet to whom not connected? - //this.j.readLock().lock(); - //try { - // Queue new packets - this.dispatchPacket(packet0, null); - this.dispatchPacket(packet1, null); - //} finally { - // this.j.readLock().unlock(); - //} - } - } - - public final void sendPackets(Packet packet0, Packet packet1, Packet packet2) { - if (this.isConnected() && this.channel.isRegistered()) { // why send packet to whom not connected? - //this.j.readLock().lock(); - //try { - // Queue new packets - this.dispatchPacket(packet0, null); - this.dispatchPacket(packet1, null); - this.dispatchPacket(packet2, null); - //} finally { - //this.j.readLock().unlock(); - //} - } - } - - public final void sendPackets(Packet packet0, Packet packet1, Packet packet2, Packet packet3, Packet packet4, Packet packet5, Packet packet6) { - if (this.isConnected() && this.channel.isRegistered()) { // why send packet to whom not connected? - //this.j.readLock().lock(); - //try { - // Queue new packets - this.dispatchPacket(packet0, null); - this.dispatchPacket(packet1, null); - this.dispatchPacket(packet2, null); - this.dispatchPacket(packet3, null); - this.dispatchPacket(packet4, null); - this.dispatchPacket(packet5, null); - this.dispatchPacket(packet6, null); - //} finally { - //this.j.readLock().unlock(); - //} - } - } - // Akarin end public void sendPacket(Packet packet, @Nullable GenericFutureListener> genericfuturelistener) { - if (this.isConnected() && this.channel.isRegistered() /*&& this.sendPacketQueue() && !(packet instanceof PacketPlayOutMapChunk && !((PacketPlayOutMapChunk) packet).isReady())*/) { // Paper - Async-Anti-Xray - Add chunk packets which are not ready or all packets if the packet queue contains chunk packets which are not ready to the packet queue and send the packets later in the right order // Akarin + if (this.isConnected() && this.sendPacketQueue() && !(packet instanceof PacketPlayOutMapChunk && !((PacketPlayOutMapChunk) packet).isReady())) { // Paper - Async-Anti-Xray - Add chunk packets which are not ready or all packets if the packet queue contains chunk packets which are not ready to the packet queue and send the packets later in the right order //this.o(); // Paper - Async-Anti-Xray - Move to if statement (this.sendPacketQueue()) - // Akarin start - //this.j.readLock().lock(); - //try { - // Dispatch or queue new packets - this.dispatchPacket(packet, genericfuturelistener); - //} finally { - // this.j.readLock().unlock(); - //} - } else if (false) { - // Akarin end - this.j.writeLock().lock(); - - try { - this.packetQueue.add(new NetworkManager.QueuedPacket(packet, genericfuturelistener)); - } finally { - this.j.writeLock().unlock(); - } + this.b(packet, genericfuturelistener); + } else { + this.packetQueue.add(new NetworkManager.QueuedPacket(packet, genericfuturelistener)); } } - // Akarin start - private final void dispatchPacket(Packet packet, @Nullable GenericFutureListener> genericFutureListener) { this.b(packet, genericFutureListener); } // Paper - OBFHELPER - private final void b(Packet packet, @Nullable GenericFutureListener> genericfuturelistener) { - if (!packet.canDispatchImmediately()) - this.pendingChunkQueue.add((PacketPlayOutMapChunk) packet); - // Akarin end + private void dispatchPacket(Packet packet, @Nullable GenericFutureListener> genericFutureListener) { this.b(packet, genericFutureListener); } // Paper - OBFHELPER + private void b(Packet packet, @Nullable GenericFutureListener> genericfuturelistener) { EnumProtocol enumprotocol = EnumProtocol.a(packet); EnumProtocol enumprotocol1 = (EnumProtocol) this.channel.attr(NetworkManager.c).get(); - //++this.r; // Akarin - unused + ++this.q; if (enumprotocol1 != enumprotocol) { - NetworkManager.g.debug("Disabled auto read"); + NetworkManager.LOGGER.debug("Disabled auto read"); this.channel.config().setAutoRead(false); } @@ -292,39 +213,23 @@ public class NetworkManager extends SimpleChannelInboundHandler> { } // Paper start - if (AkarinGlobalConfig.allowExcessiveSigns) { // Akarin java.util.List extraPackets = packet.getExtraPackets(); if (extraPackets != null && !extraPackets.isEmpty()) { for (Packet extraPacket : extraPackets) { this.dispatchPacket(extraPacket, genericfuturelistener); } } - } // Akarin // Paper end } // Paper start - Async-Anti-Xray - Stop dispatching further packets and return false if the peeked packet is a chunk packet which is not ready - public boolean sendPacketQueue() { return this.o(); } // OBFHELPER // void -> boolean // Akarin - public + private boolean sendPacketQueue() { return this.o(); } // OBFHELPER // void -> boolean private boolean o() { // void -> boolean - if (this.channel != null && this.channel.isOpen() && this.channel.isRegistered() && !this.pendingChunkQueue.isEmpty()) { - // Akarin start - Iterator iterator = this.pendingChunkQueue.iterator(); - while (iterator.hasNext()) { - PacketPlayOutMapChunk packet = iterator.next(); - if (packet.isReady()) { - this.dispatchPacket(packet, null); - iterator.remove(); - } - } - /* - if (this.packetQueue.isEmpty()) { // return if the packet queue is empty so that the write lock by Anti-Xray doesn't affect the vanilla performance at all - return true; - } + if (this.channel != null && this.channel.isOpen()) { + Queue queue = this.packetQueue; - this.j.writeLock().lock(); // readLock -> writeLock (because of race condition between peek and poll) - - try { + synchronized (this.packetQueue) { while (!this.packetQueue.isEmpty()) { NetworkManager.QueuedPacket networkmanager_queuedpacket = (NetworkManager.QueuedPacket) this.getPacketQueue().peek(); // poll -> peek @@ -337,12 +242,8 @@ public class NetworkManager extends SimpleChannelInboundHandler> { } } } - } finally { - this.j.writeLock().unlock(); // readLock -> writeLock (because of race condition between peek and poll) - } - */ - // Akarin end + } } return true; // Return true if all packets were dispatched @@ -350,20 +251,24 @@ public class NetworkManager extends SimpleChannelInboundHandler> { // Paper end public void a() { - //this.o(); // Akarin - move to scheduler - if (this.packetListener instanceof ITickable) { - ((ITickable) this.packetListener).tick(); + this.o(); + if (this.packetListener instanceof LoginListener) { + ((LoginListener) this.packetListener).tick(); + } + + if (this.packetListener instanceof PlayerConnection) { + ((PlayerConnection) this.packetListener).tick(); } if (this.channel != null) { if (enableExplicitFlush) this.channel.eventLoop().execute(() -> this.channel.flush()); // Paper - we don't need to explicit flush here, but allow opt in incase issues are found to a better version } - if (this.u++ % 20 == 0) { - this.t = this.t * 0.75F + (float) this.r * 0.25F; + if (this.t++ % 20 == 0) { this.s = this.s * 0.75F + (float) this.q * 0.25F; - this.r = 0; + this.r = this.r * 0.75F + (float) this.p * 0.25F; this.q = 0; + this.p = 0; } } @@ -378,7 +283,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { // Spigot End if (this.channel.isOpen()) { this.channel.close(); // We can't wait as this may be called from an event loop. - this.n = ichatbasecomponent; + this.m = ichatbasecomponent; } } @@ -388,7 +293,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { } public void a(SecretKey secretkey) { - this.o = true; + this.n = true; this.channel.pipeline().addBefore("splitter", "decrypt", new PacketDecrypter(MinecraftEncryption.a(2, secretkey))); this.channel.pipeline().addBefore("prepender", "encrypt", new PacketEncrypter(MinecraftEncryption.a(1, secretkey))); } @@ -407,7 +312,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { @Nullable public IChatBaseComponent j() { - return this.n; + return this.m; } public void stopReading() { @@ -441,10 +346,10 @@ public class NetworkManager extends SimpleChannelInboundHandler> { public void handleDisconnection() { if (this.channel != null && !this.channel.isOpen()) { - if (!this.p.compareAndSet(false, true)) { // Akarin - //NetworkManager.g.warn("handleDisconnection() called twice"); // Akarin + if (this.o) { + NetworkManager.LOGGER.warn("handleDisconnection() called twice"); } else { - //this.p = true; // Akarin + this.o = true; if (this.j() != null) { this.i().a(this.j()); } else if (this.i() != null) { diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java new file mode 100644 index 000000000..53a290e8b --- /dev/null +++ b/src/main/java/net/minecraft/server/NextTickListEntry.java @@ -0,0 +1,60 @@ +package net.minecraft.server; + +import java.util.Comparator; + +public class NextTickListEntry { + + private static final java.util.concurrent.atomic.AtomicLong COUNTER = new java.util.concurrent.atomic.AtomicLong(); // Paper - async chunk loading + private final T e; + public final BlockPosition a; + public final long b; + public final TickListPriority c; + private final long f; + + public NextTickListEntry(BlockPosition blockposition, T t0) { + this(blockposition, t0, 0L, TickListPriority.NORMAL); + } + + public NextTickListEntry(BlockPosition blockposition, T t0, long i, TickListPriority ticklistpriority) { + this.f = (long) (NextTickListEntry.COUNTER.getAndIncrement()); // Paper - async chunk loading + this.a = blockposition.immutableCopy(); + this.e = t0; + this.b = i; + this.c = ticklistpriority; + } + + public boolean equals(Object object) { + if (!(object instanceof NextTickListEntry)) { + return false; + } else { + NextTickListEntry nextticklistentry = (NextTickListEntry) object; + + return this.a.equals(nextticklistentry.a) && this.e == nextticklistentry.e; + } + } + + public int hashCode() { + return this.a.hashCode(); + } + + public static Comparator> a() { + return (nextticklistentry, nextticklistentry1) -> { + int i = Long.compare(nextticklistentry.b, nextticklistentry1.b); + + if (i != 0) { + return i; + } else { + i = nextticklistentry.c.compareTo(nextticklistentry1.c); + return i != 0 ? i : Long.compare(nextticklistentry.f, nextticklistentry1.f); + } + }; + } + + public String toString() { + return this.e + ": " + this.a + ", " + this.b + ", " + this.c + ", " + this.f; + } + + public T b() { + return this.e; + } +} diff --git a/src/main/java/net/minecraft/server/NibbleArray.java b/src/main/java/net/minecraft/server/NibbleArray.java index 79c5bc429..eb2c06155 100644 --- a/src/main/java/net/minecraft/server/NibbleArray.java +++ b/src/main/java/net/minecraft/server/NibbleArray.java @@ -1,12 +1,13 @@ package net.minecraft.server; +import javax.annotation.Nullable; + public class NibbleArray { - private final byte[] a; + @Nullable + protected byte[] a; - public NibbleArray() { - this.a = new byte[2048]; - } + public NibbleArray() {} public NibbleArray(byte[] abyte) { this.a = abyte; @@ -15,26 +16,38 @@ public class NibbleArray { } } + protected NibbleArray(int i) { + this.a = new byte[i]; + } + public int a(int i, int j, int k) { - return this.a(this.b(i, j, k)); + return this.b(this.b(i, j, k)); } public void a(int i, int j, int k, int l) { this.a(this.b(i, j, k), l); } - private int b(int i, int j, int k) { + protected int b(int i, int j, int k) { return j << 8 | k << 4 | i; } - public int a(int i) { - int j = this.c(i); + public int b(int i) { // PAIL: private -> public + if (this.a == null) { + return 0; + } else { + int j = this.d(i); - return this.a[j] >> ((i & 1) << 2) & 15; // Spigot + return this.a[j] >> ((i & 1) << 2) & 15; // Spigot + } } - public void a(int i, int j) { - int k = this.c(i); + public void a(int i, int j) { // PAIL: private -> public + if (this.a == null) { + this.a = new byte[2048]; + } + + int k = this.d(i); // Spigot start int shift = (i & 1) << 2; @@ -42,15 +55,45 @@ public class NibbleArray { // Spigot end } - private boolean b(int i) { + private boolean c(int i) { return (i & 1) == 0; } - private int c(int i) { + private int d(int i) { return i >> 1; } public byte[] asBytes() { + if (this.a == null) { + this.a = new byte[2048]; + } + return this.a; } + + public NibbleArray copy() { return this.b(); } // Paper - OBFHELPER + public NibbleArray b() { + return this.a == null ? new NibbleArray() : new NibbleArray((byte[]) this.a.clone()); + } + + public String toString() { + StringBuilder stringbuilder = new StringBuilder(); + + for (int i = 0; i < 4096; ++i) { + stringbuilder.append(Integer.toHexString(this.b(i))); + if ((i & 15) == 15) { + stringbuilder.append("\n"); + } + + if ((i & 255) == 255) { + stringbuilder.append("\n"); + } + } + + return stringbuilder.toString(); + } + + public boolean c() { + return this.a == null; + } } diff --git a/src/main/java/net/minecraft/server/OpList.java b/src/main/java/net/minecraft/server/OpList.java deleted file mode 100644 index d037fe5bc..000000000 --- a/src/main/java/net/minecraft/server/OpList.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import com.google.gson.JsonObject; -import com.mojang.authlib.GameProfile; -import java.io.File; -import java.util.Iterator; - -import org.bukkit.Bukkit; - -public class OpList extends JsonList { - - public OpList(File file) { - super(file); - } - - protected JsonListEntry a(JsonObject jsonobject) { - return new OpListEntry(jsonobject); - } - - public String[] getEntries() { - String[] astring = new String[this.e().size()]; - int i = 0; - - JsonListEntry jsonlistentry; - - for (Iterator iterator = this.e().iterator(); iterator.hasNext(); astring[i++] = ((GameProfile) jsonlistentry.getKey()).getName()) { - jsonlistentry = (JsonListEntry) iterator.next(); - } - - return astring; - } - - public boolean b(GameProfile gameprofile) { - OpListEntry oplistentry = (OpListEntry) this.get(gameprofile); - - return oplistentry != null ? oplistentry.b() : false; - } - - protected String a(GameProfile gameprofile) { - return AkarinUserCache.isOnlineMode() ? gameprofile.getId().toString() : gameprofile.getName(); // Akarin - } -} diff --git a/src/main/java/net/minecraft/server/Packet.java b/src/main/java/net/minecraft/server/Packet.java index 09b6d882b..8d0965a05 100644 --- a/src/main/java/net/minecraft/server/Packet.java +++ b/src/main/java/net/minecraft/server/Packet.java @@ -20,14 +20,4 @@ public interface Packet { default boolean a() { return false; } - - // Akarin start - public default io.akarin.server.core.PacketType getType() { - return io.akarin.server.core.PacketType.UNKNOWN; - } - - public default boolean canDispatchImmediately() { - return true; - } - // Akarin end } diff --git a/src/main/java/net/minecraft/server/PacketDataSerializer.java b/src/main/java/net/minecraft/server/PacketDataSerializer.java index 621aad150..dac560c63 100644 --- a/src/main/java/net/minecraft/server/PacketDataSerializer.java +++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java @@ -55,7 +55,7 @@ public class PacketDataSerializer extends ByteBuf { } public byte[] b(int i) { - int j = this.g(); + int j = this.i(); if (j > i) { throw new DecoderException("ByteArray with size " + j + " is bigger than allowed " + i); @@ -86,7 +86,7 @@ public class PacketDataSerializer extends ByteBuf { } public int[] c(int i) { - int j = this.g(); + int j = this.i(); if (j > i) { throw new DecoderException("VarIntArray with size " + j + " is bigger than allowed " + i); @@ -94,7 +94,7 @@ public class PacketDataSerializer extends ByteBuf { int[] aint = new int[j]; for (int k = 0; k < aint.length; ++k) { - aint[k] = this.g(); + aint[k] = this.i(); } return aint; @@ -124,7 +124,7 @@ public class PacketDataSerializer extends ByteBuf { return this; } - public IChatBaseComponent f() { + public IChatBaseComponent h() { return IChatBaseComponent.ChatSerializer.a(this.e(262144)); } @@ -133,15 +133,15 @@ public class PacketDataSerializer extends ByteBuf { } public > T a(Class oclass) { - return ((T[]) oclass.getEnumConstants())[this.g()]; // CraftBukkit - fix decompile error + return ((T[]) oclass.getEnumConstants())[this.i()]; // CraftBukkit - fix decompile error } public PacketDataSerializer a(Enum oenum) { return this.d(oenum.ordinal()); } - public int readVarInt() { return this.g(); } // Paper - OBFHELPER - public int g() { + public int readVarInt() { return i(); } // Paper - OBFHELPER + public int i() { int i = 0; int j = 0; @@ -158,7 +158,7 @@ public class PacketDataSerializer extends ByteBuf { return i; } - public long h() { + public long j() { long i = 0L; int j = 0; @@ -181,8 +181,8 @@ public class PacketDataSerializer extends ByteBuf { return this; } - public UUID readUUID() { return this.i(); } // Paper - OBFHELPER - public UUID i() { + public UUID readUUID() { return k(); } // Paper - OBFHELPER + public UUID k() { return new UUID(this.readLong(), this.readLong()); } @@ -221,7 +221,7 @@ public class PacketDataSerializer extends ByteBuf { } @Nullable - public NBTTagCompound j() { + public NBTTagCompound l() { int i = this.readerIndex(); byte b0 = this.readByte(); @@ -249,7 +249,7 @@ public class PacketDataSerializer extends ByteBuf { this.writeByte(itemstack.getCount()); NBTTagCompound nbttagcompound = null; - if (item.usesDurability() || item.n()) { + if (item.usesDurability() || item.m()) { // Spigot start - filter itemstack = itemstack.cloneItemStack(); CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); @@ -272,15 +272,15 @@ public class PacketDataSerializer extends ByteBuf { return this; } - public ItemStack k() { + public ItemStack m() { if (!this.readBoolean()) { return ItemStack.a; } else { - int i = this.g(); + int i = this.i(); byte b0 = this.readByte(); ItemStack itemstack = new ItemStack(Item.getById(i), b0); - itemstack.setTag(this.j()); + itemstack.setTag(this.l()); // CraftBukkit start if (itemstack.getTag() != null) { // Paper start - Fix skulls of same owner - restore orig ID since we changed it on send to client @@ -302,7 +302,7 @@ public class PacketDataSerializer extends ByteBuf { public String readUTF(int maxLength) { return this.e(maxLength); } // Paper - OBFHELPER public String e(int i) { - int j = this.g(); + int j = this.i(); if (j > i * 4) { throw new DecoderException("The received encoded string buffer length is longer than maximum allowed (" + j + " > " + i * 4 + ")"); @@ -336,7 +336,7 @@ public class PacketDataSerializer extends ByteBuf { } } - public MinecraftKey l() { + public MinecraftKey o() { return new MinecraftKey(this.e(32767)); } @@ -345,7 +345,7 @@ public class PacketDataSerializer extends ByteBuf { return this; } - public Date m() { + public Date p() { return new Date(this.readLong()); } @@ -354,6 +354,30 @@ public class PacketDataSerializer extends ByteBuf { return this; } + public MovingObjectPositionBlock q() { + BlockPosition blockposition = this.e(); + EnumDirection enumdirection = (EnumDirection) this.a(EnumDirection.class); + float f = this.readFloat(); + float f1 = this.readFloat(); + float f2 = this.readFloat(); + boolean flag = this.readBoolean(); + + return new MovingObjectPositionBlock(new Vec3D((double) ((float) blockposition.getX() + f), (double) ((float) blockposition.getY() + f1), (double) ((float) blockposition.getZ() + f2)), enumdirection, blockposition, flag); + } + + public void a(MovingObjectPositionBlock movingobjectpositionblock) { + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition(); + + this.a(blockposition); + this.a((Enum) movingobjectpositionblock.getDirection()); + Vec3D vec3d = movingobjectpositionblock.getPos(); + + this.writeFloat((float) (vec3d.x - (double) blockposition.getX())); + this.writeFloat((float) (vec3d.y - (double) blockposition.getY())); + this.writeFloat((float) (vec3d.z - (double) blockposition.getZ())); + this.writeBoolean(movingobjectpositionblock.d()); + } + public int capacity() { return this.a.capacity(); } diff --git a/src/main/java/net/minecraft/server/PacketEncoder.java b/src/main/java/net/minecraft/server/PacketEncoder.java index 4f7bc186a..b0cfef52c 100644 --- a/src/main/java/net/minecraft/server/PacketEncoder.java +++ b/src/main/java/net/minecraft/server/PacketEncoder.java @@ -11,7 +11,7 @@ import org.apache.logging.log4j.MarkerManager; public class PacketEncoder extends MessageToByteEncoder> { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final Marker b = MarkerManager.getMarker("PACKET_SENT", NetworkManager.b); private final EnumProtocolDirection c; @@ -27,8 +27,8 @@ public class PacketEncoder extends MessageToByteEncoder> { } else { Integer integer = enumprotocol.a(this.c, packet); - if (PacketEncoder.a.isDebugEnabled()) { - PacketEncoder.a.debug(PacketEncoder.b, "OUT: [{}:{}] {}", channelhandlercontext.channel().attr(NetworkManager.c).get(), integer, packet.getClass().getName()); + if (PacketEncoder.LOGGER.isDebugEnabled()) { + PacketEncoder.LOGGER.debug(PacketEncoder.b, "OUT: [{}:{}] {}", channelhandlercontext.channel().attr(NetworkManager.c).get(), integer, packet.getClass().getName()); } if (integer == null) { @@ -41,7 +41,7 @@ public class PacketEncoder extends MessageToByteEncoder> { try { packet.b(packetdataserializer); } catch (Throwable throwable) { - PacketEncoder.a.error(throwable); + PacketEncoder.LOGGER.error(throwable); throwable.printStackTrace(); // Paper - WHAT WAS IT? WHO DID THIS TO YOU? WHAT DID YOU SEE? if (packet.a()) { throw new SkipEncodeException(throwable); diff --git a/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java b/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java index f1a3be69d..8545146fb 100644 --- a/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java +++ b/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java @@ -11,13 +11,15 @@ public class PacketHandshakingInSetProtocol implements Packet public PacketLoginInCustomPayload() {} + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { - this.a = packetdataserializer.g(); + this.a = packetdataserializer.i(); if (packetdataserializer.readBoolean()) { int i = packetdataserializer.readableBytes(); @@ -25,6 +26,7 @@ public class PacketLoginInCustomPayload implements Packet } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.d(this.a); if (this.b != null) { diff --git a/src/main/java/net/minecraft/server/PacketLoginOutCustomPayload.java b/src/main/java/net/minecraft/server/PacketLoginOutCustomPayload.java index 23c96f44b..7eb230f1b 100644 --- a/src/main/java/net/minecraft/server/PacketLoginOutCustomPayload.java +++ b/src/main/java/net/minecraft/server/PacketLoginOutCustomPayload.java @@ -18,9 +18,10 @@ public class PacketLoginOutCustomPayload implements Packet= 0 && i <= 1048576) { @@ -30,6 +31,7 @@ public class PacketLoginOutCustomPayload implements Packet { this.a = enumhand; } + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { this.timestamp = System.currentTimeMillis(); // Spigot this.a = (EnumHand) packetdataserializer.a(EnumHand.class); } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.a((Enum) this.a); } diff --git a/src/main/java/net/minecraft/server/PacketPlayInChat.java b/src/main/java/net/minecraft/server/PacketPlayInChat.java index c6dbfe302..b2ca841b4 100644 --- a/src/main/java/net/minecraft/server/PacketPlayInChat.java +++ b/src/main/java/net/minecraft/server/PacketPlayInChat.java @@ -16,10 +16,12 @@ public class PacketPlayInChat implements Packet { this.a = s; } + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { this.a = packetdataserializer.e(256); } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.a(this.a); } diff --git a/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java b/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java index 4dfb6c021..03f4e32ed 100644 --- a/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java +++ b/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java @@ -18,10 +18,12 @@ public class PacketPlayInCloseWindow implements Packet { packetlistenerplayin.a(this); } + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { this.id = packetdataserializer.readByte(); } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.writeByte(this.id); } diff --git a/src/main/java/net/minecraft/server/PacketPlayInUseEntity.java b/src/main/java/net/minecraft/server/PacketPlayInUseEntity.java index 8711462e1..3f7697b39 100644 --- a/src/main/java/net/minecraft/server/PacketPlayInUseEntity.java +++ b/src/main/java/net/minecraft/server/PacketPlayInUseEntity.java @@ -17,8 +17,9 @@ public class PacketPlayInUseEntity implements Packet { this.action = PacketPlayInUseEntity.EnumEntityUseAction.ATTACK; } + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { - this.a = packetdataserializer.g(); + this.a = packetdataserializer.i(); this.action = (PacketPlayInUseEntity.EnumEntityUseAction) packetdataserializer.a(PacketPlayInUseEntity.EnumEntityUseAction.class); if (this.action == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) { this.c = new Vec3D((double) packetdataserializer.readFloat(), (double) packetdataserializer.readFloat(), (double) packetdataserializer.readFloat()); @@ -30,6 +31,7 @@ public class PacketPlayInUseEntity implements Packet { } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.d(this.a); packetdataserializer.a((Enum) this.action); diff --git a/src/main/java/net/minecraft/server/PacketPlayInUseItem.java b/src/main/java/net/minecraft/server/PacketPlayInUseItem.java index ced2336fe..5941c3a5e 100644 --- a/src/main/java/net/minecraft/server/PacketPlayInUseItem.java +++ b/src/main/java/net/minecraft/server/PacketPlayInUseItem.java @@ -4,60 +4,34 @@ import java.io.IOException; public class PacketPlayInUseItem implements Packet { - private BlockPosition a; - private EnumDirection b; - private EnumHand c; - private float d; - private float e; - private float f; + private MovingObjectPositionBlock a; + private EnumHand b; public long timestamp; public PacketPlayInUseItem() {} + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { this.timestamp = System.currentTimeMillis(); // Spigot - this.a = packetdataserializer.e(); - this.b = (EnumDirection) packetdataserializer.a(EnumDirection.class); - this.c = (EnumHand) packetdataserializer.a(EnumHand.class); - this.d = packetdataserializer.readFloat(); - this.e = packetdataserializer.readFloat(); - this.f = packetdataserializer.readFloat(); + this.b = (EnumHand) packetdataserializer.a(EnumHand.class); + this.a = packetdataserializer.q(); } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { - packetdataserializer.a(this.a); packetdataserializer.a((Enum) this.b); - packetdataserializer.a((Enum) this.c); - packetdataserializer.writeFloat(this.d); - packetdataserializer.writeFloat(this.e); - packetdataserializer.writeFloat(this.f); + packetdataserializer.a(this.a); } public void a(PacketListenerPlayIn packetlistenerplayin) { packetlistenerplayin.a(this); } - public BlockPosition b() { - return this.a; - } - - public EnumDirection c() { + public EnumHand b() { return this.b; } - public EnumHand d() { - return this.c; - } - - public float e() { - return this.d; - } - - public float f() { - return this.e; - } - - public float g() { - return this.f; + public MovingObjectPositionBlock c() { + return this.a; } } diff --git a/src/main/java/net/minecraft/server/PacketPlayOutChat.java b/src/main/java/net/minecraft/server/PacketPlayOutChat.java index 6acd41f0a..f7b2095bb 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutChat.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutChat.java @@ -19,11 +19,13 @@ public class PacketPlayOutChat implements Packet { this.b = chatmessagetype; } + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { - this.a = packetdataserializer.f(); + this.a = packetdataserializer.h(); this.b = ChatMessageType.a(packetdataserializer.readByte()); } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { // Spigot start if (components != null) { @@ -54,13 +56,8 @@ public class PacketPlayOutChat implements Packet { return this.b; } + @Override public boolean a() { return true; } - // Akarin start - @Override - public io.akarin.server.core.PacketType getType() { - return io.akarin.server.core.PacketType.PLAY_OUT_CHAT; - } - // Akarin end } diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java index 69a8af489..483317608 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java @@ -2,12 +2,9 @@ package net.minecraft.server; import com.destroystokyo.paper.antixray.ChunkPacketInfo; // Paper - Anti-Xray import com.google.common.collect.Lists; - -import io.akarin.server.core.AkarinGlobalConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import java.io.IOException; -import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; @@ -17,68 +14,82 @@ public class PacketPlayOutMapChunk implements Packet { private int a; private int b; private int c; - private byte[] d; private byte[] getData() { return this.d; } // Paper - OBFHELPER - private List e; - private boolean f; - private volatile boolean ready = false; // Paper - Async-Anti-Xray - Ready flag for the network manager + private NBTTagCompound d; + private byte[] e; private byte[] getData() { return this.e; } // Paper - OBFHELPER + private List f; + private boolean g; + private volatile boolean ready; // Paper - Async-Anti-Xray - Ready flag for the network manager public PacketPlayOutMapChunk() { this.ready = true; // Paper - Async-Anti-Xray - Set the ready flag to true } // Paper start - private final java.util.List extraPackets = AkarinGlobalConfig.allowExcessiveSigns ? new java.util.ArrayList<>() : Collections.emptyList(); // Akarin + private final java.util.List extraPackets = new java.util.ArrayList<>(); private static final int SKIP_EXCESSIVE_SIGNS_LIMIT = Integer.getInteger("Paper.excessiveSignsLimit", 500); + + @Override public java.util.List getExtraPackets() { return extraPackets; } // Paper end public PacketPlayOutMapChunk(Chunk chunk, int i) { - ChunkPacketInfo chunkPacketInfo = chunk.world.chunkPacketBlockController.getChunkPacketInfo(this, chunk, i); // Paper - Anti-Xray - Add chunk packet info - this.a = chunk.locX; - this.b = chunk.locZ; - this.f = i == 65535; - boolean flag = chunk.getWorld().worldProvider.g(); + // Paper start - add forceLoad param + this(chunk, i, false); + } + public PacketPlayOutMapChunk(Chunk chunk, int i, boolean forceLoad) { + // Paper end + ChunkPacketInfo chunkPacketInfo = chunk.world.chunkPacketBlockController.getChunkPacketInfo(this, chunk, i, forceLoad); // Paper - Anti-Xray - Add chunk packet info + ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); - this.d = new byte[this.a(chunk, flag, i)]; + this.a = chunkcoordintpair.x; + this.b = chunkcoordintpair.z; + this.g = i == 65535; + this.d = new NBTTagCompound(); + Iterator iterator = chunk.f().iterator(); + Entry entry; + + while (iterator.hasNext()) { + entry = (Entry) iterator.next(); + if (((HeightMap.Type) entry.getKey()).b()) { + this.d.set(((HeightMap.Type) entry.getKey()).a(), new NBTTagLongArray(((HeightMap) entry.getValue()).a())); + } + } + + this.e = new byte[this.a(chunk, i)]; // Paper start - Anti-Xray - Add chunk packet info if (chunkPacketInfo != null) { chunkPacketInfo.setData(this.getData()); } // Paper end - - this.c = this.writeChunk(new PacketDataSerializer(this.h()), chunk, flag, i, chunkPacketInfo); // Paper - Anti-Xray - Add chunk packet info - this.e = Lists.newArrayList(); - Iterator iterator = chunk.getTileEntities().entrySet().iterator(); + this.c = this.writeChunk(new PacketDataSerializer(this.i()), chunk, i, chunkPacketInfo); // Paper - Anti-Xray - Add chunk packet info + this.f = Lists.newArrayList(); + iterator = chunk.getTileEntities().entrySet().iterator(); int totalSigns = 0; // Paper while (iterator.hasNext()) { - Entry entry = (Entry) iterator.next(); + entry = (Entry) iterator.next(); BlockPosition blockposition = (BlockPosition) entry.getKey(); TileEntity tileentity = (TileEntity) entry.getValue(); int j = blockposition.getY() >> 4; if (this.f() || (i & 1 << j) != 0) { // Paper start - send signs separately - if (AkarinGlobalConfig.allowExcessiveSigns) { // Akarin if (tileentity instanceof TileEntitySign) { if (SKIP_EXCESSIVE_SIGNS_LIMIT < 0 || ++totalSigns < SKIP_EXCESSIVE_SIGNS_LIMIT) { - extraPackets.add(tileentity.getUpdatePacket()); + this.extraPackets.add(tileentity.getUpdatePacket()); } continue; } - } // Akarin // Paper end - - NBTTagCompound nbttagcompound = tileentity.aa_(); + NBTTagCompound nbttagcompound = tileentity.b(); if (tileentity instanceof TileEntitySkull) { TileEntitySkull.sanitizeTileEntityUUID(nbttagcompound); } // Paper - this.e.add(nbttagcompound); + this.f.add(nbttagcompound); } } - - chunk.world.chunkPacketBlockController.modifyBlocks(this, chunkPacketInfo); // Paper - Anti-Xray - Modify blocks + chunk.world.chunkPacketBlockController.modifyBlocks(this, chunkPacketInfo, forceLoad, null); // Paper - Anti-Xray - Modify blocks } // Paper start - Async-Anti-Xray - Getter and Setter for the ready flag @@ -91,38 +102,42 @@ public class PacketPlayOutMapChunk implements Packet { } // Paper end + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { this.a = packetdataserializer.readInt(); this.b = packetdataserializer.readInt(); - this.f = packetdataserializer.readBoolean(); - this.c = packetdataserializer.g(); - int i = packetdataserializer.g(); + this.g = packetdataserializer.readBoolean(); + this.c = packetdataserializer.i(); + this.d = packetdataserializer.l(); + int i = packetdataserializer.i(); if (i > 2097152) { // Paper - if this changes, update PacketEncoder throw new RuntimeException("Chunk Packet trying to allocate too much memory on read."); } else { - this.d = new byte[i]; - packetdataserializer.readBytes(this.d); - int j = packetdataserializer.g(); + this.e = new byte[i]; + packetdataserializer.readBytes(this.e); + int j = packetdataserializer.i(); - this.e = Lists.newArrayList(); + this.f = Lists.newArrayList(); for (int k = 0; k < j; ++k) { - this.e.add(packetdataserializer.j()); + this.f.add(packetdataserializer.l()); } } } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.writeInt(this.a); packetdataserializer.writeInt(this.b); - packetdataserializer.writeBoolean(this.f); + packetdataserializer.writeBoolean(this.g); packetdataserializer.d(this.c); - packetdataserializer.d(this.d.length); - packetdataserializer.writeBytes(this.d); - packetdataserializer.d(this.e.size()); - Iterator iterator = this.e.iterator(); + packetdataserializer.a(this.d); + packetdataserializer.d(this.e.length); + packetdataserializer.writeBytes(this.e); + packetdataserializer.d(this.f.size()); + Iterator iterator = this.f.iterator(); while (iterator.hasNext()) { NBTTagCompound nbttagcompound = (NBTTagCompound) iterator.next(); @@ -136,22 +151,20 @@ public class PacketPlayOutMapChunk implements Packet { packetlistenerplayout.a(this); } - private ByteBuf h() { - ByteBuf bytebuf = Unpooled.wrappedBuffer(this.d); + private ByteBuf i() { + ByteBuf bytebuf = Unpooled.wrappedBuffer(this.e); bytebuf.writerIndex(0); return bytebuf; } - // Paper start - Anti-Xray - Support default methods - public int writeChunk(PacketDataSerializer packetDataSerializer, Chunk chunk, boolean writeSkyLightArray, int chunkSectionSelector) { return this.a(packetDataSerializer, chunk, writeSkyLightArray, chunkSectionSelector); } - public int a(PacketDataSerializer packetdataserializer, Chunk chunk, boolean flag, int i) { - return this.a(packetdataserializer, chunk, flag, i, null); + public int writeChunk(PacketDataSerializer packetDataSerializer, Chunk chunk, int chunkSectionSelector) { return this.a(packetDataSerializer, chunk, chunkSectionSelector); } // Paper - OBFHELPER + public int a(PacketDataSerializer packetdataserializer, Chunk chunk, int i) { + // Paper start - Add parameter + return this.writeChunk(packetdataserializer, chunk, i, null); } - // Paper end - - public int writeChunk(PacketDataSerializer packetDataSerializer, Chunk chunk, boolean writeSkyLightArray, int chunkSectionSelector, ChunkPacketInfo chunkPacketInfo) { return this.a(packetDataSerializer, chunk, writeSkyLightArray, chunkSectionSelector, chunkPacketInfo); } // Paper - OBFHELPER // Paper - Anti-Xray - Add chunk packet info - public int a(PacketDataSerializer packetdataserializer, Chunk chunk, boolean flag, int i, ChunkPacketInfo chunkPacketInfo) { // Paper - Anti-Xray - Add chunk packet info + public int writeChunk(PacketDataSerializer packetdataserializer, Chunk chunk, int i, ChunkPacketInfo chunkPacketInfo) { + // Paper end int j = 0; ChunkSection[] achunksection = chunk.getSections(); int k = 0; @@ -161,13 +174,10 @@ public class PacketPlayOutMapChunk implements Packet { for (l = achunksection.length; k < l; ++k) { ChunkSection chunksection = achunksection[k]; - if (chunksection != Chunk.a && (!this.f() || !chunksection.a()) && (i & 1 << k) != 0) { + if (chunksection != Chunk.a && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { j |= 1 << k; + packetdataserializer.writeShort(chunksection.nonEmptyBlockCount); // Paper - Anti-Xray - Add chunk packet info chunksection.getBlocks().writeDataPaletteBlock(packetdataserializer, chunkPacketInfo, k); // Paper - Anti-Xray - Add chunk packet info - packetdataserializer.writeBytes(chunksection.getEmittedLightArray().asBytes()); - if (flag) { - packetdataserializer.writeBytes(chunksection.getSkyLightArray().asBytes()); - } } } @@ -175,14 +185,14 @@ public class PacketPlayOutMapChunk implements Packet { BiomeBase[] abiomebase = chunk.getBiomeIndex(); for (l = 0; l < abiomebase.length; ++l) { - packetdataserializer.writeInt(IRegistry.BIOME.a(abiomebase[l])); // Paper - Decompile fix + packetdataserializer.writeInt(IRegistry.BIOME.a(abiomebase[l])); // Paper - decompile fix } } return j; } - protected int a(Chunk chunk, boolean flag, int i) { + protected int a(Chunk chunk, int i) { int j = 0; ChunkSection[] achunksection = chunk.getSections(); int k = 0; @@ -190,12 +200,8 @@ public class PacketPlayOutMapChunk implements Packet { for (int l = achunksection.length; k < l; ++k) { ChunkSection chunksection = achunksection[k]; - if (chunksection != Chunk.a && (!this.f() || !chunksection.a()) && (i & 1 << k) != 0) { - j += chunksection.getBlocks().a(); - j += chunksection.getEmittedLightArray().asBytes().length; - if (flag) { - j += chunksection.getSkyLightArray().asBytes().length; - } + if (chunksection != Chunk.a && (!this.f() || !chunksection.c()) && (i & 1 << k) != 0) { + j += chunksection.j(); } } @@ -207,17 +213,6 @@ public class PacketPlayOutMapChunk implements Packet { } public boolean f() { - return this.f; + return this.g; } - // Akarin start - @Override - public io.akarin.server.core.PacketType getType() { - return io.akarin.server.core.PacketType.PLAY_OUT_MAP_CHUNK; - } - - @Override - public boolean canDispatchImmediately() { - return this.ready; - } - // Akarin end } diff --git a/src/main/java/net/minecraft/server/PacketPlayOutScoreboardTeam.java b/src/main/java/net/minecraft/server/PacketPlayOutScoreboardTeam.java index 575e3762b..6b1a914d2 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutScoreboardTeam.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutScoreboardTeam.java @@ -64,21 +64,22 @@ public class PacketPlayOutScoreboardTeam implements Packet { - - public BlockPosition position; - - public PacketPlayOutSpawnPosition() {} - - public PacketPlayOutSpawnPosition(BlockPosition blockposition) { - this.position = blockposition; - } - - public void a(PacketDataSerializer packetdataserializer) throws IOException { - this.position = packetdataserializer.e(); - } - - public void b(PacketDataSerializer packetdataserializer) throws IOException { - packetdataserializer.a(this.position); - } - - public void a(PacketListenerPlayOut packetlistenerplayout) { - packetlistenerplayout.a(this); - } - // Akarin start - @Override - public io.akarin.server.core.PacketType getType() { - return io.akarin.server.core.PacketType.PLAY_OUT_SPAWN_POSITION; - } - // Akarin end -} diff --git a/src/main/java/net/minecraft/server/PacketPlayOutTitle.java b/src/main/java/net/minecraft/server/PacketPlayOutTitle.java index 15d62cf06..535056c64 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutTitle.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutTitle.java @@ -29,10 +29,11 @@ public class PacketPlayOutTitle implements Packet { this.e = k; } + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { this.a = (PacketPlayOutTitle.EnumTitleAction) packetdataserializer.a(PacketPlayOutTitle.EnumTitleAction.class); if (this.a == PacketPlayOutTitle.EnumTitleAction.TITLE || this.a == PacketPlayOutTitle.EnumTitleAction.SUBTITLE || this.a == PacketPlayOutTitle.EnumTitleAction.ACTIONBAR) { - this.b = packetdataserializer.f(); + this.b = packetdataserializer.h(); } if (this.a == PacketPlayOutTitle.EnumTitleAction.TIMES) { @@ -54,6 +55,7 @@ public class PacketPlayOutTitle implements Packet { } // Paper end + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.a((Enum) this.a); if (this.a == PacketPlayOutTitle.EnumTitleAction.TITLE || this.a == PacketPlayOutTitle.EnumTitleAction.SUBTITLE || this.a == PacketPlayOutTitle.EnumTitleAction.ACTIONBAR) { diff --git a/src/main/java/net/minecraft/server/PacketPlayOutUpdateTime.java b/src/main/java/net/minecraft/server/PacketPlayOutUpdateTime.java index 6413f76e7..15af5927f 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutUpdateTime.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutUpdateTime.java @@ -30,11 +30,13 @@ public class PacketPlayOutUpdateTime implements Packet { // Paper end } + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { this.a = packetdataserializer.readLong(); this.b = packetdataserializer.readLong(); } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.writeLong(this.a); packetdataserializer.writeLong(this.b); diff --git a/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java b/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java new file mode 100644 index 000000000..631234324 --- /dev/null +++ b/src/main/java/net/minecraft/server/PacketPlayOutWindowItems.java @@ -0,0 +1,63 @@ +package net.minecraft.server; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +public class PacketPlayOutWindowItems implements Packet { + + private int a; + private List b; + + //Paper start + @Override + public boolean packetTooLarge(NetworkManager manager) { + for (int i = 0 ; i < this.b.size() ; i++) { + manager.sendPacket(new PacketPlayOutSetSlot(this.a, i, this.b.get(i))); + } + return true; + } + // Paper end + public PacketPlayOutWindowItems() {} + + public PacketPlayOutWindowItems(int i, NonNullList nonnulllist) { + this.a = i; + this.b = NonNullList.a(nonnulllist.size(), ItemStack.a); + + for (int j = 0; j < this.b.size(); ++j) { + this.b.set(j, ((ItemStack) nonnulllist.get(j)).cloneItemStack()); + } + + } + + @Override + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.a = packetdataserializer.readUnsignedByte(); + short short0 = packetdataserializer.readShort(); + + this.b = NonNullList.a(short0, ItemStack.a); + + for (int i = 0; i < short0; ++i) { + this.b.set(i, packetdataserializer.m()); + } + + } + + @Override + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.writeByte(this.a); + packetdataserializer.writeShort(this.b.size()); + Iterator iterator = this.b.iterator(); + + while (iterator.hasNext()) { + ItemStack itemstack = (ItemStack) iterator.next(); + + packetdataserializer.a(itemstack); + } + + } + + public void a(PacketListenerPlayOut packetlistenerplayout) { + packetlistenerplayout.a(this); + } +} diff --git a/src/main/java/net/minecraft/server/PacketPlayOutWorldBorder.java b/src/main/java/net/minecraft/server/PacketPlayOutWorldBorder.java index c15263fea..c4310bd6b 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutWorldBorder.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutWorldBorder.java @@ -23,77 +23,79 @@ public class PacketPlayOutWorldBorder implements Packet { this.d = worldborder.getCenterZ() * (worldborder.world.worldProvider instanceof WorldProviderHell ? 8 : 1); // CraftBukkit end this.f = worldborder.getSize(); - this.e = worldborder.j(); - this.g = worldborder.i(); - this.b = worldborder.l(); + this.e = worldborder.k(); + this.g = worldborder.j(); + this.b = worldborder.m(); this.i = worldborder.getWarningDistance(); this.h = worldborder.getWarningTime(); } + @Override public void a(PacketDataSerializer packetdataserializer) throws IOException { this.a = (PacketPlayOutWorldBorder.EnumWorldBorderAction) packetdataserializer.a(PacketPlayOutWorldBorder.EnumWorldBorderAction.class); switch (this.a) { - case SET_SIZE: - this.e = packetdataserializer.readDouble(); - break; - case LERP_SIZE: - this.f = packetdataserializer.readDouble(); - this.e = packetdataserializer.readDouble(); - this.g = packetdataserializer.h(); - break; - case SET_CENTER: - this.c = packetdataserializer.readDouble(); - this.d = packetdataserializer.readDouble(); - break; - case SET_WARNING_BLOCKS: - this.i = packetdataserializer.g(); - break; - case SET_WARNING_TIME: - this.h = packetdataserializer.g(); - break; - case INITIALIZE: - this.c = packetdataserializer.readDouble(); - this.d = packetdataserializer.readDouble(); - this.f = packetdataserializer.readDouble(); - this.e = packetdataserializer.readDouble(); - this.g = packetdataserializer.h(); - this.b = packetdataserializer.g(); - this.i = packetdataserializer.g(); - this.h = packetdataserializer.g(); + case SET_SIZE: + this.e = packetdataserializer.readDouble(); + break; + case LERP_SIZE: + this.f = packetdataserializer.readDouble(); + this.e = packetdataserializer.readDouble(); + this.g = packetdataserializer.j(); + break; + case SET_CENTER: + this.c = packetdataserializer.readDouble(); + this.d = packetdataserializer.readDouble(); + break; + case SET_WARNING_BLOCKS: + this.i = packetdataserializer.i(); + break; + case SET_WARNING_TIME: + this.h = packetdataserializer.i(); + break; + case INITIALIZE: + this.c = packetdataserializer.readDouble(); + this.d = packetdataserializer.readDouble(); + this.f = packetdataserializer.readDouble(); + this.e = packetdataserializer.readDouble(); + this.g = packetdataserializer.j(); + this.b = packetdataserializer.i(); + this.i = packetdataserializer.i(); + this.h = packetdataserializer.i(); } } + @Override public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.a((Enum) this.a); switch (this.a) { - case SET_SIZE: - packetdataserializer.writeDouble(this.e); - break; - case LERP_SIZE: - packetdataserializer.writeDouble(this.f); - packetdataserializer.writeDouble(this.e); - packetdataserializer.b(this.g); - break; - case SET_CENTER: - packetdataserializer.writeDouble(this.c); - packetdataserializer.writeDouble(this.d); - break; - case SET_WARNING_BLOCKS: - packetdataserializer.d(this.i); - break; - case SET_WARNING_TIME: - packetdataserializer.d(this.h); - break; - case INITIALIZE: - packetdataserializer.writeDouble(this.c); - packetdataserializer.writeDouble(this.d); - packetdataserializer.writeDouble(this.f); - packetdataserializer.writeDouble(this.e); - packetdataserializer.b(this.g); - packetdataserializer.d(this.b); - packetdataserializer.d(this.i); - packetdataserializer.d(this.h); + case SET_SIZE: + packetdataserializer.writeDouble(this.e); + break; + case LERP_SIZE: + packetdataserializer.writeDouble(this.f); + packetdataserializer.writeDouble(this.e); + packetdataserializer.b(this.g); + break; + case SET_CENTER: + packetdataserializer.writeDouble(this.c); + packetdataserializer.writeDouble(this.d); + break; + case SET_WARNING_BLOCKS: + packetdataserializer.d(this.i); + break; + case SET_WARNING_TIME: + packetdataserializer.d(this.h); + break; + case INITIALIZE: + packetdataserializer.writeDouble(this.c); + packetdataserializer.writeDouble(this.d); + packetdataserializer.writeDouble(this.f); + packetdataserializer.writeDouble(this.e); + packetdataserializer.b(this.g); + packetdataserializer.d(this.b); + packetdataserializer.d(this.i); + packetdataserializer.d(this.h); } } diff --git a/src/main/java/net/minecraft/server/PacketStatusListener.java b/src/main/java/net/minecraft/server/PacketStatusListener.java index 8aa121e2f..295c9ac22 100644 --- a/src/main/java/net/minecraft/server/PacketStatusListener.java +++ b/src/main/java/net/minecraft/server/PacketStatusListener.java @@ -23,8 +23,15 @@ public class PacketStatusListener implements PacketStatusInListener { this.networkManager = networkmanager; } + @Override public void a(IChatBaseComponent ichatbasecomponent) {} + @Override + public NetworkManager a() { + return this.networkManager; + } + + @Override public void a(PacketStatusInStart packetstatusinstart) { if (this.d) { this.networkManager.close(PacketStatusListener.a); @@ -123,7 +130,7 @@ public class PacketStatusListener implements PacketStatusInListener { ping.setFavicon(event.icon.value); ping.setMOTD(new ChatComponentText(event.getMotd())); ping.setPlayerSample(playerSample); - int version = minecraftServer.getServerPing().getServerData().getProtocolVersion(); + int version = SharedConstants.a().getProtocolVersion(); ping.setServerInfo(new ServerPing.ServerData(minecraftServer.getServerModName() + " " + minecraftServer.getVersion(), version)); this.networkManager.sendPacket(new PacketStatusOutServerInfo(ping)); @@ -134,6 +141,7 @@ public class PacketStatusListener implements PacketStatusInListener { // CraftBukkit end } + @Override public void a(PacketStatusInPing packetstatusinping) { this.networkManager.sendPacket(new PacketStatusOutPong(packetstatusinping.b())); this.networkManager.close(PacketStatusListener.a); diff --git a/src/main/java/net/minecraft/server/PaperAsyncChunkProvider.java b/src/main/java/net/minecraft/server/PaperAsyncChunkProvider.java deleted file mode 100644 index 851756d65..000000000 --- a/src/main/java/net/minecraft/server/PaperAsyncChunkProvider.java +++ /dev/null @@ -1,658 +0,0 @@ -/* - * This file is licensed under the MIT License (MIT). - * - * Copyright (c) 2018 Daniel Ennis - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package net.minecraft.server; - -import com.destroystokyo.paper.PaperConfig; -import com.destroystokyo.paper.util.PriorityQueuedExecutor; -import com.destroystokyo.paper.util.PriorityQueuedExecutor.Priority; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.generator.CustomChunkGenerator; -import org.bukkit.craftbukkit.generator.InternalChunkGenerator; - -import javax.annotation.Nullable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; - -@SuppressWarnings("unused") -public class PaperAsyncChunkProvider extends ChunkProviderServer { - - private static final int GEN_THREAD_PRIORITY = Integer.getInteger("paper.genThreadPriority", 3); - private static final int LOAD_THREAD_PRIORITY = Integer.getInteger("paper.loadThreadPriority", 4); - private static final PriorityQueuedExecutor EXECUTOR = new PriorityQueuedExecutor("PaperChunkLoader", PaperConfig.asyncChunks ? PaperConfig.asyncChunkLoadThreads : 0, LOAD_THREAD_PRIORITY); - private static final PriorityQueuedExecutor SINGLE_GEN_EXECUTOR = new PriorityQueuedExecutor("PaperChunkGenerator", PaperConfig.asyncChunks && PaperConfig.asyncChunkGeneration && !PaperConfig.asyncChunkGenThreadPerWorld ? 1 : 0, GEN_THREAD_PRIORITY); - private static final ConcurrentLinkedDeque MAIN_THREAD_QUEUE = new ConcurrentLinkedDeque<>(); - - private final PriorityQueuedExecutor generationExecutor; - //private static final PriorityQueuedExecutor generationExecutor = new PriorityQueuedExecutor("PaperChunkGen", 1); - private final Long2ObjectMap pendingChunks = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>()); - private final IAsyncTaskHandler asyncHandler; - - private final WorldServer world; - private final IChunkLoader chunkLoader; - private final MinecraftServer server; - private final boolean shouldGenSync; - - public PaperAsyncChunkProvider(WorldServer world, IChunkLoader chunkLoader, InternalChunkGenerator generator, MinecraftServer server) { - super(world, chunkLoader, generator, server); - - this.server = world.getMinecraftServer(); - this.world = world; - this.asyncHandler = server; - this.chunkLoader = chunkLoader; - String worldName = this.world.getWorld().getName(); - this.shouldGenSync = generator instanceof CustomChunkGenerator && !(((CustomChunkGenerator) generator).asyncSupported) || !PaperConfig.asyncChunkGeneration; - this.generationExecutor = PaperConfig.asyncChunkGenThreadPerWorld ? new PriorityQueuedExecutor("PaperChunkGen-" + worldName, shouldGenSync ? 0 : 1, GEN_THREAD_PRIORITY) : SINGLE_GEN_EXECUTOR; - } - - private static Priority calculatePriority(boolean isBlockingMain, boolean priority) { - if (isBlockingMain) { - return Priority.URGENT; - } - - if (priority) { - return Priority.HIGH; - } - - return Priority.NORMAL; - } - - static void stop(MinecraftServer server) { - for (WorldServer world : server.getWorlds()) { - world.getPlayerChunkMap().shutdown(); - } - } - - static void processMainThreadQueue(MinecraftServer server) { - for (WorldServer world : server.getWorlds()) { - processMainThreadQueue(world); - } - } - - static void processMainThreadQueue(World world) { - IChunkProvider chunkProvider = world.getChunkProvider(); - if (chunkProvider instanceof PaperAsyncChunkProvider) { - ((PaperAsyncChunkProvider) chunkProvider).processMainThreadQueue(); - } - } - - private void processMainThreadQueue() { - processMainThreadQueue((PendingChunk) null); - } - private boolean processMainThreadQueue(PendingChunk pending) { - Runnable run; - boolean hadLoad = false; - while ((run = MAIN_THREAD_QUEUE.poll()) != null) { - run.run(); - hadLoad = true; - if (pending != null && pending.hasPosted) { - break; - } - } - return hadLoad; - } - - @Override - public void bumpPriority(ChunkCoordIntPair coords) { - final PendingChunk pending = pendingChunks.get(coords.asLong()); - if (pending != null) { - pending.bumpPriority(Priority.HIGH); - } - } - - @Nullable - @Override - public Chunk getChunkAt(int x, int z, boolean load, boolean gen) { - return getChunkAt(x, z, load, gen, null); - } - - @Nullable - @Override - public Chunk getChunkAt(int x, int z, boolean load, boolean gen, boolean priority, Consumer consumer) { - final long key = ChunkCoordIntPair.asLong(x, z); - final Chunk chunk = this.chunks.get(key); - if (chunk != null || !load) { // return null if we aren't loading - if (consumer != null) { - consumer.accept(chunk); - } - return chunk; - } - return loadOrGenerateChunk(x, z, gen, priority, consumer); // Async overrides this method - } - - private Chunk loadOrGenerateChunk(int x, int z, boolean gen, boolean priority, Consumer consumer) { - return requestChunk(x, z, gen, priority, consumer).getChunk(); - } - - final PendingChunkRequest requestChunk(int x, int z, boolean gen, boolean priority, Consumer consumer) { - try (co.aikar.timings.Timing timing = world.timings.syncChunkLoadTimer.startTiming()) { - final long key = ChunkCoordIntPair.asLong(x, z); - final boolean isChunkThread = isChunkThread(); - final boolean isBlockingMain = consumer == null && server.isMainThread(); - final boolean loadOnThisThread = isChunkThread || isBlockingMain; - final Priority taskPriority = calculatePriority(isBlockingMain, priority); - - // Obtain a PendingChunk - final PendingChunk pending; - synchronized (pendingChunks) { - PendingChunk pendingChunk = pendingChunks.get(key); - if (pendingChunk == null) { - pending = new PendingChunk(x, z, key, gen, taskPriority); - pendingChunks.put(key, pending); - } else if (pendingChunk.hasFinished && gen && !pendingChunk.canGenerate && pendingChunk.chunk == null) { - // need to overwrite the old - pending = new PendingChunk(x, z, key, true, taskPriority); - pendingChunks.put(key, pending); - } else { - pending = pendingChunk; - if (pending.taskPriority != taskPriority) { - pending.bumpPriority(taskPriority); - } - } - } - - // Listen for when result is ready - final CompletableFuture future = new CompletableFuture<>(); - final PendingChunkRequest request = pending.addListener(future, gen, !loadOnThisThread); - - // Chunk Generation can trigger Chunk Loading, those loads may need to convert, and could be slow - // Give an opportunity for urgent tasks to jump in at these times - if (isChunkThread) { - processUrgentTasks(); - } - - if (loadOnThisThread) { - // do loads on main if blocking, or on current if we are a load/gen thread - // gen threads do trigger chunk loads - pending.loadTask.run(); - } - - if (isBlockingMain) { - while (!future.isDone()) { - // We aren't done, obtain lock on queue - synchronized (MAIN_THREAD_QUEUE) { - // We may of received our request now, check it - if (processMainThreadQueue(pending)) { - // If we processed SOMETHING, don't wait - continue; - } - try { - // We got nothing from the queue, wait until something has been added - MAIN_THREAD_QUEUE.wait(1); - } catch (InterruptedException ignored) { - } - } - // Queue has been notified or timed out, process it - processMainThreadQueue(pending); - } - // We should be done AND posted into chunk map now, return it - request.initialReturnChunk = pending.postChunk(); - } else if (consumer == null) { - // This is on another thread - request.initialReturnChunk = future.join(); - } else { - future.thenAccept((c) -> this.asyncHandler.postToMainThread(() -> consumer.accept(c))); - } - - return request; - } - } - - private void processUrgentTasks() { - final PriorityQueuedExecutor executor = PriorityQueuedExecutor.getExecutor(); - if (executor != null) { - executor.processUrgentTasks(); - } - } - - @Override - public CompletableFuture loadAllChunks(Iterable iterable, Consumer consumer) { - final Iterator iterator = iterable.iterator(); - - final List> all = new ArrayList<>(); - while (iterator.hasNext()) { - final ChunkCoordIntPair chunkcoordintpair = iterator.next(); - final CompletableFuture future = new CompletableFuture<>(); - all.add(future); - this.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, true, true, chunk -> { - future.complete(chunk); - if (consumer != null) { - consumer.accept(chunk); - } - }); - } - return CompletableFuture.allOf(all.toArray(new CompletableFuture[0])); - } - - boolean chunkGoingToExists(int x, int z) { - synchronized (pendingChunks) { - PendingChunk pendingChunk = pendingChunks.get(ChunkCoordIntPair.asLong(x, z)); - return pendingChunk != null && pendingChunk.canGenerate; - } - } - - private enum PendingStatus { - /** - * Request has just started - */ - STARTED, - /** - * Chunk is attempting to be loaded from disk - */ - LOADING, - /** - * Chunk must generate on main and is pending main - */ - GENERATION_PENDING, - /** - * Chunk is generating - */ - GENERATING, - /** - * Chunk is ready and is pending post to main - */ - PENDING_MAIN, - /** - * Could not load chunk, and did not need to generat - */ - FAIL, - /** - * Fully done with this request (may or may not of loaded) - */ - DONE, - /** - * Chunk load was cancelled (no longer needed) - */ - CANCELLED - } - - public interface CancellableChunkRequest { - void cancel(); - Chunk getChunk(); - } - - public static class PendingChunkRequest implements CancellableChunkRequest { - private final PendingChunk pending; - private final AtomicBoolean cancelled = new AtomicBoolean(false); - private volatile boolean generating; - private volatile Chunk initialReturnChunk; - - private PendingChunkRequest(PendingChunk pending) { - this.pending = pending; - this.cancelled.set(true); - } - - private PendingChunkRequest(PendingChunk pending, boolean gen) { - this.pending = pending; - this.generating = gen; - } - - public void cancel() { - this.pending.cancel(this); - } - - /** - * Will be null on asynchronous loads - */ - @Override @Nullable - public Chunk getChunk() { - return initialReturnChunk; - } - } - - private boolean isLoadThread() { - return EXECUTOR.isCurrentThread(); - } - - private boolean isGenThread() { - return generationExecutor.isCurrentThread(); - } - private boolean isChunkThread() { - return isLoadThread() || isGenThread(); - } - - private class PendingChunk implements Runnable { - private final int x; - private final int z; - private final long key; - private final long started = System.currentTimeMillis(); - private final CompletableFuture loadOnly = new CompletableFuture<>(); - private final CompletableFuture generate = new CompletableFuture<>(); - private final AtomicInteger requests = new AtomicInteger(0); - - private volatile PendingStatus status = PendingStatus.STARTED; - private volatile PriorityQueuedExecutor.PendingTask loadTask; - private volatile PriorityQueuedExecutor.PendingTask genTask; - private volatile Priority taskPriority; - private volatile boolean generating; - private volatile boolean canGenerate; - private volatile boolean isHighPriority; - private volatile boolean hasPosted; - private volatile boolean hasFinished; - private volatile Chunk chunk; - private volatile NBTTagCompound pendingLevel; - - PendingChunk(int x, int z, long key, boolean canGenerate, boolean priority) { - this.x = x; - this.z = z; - this.key = key; - this.canGenerate = canGenerate; - taskPriority = priority ? Priority.HIGH : Priority.NORMAL; - } - - PendingChunk(int x, int z, long key, boolean canGenerate, Priority taskPriority) { - this.x = x; - this.z = z; - this.key = key; - this.canGenerate = canGenerate; - this.taskPriority = taskPriority; - } - - private synchronized void setStatus(PendingStatus status) { - this.status = status; - } - - private Chunk loadChunk(int x, int z) throws IOException { - setStatus(PendingStatus.LOADING); - Object[] data = chunkLoader.loadChunk(world, x, z, null); - if (data != null) { - // Level must be loaded on main - this.pendingLevel = ((NBTTagCompound) data[1]).getCompound("Level"); - return (Chunk) data[0]; - } else { - return null; - } - } - - private Chunk generateChunk() { - synchronized (this) { - if (requests.get() <= 0) { - return null; - } - } - - try { - CompletableFuture pending = new CompletableFuture<>(); - batchScheduler.startBatch(); - batchScheduler.add(new ChunkCoordIntPair(x, z)); - - ProtoChunk protoChunk = batchScheduler.executeBatch().join(); - boolean saved = false; - if (!Bukkit.isPrimaryThread()) { - // If we are async, dispatch later - try { - chunkLoader.saveChunk(world, protoChunk, true); - saved = true; - } catch (IOException | ExceptionWorldConflict e) { - e.printStackTrace(); - } - } - Chunk chunk = new Chunk(world, protoChunk, x, z); - if (saved) { - chunk.setLastSaved(world.getTime()); - } - generateFinished(chunk); - - return chunk; - } catch (Throwable e) { - MinecraftServer.LOGGER.error("Couldn't generate chunk (" +world.getWorld().getName() + ":" + x + "," + z + ")", e); - generateFinished(null); - return null; - } - } - - boolean loadFinished(Chunk chunk) { - if (chunk != null) { - postChunkToMain(chunk); - return false; - } - loadOnly.complete(null); - - synchronized (this) { - boolean cancelled = requests.get() <= 0; - if (!canGenerate || cancelled) { - if (!cancelled) { - setStatus(PendingStatus.FAIL); - } - this.chunk = null; - this.hasFinished = true; - pendingChunks.remove(key); - return false; - } else { - setStatus(PendingStatus.GENERATING); - generating = true; - return true; - } - } - } - - void generateFinished(Chunk chunk) { - synchronized (this) { - this.chunk = chunk; - this.hasFinished = true; - } - if (chunk != null) { - postChunkToMain(chunk); - } else { - synchronized (this) { - pendingChunks.remove(key); - completeFutures(null); - } - } - } - - synchronized private void completeFutures(Chunk chunk) { - loadOnly.complete(chunk); - generate.complete(chunk); - } - - private void postChunkToMain(Chunk chunk) { - synchronized (this) { - setStatus(PendingStatus.PENDING_MAIN); - this.chunk = chunk; - this.hasFinished = true; - } - - if (server.isMainThread()) { - postChunk(); - return; - } - - // Don't post here, even if on main, it must enter the queue so we can exit any open batch - // schedulers, as post stage may trigger a new generation and cause errors - synchronized (MAIN_THREAD_QUEUE) { - if (this.taskPriority == Priority.URGENT) { - MAIN_THREAD_QUEUE.addFirst(this::postChunk); - } else { - MAIN_THREAD_QUEUE.addLast(this::postChunk); - } - MAIN_THREAD_QUEUE.notify(); - } - } - - Chunk postChunk() { - if (!server.isMainThread()) { - throw new IllegalStateException("Must post from main"); - } - synchronized (this) { - if (hasPosted || requests.get() <= 0) { // if pending is 0, all were cancelled - return chunk; - } - hasPosted = true; - } - try { - if (chunk == null) { - chunk = chunks.get(key); - completeFutures(chunk); - return chunk; - } - if (pendingLevel != null) { - chunkLoader.loadEntities(pendingLevel, chunk); - pendingLevel = null; - } - synchronized (chunks) { - final Chunk other = chunks.get(key); - if (other != null) { - this.chunk = other; - completeFutures(other); - return other; - } - if (chunk != null) { - chunks.put(key, chunk); - } - } - - chunk.addEntities(); - - completeFutures(chunk); - return chunk; - } finally { - pendingChunks.remove(key); - setStatus(PendingStatus.DONE); - } - } - - synchronized PendingChunkRequest addListener(CompletableFuture future, boolean gen, boolean autoSubmit) { - requests.incrementAndGet(); - if (loadTask == null) { - // Take care of a race condition in that a request could be cancelled after the synchronize - // on pendingChunks, but before a listener is added, which would erase these pending tasks. - genTask = generationExecutor.createPendingTask(this::generateChunk, taskPriority); - loadTask = EXECUTOR.createPendingTask(this, taskPriority); - if (autoSubmit) { - // We will execute it outside of the synchronized context immediately after - loadTask.submit(); - } - } - - if (hasFinished) { - future.complete(chunk); - return new PendingChunkRequest(this); - } else if (gen) { - canGenerate = true; - generate.thenAccept(future::complete); - } else { - if (generating) { - future.complete(null); - return new PendingChunkRequest(this); - } else { - loadOnly.thenAccept(future::complete); - } - } - - return new PendingChunkRequest(this, gen); - } - - @Override - public void run() { - try { - if (!loadFinished(loadChunk(x, z))) { - return; - } - } catch (Throwable ex) { - MinecraftServer.LOGGER.error("Couldn't load chunk (" +world.getWorld().getName() + ":" + x + "," + z + ")", ex); - if (ex instanceof IOException) { - generateFinished(null); - return; - } - } - - if (shouldGenSync) { - synchronized (this) { - setStatus(PendingStatus.GENERATION_PENDING); - if (this.taskPriority == Priority.URGENT) { - MAIN_THREAD_QUEUE.addFirst(() -> generateFinished(this.generateChunk())); - } else { - MAIN_THREAD_QUEUE.addLast(() -> generateFinished(this.generateChunk())); - } - - } - synchronized (MAIN_THREAD_QUEUE) { - MAIN_THREAD_QUEUE.notify(); - } - } else { - if (isGenThread()) { - // ideally we should never run into 1 chunk generating another chunk... - // but if we do, let's apply same solution - genTask.run(); - } else { - genTask.submit(); - } - } - } - - void bumpPriority() { - bumpPriority(Priority.HIGH); - } - - void bumpPriority(Priority newPriority) { - if (taskPriority.ordinal() >= newPriority.ordinal()) { - return; - } - - this.taskPriority = newPriority; - PriorityQueuedExecutor.PendingTask loadTask = this.loadTask; - PriorityQueuedExecutor.PendingTask genTask = this.genTask; - if (loadTask != null) { - loadTask.bumpPriority(newPriority); - } - if (genTask != null) { - genTask.bumpPriority(newPriority); - } - } - - public synchronized boolean isCancelled() { - return requests.get() <= 0; - } - - public synchronized void cancel(PendingChunkRequest request) { - synchronized (pendingChunks) { - if (!request.cancelled.compareAndSet(false, true)) { - return; - } - - if (requests.decrementAndGet() > 0) { - return; - } - - boolean c1 = genTask.cancel(); - boolean c2 = loadTask.cancel(); - loadTask = null; - genTask = null; - pendingChunks.remove(key); - setStatus(PendingStatus.CANCELLED); - } - } - } - -} diff --git a/src/main/java/net/minecraft/server/PaperLightingQueue.java b/src/main/java/net/minecraft/server/PaperLightingQueue.java deleted file mode 100644 index 46b7cfa5a..000000000 --- a/src/main/java/net/minecraft/server/PaperLightingQueue.java +++ /dev/null @@ -1,100 +0,0 @@ -package net.minecraft.server; - -import co.aikar.timings.Timing; -import io.akarin.server.core.AkarinGlobalConfig; - -import com.destroystokyo.paper.PaperConfig; -import it.unimi.dsi.fastutil.objects.ObjectCollection; - -import java.util.ArrayDeque; - -class PaperLightingQueue { - private static final long MAX_TIME = (long) (1000000 * (50 + PaperConfig.maxTickMsLostLightQueue)); - - static void processQueue(long curTime) { - final long startTime = System.nanoTime(); - final long maxTickTime = MAX_TIME - (startTime - curTime); - - if (maxTickTime <= 0) { - return; - } - - START: - for (World world : MinecraftServer.getServer().getWorlds()) { - if (!world.paperConfig.queueLightUpdates || AkarinGlobalConfig.enableAsyncLighting) { // Akarin - continue; - } - - ObjectCollection loadedChunks = ((WorldServer) world).getChunkProvider().chunks.values(); - for (Chunk chunk : loadedChunks.toArray(new Chunk[0])) { - if (chunk.lightingQueue.processQueue(startTime, maxTickTime)) { - break START; - } - } - } - } - - static class LightingQueue extends ArrayDeque { - final private Chunk chunk; - - LightingQueue(Chunk chunk) { - super(); - this.chunk = chunk; - } - - /** - * Processes the lighting queue for this chunk - * - * @param startTime If start Time is 0, we will not limit execution time - * @param maxTickTime Maximum time to spend processing lighting updates - * @return true to abort processing furthur lighting updates - */ - private boolean processQueue(long startTime, long maxTickTime) { - if (this.isEmpty()) { - return false; - } - if (isOutOfTime(maxTickTime, startTime)) { - return true; - } - try (Timing ignored = chunk.world.timings.lightingQueueTimer.startTimingUnsafe()) { - Runnable lightUpdate; - while ((lightUpdate = this.poll()) != null) { - lightUpdate.run(); - if (isOutOfTime(maxTickTime, startTime)) { - return true; - } - } - } - - return false; - } - - /** - * Flushes lighting updates to unload the chunk - */ - void processUnload() { - if (!chunk.world.paperConfig.queueLightUpdates || AkarinGlobalConfig.enableAsyncLighting) { // Akarin - return; - } - processQueue(0, 0); // No timeout - - final int radius = 1; - for (int x = chunk.locX - radius; x <= chunk.locX + radius; ++x) { - for (int z = chunk.locZ - radius; z <= chunk.locZ + radius; ++z) { - if (x == chunk.locX && z == chunk.locZ) { - continue; - } - - Chunk neighbor = chunk.world.getChunkIfLoaded(x, z); - if (neighbor != null) { - neighbor.lightingQueue.processQueue(0, 0); // No timeout - } - } - } - } - } - - private static boolean isOutOfTime(long maxTickTime, long startTime) { - return startTime > 0 && System.nanoTime() - startTime > maxTickTime; - } -} diff --git a/src/main/java/net/minecraft/server/PathEntity.java b/src/main/java/net/minecraft/server/PathEntity.java index 5cf7f3bf1..dcb4e2508 100644 --- a/src/main/java/net/minecraft/server/PathEntity.java +++ b/src/main/java/net/minecraft/server/PathEntity.java @@ -1,20 +1,24 @@ package net.minecraft.server; +import java.util.List; import javax.annotation.Nullable; public class PathEntity { - private final PathPoint[] a; public PathPoint[] getPoints() { return a; } // Paper - OBFHELPER + private final List a; public List getPoints() { return a; } // Paper - OBFHELPER private PathPoint[] b = new PathPoint[0]; private PathPoint[] c = new PathPoint[0]; - private PathPoint d; - private int e; public int getNextIndex() { return e; } // Paper - OBFHELPER - private int f; public int getPathCount() { return f; } // Paper - OBFHELPER - public boolean hasNext() { return getNextIndex() < getPathCount(); } // Paper + private int e; public int getNextIndex() { return this.e; } // Paper - OBFHELPER + private final BlockPosition f; + private final float g; + private final boolean h; + public boolean hasNext() { return getNextIndex() < getPoints().size(); } // Paper - public PathEntity(PathPoint[] apathpoint) { - this.a = apathpoint; - this.f = apathpoint.length; + public PathEntity(List list, BlockPosition blockposition, boolean flag) { + this.a = list; + this.f = blockposition; + this.g = list.isEmpty() ? Float.MAX_VALUE : ((PathPoint) this.a.get(this.a.size() - 1)).c(this.f); + this.h = flag; } public void a() { @@ -22,31 +26,37 @@ public class PathEntity { } public boolean b() { - return this.e >= this.f; + return this.e >= this.a.size(); } - @Nullable public PathPoint getFinalPoint() { return c(); } @Nullable public PathPoint c() { // Paper - OBFHELPER - return this.f > 0 ? this.a[this.f - 1] : null; + return !this.a.isEmpty() ? (PathPoint) this.a.get(this.a.size() - 1) : null; } public PathPoint a(int i) { - return this.a[i]; + return (PathPoint) this.a.get(i); } - public void a(int i, PathPoint pathpoint) { - this.a[i] = pathpoint; - } - - public int d() { - return this.f; + public List d() { + return this.a; } public void b(int i) { - this.f = i; + if (this.a.size() > i) { + this.a.subList(i, this.a.size()).clear(); + } + + } + + public void a(int i, PathPoint pathpoint) { + this.a.set(i, pathpoint); } public int e() { + return this.a.size(); + } + + public int f() { return this.e; } @@ -55,9 +65,10 @@ public class PathEntity { } public Vec3D a(Entity entity, int i) { - double d0 = (double) this.a[i].a + (double) ((int) (entity.width + 1.0F)) * 0.5D; - double d1 = (double) this.a[i].b; - double d2 = (double) this.a[i].c + (double) ((int) (entity.width + 1.0F)) * 0.5D; + PathPoint pathpoint = (PathPoint) this.a.get(i); + double d0 = (double) pathpoint.a + (double) ((int) (entity.getWidth() + 1.0F)) * 0.5D; + double d1 = (double) pathpoint.b; + double d2 = (double) pathpoint.c + (double) ((int) (entity.getWidth() + 1.0F)) * 0.5D; return new Vec3D(d0, d1, d2); } @@ -66,20 +77,23 @@ public class PathEntity { return this.a(entity, this.e); } - public Vec3D getNext() { return f(); } public Vec3D f() { // Paper - OBFHELPER - PathPoint pathpoint = this.a[this.e]; + public Vec3D getNext() { return g(); } public Vec3D g() { // Paper - OBFHELPER + PathPoint pathpoint = (PathPoint) this.a.get(this.e); return new Vec3D((double) pathpoint.a, (double) pathpoint.b, (double) pathpoint.c); } - public boolean a(PathEntity pathentity) { + public boolean a(@Nullable PathEntity pathentity) { if (pathentity == null) { return false; - } else if (pathentity.a.length != this.a.length) { + } else if (pathentity.a.size() != this.a.size()) { return false; } else { - for (int i = 0; i < this.a.length; ++i) { - if (this.a[i].a != pathentity.a[i].a || this.a[i].b != pathentity.a[i].b || this.a[i].c != pathentity.a[i].c) { + for (int i = 0; i < this.a.size(); ++i) { + PathPoint pathpoint = (PathPoint) this.a.get(i); + PathPoint pathpoint1 = (PathPoint) pathentity.a.get(i); + + if (pathpoint.a != pathpoint1.a || pathpoint.b != pathpoint1.b || pathpoint.c != pathpoint1.c) { return false; } } @@ -88,8 +102,19 @@ public class PathEntity { } } - @Nullable - public PathPoint i() { - return this.d; + public boolean h() { + return this.h; + } + + public String toString() { + return "Path(length=" + this.a.size() + ")"; + } + + public BlockPosition k() { + return this.f; + } + + public float l() { + return this.g; } } diff --git a/src/main/java/net/minecraft/server/PathPoint.java b/src/main/java/net/minecraft/server/PathPoint.java index 0dd6e46d1..18cdd2a6f 100644 --- a/src/main/java/net/minecraft/server/PathPoint.java +++ b/src/main/java/net/minecraft/server/PathPoint.java @@ -5,7 +5,7 @@ public class PathPoint { public final int a; public final int getX() { return a; } // Paper - OBFHELPER public final int b; public final int getY() { return b; } // Paper - OBFHELPER public final int c; public final int getZ() { return c; } // Paper - OBFHELPER - private final int n; + private final int m; public int d = -1; public float e; public float f; @@ -14,15 +14,14 @@ public class PathPoint { public boolean i; public float j; public float k; - public float l; - public PathType m; + public PathType l; public PathPoint(int i, int j, int k) { - this.m = PathType.BLOCKED; + this.l = PathType.BLOCKED; this.a = i; this.b = j; this.c = k; - this.n = b(i, j, k); + this.m = b(i, j, k); } public PathPoint a(int i, int j, int k) { @@ -37,7 +36,6 @@ public class PathPoint { pathpoint.j = this.j; pathpoint.k = this.k; pathpoint.l = this.l; - pathpoint.m = this.m; return pathpoint; } @@ -69,25 +67,33 @@ public class PathPoint { return f + f1 + f2; } + public float c(BlockPosition blockposition) { + float f = (float) Math.abs(blockposition.getX() - this.a); + float f1 = (float) Math.abs(blockposition.getY() - this.b); + float f2 = (float) Math.abs(blockposition.getZ() - this.c); + + return f + f1 + f2; + } + public boolean equals(Object object) { if (!(object instanceof PathPoint)) { return false; } else { PathPoint pathpoint = (PathPoint) object; - return this.n == pathpoint.n && this.a == pathpoint.a && this.b == pathpoint.b && this.c == pathpoint.c; + return this.m == pathpoint.m && this.a == pathpoint.a && this.b == pathpoint.b && this.c == pathpoint.c; } } public int hashCode() { - return this.n; + return this.m; } - public boolean a() { + public boolean c() { return this.d >= 0; } public String toString() { - return this.a + ", " + this.b + ", " + this.c; + return "Node{x=" + this.a + ", y=" + this.b + ", z=" + this.c + '}'; } } diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java index 89d51d471..0cec80ec7 100644 --- a/src/main/java/net/minecraft/server/Pathfinder.java +++ b/src/main/java/net/minecraft/server/Pathfinder.java @@ -1,7 +1,16 @@ package net.minecraft.server; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nullable; public class Pathfinder { @@ -9,115 +18,130 @@ public class Pathfinder { private final Path a = new Path(); private final Set b = Sets.newHashSet(); private final PathPoint[] c = new PathPoint[32]; - private PathfinderAbstract d; public PathfinderAbstract getPathfinder() { return d; } // Paper - OBFHELPER + private final int d; + private PathfinderAbstract e; public PathfinderAbstract getPathfinder() { return this.e; } // Paper - OBFHELPER - public Pathfinder(PathfinderAbstract pathfinderabstract) { - this.d = pathfinderabstract; + public Pathfinder(PathfinderAbstract pathfinderabstract, int i) { + this.e = pathfinderabstract; + this.d = i; } @Nullable - public PathEntity a(IBlockAccess iblockaccess, EntityInsentient entityinsentient, Entity entity, float f) { - return this.a(iblockaccess, entityinsentient, entity.locX, entity.getBoundingBox().minY, entity.locZ, f); - } - - @Nullable - public PathEntity a(IBlockAccess iblockaccess, EntityInsentient entityinsentient, BlockPosition blockposition, float f) { - return this.a(iblockaccess, entityinsentient, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), f); - } - - @Nullable - private PathEntity a(IBlockAccess iblockaccess, EntityInsentient entityinsentient, double d0, double d1, double d2, float f) { + public PathEntity a(IWorldReader iworldreader, EntityInsentient entityinsentient, Set set, float f, int i) { this.a.a(); - this.d.a(iblockaccess, entityinsentient); - PathPoint pathpoint = this.d.b(); - PathPoint pathpoint1 = this.d.a(d0, d1, d2); - PathEntity pathentity = this.a(pathpoint, pathpoint1, f); + this.e.a(iworldreader, entityinsentient); + PathPoint pathpoint = this.e.b(); + Map map = (Map) set.stream().collect(Collectors.toMap((blockposition) -> { + return this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); + }, Function.identity())); + PathEntity pathentity = this.a(pathpoint, map, f, i); - this.d.a(); + this.e.a(); return pathentity; } @Nullable - private PathEntity a(PathPoint pathpoint, PathPoint pathpoint1, float f) { + private PathEntity a(PathPoint pathpoint, Map map, float f, int i) { + Set set = map.keySet(); + pathpoint.e = 0.0F; - pathpoint.f = pathpoint.c(pathpoint1); + pathpoint.f = this.a(pathpoint, set); pathpoint.g = pathpoint.f; this.a.a(); this.b.clear(); this.a.a(pathpoint); - PathPoint pathpoint2 = pathpoint; - int i = 0; + int j = 0; while (!this.a.e()) { - ++i; - if (i >= 200) { + ++j; + if (j >= this.d) { break; } - PathPoint pathpoint3 = this.a.c(); + PathPoint pathpoint1 = this.a.c(); - if (pathpoint3.equals(pathpoint1)) { - pathpoint2 = pathpoint1; + pathpoint1.i = true; + set.stream().filter((pathdestination) -> { + return pathpoint1.c((PathPoint) pathdestination) <= (float) i; + }).forEach(PathDestination::e); + if (set.stream().anyMatch(PathDestination::f)) { break; } - if (pathpoint3.c(pathpoint1) < pathpoint2.c(pathpoint1)) { - pathpoint2 = pathpoint3; - } + if (pathpoint1.a(pathpoint) < f) { + int k = this.e.a(this.c, pathpoint1); - pathpoint3.i = true; - int j = this.d.a(this.c, pathpoint3, pathpoint1, f); + for (int l = 0; l < k; ++l) { + PathPoint pathpoint2 = this.c[l]; + float f1 = pathpoint1.a(pathpoint2); - for (int k = 0; k < j; ++k) { - PathPoint pathpoint4 = this.c[k]; - float f1 = pathpoint3.c(pathpoint4); + pathpoint2.j = pathpoint1.j + f1; + float f2 = pathpoint1.e + f1 + pathpoint2.k; - pathpoint4.j = pathpoint3.j + f1; - pathpoint4.k = f1 + pathpoint4.l; - float f2 = pathpoint3.e + pathpoint4.k; - - if (pathpoint4.j < f && (!pathpoint4.a() || f2 < pathpoint4.e)) { - pathpoint4.h = pathpoint3; - pathpoint4.e = f2; - pathpoint4.f = pathpoint4.c(pathpoint1) + pathpoint4.l; - if (pathpoint4.a()) { - this.a.a(pathpoint4, pathpoint4.e + pathpoint4.f); - } else { - pathpoint4.g = pathpoint4.e + pathpoint4.f; - this.a.a(pathpoint4); + if (pathpoint2.j < f && (!pathpoint2.c() || f2 < pathpoint2.e)) { + pathpoint2.h = pathpoint1; + pathpoint2.e = f2; + pathpoint2.f = this.a(pathpoint2, set) * 1.5F; + if (pathpoint2.c()) { + this.a.a(pathpoint2, pathpoint2.e + pathpoint2.f); + } else { + pathpoint2.g = pathpoint2.e + pathpoint2.f; + this.a.a(pathpoint2); + } } } } } - if (pathpoint2 == pathpoint) { + Stream stream; + + if (set.stream().anyMatch(PathDestination::f)) { + stream = set.stream().filter(PathDestination::f).map((pathdestination) -> { + return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), true); + }).sorted(Comparator.comparingInt(PathEntity::e)); + } else { + stream = set.stream().map((pathdestination) -> { + return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), false); + }).sorted(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e)); + } + + Optional optional = stream.findFirst(); + + if (!optional.isPresent()) { return null; } else { - PathEntity pathentity = this.a(pathpoint, pathpoint2); + PathEntity pathentity = (PathEntity) optional.get(); return pathentity; } } - private PathEntity a(PathPoint pathpoint, PathPoint pathpoint1) { - int i = 1; + private float a(PathPoint pathpoint, Set set) { + float f = Float.MAX_VALUE; - PathPoint pathpoint2; + float f1; - for (pathpoint2 = pathpoint1; pathpoint2.h != null; pathpoint2 = pathpoint2.h) { - ++i; + for (Iterator iterator = set.iterator(); iterator.hasNext(); f = Math.min(f1, f)) { + PathDestination pathdestination = (PathDestination) iterator.next(); + + f1 = pathpoint.a(pathdestination); + pathdestination.a(f1, pathpoint); } - PathPoint[] apathpoint = new PathPoint[i]; + return f; + } - pathpoint2 = pathpoint1; - --i; + private PathEntity a(PathPoint pathpoint, BlockPosition blockposition, boolean flag) { + List list = Lists.newArrayList(); + PathPoint pathpoint1 = pathpoint; - for (apathpoint[i] = pathpoint1; pathpoint2.h != null; apathpoint[i] = pathpoint2) { - pathpoint2 = pathpoint2.h; - --i; + list.add(0, pathpoint); + + while (pathpoint1.h != null) { + pathpoint1 = pathpoint1.h; + list.add(0, pathpoint1); } - return new PathEntity(apathpoint); + return new PathEntity(list, blockposition, flag); } } diff --git a/src/main/java/net/minecraft/server/PathfinderAbstract.java b/src/main/java/net/minecraft/server/PathfinderAbstract.java deleted file mode 100644 index d722c8513..000000000 --- a/src/main/java/net/minecraft/server/PathfinderAbstract.java +++ /dev/null @@ -1,78 +0,0 @@ -package net.minecraft.server; - -public abstract class PathfinderAbstract { - - protected IBlockAccess a; - protected EntityInsentient b; - public World world; // Paper - protected final IntHashMap c = new IntHashMap<>(); - protected int d; - protected int e; - protected int f; - protected boolean g; - protected boolean h; - protected boolean i; - - public PathfinderAbstract() {} - - public void a(IBlockAccess iblockaccess, EntityInsentient entityinsentient) { - this.a = iblockaccess; - if (iblockaccess instanceof World) world = (World) iblockaccess; // Paper - this.b = entityinsentient; - this.c.c(); - this.d = MathHelper.d(entityinsentient.width + 1.0F); - this.e = MathHelper.d(entityinsentient.length + 1.0F); - this.f = MathHelper.d(entityinsentient.width + 1.0F); - } - - public void a() { - this.a = null; - this.b = null; - } - - protected PathPoint a(int i, int j, int k) { - int l = PathPoint.b(i, j, k); - PathPoint pathpoint = (PathPoint) this.c.get(l); - - if (pathpoint == null) { - pathpoint = new PathPoint(i, j, k); - this.c.a(l, pathpoint); - } - - return pathpoint; - } - - public abstract PathPoint b(); - - public abstract PathPoint a(double d0, double d1, double d2); - - public abstract int a(PathPoint[] apathpoint, PathPoint pathpoint, PathPoint pathpoint1, float f); - - public abstract PathType a(IBlockAccess iblockaccess, int i, int j, int k, EntityInsentient entityinsentient, int l, int i1, int j1, boolean flag, boolean flag1); - - public abstract PathType a(IBlockAccess iblockaccess, int i, int j, int k); - - public void a(boolean flag) { - this.g = flag; - } - - public void b(boolean flag) { - this.h = flag; - } - - public void c(boolean flag) { - this.i = flag; - } - - public boolean c() { - return this.g; - } - - public boolean d() { - return this.h; - } - - public boolean e() { - return this.i; - } -} diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java deleted file mode 100644 index a19853463..000000000 --- a/src/main/java/net/minecraft/server/PathfinderGoal.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.minecraft.server; - -public abstract class PathfinderGoal { - - private int a; - - public PathfinderGoal() {} - - public abstract boolean a(); - - public boolean b() { - return this.a(); - } - - public boolean f() { - return true; - } - - public void c() {} - - public void d() { - onTaskReset(); // Paper - } - public void onTaskReset() {} // Paper - - public void e() {} - - public void a(int i) { - this.a = i; - } - - public int h() { - return this.a; - } -} diff --git a/src/main/java/net/minecraft/server/PathfinderGoalBreakDoor.java b/src/main/java/net/minecraft/server/PathfinderGoalBreakDoor.java index 74da8a935..584b35e1d 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalBreakDoor.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalBreakDoor.java @@ -1,59 +1,85 @@ package net.minecraft.server; +import java.util.function.Predicate; + public class PathfinderGoalBreakDoor extends PathfinderGoalDoorInteract { - private int d; - private int e = -1; + private final Predicate g; + protected int a; + protected int b; + protected int c; - public PathfinderGoalBreakDoor(EntityInsentient entityinsentient) { + public PathfinderGoalBreakDoor(EntityInsentient entityinsentient, Predicate predicate) { super(entityinsentient); + this.b = -1; + this.c = -1; + this.g = predicate; } + public PathfinderGoalBreakDoor(EntityInsentient entityinsentient, int i, Predicate predicate) { + this(entityinsentient, predicate); + this.c = i; + } + + protected int f() { + return Math.max(240, this.c); + } + + @Override public boolean a() { - return !super.a() ? false : (!this.a.world.getGameRules().getBoolean("mobGriefing") ? false : !this.g()); + return !super.a() ? false : (!this.entity.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? false : this.a(this.entity.world.getDifficulty()) && !this.g()); } + @Override public void c() { super.c(); - this.d = 0; + this.a = 0; } + @Override public boolean b() { - double d0 = this.a.c(this.b); - - return this.d <= 240 && !this.g() && d0 < 4.0D; + return this.a <= this.f() && !this.g() && this.door.a((IPosition) this.entity.getPositionVector(), 2.0D) && this.a(this.entity.world.getDifficulty()); } + @Override public void d() { super.d(); - this.a.world.c(this.a.getId(), this.b, -1); + this.entity.world.a(this.entity.getId(), this.door, -1); } + @Override public void e() { super.e(); - if (this.a.getRandom().nextInt(20) == 0) { - this.a.world.triggerEffect(1019, this.b, 0); + if (this.entity.getRandom().nextInt(20) == 0) { + this.entity.world.triggerEffect(1019, this.door, 0); + if (!this.entity.at) { + this.entity.a(this.entity.getRaisedHand()); + } } - ++this.d; - int i = (int) ((float) this.d / 240.0F * 10.0F); + ++this.a; + int i = (int) ((float) this.a / (float) this.f() * 10.0F); - if (i != this.e) { - this.a.world.c(this.a.getId(), this.b, i); - this.e = i; + if (i != this.b) { + this.entity.world.a(this.entity.getId(), this.door, i); + this.b = i; } - if (this.d == 240 && this.a.world.getDifficulty() == EnumDifficulty.HARD) { + if (this.a == this.f() && this.a(this.entity.world.getDifficulty())) { // CraftBukkit start - if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreakDoorEvent(this.a, this.b.getX(), this.b.getY(), this.b.getZ()).isCancelled()) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreakDoorEvent(this.entity, this.door).isCancelled()) { this.c(); return; } // CraftBukkit end - this.a.world.setAir(this.b); - this.a.world.triggerEffect(1021, this.b, 0); - this.a.world.triggerEffect(2001, this.b, Block.getCombinedId(this.a.world.getType(this.b))); + this.entity.world.a(this.door, false); + this.entity.world.triggerEffect(1021, this.door, 0); + this.entity.world.triggerEffect(2001, this.door, Block.getCombinedId(this.entity.world.getType(this.door))); } } + + private boolean a(EnumDifficulty enumdifficulty) { + return this.g.test(enumdifficulty); + } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalBreed.java b/src/main/java/net/minecraft/server/PathfinderGoalBreed.java index 59935b176..0cc34400b 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalBreed.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalBreed.java @@ -1,17 +1,19 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.Iterator; import java.util.List; -import java.util.Random; +import javax.annotation.Nullable; public class PathfinderGoalBreed extends PathfinderGoal { + private static final PathfinderTargetCondition d = (new PathfinderTargetCondition()).a(8.0D).a().b().c(); protected final EntityAnimal animal; - private final Class d; - protected World b; + private final Class e; + protected final World b; protected EntityAnimal partner; - private int e; - private final double f; + private int f; + private final double g; public PathfinderGoalBreed(EntityAnimal entityanimal, double d0) { this(entityanimal, d0, entityanimal.getClass()); @@ -20,41 +22,46 @@ public class PathfinderGoalBreed extends PathfinderGoal { public PathfinderGoalBreed(EntityAnimal entityanimal, double d0, Class oclass) { this.animal = entityanimal; this.b = entityanimal.world; - this.d = oclass; - this.f = d0; - this.a(3); + this.e = oclass; + this.g = d0; + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); } + @Override public boolean a() { if (!this.animal.isInLove()) { return false; } else { - this.partner = this.i(); + this.partner = this.h(); return this.partner != null; } } + @Override public boolean b() { - return this.partner.isAlive() && this.partner.isInLove() && this.e < 60; + return this.partner.isAlive() && this.partner.isInLove() && this.f < 60; } + @Override public void d() { this.partner = null; - this.e = 0; + this.f = 0; } + @Override public void e() { - this.animal.getControllerLook().a(this.partner, 10.0F, (float) this.animal.K()); - this.animal.getNavigation().a((Entity) this.partner, this.f); - ++this.e; - if (this.e >= 60 && this.animal.h(this.partner) < 9.0D) { + this.animal.getControllerLook().a(this.partner, 10.0F, (float) this.animal.M()); + this.animal.getNavigation().a((Entity) this.partner, this.g); + ++this.f; + if (this.f >= 60 && this.animal.h((Entity) this.partner) < 9.0D) { this.g(); } } - private EntityAnimal i() { - List list = this.b.a(this.d, this.animal.getBoundingBox().g(8.0D)); + @Nullable + private EntityAnimal h() { + List list = this.b.a(this.e, PathfinderGoalBreed.d, this.animal, this.animal.getBoundingBox().g(8.0D)); double d0 = Double.MAX_VALUE; EntityAnimal entityanimal = null; Iterator iterator = list.iterator(); @@ -62,9 +69,9 @@ public class PathfinderGoalBreed extends PathfinderGoal { while (iterator.hasNext()) { EntityAnimal entityanimal1 = (EntityAnimal) iterator.next(); - if (this.animal.mate(entityanimal1) && this.animal.h(entityanimal1) < d0) { + if (this.animal.mate(entityanimal1) && this.animal.h((Entity) entityanimal1) < d0) { entityanimal = entityanimal1; - d0 = this.animal.h(entityanimal1); + d0 = this.animal.h((Entity) entityanimal1); } } @@ -106,24 +113,8 @@ public class PathfinderGoalBreed extends PathfinderGoal { entityageable.setAgeRaw(-24000); entityageable.setPositionRotation(this.animal.locX, this.animal.locY, this.animal.locZ, 0.0F, 0.0F); this.b.addEntity(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason - // Akarin start - this handle by client - /* - Random random = this.animal.getRandom(); - - for (int i = 0; i < 7; ++i) { - double d0 = random.nextGaussian() * 0.02D; - double d1 = random.nextGaussian() * 0.02D; - double d2 = random.nextGaussian() * 0.02D; - double d3 = random.nextDouble() * (double) this.animal.width * 2.0D - (double) this.animal.width; - double d4 = 0.5D + random.nextDouble() * (double) this.animal.length; - double d5 = random.nextDouble() * (double) this.animal.width * 2.0D - (double) this.animal.width; - - this.b.addParticle(Particles.A, this.animal.locX + d3, this.animal.locY + d4, this.animal.locZ + d5, d0, d1, d2); - } - */ - // Akarin end - - if (this.b.getGameRules().getBoolean("doMobLoot")) { + this.b.broadcastEntityEffect(this.animal, (byte) 18); + if (this.b.getGameRules().getBoolean(GameRules.DO_MOB_LOOT)) { // CraftBukkit start - use event experience if (experience > 0) { this.b.addEntity(new EntityExperienceOrb(this.b, this.animal.locX, this.animal.locY, this.animal.locZ, experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, entityageable)); // Paper diff --git a/src/main/java/net/minecraft/server/PathfinderGoalDefendVillage.java b/src/main/java/net/minecraft/server/PathfinderGoalDefendVillage.java index d6969293a..9a67f5b55 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalDefendVillage.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalDefendVillage.java @@ -1,36 +1,47 @@ package net.minecraft.server; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; + public class PathfinderGoalDefendVillage extends PathfinderGoalTarget { private final EntityIronGolem a; private EntityLiving b; + private final PathfinderTargetCondition c = (new PathfinderTargetCondition()).a(64.0D); public PathfinderGoalDefendVillage(EntityIronGolem entityirongolem) { super(entityirongolem, false, true); this.a = entityirongolem; - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); } + @Override public boolean a() { - Village village = this.a.l(); + AxisAlignedBB axisalignedbb = this.a.getBoundingBox().grow(10.0D, 8.0D, 10.0D); + List list = this.a.world.a(EntityVillager.class, this.c, this.a, axisalignedbb); + List list1 = this.a.world.a(this.c, (EntityLiving) this.a, axisalignedbb); + Iterator iterator = list.iterator(); - if (village == null) { - return false; - } else { - this.b = village.b((EntityLiving) this.a); - if (this.b instanceof EntityCreeper) { - return false; - } else if (this.a(this.b, false)) { - return true; - } else if (this.e.getRandom().nextInt(20) == 0) { - this.b = village.c((EntityLiving) this.a); - return this.a(this.b, false); - } else { - return false; + while (iterator.hasNext()) { + EntityLiving entityliving = (EntityLiving) iterator.next(); + EntityVillager entityvillager = (EntityVillager) entityliving; + Iterator iterator1 = list1.iterator(); + + while (iterator1.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator1.next(); + int i = entityvillager.f(entityhuman); + + if (i <= -100) { + this.b = entityhuman; + } } } + + return this.b != null; } + @Override public void c() { this.a.setGoalTarget(this.b, org.bukkit.event.entity.EntityTargetEvent.TargetReason.DEFEND_VILLAGE, true); // CraftBukkit - reason super.c(); diff --git a/src/main/java/net/minecraft/server/PathfinderGoalDoorInteract.java b/src/main/java/net/minecraft/server/PathfinderGoalDoorInteract.java deleted file mode 100644 index 92eb29052..000000000 --- a/src/main/java/net/minecraft/server/PathfinderGoalDoorInteract.java +++ /dev/null @@ -1,109 +0,0 @@ -package net.minecraft.server; - -public abstract class PathfinderGoalDoorInteract extends PathfinderGoal { - - protected EntityInsentient a; - protected BlockPosition b; - protected boolean c; - private boolean d; - private float e; - private float f; - - public PathfinderGoalDoorInteract(EntityInsentient entityinsentient) { - this.b = BlockPosition.ZERO; - this.a = entityinsentient; - if (!(entityinsentient.getNavigation() instanceof Navigation)) { - throw new IllegalArgumentException("Unsupported mob type for DoorInteractGoal"); - } - } - - protected boolean g() { - if (!this.c) { - return false; - } else { - IBlockData iblockdata = this.a.world.getType(this.b); - - if (!(iblockdata.getBlock() instanceof BlockDoor)) { - this.c = false; - return false; - } else { - return (Boolean) iblockdata.get(BlockDoor.OPEN); - } - } - } - - protected void a(boolean flag) { - if (this.c) { - IBlockData iblockdata = this.a.world.getType(this.b); - - if (iblockdata.getBlock() instanceof BlockDoor) { - // CraftBukkit start - entities opening doors - org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(this.a.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(this.a.world, this.b)); - this.a.world.getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - // CaftBukkit end - - ((BlockDoor) iblockdata.getBlock()).setDoor(this.a.world, this.b, flag); - } - } - - } - - public boolean a() { - if (!this.a.positionChanged) { - return false; - } else { - Navigation navigation = (Navigation) this.a.getNavigation(); - PathEntity pathentity = navigation.m(); - - if (pathentity != null && !pathentity.b() && navigation.g()) { - for (int i = 0; i < Math.min(pathentity.e() + 2, pathentity.d()); ++i) { - PathPoint pathpoint = pathentity.a(i); - - this.b = new BlockPosition(pathpoint.a, pathpoint.b + 1, pathpoint.c); - if (this.a.d((double) this.b.getX(), this.a.locY, (double) this.b.getZ()) <= 2.25D) { - this.c = this.a(this.b); - if (this.c) { - return true; - } - } - } - - this.b = (new BlockPosition(this.a)).up(); - this.c = this.a(this.b); - return this.c; - } else { - return false; - } - } - } - - public boolean b() { - return !this.d; - } - - public void c() { - this.d = false; - this.e = (float) ((double) ((float) this.b.getX() + 0.5F) - this.a.locX); - this.f = (float) ((double) ((float) this.b.getZ() + 0.5F) - this.a.locZ); - } - - public void e() { - float f = (float) ((double) ((float) this.b.getX() + 0.5F) - this.a.locX); - float f1 = (float) ((double) ((float) this.b.getZ() + 0.5F) - this.a.locZ); - float f2 = this.e * f + this.f * f1; - - if (f2 < 0.0F) { - this.d = true; - } - - } - - private boolean a(BlockPosition blockposition) { - IBlockData iblockdata = this.a.world.getType(blockposition); - - return iblockdata.getBlock() instanceof BlockDoor && iblockdata.getMaterial() == Material.WOOD; - } -} diff --git a/src/main/java/net/minecraft/server/PathfinderGoalEatTile.java b/src/main/java/net/minecraft/server/PathfinderGoalEatTile.java index e887da2f6..e9679bb46 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalEatTile.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalEatTile.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.function.Predicate; // CraftBukkit start @@ -16,29 +17,33 @@ public class PathfinderGoalEatTile extends PathfinderGoal { public PathfinderGoalEatTile(EntityInsentient entityinsentient) { this.b = entityinsentient; this.c = entityinsentient.world; - this.a(7); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK, PathfinderGoal.Type.JUMP)); } + @Override public boolean a() { if (this.b.getRandom().nextInt(this.b.isBaby() ? 50 : 1000) != 0) { return false; } else { - BlockPosition blockposition = new BlockPosition(this.b.locX, this.b.locY, this.b.locZ); + BlockPosition blockposition = new BlockPosition(this.b); return PathfinderGoalEatTile.a.test(this.c.getType(blockposition)) ? true : this.c.getType(blockposition.down()).getBlock() == Blocks.GRASS_BLOCK; } } + @Override public void c() { this.d = 40; this.c.broadcastEntityEffect(this.b, (byte) 10); - this.b.getNavigation().q(); + this.b.getNavigation().o(); } + @Override public void d() { this.d = 0; } + @Override public boolean b() { return this.d > 0; } @@ -47,29 +52,30 @@ public class PathfinderGoalEatTile extends PathfinderGoal { return this.d; } + @Override public void e() { this.d = Math.max(0, this.d - 1); if (this.d == 4) { - BlockPosition blockposition = new BlockPosition(this.b.locX, this.b.locY, this.b.locZ); + BlockPosition blockposition = new BlockPosition(this.b); if (PathfinderGoalEatTile.a.test(this.c.getType(blockposition))) { // CraftBukkit - if (!CraftEventFactory.callEntityChangeBlockEvent(this.b, blockposition, Blocks.AIR.getBlockData(), !this.c.getGameRules().getBoolean("mobGriefing")).isCancelled()) { - this.c.setAir(blockposition, false); + if (!CraftEventFactory.callEntityChangeBlockEvent(this.b, blockposition, Blocks.AIR.getBlockData(), !this.c.getGameRules().getBoolean(GameRules.MOB_GRIEFING)).isCancelled()) { + this.c.b(blockposition, false); } - this.b.x(); + this.b.blockEaten(); } else { BlockPosition blockposition1 = blockposition.down(); if (this.c.getType(blockposition1).getBlock() == Blocks.GRASS_BLOCK) { // CraftBukkit - if (!CraftEventFactory.callEntityChangeBlockEvent(this.b, blockposition, Blocks.AIR.getBlockData(), !this.c.getGameRules().getBoolean("mobGriefing")).isCancelled()) { + if (!CraftEventFactory.callEntityChangeBlockEvent(this.b, blockposition, Blocks.AIR.getBlockData(), !this.c.getGameRules().getBoolean(GameRules.MOB_GRIEFING)).isCancelled()) { this.c.triggerEffect(2001, blockposition1, Block.getCombinedId(Blocks.GRASS_BLOCK.getBlockData())); this.c.setTypeAndData(blockposition1, Blocks.DIRT.getBlockData(), 2); } - this.b.x(); + this.b.blockEaten(); } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalFloat.java b/src/main/java/net/minecraft/server/PathfinderGoalFloat.java index 38a0b2db1..2e23b5de5 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalFloat.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalFloat.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import java.util.EnumSet; + public class PathfinderGoalFloat extends PathfinderGoal { private final EntityInsentient a; @@ -7,19 +9,23 @@ public class PathfinderGoalFloat extends PathfinderGoal { public PathfinderGoalFloat(EntityInsentient entityinsentient) { this.a = entityinsentient; if (entityinsentient.getWorld().paperConfig.nerfedMobsShouldJump) entityinsentient.goalFloat = this; // Paper - this.a(4); + this.a(EnumSet.of(PathfinderGoal.Type.JUMP)); entityinsentient.getNavigation().d(true); } - public boolean validConditions() { return this.a(); } // Paper - OBFHELPER + public final boolean validConditions() { return this.a(); } // Paper - OBFHELPER + @Override public boolean a() { - return this.a.isInWater() && this.a.bY() > 0.4D || this.a.ax(); + double d0 = (double) this.a.getHeadHeight() < 0.4D ? 0.2D : 0.4D; + + return this.a.isInWater() && this.a.cf() > d0 || this.a.aD(); } public void update() { this.e(); } // Paper - OBFHELPER + @Override public void e() { if (this.a.getRandom().nextFloat() < 0.8F) { - this.a.getControllerJump().a(); + this.a.getControllerJump().jump(); } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalFollowOwner.java b/src/main/java/net/minecraft/server/PathfinderGoalFollowOwner.java index d7f219454..896d2d56a 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalFollowOwner.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalFollowOwner.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.EnumSet; // CraftBukkit start import org.bukkit.Location; import org.bukkit.craftbukkit.entity.CraftEntity; @@ -8,9 +9,9 @@ import org.bukkit.event.entity.EntityTeleportEvent; public class PathfinderGoalFollowOwner extends PathfinderGoal { - private final EntityTameableAnimal b; + protected final EntityTameableAnimal a; private EntityLiving c; - protected final IWorldReader a; + protected final IWorldReader b; private final double d; private final NavigationAbstract e; private int f; @@ -19,28 +20,29 @@ public class PathfinderGoalFollowOwner extends PathfinderGoal { private float i; public PathfinderGoalFollowOwner(EntityTameableAnimal entitytameableanimal, double d0, float f, float f1) { - this.b = entitytameableanimal; - this.a = entitytameableanimal.world; + this.a = entitytameableanimal; + this.b = entitytameableanimal.world; this.d = d0; this.e = entitytameableanimal.getNavigation(); this.h = f; this.g = f1; - this.a(3); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); if (!(entitytameableanimal.getNavigation() instanceof Navigation) && !(entitytameableanimal.getNavigation() instanceof NavigationFlying)) { throw new IllegalArgumentException("Unsupported mob type for FollowOwnerGoal"); } } + @Override public boolean a() { - EntityLiving entityliving = this.b.getOwner(); + EntityLiving entityliving = this.a.getOwner(); if (entityliving == null) { return false; } else if (entityliving instanceof EntityHuman && ((EntityHuman) entityliving).isSpectator()) { return false; - } else if (this.b.isSitting()) { + } else if (this.a.isSitting()) { return false; - } else if (this.b.h(entityliving) < (double) (this.h * this.h)) { + } else if (this.a.h((Entity) entityliving) < (double) (this.h * this.h)) { return false; } else { this.c = entityliving; @@ -48,50 +50,54 @@ public class PathfinderGoalFollowOwner extends PathfinderGoal { } } + @Override public boolean b() { - return !this.e.p() && this.b.h(this.c) > (double) (this.g * this.g) && !this.b.isSitting(); + return !this.e.n() && this.a.h((Entity) this.c) > (double) (this.g * this.g) && !this.a.isSitting(); } + @Override public void c() { this.f = 0; - this.i = this.b.a(PathType.WATER); - this.b.a(PathType.WATER, 0.0F); + this.i = this.a.a(PathType.WATER); + this.a.a(PathType.WATER, 0.0F); } + @Override public void d() { this.c = null; - this.e.q(); - this.b.a(PathType.WATER, this.i); + this.e.o(); + this.a.a(PathType.WATER, this.i); } + @Override public void e() { - this.b.getControllerLook().a(this.c, 10.0F, (float) this.b.K()); - if (!this.b.isSitting()) { + this.a.getControllerLook().a(this.c, 10.0F, (float) this.a.M()); + if (!this.a.isSitting()) { if (--this.f <= 0) { this.f = 10; if (!this.e.a((Entity) this.c, this.d)) { - if (!this.b.isLeashed() && !this.b.isPassenger()) { - if (this.b.h(this.c) >= 144.0D) { + if (!this.a.isLeashed() && !this.a.isPassenger()) { + if (this.a.h((Entity) this.c) >= 144.0D) { int i = MathHelper.floor(this.c.locX) - 2; int j = MathHelper.floor(this.c.locZ) - 2; int k = MathHelper.floor(this.c.getBoundingBox().minY); for (int l = 0; l <= 4; ++l) { for (int i1 = 0; i1 <= 4; ++i1) { - if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && this.a(i, j, k, l, i1)) { + if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && this.a(new BlockPosition(i + l, k - 1, j + i1))) { // CraftBukkit start - CraftEntity entity = this.b.getBukkitEntity(); - Location to = new Location(entity.getWorld(), (double) ((float) (i + l) + 0.5F), (double) k, (double) ((float) (j + i1) + 0.5F), this.b.yaw, this.b.pitch); + CraftEntity entity = this.a.getBukkitEntity(); + Location to = new Location(entity.getWorld(), (double) ((float) (i + l) + 0.5F), (double) k, (double) ((float) (j + i1) + 0.5F), this.a.yaw, this.a.pitch); EntityTeleportEvent event = new EntityTeleportEvent(entity, entity.getLocation(), to); - this.b.world.getServer().getPluginManager().callEvent(event); + this.a.world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return; } to = event.getTo(); - this.b.setPositionRotation(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch()); + this.a.setPositionRotation(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch()); // CraftBukkit end - this.e.q(); + this.e.o(); return; } } @@ -104,10 +110,9 @@ public class PathfinderGoalFollowOwner extends PathfinderGoal { } } - protected boolean a(int i, int j, int k, int l, int i1) { - BlockPosition blockposition = new BlockPosition(i + l, k - 1, j + i1); - IBlockData iblockdata = this.a.getType(blockposition); + protected boolean a(BlockPosition blockposition) { + IBlockData iblockdata = this.b.getType(blockposition); - return iblockdata.c(this.a, blockposition, EnumDirection.DOWN) == EnumBlockFaceShape.SOLID && iblockdata.a((Entity) this.b) && this.a.isEmpty(blockposition.up()) && this.a.isEmpty(blockposition.up(2)); + return iblockdata.a((IBlockAccess) this.b, blockposition, this.a.getEntityType()) && this.b.isEmpty(blockposition.up()) && this.b.isEmpty(blockposition.up(2)); } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java deleted file mode 100644 index 756d63239..000000000 --- a/src/main/java/net/minecraft/server/PathfinderGoalGotoTarget.java +++ /dev/null @@ -1,116 +0,0 @@ -package net.minecraft.server; - -public abstract class PathfinderGoalGotoTarget extends PathfinderGoal { - - private final EntityCreature f;public EntityCreature getEntity() { return f; } // Paper - OBFHELPER - public double a; - protected int b; - protected int c; - private int g; - protected BlockPosition d; public BlockPosition getTarget() { return d; } public void setTarget(BlockPosition pos) { this.d = pos; getEntity().movingTarget = pos != BlockPosition.ZERO ? pos : null; } // Paper - OBFHELPER - private boolean h; - private final int i; - private final int j; - public int e; - - public PathfinderGoalGotoTarget(EntityCreature entitycreature, double d0, int i) { - this(entitycreature, d0, i, 1); - } - // Paper start - activation range improvements - @Override - public void onTaskReset() { - super.onTaskReset(); - setTarget(BlockPosition.ZERO); - } - // Paper end - - public PathfinderGoalGotoTarget(EntityCreature entitycreature, double d0, int i, int j) { - this.d = BlockPosition.ZERO; - this.f = entitycreature; - this.a = d0; - this.i = i; - this.e = 0; - this.j = j; - this.a(5); - } - - public boolean a() { - if (this.b > 0) { - --this.b; - return false; - } else { - this.b = this.a(this.f); - return this.l(); - } - } - - protected int a(EntityCreature entitycreature) { - return 200 + entitycreature.getRandom().nextInt(200); - } - - public boolean b() { - return this.c >= -this.g && this.c <= 1200 && this.a(this.f.world, this.d); - } - - public void c() { - this.f.getNavigation().a((double) ((float) this.d.getX()) + 0.5D, (double) (this.d.getY() + 1), (double) ((float) this.d.getZ()) + 0.5D, this.a); - this.c = 0; - this.g = this.f.getRandom().nextInt(this.f.getRandom().nextInt(1200) + 1200) + 1200; - } - - public double g() { - return 1.0D; - } - - public void e() { - if (this.f.d(this.d.up()) > this.g()) { - this.h = false; - ++this.c; - if (this.i()) { - this.f.getNavigation().a((double) ((float) this.d.getX()) + 0.5D, (double) (this.d.getY() + this.j()), (double) ((float) this.d.getZ()) + 0.5D, this.a); - } - } else { - this.h = true; - --this.c; - } - - } - - public boolean i() { - return this.c % 40 == 0; - } - - public int j() { - return 1; - } - - protected boolean k() { - return this.h; - } - - private boolean l() { - int i = this.i; - int j = this.j; - BlockPosition blockposition = new BlockPosition(this.f); - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - - for (int k = this.e; k <= j; k = k > 0 ? -k : 1 - k) { - for (int l = 0; l < i; ++l) { - for (int i1 = 0; i1 <= l; i1 = i1 > 0 ? -i1 : 1 - i1) { - for (int j1 = i1 < l && i1 > -l ? l : 0; j1 <= l; j1 = j1 > 0 ? -j1 : 1 - j1) { - blockposition_mutableblockposition.g(blockposition).d(i1, k - 1, j1); - if (this.f.f((BlockPosition) blockposition_mutableblockposition) && this.a(this.f.world, blockposition_mutableblockposition)) { - this.d = blockposition_mutableblockposition; - setTarget(blockposition_mutableblockposition.toBlockPosition()); // Paper - return true; - } - } - } - } - } - - return false; - } - - protected abstract boolean a(IWorldReader iworldreader, BlockPosition blockposition); -} diff --git a/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java b/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java index 887e4461f..f09374413 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalHorseTrap.java @@ -8,15 +8,17 @@ public class PathfinderGoalHorseTrap extends PathfinderGoal { this.a = entityhorseskeleton; } + @Override public boolean a() { return this.a.world.isPlayerNearby(this.a.locX, this.a.locY, this.a.locZ, 10.0D); } + @Override public void e() { if (!new com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent((org.bukkit.entity.SkeletonHorse) this.a.getBukkitEntity()).callEvent()) return; // Paper DifficultyDamageScaler difficultydamagescaler = this.a.world.getDamageScaler(new BlockPosition(this.a)); - this.a.s(false); + this.a.r(false); this.a.setTamed(true); this.a.setAgeRaw(0); ((WorldServer) this.a.world).strikeLightning(new EntityLightning(this.a.world, this.a.locX, this.a.locY, this.a.locZ, true), org.bukkit.event.weather.LightningStrikeEvent.Cause.TRAP); // CraftBukkit @@ -36,12 +38,12 @@ public class PathfinderGoalHorseTrap extends PathfinderGoal { } private EntityHorseAbstract a(DifficultyDamageScaler difficultydamagescaler) { - EntityHorseSkeleton entityhorseskeleton = EntityTypes.SKELETON_HORSE.create(a.world); // Paper + EntityHorseSkeleton entityhorseskeleton = (EntityHorseSkeleton) EntityTypes.SKELETON_HORSE.a(this.a.world); - entityhorseskeleton.prepare(difficultydamagescaler, (GroupDataEntity) null, (NBTTagCompound) null); + entityhorseskeleton.prepare(this.a.world, difficultydamagescaler, EnumMobSpawn.TRIGGERED, (GroupDataEntity) null, (NBTTagCompound) null); entityhorseskeleton.setPosition(this.a.locX, this.a.locY, this.a.locZ); entityhorseskeleton.noDamageTicks = 60; - entityhorseskeleton.di(); + entityhorseskeleton.setPersistent(); entityhorseskeleton.setTamed(true); entityhorseskeleton.setAgeRaw(0); if (!entityhorseskeleton.world.addEntity(entityhorseskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRAP)) return null; // CraftBukkit @@ -49,12 +51,12 @@ public class PathfinderGoalHorseTrap extends PathfinderGoal { } private EntitySkeleton a(DifficultyDamageScaler difficultydamagescaler, EntityHorseAbstract entityhorseabstract) { - EntitySkeleton entityskeleton = EntityTypes.SKELETON.create(entityhorseabstract.world); // Paper + EntitySkeleton entityskeleton = (EntitySkeleton) EntityTypes.SKELETON.a(entityhorseabstract.world); - entityskeleton.prepare(difficultydamagescaler, (GroupDataEntity) null, (NBTTagCompound) null); + entityskeleton.prepare(entityhorseabstract.world, difficultydamagescaler, EnumMobSpawn.TRIGGERED, (GroupDataEntity) null, (NBTTagCompound) null); entityskeleton.setPosition(entityhorseabstract.locX, entityhorseabstract.locY, entityhorseabstract.locZ); entityskeleton.noDamageTicks = 60; - entityskeleton.di(); + entityskeleton.setPersistent(); if (entityskeleton.getEquipment(EnumItemSlot.HEAD).isEmpty()) { entityskeleton.setSlot(EnumItemSlot.HEAD, new ItemStack(Items.IRON_HELMET)); } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalHurtByTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalHurtByTarget.java index 0b1ed139f..a9bfa5f6a 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalHurtByTarget.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalHurtByTarget.java @@ -1,34 +1,59 @@ package net.minecraft.server; +import java.util.EnumSet; import java.util.Iterator; import java.util.List; public class PathfinderGoalHurtByTarget extends PathfinderGoalTarget { - private final boolean a; - private int b; - private final Class[] c; + private static final PathfinderTargetCondition a = (new PathfinderTargetCondition()).c().e(); + private boolean b; + private int c; + private final Class[] d; + private Class[] i; - public PathfinderGoalHurtByTarget(EntityCreature entitycreature, boolean flag, Class... aclass) { + public PathfinderGoalHurtByTarget(EntityCreature entitycreature, Class... aclass) { super(entitycreature, true); - this.a = flag; - this.c = aclass; - this.a(1); + this.d = aclass; + this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); } + @Override public boolean a() { - int i = this.e.cg(); + int i = this.e.ct(); EntityLiving entityliving = this.e.getLastDamager(); - return i != this.b && entityliving != null && this.a(entityliving, false); + if (i != this.c && entityliving != null) { + Class[] aclass = this.d; + int j = aclass.length; + + for (int k = 0; k < j; ++k) { + Class oclass = aclass[k]; + + if (oclass.isAssignableFrom(entityliving.getClass())) { + return false; + } + } + + return this.a(entityliving, PathfinderGoalHurtByTarget.a); + } else { + return false; + } } + public PathfinderGoalHurtByTarget a(Class... aclass) { + this.b = true; + this.i = aclass; + return this; + } + + @Override public void c() { this.e.setGoalTarget(this.e.getLastDamager(), org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit - reason this.g = this.e.getGoalTarget(); - this.b = this.e.cg(); + this.c = this.e.ct(); this.h = 300; - if (this.a) { + if (this.b) { this.g(); } @@ -36,36 +61,40 @@ public class PathfinderGoalHurtByTarget extends PathfinderGoalTarget { } protected void g() { - double d0 = this.i(); - List list = this.e.world.a(this.e.getClass(), (new AxisAlignedBB(this.e.locX, this.e.locY, this.e.locZ, this.e.locX + 1.0D, this.e.locY + 1.0D, this.e.locZ + 1.0D)).grow(d0, 10.0D, d0)); + double d0 = this.k(); + List list = this.e.world.b(this.e.getClass(), (new AxisAlignedBB(this.e.locX, this.e.locY, this.e.locZ, this.e.locX + 1.0D, this.e.locY + 1.0D, this.e.locZ + 1.0D)).grow(d0, 10.0D, d0)); Iterator iterator = list.iterator(); while (iterator.hasNext()) { - EntityCreature entitycreature = (EntityCreature) iterator.next(); + EntityInsentient entityinsentient = (EntityInsentient) iterator.next(); - if (this.e != entitycreature && entitycreature.getGoalTarget() == null && (!(this.e instanceof EntityTameableAnimal) || ((EntityTameableAnimal) this.e).getOwner() == ((EntityTameableAnimal) entitycreature).getOwner()) && !entitycreature.r(this.e.getLastDamager())) { - boolean flag = false; - Class[] aclass = this.c; - int i = aclass.length; + if (this.e != entityinsentient && entityinsentient.getGoalTarget() == null && (!(this.e instanceof EntityTameableAnimal) || ((EntityTameableAnimal) this.e).getOwner() == ((EntityTameableAnimal) entityinsentient).getOwner()) && !entityinsentient.r(this.e.getLastDamager())) { + if (this.i != null) { + boolean flag = false; + Class[] aclass = this.i; + int i = aclass.length; - for (int j = 0; j < i; ++j) { - Class oclass = aclass[j]; + for (int j = 0; j < i; ++j) { + Class oclass = aclass[j]; - if (entitycreature.getClass() == oclass) { - flag = true; - break; + if (entityinsentient.getClass() == oclass) { + flag = true; + break; + } + } + + if (flag) { + continue; } } - if (!flag) { - this.a(entitycreature, this.e.getLastDamager()); - } + this.a(entityinsentient, this.e.getLastDamager()); } } } - protected void a(EntityCreature entitycreature, EntityLiving entityliving) { - entitycreature.setGoalTarget(entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true); // CraftBukkit - reason + protected void a(EntityInsentient entityinsentient, EntityLiving entityliving) { + entityinsentient.setGoalTarget(entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true); // CraftBukkit - reason } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalMakeLove.java b/src/main/java/net/minecraft/server/PathfinderGoalMakeLove.java deleted file mode 100644 index d0ff2a871..000000000 --- a/src/main/java/net/minecraft/server/PathfinderGoalMakeLove.java +++ /dev/null @@ -1,98 +0,0 @@ -package net.minecraft.server; - -public class PathfinderGoalMakeLove extends PathfinderGoal { - - private final EntityVillager a; - private EntityVillager b; - private final World c; - private int d; - private Village e; - - public PathfinderGoalMakeLove(EntityVillager entityvillager) { - this.a = entityvillager; - this.c = entityvillager.world; - this.a(3); - } - - public boolean a() { - if (this.a.getAge() != 0) { - return false; - } else if (this.a.getRandom().nextInt(500) != 0) { - return false; - } else { - this.e = this.c.af().getClosestVillage(new BlockPosition(this.a), 0); - if (this.e == null) { - return false; - } else if (this.g() && this.a.u(true)) { - Entity entity = this.c.a(EntityVillager.class, this.a.getBoundingBox().grow(8.0D, 3.0D, 8.0D), (Entity) this.a); - - if (entity == null) { - return false; - } else { - this.b = (EntityVillager) entity; - return this.b.getAge() == 0 && this.b.u(true); - } - } else { - return false; - } - } - } - - public void c() { - this.d = 300; - this.a.s(true); - } - - public void d() { - this.e = null; - this.b = null; - this.a.s(false); - } - - public boolean b() { - return this.d >= 0 && this.g() && this.a.getAge() == 0 && this.a.u(false); - } - - public void e() { - --this.d; - this.a.getControllerLook().a(this.b, 10.0F, 30.0F); - if (this.a.h(this.b) > 2.25D) { - this.a.getNavigation().a((Entity) this.b, 0.25D); - } else if (this.d == 0 && this.b.isInLove()) { - this.i(); - } - - if (this.a.getRandom().nextInt(35) == 0) { - this.c.broadcastEntityEffect(this.a, (byte) 12); - } - - } - - private boolean g() { - if (!this.e.i()) { - return false; - } else { - int i = (int) ((double) ((float) this.e.c()) * 0.35D); - - return this.e.e() < i; - } - } - - private void i() { - EntityVillager entityvillager = this.a.createChild(this.b); - // CraftBukkit start - call EntityBreedEvent - if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(entityvillager, this.a, this.b, null, null, 0).isCancelled()) { - return; - } - // CraftBukkit end - - this.b.setAgeRaw(6000); - this.a.setAgeRaw(6000); - this.b.v(false); - this.a.v(false); - entityvillager.setAgeRaw(-24000); - entityvillager.setPositionRotation(this.a.locX, this.a.locY, this.a.locZ, 0.0F, 0.0F); - this.c.addEntity(entityvillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason - this.c.broadcastEntityEffect(entityvillager, (byte) 12); - } -} diff --git a/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java index f64532f8b..3295dfa98 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java @@ -1,62 +1,39 @@ package net.minecraft.server; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.function.Function; +import java.util.EnumSet; import java.util.function.Predicate; import javax.annotation.Nullable; public class PathfinderGoalNearestAttackableTarget extends PathfinderGoalTarget { protected final Class a; - private final int i; - protected final PathfinderGoalNearestAttackableTarget.DistanceComparator b; - protected final Predicate c; - protected T d; + protected final int b; + protected EntityLiving c; + protected PathfinderTargetCondition d; - public PathfinderGoalNearestAttackableTarget(EntityCreature entitycreature, Class oclass, boolean flag) { - this(entitycreature, oclass, flag, false); + public PathfinderGoalNearestAttackableTarget(EntityInsentient entityinsentient, Class oclass, boolean flag) { + this(entityinsentient, oclass, flag, false); } - public PathfinderGoalNearestAttackableTarget(EntityCreature entitycreature, Class oclass, boolean flag, boolean flag1) { - this(entitycreature, oclass, 10, flag, flag1, (Predicate) null); + public PathfinderGoalNearestAttackableTarget(EntityInsentient entityinsentient, Class oclass, boolean flag, boolean flag1) { + this(entityinsentient, oclass, 10, flag, flag1, (Predicate) null); } - public PathfinderGoalNearestAttackableTarget(EntityCreature entitycreature, Class oclass, int i, boolean flag, boolean flag1, @Nullable Predicate predicate) { - super(entitycreature, flag, flag1); + public PathfinderGoalNearestAttackableTarget(EntityInsentient entityinsentient, Class oclass, int i, boolean flag, boolean flag1, @Nullable Predicate predicate) { + super(entityinsentient, flag, flag1); this.a = oclass; - this.i = i; - this.b = new PathfinderGoalNearestAttackableTarget.DistanceComparator(entitycreature); - this.a(1); - this.c = (entityliving) -> { - return entityliving == null ? false : (predicate != null && !predicate.test(entityliving) ? false : (!IEntitySelector.f.test(entityliving) ? false : this.a(entityliving, false))); - }; + this.b = i; + this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); + this.d = (new PathfinderTargetCondition()).a(this.k()).a(predicate); } + @Override public boolean a() { - if (this.i > 0 && this.e.getRandom().nextInt(this.i) != 0) { + if (this.b > 0 && this.e.getRandom().nextInt(this.b) != 0) { return false; - } else if (this.a != EntityHuman.class && this.a != EntityPlayer.class) { - List list = this.e.world.a(this.a, this.a(this.i()), this.c); - - if (list.isEmpty()) { - return false; - } else { - Collections.sort(list, this.b); - this.d = (T) list.get(0); // CraftBukkit - fix decompile error - return true; - } } else { - this.d = (T) this.e.world.a(this.e.locX, this.e.locY + (double) this.e.getHeadHeight(), this.e.locZ, this.i(), this.i(), new Function() { // CraftBukkit - fix decompile error - @Nullable - public Double apply(@Nullable EntityHuman entityhuman) { - ItemStack itemstack = entityhuman.getEquipment(EnumItemSlot.HEAD); - - return (!(PathfinderGoalNearestAttackableTarget.this.e instanceof EntitySkeleton) || itemstack.getItem() != Items.SKELETON_SKULL) && (!(PathfinderGoalNearestAttackableTarget.this.e instanceof EntityZombie) || itemstack.getItem() != Items.ZOMBIE_HEAD) && (!(PathfinderGoalNearestAttackableTarget.this.e instanceof EntityCreeper) || itemstack.getItem() != Items.CREEPER_HEAD) ? 1.0D : 0.5D; - } - }, (Predicate) this.c); // CraftBukkit - fix decompile error - return this.d != null; + this.g(); + return this.c != null; } } @@ -64,24 +41,18 @@ public class PathfinderGoalNearestAttackableTarget exten return this.e.getBoundingBox().grow(d0, 4.0D, d0); } + protected void g() { + if (this.a != EntityHuman.class && this.a != EntityPlayer.class) { + this.c = this.e.world.b(this.a, this.d, this.e, this.e.locX, this.e.locY + (double) this.e.getHeadHeight(), this.e.locZ, this.a(this.k())); + } else { + this.c = this.e.world.a(this.d, this.e, this.e.locX, this.e.locY + (double) this.e.getHeadHeight(), this.e.locZ); + } + + } + + @Override public void c() { - this.e.setGoalTarget(this.d, d instanceof EntityPlayer ? org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER : org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY, true); // Craftbukkit - reason + this.e.setGoalTarget(this.c, c instanceof EntityPlayer ? org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER : org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY, true); // Craftbukkit - reason super.c(); } - - public static class DistanceComparator implements Comparator { - - private final Entity a; - - public DistanceComparator(Entity entity) { - this.a = entity; - } - - public int compare(Entity entity, Entity entity1) { - double d0 = this.a.h(entity); - double d1 = this.a.h(entity1); - - return d0 < d1 ? -1 : (d0 > d1 ? 1 : 0); - } - } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTargetInsentient.java b/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTargetInsentient.java deleted file mode 100644 index 8eaa641b8..000000000 --- a/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTargetInsentient.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.minecraft.server; - -import java.util.Collections; -import java.util.List; -import java.util.function.Predicate; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class PathfinderGoalNearestAttackableTargetInsentient extends PathfinderGoal { - - private static final Logger a = LogManager.getLogger(); - private final EntityInsentient b; - private final Predicate c; - private final PathfinderGoalNearestAttackableTarget.DistanceComparator d; - private EntityLiving e; - private final Class f; - - public PathfinderGoalNearestAttackableTargetInsentient(EntityInsentient entityinsentient, Class oclass) { - this.b = entityinsentient; - this.f = oclass; - if (entityinsentient instanceof EntityCreature) { - PathfinderGoalNearestAttackableTargetInsentient.a.warn("Use NearestAttackableTargetGoal.class for PathfinerMob mobs!"); - } - - this.c = (entityliving) -> { - double d0 = this.g(); - - if (entityliving.isSneaking()) { - d0 *= 0.800000011920929D; - } - - return entityliving.isInvisible() ? false : ((double) entityliving.g(this.b) > d0 ? false : PathfinderGoalTarget.a(this.b, entityliving, false, true)); - }; - this.d = new PathfinderGoalNearestAttackableTarget.DistanceComparator(entityinsentient); - } - - public boolean a() { - double d0 = this.g(); - List list = this.b.world.a(this.f, this.b.getBoundingBox().grow(d0, 4.0D, d0), this.c); - - Collections.sort(list, this.d); - if (list.isEmpty()) { - return false; - } else { - this.e = (EntityLiving) list.get(0); - return true; - } - } - - public boolean b() { - EntityLiving entityliving = this.b.getGoalTarget(); - - if (entityliving == null) { - return false; - } else if (!entityliving.isAlive()) { - return false; - } else { - double d0 = this.g(); - - return this.b.h(entityliving) > d0 * d0 ? false : !(entityliving instanceof EntityPlayer) || !((EntityPlayer) entityliving).playerInteractManager.isCreative(); - } - } - - public void c() { - this.b.setGoalTarget(this.e, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY, true); // CraftBukkit - reason - super.c(); - } - - public void d() { - this.b.setGoalTarget((EntityLiving) null); - super.c(); - } - - protected double g() { - AttributeInstance attributeinstance = this.b.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); - - return attributeinstance == null ? 16.0D : attributeinstance.getValue(); - } -} diff --git a/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtByTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtByTarget.java index 834486024..5b99b0ddd 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtByTarget.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtByTarget.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import java.util.EnumSet; + public class PathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget { private final EntityTameableAnimal a; @@ -9,32 +11,34 @@ public class PathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget { public PathfinderGoalOwnerHurtByTarget(EntityTameableAnimal entitytameableanimal) { super(entitytameableanimal, false); this.a = entitytameableanimal; - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); } + @Override public boolean a() { - if (!this.a.isTamed()) { - return false; - } else { + if (this.a.isTamed() && !this.a.isSitting()) { EntityLiving entityliving = this.a.getOwner(); if (entityliving == null) { return false; } else { this.b = entityliving.getLastDamager(); - int i = entityliving.cg(); + int i = entityliving.ct(); - return i != this.c && this.a(this.b, false) && this.a.a(this.b, entityliving); + return i != this.c && this.a(this.b, PathfinderTargetCondition.a) && this.a.a(this.b, entityliving); } + } else { + return false; } } + @Override public void c() { this.e.setGoalTarget(this.b, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_OWNER, true); // CraftBukkit - reason EntityLiving entityliving = this.a.getOwner(); if (entityliving != null) { - this.c = entityliving.cg(); + this.c = entityliving.ct(); } super.c(); diff --git a/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtTarget.java index 7ea80b890..eb99159c8 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtTarget.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtTarget.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import java.util.EnumSet; + public class PathfinderGoalOwnerHurtTarget extends PathfinderGoalTarget { private final EntityTameableAnimal a; @@ -9,32 +11,34 @@ public class PathfinderGoalOwnerHurtTarget extends PathfinderGoalTarget { public PathfinderGoalOwnerHurtTarget(EntityTameableAnimal entitytameableanimal) { super(entitytameableanimal, false); this.a = entitytameableanimal; - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); } + @Override public boolean a() { - if (!this.a.isTamed()) { - return false; - } else { + if (this.a.isTamed() && !this.a.isSitting()) { EntityLiving entityliving = this.a.getOwner(); if (entityliving == null) { return false; } else { - this.b = entityliving.ch(); - int i = entityliving.ci(); + this.b = entityliving.cu(); + int i = entityliving.cv(); - return i != this.c && this.a(this.b, false) && this.a.a(this.b, entityliving); + return i != this.c && this.a(this.b, PathfinderTargetCondition.a) && this.a.a(this.b, entityliving); } + } else { + return false; } } + @Override public void c() { this.e.setGoalTarget(this.b, org.bukkit.event.entity.EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET, true); // CraftBukkit - reason EntityLiving entityliving = this.a.getOwner(); if (entityliving != null) { - this.c = entityliving.ci(); + this.c = entityliving.cv(); } super.c(); diff --git a/src/main/java/net/minecraft/server/PathfinderGoalPanic.java b/src/main/java/net/minecraft/server/PathfinderGoalPanic.java index 9377c1fba..f399683b7 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalPanic.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalPanic.java @@ -1,11 +1,12 @@ package net.minecraft.server; +import java.util.EnumSet; import javax.annotation.Nullable; public class PathfinderGoalPanic extends PathfinderGoal { protected final EntityCreature a; - protected double b; + protected final double b; protected double c; protected double d; protected double e; @@ -13,9 +14,10 @@ public class PathfinderGoalPanic extends PathfinderGoal { public PathfinderGoalPanic(EntityCreature entitycreature, double d0) { this.a = entitycreature; this.b = d0; - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); } + @Override public boolean a() { if (this.a.getLastDamager() == null && !this.a.isBurning()) { return false; @@ -48,10 +50,12 @@ public class PathfinderGoalPanic extends PathfinderGoal { } } + @Override public void c() { this.a.getNavigation().a(this.c, this.d, this.e, this.b); } + @Override public boolean b() { // CraftBukkit start - introduce a temporary timeout hack until this is fixed properly if ((this.a.ticksLived - this.a.hurtTimestamp) > 100) { @@ -59,7 +63,7 @@ public class PathfinderGoalPanic extends PathfinderGoal { return false; } // CraftBukkit end - return !this.a.getNavigation().p(); + return !this.a.getNavigation().n(); } @Nullable @@ -75,7 +79,7 @@ public class PathfinderGoalPanic extends PathfinderGoal { for (int j1 = k - i; j1 <= k + i; ++j1) { for (int k1 = l - j; k1 <= l + j; ++k1) { for (int l1 = i1 - i; l1 <= i1 + i; ++l1) { - blockposition_mutableblockposition.c(j1, k1, l1); + blockposition_mutableblockposition.d(j1, k1, l1); if (iblockaccess.getFluid(blockposition_mutableblockposition).a(TagsFluid.WATER)) { float f1 = (float) ((j1 - k) * (j1 - k) + (k1 - l) * (k1 - l) + (l1 - i1) * (l1 - i1)); diff --git a/src/main/java/net/minecraft/server/PathfinderGoalRemoveBlock.java b/src/main/java/net/minecraft/server/PathfinderGoalRemoveBlock.java index 3ca32123b..7ccb3d5c0 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalRemoveBlock.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalRemoveBlock.java @@ -9,44 +9,55 @@ import org.bukkit.event.entity.EntityInteractEvent; public class PathfinderGoalRemoveBlock extends PathfinderGoalGotoTarget { - private final Block f; + private final Block g; private final EntityInsentient entity; - private int h; + private int i; private World world; // Paper public PathfinderGoalRemoveBlock(Block block, EntityCreature entitycreature, double d0, int i) { super(entitycreature, d0, 24, i); - this.f = block; + this.g = block; this.entity = entitycreature; this.world = entitycreature.world; // Paper } + @Override public boolean a() { - return !this.entity.world.getGameRules().getBoolean("mobGriefing") ? false : (this.entity.getRandom().nextInt(20) != 0 ? false : super.a()); + if (!this.entity.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING)) { + return false; + } else if (this.c > 0) { + --this.c; + return false; + } else if (this.m()) { + this.c = 20; + return true; + } else { + this.c = this.a(this.a); + return false; + } } - protected int a(EntityCreature entitycreature) { - return 0; - } - - public boolean b() { - return super.b(); + private boolean m() { + return this.e != null && this.a((IWorldReader) this.a.world, this.e) ? true : this.l(); } + @Override public void d() { super.d(); this.entity.fallDistance = 1.0F; } + @Override public void c() { super.c(); - this.h = 0; + this.i = 0; } public void a(GeneratorAccess generatoraccess, BlockPosition blockposition) {} public void a(World world, BlockPosition blockposition) {} + @Override public void e() { super.e(); World world = this.entity.world; @@ -55,23 +66,27 @@ public class PathfinderGoalRemoveBlock extends PathfinderGoalGotoTarget { Random random = this.entity.getRandom(); if (this.k() && blockposition1 != null) { - if (this.h > 0) { - this.entity.motY = 0.3D; + Vec3D vec3d; + double d0; + + if (this.i > 0) { + vec3d = this.entity.getMot(); + this.entity.setMot(vec3d.x, 0.3D, vec3d.z); if (!world.isClientSide) { - double d0 = 0.08D; - - ((WorldServer) world).a(new ParticleParamItem(Particles.C, new ItemStack(Items.EGG)), (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.7D, (double) blockposition1.getZ() + 0.5D, 3, ((double) random.nextFloat() - 0.5D) * 0.08D, ((double) random.nextFloat() - 0.5D) * 0.08D, ((double) random.nextFloat() - 0.5D) * 0.08D, 0.15000000596046448D); + d0 = 0.08D; + ((WorldServer) world).a(new ParticleParamItem(Particles.ITEM, new ItemStack(Items.EGG)), (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.7D, (double) blockposition1.getZ() + 0.5D, 3, ((double) random.nextFloat() - 0.5D) * 0.08D, ((double) random.nextFloat() - 0.5D) * 0.08D, ((double) random.nextFloat() - 0.5D) * 0.08D, 0.15000000596046448D); } } - if (this.h % 2 == 0) { - this.entity.motY = -0.3D; - if (this.h % 6 == 0) { - this.a((GeneratorAccess) world, this.d); + if (this.i % 2 == 0) { + vec3d = this.entity.getMot(); + this.entity.setMot(vec3d.x, -0.3D, vec3d.z); + if (this.i % 6 == 0) { + this.a((GeneratorAccess) world, this.e); } } - if (this.h > 60) { + if (this.i > 60) { // CraftBukkit start - Step on eggs EntityInteractEvent event = new EntityInteractEvent(this.entity.getBukkitEntity(), CraftBlock.at(world, blockposition1)); world.getServer().getPluginManager().callEvent((EntityInteractEvent) event); @@ -80,21 +95,21 @@ public class PathfinderGoalRemoveBlock extends PathfinderGoalGotoTarget { return; } // CraftBukkit end - world.setAir(blockposition1); + world.a(blockposition1, false); if (!world.isClientSide) { for (int i = 0; i < 20; ++i) { + d0 = random.nextGaussian() * 0.02D; double d1 = random.nextGaussian() * 0.02D; double d2 = random.nextGaussian() * 0.02D; - double d3 = random.nextGaussian() * 0.02D; - ((WorldServer) world).a(Particles.J, (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D, 1, d1, d2, d3, 0.15000000596046448D); + ((WorldServer) world).a(Particles.POOF, (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D, 1, d0, d1, d2, 0.15000000596046448D); } - this.a(world, this.d); + this.a(world, blockposition1); } } - ++this.h; + ++this.i; } } @@ -103,17 +118,17 @@ public class PathfinderGoalRemoveBlock extends PathfinderGoalGotoTarget { private BlockPosition a(BlockPosition blockposition, IBlockAccess iblockaccess) { Block block = world.getBlockIfLoaded(blockposition); // Paper if (block == null) return null; // Paper - if (block == this.f) { // Paper + if (block == this.g) { // Paper return blockposition; } else { - BlockPosition[] ablockposition = new BlockPosition[] { blockposition.down(), blockposition.west(), blockposition.east(), blockposition.north(), blockposition.south(), blockposition.down().down()}; + BlockPosition[] ablockposition = new BlockPosition[]{blockposition.down(), blockposition.west(), blockposition.east(), blockposition.north(), blockposition.south(), blockposition.down().down()}; BlockPosition[] ablockposition1 = ablockposition; int i = ablockposition.length; for (int j = 0; j < i; ++j) { BlockPosition blockposition1 = ablockposition1[j]; - if (world.getBlockIfLoaded(blockposition1) == this.f) { // Paper + if (world.getBlockIfLoaded(blockposition1) == this.g) { // Paper return blockposition1; } } @@ -122,10 +137,10 @@ public class PathfinderGoalRemoveBlock extends PathfinderGoalGotoTarget { } } + @Override protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) { - Block block = world.getBlockIfLoaded(blockposition); // Paper - if (block == null) return false; // Paper + IChunkAccess ichunkaccess = iworldreader.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper - return block == this.f && iworldreader.getType(blockposition.up()).isAir() && iworldreader.getType(blockposition.up(2)).isAir(); + return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).getBlock() == this.g && ichunkaccess.getType(blockposition.up()).isAir() && ichunkaccess.getType(blockposition.up(2)).isAir(); } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java deleted file mode 100644 index a3b428885..000000000 --- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java +++ /dev/null @@ -1,190 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Sets; -import java.util.Iterator; -import java.util.Set; -import javax.annotation.Nullable; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class PathfinderGoalSelector { - - private static final Logger a = LogManager.getLogger(); - private final Set b = Sets.newLinkedHashSet(); - private final Set c = Sets.newLinkedHashSet();private Set getExecutingTasks() { return c; }// Paper - OBFHELPER - private final MethodProfiler d; - private int e;private int getCurRate() { return e; } private void incRate() { this.e++; }// Paper - OBFHELPER - private int f = 3;private int getTickRate() { return f; } // Paper - OBFHELPER - private int g; - - public PathfinderGoalSelector(MethodProfiler methodprofiler) { - this.d = methodprofiler; - } - - public void a(int i, PathfinderGoal pathfindergoal) { - this.b.add(new PathfinderGoalSelector.PathfinderGoalSelectorItem(i, pathfindergoal)); - } - - // Paper start - public boolean inactiveTick() { - if (getCurRate() % getTickRate() != 0) { - incRate(); - return false; - } else { - return true; - } - } - public boolean hasTasks() { - return !getExecutingTasks().isEmpty(); - } - // Paper end - - public void a(PathfinderGoal pathfindergoal) { - Iterator iterator = this.b.iterator(); - - PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem; - PathfinderGoal pathfindergoal1; - - do { - if (!iterator.hasNext()) { - return; - } - - pathfindergoalselector_pathfindergoalselectoritem = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); - pathfindergoal1 = pathfindergoalselector_pathfindergoalselectoritem.a; - } while (pathfindergoal1 != pathfindergoal); - - if (pathfindergoalselector_pathfindergoalselectoritem.c) { - pathfindergoalselector_pathfindergoalselectoritem.c = false; - pathfindergoalselector_pathfindergoalselectoritem.a.d(); - this.c.remove(pathfindergoalselector_pathfindergoalselectoritem); - } - - iterator.remove(); - } - - public void doTick() { - //this.d.enter("goalSetup"); // Akarin - remove caller - Iterator iterator; - PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem; - - if (this.e++ % this.f == 0) { - iterator = this.b.iterator(); - - while (iterator.hasNext()) { - pathfindergoalselector_pathfindergoalselectoritem = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); - if (pathfindergoalselector_pathfindergoalselectoritem.c) { - if (!this.b(pathfindergoalselector_pathfindergoalselectoritem) || !this.a(pathfindergoalselector_pathfindergoalselectoritem)) { - pathfindergoalselector_pathfindergoalselectoritem.c = false; - pathfindergoalselector_pathfindergoalselectoritem.a.d(); - this.c.remove(pathfindergoalselector_pathfindergoalselectoritem); - } - } else if (this.b(pathfindergoalselector_pathfindergoalselectoritem) && pathfindergoalselector_pathfindergoalselectoritem.a.a()) { - pathfindergoalselector_pathfindergoalselectoritem.c = true; - pathfindergoalselector_pathfindergoalselectoritem.a.c(); - this.c.add(pathfindergoalselector_pathfindergoalselectoritem); - } - } - } else { - iterator = this.c.iterator(); - - while (iterator.hasNext()) { - pathfindergoalselector_pathfindergoalselectoritem = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); - if (!this.a(pathfindergoalselector_pathfindergoalselectoritem)) { - pathfindergoalselector_pathfindergoalselectoritem.c = false; - pathfindergoalselector_pathfindergoalselectoritem.a.d(); - iterator.remove(); - } - } - } - - //this.d.exit(); // Akarin - remove caller - if (!this.c.isEmpty()) { - //this.d.enter("goalTick"); // Akarin - remove caller - iterator = this.c.iterator(); - - while (iterator.hasNext()) { - pathfindergoalselector_pathfindergoalselectoritem = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); - pathfindergoalselector_pathfindergoalselectoritem.a.e(); - } - - //this.d.exit(); // Akarin - remove caller - } - - } - - private boolean a(PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem) { - return pathfindergoalselector_pathfindergoalselectoritem.a.b(); - } - - private boolean b(PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem) { - if (this.c.isEmpty()) { - return true; - } else if (this.b(pathfindergoalselector_pathfindergoalselectoritem.a.h())) { - return false; - } else { - Iterator iterator = this.c.iterator(); - - while (iterator.hasNext()) { - PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem1 = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); - - if (pathfindergoalselector_pathfindergoalselectoritem1 != pathfindergoalselector_pathfindergoalselectoritem) { - if (pathfindergoalselector_pathfindergoalselectoritem.b >= pathfindergoalselector_pathfindergoalselectoritem1.b) { - if (!this.a(pathfindergoalselector_pathfindergoalselectoritem, pathfindergoalselector_pathfindergoalselectoritem1)) { - return false; - } - } else if (!pathfindergoalselector_pathfindergoalselectoritem1.a.f()) { - return false; - } - } - } - - return true; - } - } - - private boolean a(PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem, PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem1) { - return (pathfindergoalselector_pathfindergoalselectoritem.a.h() & pathfindergoalselector_pathfindergoalselectoritem1.a.h()) == 0; - } - - public boolean b(int i) { - return (this.g & i) > 0; - } - - public void c(int i) { - this.g |= i; - } - - public void d(int i) { - this.g &= ~i; - } - - public void a(int i, boolean flag) { - if (flag) { - this.d(i); - } else { - this.c(i); - } - - } - - class PathfinderGoalSelectorItem { - - public final PathfinderGoal a; - public final int b; - public boolean c; - - public PathfinderGoalSelectorItem(int i, PathfinderGoal pathfindergoal) { - this.b = i; - this.a = pathfindergoal; - } - - public boolean equals(@Nullable Object object) { - return this == object ? true : (object != null && this.getClass() == object.getClass() ? this.a.equals(((PathfinderGoalSelector.PathfinderGoalSelectorItem) object).a) : false); - } - - public int hashCode() { - return this.a.hashCode(); - } - } -} diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSit.java b/src/main/java/net/minecraft/server/PathfinderGoalSit.java index c5df8681c..3bb38030c 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalSit.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalSit.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import java.util.EnumSet; + public class PathfinderGoalSit extends PathfinderGoal { private final EntityTameableAnimal entity; @@ -7,28 +9,36 @@ public class PathfinderGoalSit extends PathfinderGoal { public PathfinderGoalSit(EntityTameableAnimal entitytameableanimal) { this.entity = entitytameableanimal; - this.a(5); + this.a(EnumSet.of(PathfinderGoal.Type.JUMP, PathfinderGoal.Type.MOVE)); } + @Override + public boolean b() { + return this.willSit; + } + + @Override public boolean a() { if (!this.entity.isTamed()) { return this.willSit && this.entity.getGoalTarget() == null; // CraftBukkit - Allow sitting for wild animals - } else if (this.entity.aq()) { + } else if (this.entity.av()) { return false; } else if (!this.entity.onGround) { return false; } else { EntityLiving entityliving = this.entity.getOwner(); - return entityliving == null ? true : (this.entity.h(entityliving) < 144.0D && entityliving.getLastDamager() != null ? false : this.willSit); + return entityliving == null ? true : (this.entity.h((Entity) entityliving) < 144.0D && entityliving.getLastDamager() != null ? false : this.willSit); } } + @Override public void c() { - this.entity.getNavigation().q(); + this.entity.getNavigation().o(); this.entity.setSitting(true); } + @Override public void d() { this.entity.setSitting(false); } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalTame.java b/src/main/java/net/minecraft/server/PathfinderGoalTame.java index 9d185e73e..85fd50b3d 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalTame.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalTame.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import java.util.EnumSet; + public class PathfinderGoalTame extends PathfinderGoal { private final EntityHorseAbstract entity; @@ -11,9 +13,10 @@ public class PathfinderGoalTame extends PathfinderGoal { public PathfinderGoalTame(EntityHorseAbstract entityhorseabstract, double d0) { this.entity = entityhorseabstract; this.b = d0; - this.a(1); + this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); } + @Override public boolean a() { if (!this.entity.isTamed() && this.entity.isVehicle()) { Vec3D vec3d = RandomPositionGenerator.a(this.entity, 5, 4); @@ -31,17 +34,20 @@ public class PathfinderGoalTame extends PathfinderGoal { } } + @Override public void c() { this.entity.getNavigation().a(this.c, this.d, this.e, this.b); } + @Override public boolean b() { - return !this.entity.isTamed() && !this.entity.getNavigation().p() && this.entity.isVehicle(); + return !this.entity.isTamed() && !this.entity.getNavigation().n() && this.entity.isVehicle(); } + @Override public void e() { if (!this.entity.isTamed() && this.entity.getRandom().nextInt(50) == 0) { - Entity entity = (Entity) this.entity.bP().get(0); + Entity entity = (Entity) this.entity.getPassengers().get(0); if (entity == null) { return; @@ -57,11 +63,11 @@ public class PathfinderGoalTame extends PathfinderGoal { return; } - this.entity.r(5); + this.entity.u(5); } this.entity.ejectPassengers(); - this.entity.dZ(); + this.entity.eu(); this.entity.world.broadcastEntityEffect(this.entity, (byte) 6); } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalTarget.java index f986c8fc8..f15d8bf83 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalTarget.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalTarget.java @@ -5,8 +5,8 @@ import org.bukkit.event.entity.EntityTargetEvent; // CraftBukkit public abstract class PathfinderGoalTarget extends PathfinderGoal { - protected final EntityCreature e; - protected boolean f; + protected final EntityInsentient e; + protected final boolean f; private final boolean a; private int b; private int c; @@ -14,17 +14,18 @@ public abstract class PathfinderGoalTarget extends PathfinderGoal { protected EntityLiving g; protected int h; - public PathfinderGoalTarget(EntityCreature entitycreature, boolean flag) { - this(entitycreature, flag, false); + public PathfinderGoalTarget(EntityInsentient entityinsentient, boolean flag) { + this(entityinsentient, flag, false); } - public PathfinderGoalTarget(EntityCreature entitycreature, boolean flag, boolean flag1) { + public PathfinderGoalTarget(EntityInsentient entityinsentient, boolean flag, boolean flag1) { this.h = 60; - this.e = entitycreature; + this.e = entityinsentient; this.f = flag; this.a = flag1; } + @Override public boolean b() { EntityLiving entityliving = this.e.getGoalTarget(); @@ -43,9 +44,9 @@ public abstract class PathfinderGoalTarget extends PathfinderGoal { if (scoreboardteambase != null && scoreboardteambase1 == scoreboardteambase) { return false; } else { - double d0 = this.i(); + double d0 = this.k(); - if (this.e.h(entityliving) > d0 * d0) { + if (this.e.h((Entity) entityliving) > d0 * d0) { return false; } else { if (this.f) { @@ -67,55 +68,31 @@ public abstract class PathfinderGoalTarget extends PathfinderGoal { } } - protected double i() { + protected double k() { AttributeInstance attributeinstance = this.e.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); return attributeinstance == null ? 16.0D : attributeinstance.getValue(); } + @Override public void c() { this.b = 0; this.c = 0; this.d = 0; } + @Override public void d() { this.e.setGoalTarget((EntityLiving) null, EntityTargetEvent.TargetReason.FORGOT_TARGET, true); // CraftBukkit this.g = null; } - public static boolean a(EntityInsentient entityinsentient, @Nullable EntityLiving entityliving, boolean flag, boolean flag1) { + protected boolean a(@Nullable EntityLiving entityliving, PathfinderTargetCondition pathfindertargetcondition) { if (entityliving == null) { return false; - } else if (entityliving == entityinsentient) { + } else if (!pathfindertargetcondition.a(this.e, entityliving)) { return false; - } else if (!entityliving.isAlive()) { - return false; - } else if (!entityinsentient.b(entityliving.getClass())) { - return false; - } else if (entityinsentient.r(entityliving)) { - return false; - } else { - if (entityinsentient instanceof EntityOwnable && ((EntityOwnable) entityinsentient).getOwnerUUID() != null) { - if (entityliving instanceof EntityOwnable && ((EntityOwnable) entityinsentient).getOwnerUUID().equals(((EntityOwnable) entityliving).getOwnerUUID())) { - return false; - } - - if (entityliving == ((EntityOwnable) entityinsentient).getOwner()) { - return false; - } - } else if (entityliving instanceof EntityHuman && !flag && ((EntityHuman) entityliving).abilities.isInvulnerable) { - return false; - } - - return !flag1 || entityinsentient.getEntitySenses().a(entityliving); - } - } - - protected boolean a(@Nullable EntityLiving entityliving, boolean flag) { - if (!a(this.e, entityliving, flag, this.f)) { - return false; - } else if (!this.e.f(new BlockPosition(entityliving))) { + } else if (!this.e.a(new BlockPosition(entityliving))) { return false; } else { if (this.a) { @@ -138,7 +115,7 @@ public abstract class PathfinderGoalTarget extends PathfinderGoal { private boolean a(EntityLiving entityliving) { this.c = 10 + this.e.getRandom().nextInt(5); - PathEntity pathentity = this.e.getNavigation().a((Entity) entityliving); + PathEntity pathentity = this.e.getNavigation().a((Entity) entityliving, 0); if (pathentity == null) { return false; @@ -156,7 +133,7 @@ public abstract class PathfinderGoalTarget extends PathfinderGoal { } } - public PathfinderGoalTarget b(int i) { + public PathfinderGoalTarget a(int i) { this.h = i; return this; } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalTargetNearestPlayer.java b/src/main/java/net/minecraft/server/PathfinderGoalTargetNearestPlayer.java deleted file mode 100644 index df676f2d6..000000000 --- a/src/main/java/net/minecraft/server/PathfinderGoalTargetNearestPlayer.java +++ /dev/null @@ -1,102 +0,0 @@ -package net.minecraft.server; - -import java.util.Collections; -import java.util.List; -import java.util.function.Predicate; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class PathfinderGoalTargetNearestPlayer extends PathfinderGoal { - - private static final Logger a = LogManager.getLogger(); - private final EntityInsentient b; - private final Predicate c; - private final PathfinderGoalNearestAttackableTarget.DistanceComparator d; - private EntityLiving e; - - public PathfinderGoalTargetNearestPlayer(EntityInsentient entityinsentient) { - this.b = entityinsentient; - if (entityinsentient instanceof EntityCreature) { - PathfinderGoalTargetNearestPlayer.a.warn("Use NearestAttackableTargetGoal.class for PathfinerMob mobs!"); - } - - this.c = (entity) -> { - if (!(entity instanceof EntityHuman)) { - return false; - } else if (((EntityHuman) entity).abilities.isInvulnerable) { - return false; - } else { - double d0 = this.g(); - - if (entity.isSneaking()) { - d0 *= 0.800000011920929D; - } - - if (entity.isInvisible()) { - float f = ((EntityHuman) entity).dk(); - - if (f < 0.1F) { - f = 0.1F; - } - - d0 *= (double) (0.7F * f); - } - - return (double) entity.g(this.b) > d0 ? false : PathfinderGoalTarget.a(this.b, (EntityLiving) entity, false, true); - } - }; - this.d = new PathfinderGoalNearestAttackableTarget.DistanceComparator(entityinsentient); - } - - public boolean a() { - double d0 = this.g(); - List list = this.b.world.a(EntityHuman.class, this.b.getBoundingBox().grow(d0, 4.0D, d0), this.c); - - Collections.sort(list, this.d); - if (list.isEmpty()) { - return false; - } else { - this.e = (EntityLiving) list.get(0); - return true; - } - } - - public boolean b() { - EntityLiving entityliving = this.b.getGoalTarget(); - - if (entityliving == null) { - return false; - } else if (!entityliving.isAlive()) { - return false; - } else if (entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.isInvulnerable) { - return false; - } else { - ScoreboardTeamBase scoreboardteambase = this.b.getScoreboardTeam(); - ScoreboardTeamBase scoreboardteambase1 = entityliving.getScoreboardTeam(); - - if (scoreboardteambase != null && scoreboardteambase1 == scoreboardteambase) { - return false; - } else { - double d0 = this.g(); - - return this.b.h(entityliving) > d0 * d0 ? false : !(entityliving instanceof EntityPlayer) || !((EntityPlayer) entityliving).playerInteractManager.isCreative(); - } - } - } - - public void c() { - this.b.setGoalTarget(this.e, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit - added reason - super.c(); - } - - public void d() { - this.b.setGoalTarget((EntityLiving) null); - super.c(); - } - - protected double g() { - AttributeInstance attributeinstance = this.b.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); - - return attributeinstance == null ? 16.0D : attributeinstance.getValue(); - } -} diff --git a/src/main/java/net/minecraft/server/PathfinderGoalTempt.java b/src/main/java/net/minecraft/server/PathfinderGoalTempt.java index 1f3ae55a0..d1164dd68 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalTempt.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalTempt.java @@ -1,5 +1,6 @@ package net.minecraft.server; +import java.util.EnumSet; // CraftBukkit start import org.bukkit.craftbukkit.entity.CraftLivingEntity; import org.bukkit.craftbukkit.event.CraftEventFactory; @@ -9,18 +10,19 @@ import org.bukkit.event.entity.EntityTargetLivingEntityEvent; public class PathfinderGoalTempt extends PathfinderGoal { - private final EntityCreature a; - private final double b; - private double c; - private double d; + private static final PathfinderTargetCondition c = (new PathfinderTargetCondition()).a(10.0D).a().b().d().c(); + protected final EntityCreature a; + private final double d; private double e; private double f; private double g; - private EntityLiving target; // CraftBukkit - private int i; - private boolean j; - private final RecipeItemStack k; - private final boolean l; + private double h; + private double i; + protected EntityLiving target; // CraftBukkit + private int j; + private boolean k; + private final RecipeItemStack l; + private final boolean m; public PathfinderGoalTempt(EntityCreature entitycreature, double d0, RecipeItemStack recipeitemstack, boolean flag) { this(entitycreature, d0, flag, recipeitemstack); @@ -28,21 +30,22 @@ public class PathfinderGoalTempt extends PathfinderGoal { public PathfinderGoalTempt(EntityCreature entitycreature, double d0, boolean flag, RecipeItemStack recipeitemstack) { this.a = entitycreature; - this.b = d0; - this.k = recipeitemstack; - this.l = flag; - this.a(3); + this.d = d0; + this.l = recipeitemstack; + this.m = flag; + this.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); if (!(entitycreature.getNavigation() instanceof Navigation)) { throw new IllegalArgumentException("Unsupported mob type for TemptGoal"); } } + @Override public boolean a() { - if (this.i > 0) { - --this.i; + if (this.j > 0) { + --this.j; return false; } else { - this.target = this.a.world.findNearbyPlayer(this.a, 10.0D); + this.target = this.a.world.a(PathfinderGoalTempt.c, (EntityLiving) this.a); // CraftBukkit start boolean tempt = this.target == null ? false : this.a(this.target.getItemInMainHand()) || this.a(this.target.getItemInOffHand()); if (tempt) { @@ -58,57 +61,65 @@ public class PathfinderGoalTempt extends PathfinderGoal { } protected boolean a(ItemStack itemstack) { - return this.k.test(itemstack); + return this.l.test(itemstack); } + @Override public boolean b() { - if (this.l) { - if (this.a.h(this.target) < 36.0D) { - if (this.target.d(this.c, this.d, this.e) > 0.010000000000000002D) { + if (this.g()) { + if (this.a.h((Entity) this.target) < 36.0D) { + if (this.target.e(this.e, this.f, this.g) > 0.010000000000000002D) { return false; } - if (Math.abs((double) this.target.pitch - this.f) > 5.0D || Math.abs((double) this.target.yaw - this.g) > 5.0D) { + if (Math.abs((double) this.target.pitch - this.h) > 5.0D || Math.abs((double) this.target.yaw - this.i) > 5.0D) { return false; } } else { - this.c = this.target.locX; - this.d = this.target.locY; - this.e = this.target.locZ; + this.e = this.target.locX; + this.f = this.target.locY; + this.g = this.target.locZ; } - this.f = (double) this.target.pitch; - this.g = (double) this.target.yaw; + this.h = (double) this.target.pitch; + this.i = (double) this.target.yaw; } return this.a(); } - public void c() { - this.c = this.target.locX; - this.d = this.target.locY; - this.e = this.target.locZ; - this.j = true; + protected boolean g() { + return this.m; } + @Override + public void c() { + this.e = this.target.locX; + this.f = this.target.locY; + this.g = this.target.locZ; + this.k = true; + } + + @Override public void d() { this.target = null; - this.a.getNavigation().q(); - this.i = 100; - this.j = false; + this.a.getNavigation().o(); + this.j = 100; + this.k = false; } + @Override public void e() { - this.a.getControllerLook().a(this.target, (float) (this.a.L() + 20), (float) this.a.K()); - if (this.a.h(this.target) < 6.25D) { - this.a.getNavigation().q(); + this.a.getControllerLook().a(this.target, (float) (this.a.dA() + 20), (float) this.a.M()); + if (this.a.h((Entity) this.target) < 6.25D) { + this.a.getNavigation().o(); } else { - this.a.getNavigation().a((Entity) this.target, this.b); + this.a.getNavigation().a((Entity) this.target, this.d); } } - public boolean g() { - return this.j; + public boolean h() { + return this.k; } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalVillagerFarm.java b/src/main/java/net/minecraft/server/PathfinderGoalVillagerFarm.java deleted file mode 100644 index be418203a..000000000 --- a/src/main/java/net/minecraft/server/PathfinderGoalVillagerFarm.java +++ /dev/null @@ -1,117 +0,0 @@ -package net.minecraft.server; - -public class PathfinderGoalVillagerFarm extends PathfinderGoalGotoTarget { - - private final EntityVillager f; - private boolean g; - private boolean h; - private int i; - - public PathfinderGoalVillagerFarm(EntityVillager entityvillager, double d0) { - super(entityvillager, d0, 16); - this.f = entityvillager; - } - - public boolean a() { - if (this.b <= 0) { - if (!this.f.world.getGameRules().getBoolean("mobGriefing")) { - return false; - } - - this.i = -1; - this.g = this.f.dH(); - this.h = this.f.dG(); - } - - return super.a(); - } - - public boolean b() { - return this.i >= 0 && super.b(); - } - - public void e() { - super.e(); - this.f.getControllerLook().a((double) this.d.getX() + 0.5D, (double) (this.d.getY() + 1), (double) this.d.getZ() + 0.5D, 10.0F, (float) this.f.K()); - if (this.k()) { - World world = this.f.world; - BlockPosition blockposition = this.d.up(); - IBlockData iblockdata = world.getType(blockposition); - Block block = iblockdata.getBlock(); - - if (this.i == 0 && block instanceof BlockCrops && ((BlockCrops) block).w(iblockdata)) { - // CraftBukkit start - if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.f, blockposition, Blocks.AIR.getBlockData()).isCancelled()) { - world.setAir(blockposition, true); - } - // CraftBukkit end - } else if (this.i == 1 && iblockdata.isAir()) { - InventorySubcontainer inventorysubcontainer = this.f.dD(); - - for (int i = 0; i < inventorysubcontainer.getSize(); ++i) { - ItemStack itemstack = inventorysubcontainer.getItem(i); - boolean flag = false; - - if (!itemstack.isEmpty()) { - // CraftBukkit start - Block planted = null; - if (itemstack.getItem() == Items.WHEAT_SEEDS) { - planted = Blocks.WHEAT; - flag = true; - } else if (itemstack.getItem() == Items.POTATO) { - planted = Blocks.POTATOES; - flag = true; - } else if (itemstack.getItem() == Items.CARROT) { - planted = Blocks.CARROTS; - flag = true; - } else if (itemstack.getItem() == Items.BEETROOT_SEEDS) { - planted = Blocks.BEETROOTS; - flag = true; - } - - if (planted != null && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.f, blockposition, planted.getBlockData()).isCancelled()) { - world.setTypeAndData(blockposition, planted.getBlockData(), 3); - } else { - flag = false; - } - // CraftBukkit end - } - - if (flag) { - itemstack.subtract(1); - if (itemstack.isEmpty()) { - inventorysubcontainer.setItem(i, ItemStack.a); - } - break; - } - } - } - - this.i = -1; - this.b = 10; - } - - } - - protected boolean a(IWorldReader iworldreader, BlockPosition blockposition) { - Block block = iworldreader.getType(blockposition).getBlock(); - - if (block == Blocks.FARMLAND) { - blockposition = blockposition.up(); - IBlockData iblockdata = iworldreader.getType(blockposition); - - block = iblockdata.getBlock(); - if (block instanceof BlockCrops && ((BlockCrops) block).w(iblockdata) && this.h && (this.i == 0 || this.i < 0)) { - this.i = 0; - return true; - } - - if (iblockdata.isAir() && this.g && (this.i == 1 || this.i < 0)) { - this.i = 1; - return true; - } - } - - return false; - } -} diff --git a/src/main/java/net/minecraft/server/PathfinderNormal.java b/src/main/java/net/minecraft/server/PathfinderNormal.java index e45bdb581..45fd13503 100644 --- a/src/main/java/net/minecraft/server/PathfinderNormal.java +++ b/src/main/java/net/minecraft/server/PathfinderNormal.java @@ -12,34 +12,37 @@ public class PathfinderNormal extends PathfinderAbstract { public PathfinderNormal() {} - public void a(IBlockAccess iblockaccess, EntityInsentient entityinsentient) { - super.a(iblockaccess, entityinsentient); + @Override + public void a(IWorldReader iworldreader, EntityInsentient entityinsentient) { + super.a(iworldreader, entityinsentient); this.j = entityinsentient.a(PathType.WATER); } + @Override public void a() { this.b.a(PathType.WATER, this.j); super.a(); } + @Override public PathPoint b() { int i; BlockPosition blockposition; if (this.e() && this.b.isInWater()) { - i = (int) this.b.getBoundingBox().minY; - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(MathHelper.floor(this.b.locX), i, MathHelper.floor(this.b.locZ)); + i = MathHelper.floor(this.b.getBoundingBox().minY); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(this.b.locX, (double) i, this.b.locZ); - for (Block block = this.a.getType(blockposition_mutableblockposition).getBlock(); block == Blocks.WATER; block = this.a.getType(blockposition_mutableblockposition).getBlock()) { + for (IBlockData iblockdata = this.a.getType(blockposition_mutableblockposition); iblockdata.getBlock() == Blocks.WATER || iblockdata.p() == FluidTypes.WATER.a(false); iblockdata = this.a.getType(blockposition_mutableblockposition)) { ++i; - blockposition_mutableblockposition.c(MathHelper.floor(this.b.locX), i, MathHelper.floor(this.b.locZ)); + blockposition_mutableblockposition.c(this.b.locX, (double) i, this.b.locZ); } --i; } else if (this.b.onGround) { i = MathHelper.floor(this.b.getBoundingBox().minY + 0.5D); } else { - for (blockposition = new BlockPosition(this.b); (this.a.getType(blockposition).isAir() || this.a.getType(blockposition).a(this.a, blockposition, PathMode.LAND)) && blockposition.getY() > 0; blockposition = blockposition.down()) { + for (blockposition = new BlockPosition(this.b); (this.a.getType(blockposition).isAir() || this.a.getType(blockposition).a((IBlockAccess) this.a, blockposition, PathMode.LAND)) && blockposition.getY() > 0; blockposition = blockposition.down()) { ; } @@ -71,108 +74,114 @@ public class PathfinderNormal extends PathfinderAbstract { return this.a(blockposition.getX(), i, blockposition.getZ()); } - public PathPoint a(double d0, double d1, double d2) { - return this.a(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); + @Override + public PathDestination a(double d0, double d1, double d2) { + return new PathDestination(this.a(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2))); } - public int a(PathPoint[] apathpoint, PathPoint pathpoint, PathPoint pathpoint1, float f) { + @Override + public int a(PathPoint[] apathpoint, PathPoint pathpoint) { int i = 0; int j = 0; PathType pathtype = this.a(this.b, pathpoint.a, pathpoint.b + 1, pathpoint.c); if (this.b.a(pathtype) >= 0.0F) { - j = MathHelper.d(Math.max(1.0F, this.b.Q)); + j = MathHelper.d(Math.max(1.0F, this.b.K)); } - double d0 = a(this.a, new BlockPosition(pathpoint.a, pathpoint.b, pathpoint.c)); - PathPoint pathpoint2 = this.a(pathpoint.a, pathpoint.b, pathpoint.c + 1, j, d0, EnumDirection.SOUTH); - PathPoint pathpoint3 = this.a(pathpoint.a - 1, pathpoint.b, pathpoint.c, j, d0, EnumDirection.WEST); - PathPoint pathpoint4 = this.a(pathpoint.a + 1, pathpoint.b, pathpoint.c, j, d0, EnumDirection.EAST); - PathPoint pathpoint5 = this.a(pathpoint.a, pathpoint.b, pathpoint.c - 1, j, d0, EnumDirection.NORTH); + double d0 = a((IBlockAccess) this.a, new BlockPosition(pathpoint.a, pathpoint.b, pathpoint.c)); + PathPoint pathpoint1 = this.a(pathpoint.a, pathpoint.b, pathpoint.c + 1, j, d0, EnumDirection.SOUTH); - if (pathpoint2 != null && !pathpoint2.i && pathpoint2.a(pathpoint1) < f) { + if (pathpoint1 != null && !pathpoint1.i && pathpoint1.k >= 0.0F) { + apathpoint[i++] = pathpoint1; + } + + PathPoint pathpoint2 = this.a(pathpoint.a - 1, pathpoint.b, pathpoint.c, j, d0, EnumDirection.WEST); + + if (pathpoint2 != null && !pathpoint2.i && pathpoint2.k >= 0.0F) { apathpoint[i++] = pathpoint2; } - if (pathpoint3 != null && !pathpoint3.i && pathpoint3.a(pathpoint1) < f) { + PathPoint pathpoint3 = this.a(pathpoint.a + 1, pathpoint.b, pathpoint.c, j, d0, EnumDirection.EAST); + + if (pathpoint3 != null && !pathpoint3.i && pathpoint3.k >= 0.0F) { apathpoint[i++] = pathpoint3; } - if (pathpoint4 != null && !pathpoint4.i && pathpoint4.a(pathpoint1) < f) { + PathPoint pathpoint4 = this.a(pathpoint.a, pathpoint.b, pathpoint.c - 1, j, d0, EnumDirection.NORTH); + + if (pathpoint4 != null && !pathpoint4.i && pathpoint4.k >= 0.0F) { apathpoint[i++] = pathpoint4; } - if (pathpoint5 != null && !pathpoint5.i && pathpoint5.a(pathpoint1) < f) { + PathPoint pathpoint5 = this.a(pathpoint.a - 1, pathpoint.b, pathpoint.c - 1, j, d0, EnumDirection.NORTH); + + if (this.a(pathpoint, pathpoint2, pathpoint4, pathpoint5)) { apathpoint[i++] = pathpoint5; } - boolean flag = pathpoint5 == null || pathpoint5.m == PathType.OPEN || pathpoint5.l != 0.0F; - boolean flag1 = pathpoint2 == null || pathpoint2.m == PathType.OPEN || pathpoint2.l != 0.0F; - boolean flag2 = pathpoint4 == null || pathpoint4.m == PathType.OPEN || pathpoint4.l != 0.0F; - boolean flag3 = pathpoint3 == null || pathpoint3.m == PathType.OPEN || pathpoint3.l != 0.0F; - PathPoint pathpoint6; + PathPoint pathpoint6 = this.a(pathpoint.a + 1, pathpoint.b, pathpoint.c - 1, j, d0, EnumDirection.NORTH); - if (flag && flag3) { - pathpoint6 = this.a(pathpoint.a - 1, pathpoint.b, pathpoint.c - 1, j, d0, EnumDirection.NORTH); - if (pathpoint6 != null && !pathpoint6.i && pathpoint6.a(pathpoint1) < f) { - apathpoint[i++] = pathpoint6; - } + if (this.a(pathpoint, pathpoint3, pathpoint4, pathpoint6)) { + apathpoint[i++] = pathpoint6; } - if (flag && flag2) { - pathpoint6 = this.a(pathpoint.a + 1, pathpoint.b, pathpoint.c - 1, j, d0, EnumDirection.NORTH); - if (pathpoint6 != null && !pathpoint6.i && pathpoint6.a(pathpoint1) < f) { - apathpoint[i++] = pathpoint6; - } + PathPoint pathpoint7 = this.a(pathpoint.a - 1, pathpoint.b, pathpoint.c + 1, j, d0, EnumDirection.SOUTH); + + if (this.a(pathpoint, pathpoint2, pathpoint1, pathpoint7)) { + apathpoint[i++] = pathpoint7; } - if (flag1 && flag3) { - pathpoint6 = this.a(pathpoint.a - 1, pathpoint.b, pathpoint.c + 1, j, d0, EnumDirection.SOUTH); - if (pathpoint6 != null && !pathpoint6.i && pathpoint6.a(pathpoint1) < f) { - apathpoint[i++] = pathpoint6; - } - } + PathPoint pathpoint8 = this.a(pathpoint.a + 1, pathpoint.b, pathpoint.c + 1, j, d0, EnumDirection.SOUTH); - if (flag1 && flag2) { - pathpoint6 = this.a(pathpoint.a + 1, pathpoint.b, pathpoint.c + 1, j, d0, EnumDirection.SOUTH); - if (pathpoint6 != null && !pathpoint6.i && pathpoint6.a(pathpoint1) < f) { - apathpoint[i++] = pathpoint6; - } + if (this.a(pathpoint, pathpoint3, pathpoint1, pathpoint8)) { + apathpoint[i++] = pathpoint8; } return i; } + private boolean a(PathPoint pathpoint, @Nullable PathPoint pathpoint1, @Nullable PathPoint pathpoint2, @Nullable PathPoint pathpoint3) { + return pathpoint3 != null && pathpoint2 != null && pathpoint1 != null ? (pathpoint3.i ? false : (pathpoint2.b <= pathpoint.b && pathpoint1.b <= pathpoint.b ? pathpoint3.k >= 0.0F && (pathpoint2.b < pathpoint.b || pathpoint2.k >= 0.0F) && (pathpoint1.b < pathpoint.b || pathpoint1.k >= 0.0F) : false)) : false; + } + + public static double a(IBlockAccess iblockaccess, BlockPosition blockposition) { + BlockPosition blockposition1 = blockposition.down(); + VoxelShape voxelshape = iblockaccess.getType(blockposition1).getCollisionShape(iblockaccess, blockposition1); + + return (double) blockposition1.getY() + (voxelshape.isEmpty() ? 0.0D : voxelshape.c(EnumDirection.EnumAxis.Y)); + } + @Nullable private PathPoint a(int i, int j, int k, int l, double d0, EnumDirection enumdirection) { PathPoint pathpoint = null; BlockPosition blockposition = new BlockPosition(i, j, k); - double d1 = a(this.a, blockposition); + double d1 = a((IBlockAccess) this.a, blockposition); if (d1 - d0 > 1.125D) { return null; } else { PathType pathtype = this.a(this.b, i, j, k); float f = this.b.a(pathtype); - double d2 = (double) this.b.width / 2.0D; + double d2 = (double) this.b.getWidth() / 2.0D; if (f >= 0.0F) { pathpoint = this.a(i, j, k); - pathpoint.m = pathtype; - pathpoint.l = Math.max(pathpoint.l, f); + pathpoint.l = pathtype; + pathpoint.k = Math.max(pathpoint.k, f); } if (pathtype == PathType.WALKABLE) { return pathpoint; } else { - if (pathpoint == null && l > 0 && pathtype != PathType.FENCE && pathtype != PathType.TRAPDOOR) { + if ((pathpoint == null || pathpoint.k < 0.0F) && l > 0 && pathtype != PathType.FENCE && pathtype != PathType.TRAPDOOR) { pathpoint = this.a(i, j + 1, k, l - 1, d0, enumdirection); - if (pathpoint != null && (pathpoint.m == PathType.OPEN || pathpoint.m == PathType.WALKABLE) && this.b.width < 1.0F) { + if (pathpoint != null && (pathpoint.l == PathType.OPEN || pathpoint.l == PathType.WALKABLE) && this.b.getWidth() < 1.0F) { double d3 = (double) (i - enumdirection.getAdjacentX()) + 0.5D; double d4 = (double) (k - enumdirection.getAdjacentZ()) + 0.5D; - AxisAlignedBB axisalignedbb = new AxisAlignedBB(d3 - d2, (double) j + 0.001D, d4 - d2, d3 + d2, (double) this.b.length + a(this.a, blockposition.up()) - 0.002D, d4 + d2); + AxisAlignedBB axisalignedbb = new AxisAlignedBB(d3 - d2, a((IBlockAccess) this.a, new BlockPosition(d3, (double) (j + 1), d4)) + 0.001D, d4 - d2, d3 + d2, (double) this.b.getHeight() + a((IBlockAccess) this.a, new BlockPosition(pathpoint.a, pathpoint.b, pathpoint.c)) - 0.002D, d4 + d2); - if (!this.b.world.getCubes((Entity) null, axisalignedbb)) { + if (!this.a.getCubes(this.b, axisalignedbb)) { pathpoint = null; } } @@ -191,48 +200,63 @@ public class PathfinderNormal extends PathfinderAbstract { } pathpoint = this.a(i, j, k); - pathpoint.m = pathtype; - pathpoint.l = Math.max(pathpoint.l, this.b.a(pathtype)); + pathpoint.l = pathtype; + pathpoint.k = Math.max(pathpoint.k, this.b.a(pathtype)); } } if (pathtype == PathType.OPEN) { - AxisAlignedBB axisalignedbb1 = new AxisAlignedBB((double) i - d2 + 0.5D, (double) j + 0.001D, (double) k - d2 + 0.5D, (double) i + d2 + 0.5D, (double) ((float) j + this.b.length), (double) k + d2 + 0.5D); + AxisAlignedBB axisalignedbb1 = new AxisAlignedBB((double) i - d2 + 0.5D, (double) j + 0.001D, (double) k - d2 + 0.5D, (double) i + d2 + 0.5D, (double) ((float) j + this.b.getHeight()), (double) k + d2 + 0.5D); - if (!this.b.world.getCubes((Entity) null, axisalignedbb1)) { + if (!this.a.getCubes(this.b, axisalignedbb1)) { return null; } - if (this.b.width >= 1.0F) { + if (this.b.getWidth() >= 1.0F) { PathType pathtype1 = this.a(this.b, i, j - 1, k); if (pathtype1 == PathType.BLOCKED) { pathpoint = this.a(i, j, k); - pathpoint.m = PathType.WALKABLE; - pathpoint.l = Math.max(pathpoint.l, f); + pathpoint.l = PathType.WALKABLE; + pathpoint.k = Math.max(pathpoint.k, f); return pathpoint; } } int i1 = 0; + int j1 = j; - while (j > 0 && pathtype == PathType.OPEN) { + while (pathtype == PathType.OPEN) { --j; - if (i1++ >= this.b.bn()) { - return null; + PathPoint pathpoint1; + + if (j < 0) { + pathpoint1 = this.a(i, j1, k); + pathpoint1.l = PathType.BLOCKED; + pathpoint1.k = -1.0F; + return pathpoint1; + } + + pathpoint1 = this.a(i, j, k); + if (i1++ >= this.b.bv()) { + pathpoint1.l = PathType.BLOCKED; + pathpoint1.k = -1.0F; + return pathpoint1; } pathtype = this.a(this.b, i, j, k); f = this.b.a(pathtype); if (pathtype != PathType.OPEN && f >= 0.0F) { - pathpoint = this.a(i, j, k); - pathpoint.m = pathtype; - pathpoint.l = Math.max(pathpoint.l, f); + pathpoint = pathpoint1; + pathpoint1.l = pathtype; + pathpoint1.k = Math.max(pathpoint1.k, f); break; } if (f < 0.0F) { - return null; + pathpoint1.l = PathType.BLOCKED; + pathpoint1.k = -1.0F; + return pathpoint1; } } } @@ -242,17 +266,11 @@ public class PathfinderNormal extends PathfinderAbstract { } } - public static double a(IBlockAccess iblockaccess, BlockPosition blockposition) { - BlockPosition blockposition1 = blockposition.down(); - VoxelShape voxelshape = iblockaccess.getType(blockposition1).getCollisionShape(iblockaccess, blockposition1); - - return (double) blockposition1.getY() + (voxelshape.isEmpty() ? 0.0D : voxelshape.c(EnumDirection.EnumAxis.Y)); - } - + @Override public PathType a(IBlockAccess iblockaccess, int i, int j, int k, EntityInsentient entityinsentient, int l, int i1, int j1, boolean flag, boolean flag1) { EnumSet enumset = EnumSet.noneOf(PathType.class); PathType pathtype = PathType.BLOCKED; - double d0 = (double) entityinsentient.width / 2.0D; + double d0 = (double) entityinsentient.getWidth() / 2.0D; BlockPosition blockposition = new BlockPosition(entityinsentient); pathtype = this.a(iblockaccess, i, j, k, l, i1, j1, flag, flag1, enumset, pathtype, blockposition); @@ -291,18 +309,7 @@ public class PathfinderNormal extends PathfinderAbstract { int l2 = i2 + k; PathType pathtype1 = this.a(iblockaccess, j2, k2, l2); - if (pathtype1 == PathType.DOOR_WOOD_CLOSED && flag && flag1) { - pathtype1 = PathType.WALKABLE; - } - - if (pathtype1 == PathType.DOOR_OPEN && !flag1) { - pathtype1 = PathType.BLOCKED; - } - - if (pathtype1 == PathType.RAIL && !(iblockaccess.getType(blockposition).getBlock() instanceof BlockMinecartTrackAbstract) && !(iblockaccess.getType(blockposition.down()).getBlock() instanceof BlockMinecartTrackAbstract)) { - pathtype1 = PathType.FENCE; - } - + pathtype1 = this.a(iblockaccess, flag, flag1, blockposition, pathtype1); if (k1 == 0 && l1 == 0 && i2 == 0) { pathtype = pathtype1; } @@ -315,6 +322,26 @@ public class PathfinderNormal extends PathfinderAbstract { return pathtype; } + protected PathType a(IBlockAccess iblockaccess, boolean flag, boolean flag1, BlockPosition blockposition, PathType pathtype) { + if (pathtype == PathType.DOOR_WOOD_CLOSED && flag && flag1) { + pathtype = PathType.WALKABLE; + } + + if (pathtype == PathType.DOOR_OPEN && !flag1) { + pathtype = PathType.BLOCKED; + } + + if (pathtype == PathType.RAIL && !(iblockaccess.getType(blockposition).getBlock() instanceof BlockMinecartTrackAbstract) && !(iblockaccess.getType(blockposition.down()).getBlock() instanceof BlockMinecartTrackAbstract)) { + pathtype = PathType.FENCE; + } + + if (pathtype == PathType.LEAVES) { + pathtype = PathType.BLOCKED; + } + + return pathtype; + } + private PathType a(EntityInsentient entityinsentient, BlockPosition blockposition) { return this.a(entityinsentient, blockposition.getX(), blockposition.getY(), blockposition.getZ()); } @@ -323,22 +350,27 @@ public class PathfinderNormal extends PathfinderAbstract { return this.a(this.a, i, j, k, entityinsentient, this.d, this.e, this.f, this.d(), this.c()); } + @Override public PathType a(IBlockAccess iblockaccess, int i, int j, int k) { PathType pathtype = this.b(iblockaccess, i, j, k); if (pathtype == PathType.OPEN && j >= 1) { - Block block = world.getBlockIfLoaded(new BlockPosition(i, j - 1, k)); // Paper + Block block = iblockaccess.getBlockIfLoaded(new BlockPosition(i, j - 1, k)); // Paper if (block == null) return PathType.BLOCKED; // Paper PathType pathtype1 = this.b(iblockaccess, i, j - 1, k); pathtype = pathtype1 != PathType.WALKABLE && pathtype1 != PathType.OPEN && pathtype1 != PathType.WATER && pathtype1 != PathType.LAVA ? PathType.WALKABLE : PathType.OPEN; - if (pathtype1 == PathType.DAMAGE_FIRE || block == Blocks.MAGMA_BLOCK) { + if (pathtype1 == PathType.DAMAGE_FIRE || block == Blocks.MAGMA_BLOCK || block == Blocks.CAMPFIRE) { pathtype = PathType.DAMAGE_FIRE; } if (pathtype1 == PathType.DAMAGE_CACTUS) { pathtype = PathType.DAMAGE_CACTUS; } + + if (pathtype1 == PathType.DAMAGE_OTHER) { + pathtype = PathType.DAMAGE_OTHER; + } } pathtype = this.a(iblockaccess, i, j, k, pathtype); @@ -354,13 +386,15 @@ public class PathfinderNormal extends PathfinderAbstract { for (int l = -1; l <= 1; ++l) { for (int i1 = -1; i1 <= 1; ++i1) { if (l != 0 || i1 != 0) { - Block block = world.getBlockIfLoaded(blockposition_pooledblockposition.c(l + i, j, i1 + k)); // Paper + Block block = iblockaccess.getBlockIfLoaded(blockposition_pooledblockposition.d(l + i, j, i1 + k)); // Paper if (block == null) pathtype = PathType.BLOCKED; // Paper else if (block == Blocks.CACTUS) { // Paper pathtype = PathType.DANGER_CACTUS; } else if (block == Blocks.FIRE) { pathtype = PathType.DANGER_FIRE; + } else if (block == Blocks.SWEET_BERRY_BUSH) { + pathtype = PathType.DANGER_OTHER; } } } @@ -389,7 +423,7 @@ public class PathfinderNormal extends PathfinderAbstract { protected PathType b(IBlockAccess iblockaccess, int i, int j, int k) { BlockPosition blockposition = new BlockPosition(i, j, k); - IBlockData iblockdata = world.getTypeIfLoaded(blockposition); // Paper + IBlockData iblockdata = iblockaccess.getTypeIfLoaded(blockposition); // Paper if (iblockdata == null) return PathType.BLOCKED; // Paper Block block = iblockdata.getBlock(); Material material = iblockdata.getMaterial(); @@ -401,6 +435,8 @@ public class PathfinderNormal extends PathfinderAbstract { return PathType.DAMAGE_FIRE; } else if (block == Blocks.CACTUS) { return PathType.DAMAGE_CACTUS; + } else if (block == Blocks.SWEET_BERRY_BUSH) { + return PathType.DAMAGE_OTHER; } else if (block instanceof BlockDoor && material == Material.WOOD && !(Boolean) iblockdata.get(BlockDoor.OPEN)) { return PathType.DOOR_WOOD_CLOSED; } else if (block instanceof BlockDoor && material == Material.ORE && !(Boolean) iblockdata.get(BlockDoor.OPEN)) { @@ -409,7 +445,9 @@ public class PathfinderNormal extends PathfinderAbstract { return PathType.DOOR_OPEN; } else if (block instanceof BlockMinecartTrackAbstract) { return PathType.RAIL; - } else if (!(block instanceof BlockFence) && !(block instanceof BlockCobbleWall) && (!(block instanceof BlockFenceGate) || (Boolean) iblockdata.get(BlockFenceGate.OPEN))) { + } else if (block instanceof BlockLeaves) { + return PathType.LEAVES; + } else if (!block.a(TagsBlock.FENCES) && !block.a(TagsBlock.WALLS) && (!(block instanceof BlockFenceGate) || (Boolean) iblockdata.get(BlockFenceGate.OPEN))) { Fluid fluid = iblockaccess.getFluid(blockposition); return fluid.a(TagsFluid.WATER) ? PathType.WATER : (fluid.a(TagsFluid.LAVA) ? PathType.LAVA : (iblockdata.a(iblockaccess, blockposition, PathMode.LAND) ? PathType.OPEN : PathType.BLOCKED)); diff --git a/src/main/java/net/minecraft/server/PersistentRaid.java b/src/main/java/net/minecraft/server/PersistentRaid.java new file mode 100644 index 000000000..79d16eef9 --- /dev/null +++ b/src/main/java/net/minecraft/server/PersistentRaid.java @@ -0,0 +1,202 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.Nullable; + +public class PersistentRaid extends PersistentBase { + + public final Map a = Maps.newHashMap(); // PAIL rename raids, private -> public + private final WorldServer b; + private int c; + private int d; + + public PersistentRaid(WorldServer worldserver) { + super(a(worldserver.worldProvider)); + this.b = worldserver; + this.c = 1; + this.b(); + } + + public Raid a(int i) { + return (Raid) this.a.get(i); + } + + public void a() { + ++this.d; + Iterator iterator = this.a.values().iterator(); + + while (iterator.hasNext()) { + Raid raid = (Raid) iterator.next(); + + if (this.b.getGameRules().getBoolean(GameRules.x)) { + raid.n(); + } + + if (raid.d()) { + iterator.remove(); + this.b(); + } else { + raid.o(); + } + } + + if (this.d % 200 == 0) { + this.b(); + } + + PacketDebug.a(this.b, this.a.values()); + } + + public static boolean a(EntityRaider entityraider, Raid raid) { + return entityraider != null && raid != null && raid.i() != null ? entityraider.isAlive() && entityraider.ei() && entityraider.cw() <= 2400 && entityraider.world.getWorldProvider().getDimensionManager() == raid.i().getWorldProvider().getDimensionManager() : false; + } + + @Nullable + public Raid a(EntityPlayer entityplayer) { + if (entityplayer.isSpectator()) { + return null; + } else if (this.b.getGameRules().getBoolean(GameRules.x)) { + return null; + } else { + DimensionManager dimensionmanager = entityplayer.world.getWorldProvider().getDimensionManager(); + + if (dimensionmanager == DimensionManager.NETHER) { + return null; + } else { + BlockPosition blockposition = new BlockPosition(entityplayer); + List list = (List) this.b.B().b(VillagePlaceType.a, blockposition, 64, VillagePlace.Occupancy.IS_OCCUPIED).collect(Collectors.toList()); + int i = 0; + Vec3D vec3d = new Vec3D(0.0D, 0.0D, 0.0D); + + for (Iterator iterator = list.iterator(); iterator.hasNext(); ++i) { + VillagePlaceRecord villageplacerecord = (VillagePlaceRecord) iterator.next(); + BlockPosition blockposition1 = villageplacerecord.f(); + + vec3d = vec3d.add((double) blockposition1.getX(), (double) blockposition1.getY(), (double) blockposition1.getZ()); + } + + BlockPosition blockposition2; + + if (i > 0) { + vec3d = vec3d.a(1.0D / (double) i); + blockposition2 = new BlockPosition(vec3d); + } else { + blockposition2 = blockposition; + } + + Raid raid = this.a(entityplayer.getWorldServer(), blockposition2); + boolean flag = false; + + if (!raid.j()) { + /* CraftBukkit - moved down + if (!this.a.containsKey(raid.u())) { + this.a.put(raid.u(), raid); + } + */ + + flag = true; + // CraftBukkit start - fixed a bug with raid: players could add up Bad Omen level even when the raid had finished + } else if (raid.isInProgress() && raid.m() < raid.l()) { + flag = true; + // CraftBukkit end + } else { + entityplayer.removeEffect(MobEffects.BAD_OMEN); + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) 43)); + } + + if (flag) { + // CraftBukkit start + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callRaidTriggerEvent(raid, entityplayer)) { + entityplayer.removeEffect(MobEffects.BAD_OMEN); + return null; + } + + if (!this.a.containsKey(raid.u())) { + this.a.put(raid.u(), raid); + } + // CraftBukkit end + raid.a((EntityHuman) entityplayer); + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) 43)); + if (!raid.c()) { + entityplayer.a(StatisticList.RAID_TRIGGER); + CriterionTriggers.I.a(entityplayer); + } + } + + this.b(); + return raid; + } + } + } + + private Raid a(WorldServer worldserver, BlockPosition blockposition) { + Raid raid = worldserver.c_(blockposition); + + return raid != null ? raid : new Raid(this.e(), worldserver, blockposition); + } + + @Override + public void a(NBTTagCompound nbttagcompound) { + this.c = nbttagcompound.getInt("NextAvailableID"); + this.d = nbttagcompound.getInt("Tick"); + NBTTagList nbttaglist = nbttagcompound.getList("Raids", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); + Raid raid = new Raid(this.b, nbttagcompound1); + + this.a.put(raid.u(), raid); + } + + } + + @Override + public NBTTagCompound b(NBTTagCompound nbttagcompound) { + nbttagcompound.setInt("NextAvailableID", this.c); + nbttagcompound.setInt("Tick", this.d); + NBTTagList nbttaglist = new NBTTagList(); + Iterator iterator = this.a.values().iterator(); + + while (iterator.hasNext()) { + Raid raid = (Raid) iterator.next(); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + raid.a(nbttagcompound1); + nbttaglist.add(nbttagcompound1); + } + + nbttagcompound.set("Raids", nbttaglist); + return nbttagcompound; + } + + public static String a(WorldProvider worldprovider) { + return "raids" + worldprovider.getDimensionManager().getSuffix(); + } + + private int e() { + return ++this.c; + } + + @Nullable + public Raid a(BlockPosition blockposition, int i) { + Raid raid = null; + double d0 = (double) i; + Iterator iterator = this.a.values().iterator(); + + while (iterator.hasNext()) { + Raid raid1 = (Raid) iterator.next(); + double d1 = raid1.t().m(blockposition); + + if (raid1.v() && d1 < d0) { + raid = raid1; + d0 = d1; + } + } + + return raid; + } +} diff --git a/src/main/java/net/minecraft/server/PersistentScoreboard.java b/src/main/java/net/minecraft/server/PersistentScoreboard.java index 3a9dfb979..de7ac6c20 100644 --- a/src/main/java/net/minecraft/server/PersistentScoreboard.java +++ b/src/main/java/net/minecraft/server/PersistentScoreboard.java @@ -7,16 +7,12 @@ import org.apache.logging.log4j.Logger; public class PersistentScoreboard extends PersistentBase { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private Scoreboard b; private NBTTagCompound c; public PersistentScoreboard() { - this("scoreboard"); - } - - public PersistentScoreboard(String s) { - super(s); + super("scoreboard"); } public void a(Scoreboard scoreboard) { @@ -27,6 +23,7 @@ public class PersistentScoreboard extends PersistentBase { } + @Override public void a(NBTTagCompound nbttagcompound) { if (this.b == null) { this.c = nbttagcompound; @@ -139,9 +136,8 @@ public class PersistentScoreboard extends PersistentBase { protected void b(NBTTagList nbttaglist) { for (int i = 0; i < nbttaglist.size(); ++i) { NBTTagCompound nbttagcompound = nbttaglist.getCompound(i); - IScoreboardCriteria iscoreboardcriteria = IScoreboardCriteria.a(nbttagcompound.getString("CriteriaName")); - if (iscoreboardcriteria != null) { + IScoreboardCriteria.a(nbttagcompound.getString("CriteriaName")).ifPresent((iscoreboardcriteria) -> { String s = nbttagcompound.getString("Name"); if (s.length() > 16) { @@ -152,17 +148,18 @@ public class PersistentScoreboard extends PersistentBase { IScoreboardCriteria.EnumScoreboardHealthDisplay iscoreboardcriteria_enumscoreboardhealthdisplay = IScoreboardCriteria.EnumScoreboardHealthDisplay.a(nbttagcompound.getString("RenderType")); this.b.registerObjective(s, iscoreboardcriteria, ichatbasecomponent, iscoreboardcriteria_enumscoreboardhealthdisplay); - } + }); } } + @Override public NBTTagCompound b(NBTTagCompound nbttagcompound) { if (this.b == null) { - PersistentScoreboard.a.warn("Tried to save scoreboard without having a scoreboard..."); + PersistentScoreboard.LOGGER.warn("Tried to save scoreboard without having a scoreboard..."); return nbttagcompound; } else { - nbttagcompound.set("Objectives", this.b()); + nbttagcompound.set("Objectives", this.e()); nbttagcompound.set("PlayerScores", this.b.i()); nbttagcompound.set("Teams", this.a()); this.d(nbttagcompound); @@ -199,11 +196,11 @@ public class PersistentScoreboard extends PersistentBase { while (iterator1.hasNext()) { String s = (String) iterator1.next(); - nbttaglist1.add((NBTBase) (new NBTTagString(s))); + nbttaglist1.add(new NBTTagString(s)); } nbttagcompound.set("Players", nbttaglist1); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); } return nbttaglist; @@ -228,7 +225,7 @@ public class PersistentScoreboard extends PersistentBase { } - protected NBTTagList b() { + protected NBTTagList e() { NBTTagList nbttaglist = new NBTTagList(); Collection collection = this.b.getObjectives(); Iterator iterator = collection.iterator(); @@ -243,7 +240,7 @@ public class PersistentScoreboard extends PersistentBase { nbttagcompound.setString("CriteriaName", scoreboardobjective.getCriteria().getName()); nbttagcompound.setString("DisplayName", IChatBaseComponent.ChatSerializer.a(scoreboardobjective.getDisplayName())); nbttagcompound.setString("RenderType", scoreboardobjective.getRenderType().a()); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); } } diff --git a/src/main/java/net/minecraft/server/PersistentVillage.java b/src/main/java/net/minecraft/server/PersistentVillage.java deleted file mode 100644 index e40cd4186..000000000 --- a/src/main/java/net/minecraft/server/PersistentVillage.java +++ /dev/null @@ -1,268 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import java.util.Iterator; -import java.util.List; -import javax.annotation.Nullable; - -public class PersistentVillage extends PersistentBase { - - private World world; - private final List b = Lists.newArrayList(); - private final List c = Lists.newArrayList(); - private final List villages = Lists.newArrayList(); - private int time; - - public PersistentVillage(String s) { - super(s); - } - - public PersistentVillage(World world) { - super(a(world.worldProvider)); - this.world = world; - this.c(); - } - - public void a(World world) { - this.world = world; - Iterator iterator = this.villages.iterator(); - - while (iterator.hasNext()) { - Village village = (Village) iterator.next(); - - village.a(world); - } - - } - - public void a(BlockPosition blockposition) { - if (this.b.size() <= 64) { - if (!this.d(blockposition)) { - this.b.add(blockposition); - } - - } - } - - public void tick() { - ++this.time; - Iterator iterator = this.villages.iterator(); - - while (iterator.hasNext()) { - Village village = (Village) iterator.next(); - - village.a(this.time); - } - - this.f(); - this.g(); - this.h(); - if (this.time % 400 == 0) { - this.c(); - } - - } - - private void f() { - Iterator iterator = this.villages.iterator(); - - while (iterator.hasNext()) { - Village village = (Village) iterator.next(); - - if (village.g()) { - iterator.remove(); - this.c(); - } - } - - } - - public List getVillages() { - return this.villages; - } - - public Village getClosestVillage(BlockPosition blockposition, int i) { - Village village = null; - double d0 = 3.4028234663852886E38D; - Iterator iterator = this.villages.iterator(); - - while (iterator.hasNext()) { - Village village1 = (Village) iterator.next(); - double d1 = village1.a().n(blockposition); - - if (d1 < d0) { - float f = (float) (i + village1.b()); - - if (d1 <= (double) (f * f)) { - village = village1; - d0 = d1; - } - } - } - - return village; - } - - private void g() { - if (!this.b.isEmpty()) { - this.b((BlockPosition) this.b.remove(0)); - } - } - - private void h() { - for (int i = 0; i < this.c.size(); ++i) { - VillageDoor villagedoor = (VillageDoor) this.c.get(i); - Village village = this.getClosestVillage(villagedoor.d(), 32); - - if (village == null) { - village = new Village(this.world); - this.villages.add(village); - this.c(); - } - - village.a(villagedoor); - } - - this.c.clear(); - } - - private void b(BlockPosition blockposition) { - boolean flag = true; - boolean flag1 = true; - boolean flag2 = true; - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - - for (int i = -16; i < 16; ++i) { - for (int j = -4; j < 4; ++j) { - for (int k = -16; k < 16; ++k) { - blockposition_mutableblockposition.g(blockposition).d(i, j, k); - IBlockData iblockdata = this.world.paperConfig.villagesLoadChunks ? this.world.getType(blockposition_mutableblockposition) : this.world.getTypeIfLoaded(blockposition_mutableblockposition); // Paper - - if (this.a(iblockdata)) { - VillageDoor villagedoor = this.c(blockposition_mutableblockposition); - - if (villagedoor == null) { - this.a(iblockdata, blockposition_mutableblockposition); - } else { - villagedoor.a(this.time); - } - } - } - } - } - - } - - @Nullable - private VillageDoor c(BlockPosition blockposition) { - Iterator iterator = this.c.iterator(); - - VillageDoor villagedoor; - - do { - if (!iterator.hasNext()) { - iterator = this.villages.iterator(); - - VillageDoor villagedoor1; - - do { - if (!iterator.hasNext()) { - return null; - } - - Village village = (Village) iterator.next(); - - villagedoor1 = village.e(blockposition); - } while (villagedoor1 == null); - - return villagedoor1; - } - - villagedoor = (VillageDoor) iterator.next(); - } while (villagedoor.d().getX() != blockposition.getX() || villagedoor.d().getZ() != blockposition.getZ() || Math.abs(villagedoor.d().getY() - blockposition.getY()) > 1); - - return villagedoor; - } - - private void a(IBlockData iblockdata, BlockPosition blockposition) { - EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockDoor.FACING); - EnumDirection enumdirection1 = enumdirection.opposite(); - int i = this.a(blockposition, enumdirection, 5); - int j = this.a(blockposition, enumdirection1, i + 1); - - if (i != j) { - this.c.add(new VillageDoor(blockposition, i < j ? enumdirection : enumdirection1, this.time)); - } - - } - - private int a(BlockPosition blockposition, EnumDirection enumdirection, int i) { - int j = 0; - - for (int k = 1; k <= 5; ++k) { - if (this.world.e(blockposition.shift(enumdirection, k))) { - ++j; - if (j >= i) { - return j; - } - } - } - - return j; - } - - private boolean d(BlockPosition blockposition) { - Iterator iterator = this.b.iterator(); - - BlockPosition blockposition1; - - do { - if (!iterator.hasNext()) { - return false; - } - - blockposition1 = (BlockPosition) iterator.next(); - } while (!blockposition1.equals(blockposition)); - - return true; - } - - private boolean a(IBlockData iblockdata) { - return iblockdata != null && iblockdata.getBlock() instanceof BlockDoor && iblockdata.getMaterial() == Material.WOOD; // Paper - } - - public void a(NBTTagCompound nbttagcompound) { - this.time = nbttagcompound.getInt("Tick"); - NBTTagList nbttaglist = nbttagcompound.getList("Villages", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); - Village village = new Village(world); // Paper - - village.a(nbttagcompound1); - this.villages.add(village); - } - - } - - public NBTTagCompound b(NBTTagCompound nbttagcompound) { - nbttagcompound.setInt("Tick", this.time); - NBTTagList nbttaglist = new NBTTagList(); - Iterator iterator = this.villages.iterator(); - - while (iterator.hasNext()) { - Village village = (Village) iterator.next(); - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - - village.b(nbttagcompound1); - nbttaglist.add((NBTBase) nbttagcompound1); - } - - nbttagcompound.set("Villages", nbttaglist); - return nbttagcompound; - } - - public static String a(WorldProvider worldprovider) { - return "villages" + worldprovider.getDimensionManager().d(); - } -} diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java index 6a80d640f..34d0ab0d5 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java +++ b/src/main/java/net/minecraft/server/PlayerChunk.java @@ -1,207 +1,147 @@ package net.minecraft.server; -import com.google.common.collect.Lists; -import java.util.Iterator; +import com.mojang.datafixers.util.Either; import java.util.List; -import java.util.function.Predicate; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.function.IntConsumer; +import java.util.function.IntSupplier; +import java.util.stream.Stream; import javax.annotation.Nullable; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; public class PlayerChunk { - private static final Logger a = LogManager.getLogger(); - private final PlayerChunkMap playerChunkMap; - public final List players = Lists.newArrayList(); - private final ChunkCoordIntPair location; - private final short[] dirtyBlocks = new short[64]; - @Nullable - public Chunk chunk; + public static final Either UNLOADED_CHUNK_ACCESS = Either.right(PlayerChunk.Failure.b); + public static final CompletableFuture> UNLOADED_CHUNK_ACCESS_FUTURE = CompletableFuture.completedFuture(PlayerChunk.UNLOADED_CHUNK_ACCESS); + public static final Either UNLOADED_CHUNK = Either.right(PlayerChunk.Failure.b); + private static final CompletableFuture> UNLOADED_CHUNK_FUTURE = CompletableFuture.completedFuture(PlayerChunk.UNLOADED_CHUNK); + private static final List CHUNK_STATUSES = ChunkStatus.a(); + private static final PlayerChunk.State[] CHUNK_STATES = PlayerChunk.State.values(); + private final AtomicReferenceArray>> statusFutures; + private volatile CompletableFuture> fullChunkFuture; + private volatile CompletableFuture> tickingFuture; + private volatile CompletableFuture> entityTickingFuture; + private CompletableFuture chunkSave; + public int oldTicketLevel; + private int ticketLevel; + private int n; + final ChunkCoordIntPair location; // Paper - private -> package + private final short[] dirtyBlocks; private int dirtyCount; - private int h; - private long i; - boolean done; // Paper - package-private - boolean chunkExists; // Paper - // Paper start - PaperAsyncChunkProvider.CancellableChunkRequest chunkRequest; - private java.util.function.Consumer chunkLoadedConsumer = chunk -> { - chunkRequest = null; - PlayerChunk pChunk = PlayerChunk.this; - pChunk.chunk = chunk; - markChunkUsed(); // Paper - delay chunk unloads - }; - private boolean markedHigh = false; - void checkHighPriority(EntityPlayer player) { - if (done || markedHigh || chunk != null) { - return; - } - final double dist = getDistance(player.locX, player.locZ); - if (dist > 8) { - return; - } - if (dist >= 3 && getDistance(player, 5) > 3.5) { - return; - } + private int r; + private int s; + private int t; + private int u; + private final LightEngine lightEngine; + private final PlayerChunk.c w; + public final PlayerChunk.d players; + private boolean hasBeenLoaded; - markedHigh = true; - playerChunkMap.getWorld().getChunkProvider().bumpPriority(location); - if (chunkRequest == null) { - requestChunkIfNeeded(PlayerChunkMap.CAN_GEN_CHUNKS.test(player)); - } - } - private void requestChunkIfNeeded(boolean flag) { - if (chunkRequest == null) { - chunkRequest = this.playerChunkMap.getWorld().getChunkProvider().requestChunk(this.location.x, this.location.z, flag, markedHigh, chunkLoadedConsumer); - this.chunk = chunkRequest.getChunk(); // Paper) - markChunkUsed(); // Paper - delay chunk unloads - } - } - private double getDistance(EntityPlayer player, int inFront) { - final float yaw = MathHelper.normalizeYaw(player.yaw); - final double x = player.locX + (inFront * Math.cos(Math.toRadians(yaw))); - final double z = player.locZ + (inFront * Math.sin(Math.toRadians(yaw))); - return getDistance(x, z); + public PlayerChunk(ChunkCoordIntPair chunkcoordintpair, int i, LightEngine lightengine, PlayerChunk.c playerchunk_c, PlayerChunk.d playerchunk_d) { + this.statusFutures = new AtomicReferenceArray(PlayerChunk.CHUNK_STATUSES.size()); + this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; + this.tickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; + this.entityTickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; + this.chunkSave = CompletableFuture.completedFuture(null); // CraftBukkit - decompile error + this.dirtyBlocks = new short[64]; + this.location = chunkcoordintpair; + this.lightEngine = lightengine; + this.w = playerchunk_c; + this.players = playerchunk_d; + this.oldTicketLevel = PlayerChunkMap.GOLDEN_TICKET + 1; + this.ticketLevel = this.oldTicketLevel; + this.n = this.oldTicketLevel; + this.a(i); } - private double getDistance(double blockX, double blockZ) { - final double x = location.x - ((int)Math.floor(blockX) >> 4); - final double z = location.z - ((int)Math.floor(blockZ) >> 4); - return Math.sqrt((x * x) + (z * z)); + // CraftBukkit start + public Chunk getFullChunk() { + if (!getChunkState(this.oldTicketLevel).isAtLeast(PlayerChunk.State.BORDER)) return null; // note: using oldTicketLevel for isLoaded checks + CompletableFuture> statusFuture = this.getStatusFutureUnchecked(ChunkStatus.FULL); + Either either = (Either) statusFuture.getNow(null); + return either == null ? null : (Chunk) either.left().orElse(null); + } + // CraftBukkit end + // Paper start - "real" get full chunk immediately + public Chunk getFullChunkIfCached() { + // Note: Copied from above without ticket level check + CompletableFuture> statusFuture = this.getStatusFutureUnchecked(ChunkStatus.FULL); + Either either = (Either) statusFuture.getNow(null); + return either == null ? null : (Chunk) either.left().orElse(null); } - public PlayerChunk(PlayerChunkMap playerchunkmap, int i, int j) { - this.playerChunkMap = playerchunkmap; - this.location = new ChunkCoordIntPair(i, j); - ChunkProviderServer chunkproviderserver = playerchunkmap.getWorld().getChunkProvider(); - - chunkproviderserver.a(i, j); - this.chunk = chunkproviderserver.getChunkAt(i, j, false, false); // Paper - this.chunkExists = this.chunk != null || chunkproviderserver.chunkGoingToExists(i, j); // Paper - markChunkUsed(); // Paper - delay chunk unloads + public IChunkAccess getAvailableChunkNow() { + // TODO can we just getStatusFuture(EMPTY)? + for (ChunkStatus curr = ChunkStatus.FULL, next = curr.getPreviousStatus(); curr != next; curr = next, next = next.getPreviousStatus()) { + CompletableFuture> future = this.getStatusFutureUnchecked(curr); + Either either = future.getNow(null); + if (either == null || !either.left().isPresent()) { + continue; + } + return either.left().get(); + } + return null; } - - // Paper start - private void markChunkUsed() { - if (!chunkHasPlayers && chunkRequest != null) { - chunkRequest.cancel(); - chunkRequest = null; - } - if (chunk == null) { - return; - } - if (chunkHasPlayers) { - chunk.scheduledForUnload = null; - } else if (chunk.scheduledForUnload == null) { - chunk.scheduledForUnload = System.currentTimeMillis(); - } - } - private boolean chunkHasPlayers = false; // Paper end - public ChunkCoordIntPair a() { - return this.location; + public CompletableFuture> getStatusFutureUnchecked(ChunkStatus chunkstatus) { + CompletableFuture> completablefuture = (CompletableFuture) this.statusFutures.get(chunkstatus.c()); + + return completablefuture == null ? PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE : completablefuture; } - public void a(EntityPlayer entityplayer) { - if (this.players.contains(entityplayer)) { - PlayerChunk.a.debug("Failed to add player. {} already is in chunk {}, {}", entityplayer, this.location.x, this.location.z); - } else { - if (this.players.isEmpty()) { - this.i = this.playerChunkMap.getWorld().getTime(); - chunkHasPlayers = true; // Paper - delay chunk unloads - markChunkUsed(); // Paper - delay chunk unloads - } - - this.players.add(entityplayer); - if (this.done) { - this.sendChunk(entityplayer); - } else checkHighPriority(entityplayer); // Paper - - } + public CompletableFuture> b(ChunkStatus chunkstatus) { + return getChunkStatus(this.ticketLevel).b(chunkstatus) ? this.getStatusFutureUnchecked(chunkstatus) : PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE; } - public void b(EntityPlayer entityplayer) { - if (this.players.contains(entityplayer)) { - if (this.done) { - entityplayer.playerConnection.sendPacket(new PacketPlayOutUnloadChunk(this.location.x, this.location.z)); - } - - this.players.remove(entityplayer); - if (this.players.isEmpty()) { - chunkHasPlayers = false; // Paper - delay chunk unloads - markChunkUsed(); // Paper - delay chunk unloads - this.playerChunkMap.b(this); - } - - } + public CompletableFuture> a() { + return this.tickingFuture; } - public boolean a(boolean flag) { - if (this.chunk != null) { - return true; - } else { - // Paper start - async chunks - requestChunkIfNeeded(flag); - // Paper end - return this.chunk != null; - } + public CompletableFuture> b() { + return this.entityTickingFuture; } - public boolean sendAll() { return b(); } // Paper - OBFHELPER - public boolean b() { - if (this.done) { - return true; - } else if (this.chunk == null) { - return false; - } else if (!this.chunk.isReady()) { - return false; - } else if (!this.chunk.world.chunkPacketBlockController.onChunkPacketCreate(this.chunk, '\uffff', false)) { // Paper - Anti-Xray - Load nearby chunks if necessary - return false; // Paper - Anti-Xray - Wait and try again later - } else { - this.dirtyCount = 0; - this.h = 0; - this.done = true; - if (!this.players.isEmpty()) { - Packet packet = new PacketPlayOutMapChunk(this.chunk, 65535); - Iterator iterator = this.players.iterator(); + public CompletableFuture> c() { + return this.fullChunkFuture; + } - while (iterator.hasNext()) { - EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + @Nullable + public Chunk getChunk() { + CompletableFuture> completablefuture = this.a(); + Either either = (Either) completablefuture.getNow(null); // CraftBukkit - decompile error - entityplayer.playerConnection.sendPacket(packet); - this.playerChunkMap.getWorld().getTracker().a(entityplayer, this.chunk); + return either == null ? null : (Chunk) either.left().orElse(null); // CraftBukkit - decompile error + } + + @Nullable + public IChunkAccess f() { + for (int i = PlayerChunk.CHUNK_STATUSES.size() - 1; i >= 0; --i) { + ChunkStatus chunkstatus = (ChunkStatus) PlayerChunk.CHUNK_STATUSES.get(i); + CompletableFuture> completablefuture = this.getStatusFutureUnchecked(chunkstatus); + + if (!completablefuture.isCompletedExceptionally()) { + Optional optional = ((Either) completablefuture.getNow(PlayerChunk.UNLOADED_CHUNK_ACCESS)).left(); + + if (optional.isPresent()) { + return (IChunkAccess) optional.get(); } } - - return true; } + + return null; } - public void sendChunk(EntityPlayer entityplayer) { - if (this.done) { - this.chunk.world.chunkPacketBlockController.onChunkPacketCreate(this.chunk, '\uffff', true); // Paper - Anti-Xray - Load nearby chunks if necessary - entityplayer.playerConnection.sendPacket(new PacketPlayOutMapChunk(this.chunk, 65535)); - this.playerChunkMap.getWorld().getTracker().a(entityplayer, this.chunk); - } - } - - public void c() { - long i = this.playerChunkMap.getWorld().getTime(); - - if (this.chunk != null) { - this.chunk.b(this.chunk.m() + i - this.i); - } - - this.i = i; + public CompletableFuture getChunkSave() { + return this.chunkSave; } public void a(int i, int j, int k) { - if (this.done) { - if (this.dirtyCount == 0) { - this.playerChunkMap.a(this); - } + Chunk chunk = this.getChunk(); - this.h |= 1 << (j >> 4); + if (chunk != null) { + this.r |= 1 << (j >> 4); if (this.dirtyCount < 64) { short short0 = (short) (i << 12 | k << 8 | j); @@ -217,114 +157,330 @@ public class PlayerChunk { } } - public void a(Packet packet) { - if (this.done) { - for (int i = 0; i < this.players.size(); ++i) { - ((EntityPlayer) this.players.get(i)).playerConnection.sendPacket(packet); + public void a(EnumSkyBlock enumskyblock, int i) { + Chunk chunk = this.getChunk(); + + if (chunk != null) { + chunk.setNeedsSaving(true); + if (enumskyblock == EnumSkyBlock.SKY) { + this.u |= 1 << i - -1; + } else { + this.t |= 1 << i - -1; } } } - public void d() { - if (this.done && this.chunk != null) { - if (this.dirtyCount != 0) { - int i; - int j; - int k; + public void a(Chunk chunk) { + if (this.dirtyCount != 0 || this.u != 0 || this.t != 0) { + World world = chunk.getWorld(); - if (this.dirtyCount == 1) { - i = (this.dirtyBlocks[0] >> 12 & 15) + this.location.x * 16; - j = this.dirtyBlocks[0] & 255; - k = (this.dirtyBlocks[0] >> 8 & 15) + this.location.z * 16; - BlockPosition blockposition = new BlockPosition(i, j, k); + if (this.dirtyCount == 64) { + // Paper start - Anti-Xray - Load nearby chunks if necessary + if (!chunk.world.chunkPacketBlockController.onChunkPacketCreate(chunk, '\uffff', false)) { + return; + } + // Paper end + this.s = -1; + } - this.a((Packet) (new PacketPlayOutBlockChange(this.playerChunkMap.getWorld(), blockposition))); - if (this.playerChunkMap.getWorld().getType(blockposition).getBlock().isTileEntity()) { - this.a(this.playerChunkMap.getWorld().getTileEntity(blockposition)); - } - } else if (this.dirtyCount == 64) { - // Paper - Anti-Xray - Loading chunks here could cause a ConcurrentModificationException #1104 - // Paper - Anti-Xray - TODO: Check if this is still the case for 1.13 - //this.chunk.world.chunkPacketBlockController.onChunkPacketCreate(this.chunk, this.h, true); // Paper - Anti-Xray - Load nearby chunks if necessary - this.a((Packet) (new PacketPlayOutMapChunk(this.chunk, this.h))); - } else { - this.a((Packet) (new PacketPlayOutMultiBlockChange(this.dirtyCount, this.dirtyBlocks, this.chunk))); + int i; + int j; - for (i = 0; i < this.dirtyCount; ++i) { - j = (this.dirtyBlocks[i] >> 12 & 15) + this.location.x * 16; - k = this.dirtyBlocks[i] & 255; - int l = (this.dirtyBlocks[i] >> 8 & 15) + this.location.z * 16; - BlockPosition blockposition1 = new BlockPosition(j, k, l); - - if (this.playerChunkMap.getWorld().getType(blockposition1).getBlock().isTileEntity()) { - this.a(this.playerChunkMap.getWorld().getTileEntity(blockposition1)); - } - } + if (this.u != 0 || this.t != 0) { + this.a(new PacketPlayOutLightUpdate(chunk.getPos(), this.lightEngine, this.u & ~this.s, this.t & ~this.s), true); + i = this.u & this.s; + j = this.t & this.s; + if (i != 0 || j != 0) { + this.a(new PacketPlayOutLightUpdate(chunk.getPos(), this.lightEngine, i, j), false); } - this.dirtyCount = 0; - this.h = 0; + this.u = 0; + this.t = 0; + this.s &= ~(this.u & this.t); } + + int k; + + if (this.dirtyCount == 1) { + i = (this.dirtyBlocks[0] >> 12 & 15) + this.location.x * 16; + j = this.dirtyBlocks[0] & 255; + k = (this.dirtyBlocks[0] >> 8 & 15) + this.location.z * 16; + BlockPosition blockposition = new BlockPosition(i, j, k); + + this.a(new PacketPlayOutBlockChange(world, blockposition), false); + if (world.getType(blockposition).getBlock().isTileEntity()) { + this.a(world, blockposition); + } + } else if (this.dirtyCount == 64) { + this.a(new PacketPlayOutMapChunk(chunk, this.r, true), false); // Paper - Anti-Xray + } else if (this.dirtyCount != 0) { + this.a(new PacketPlayOutMultiBlockChange(this.dirtyCount, this.dirtyBlocks, chunk), false); + + for (i = 0; i < this.dirtyCount; ++i) { + j = (this.dirtyBlocks[i] >> 12 & 15) + this.location.x * 16; + k = this.dirtyBlocks[i] & 255; + int l = (this.dirtyBlocks[i] >> 8 & 15) + this.location.z * 16; + BlockPosition blockposition1 = new BlockPosition(j, k, l); + + if (world.getType(blockposition1).getBlock().isTileEntity()) { + this.a(world, blockposition1); + } + } + } + + this.dirtyCount = 0; + this.r = 0; } } - private void a(@Nullable TileEntity tileentity) { + private void a(World world, BlockPosition blockposition) { + TileEntity tileentity = world.getTileEntity(blockposition); + if (tileentity != null) { PacketPlayOutTileEntityData packetplayouttileentitydata = tileentity.getUpdatePacket(); if (packetplayouttileentitydata != null) { - this.a((Packet) packetplayouttileentitydata); + this.a(packetplayouttileentitydata, false); } } } - public boolean d(EntityPlayer entityplayer) { - return this.players.contains(entityplayer); + private void a(Packet packet, boolean flag) { + this.players.a(this.location, flag).forEach((entityplayer) -> { + entityplayer.playerConnection.sendPacket(packet); + }); } - public boolean a(Predicate predicate) { - return this.players.stream().anyMatch(predicate); - } + public CompletableFuture> a(ChunkStatus chunkstatus, PlayerChunkMap playerchunkmap) { + int i = chunkstatus.c(); + CompletableFuture> completablefuture = (CompletableFuture) this.statusFutures.get(i); - public boolean a(double d0, Predicate predicate) { - int i = 0; + if (completablefuture != null) { + Either either = (Either) completablefuture.getNow(null); // CraftBukkit - decompile error - for (int j = this.players.size(); i < j; ++i) { - EntityPlayer entityplayer = (EntityPlayer) this.players.get(i); - - if (predicate.test(entityplayer) && this.location.a(entityplayer) < d0 * d0) { - return true; + if (either == null || either.left().isPresent()) { + return completablefuture; } } - return false; + if (getChunkStatus(this.ticketLevel).b(chunkstatus)) { + CompletableFuture> completablefuture1 = playerchunkmap.a(this, chunkstatus); + + this.a(completablefuture1); + this.statusFutures.set(i, completablefuture1); + return completablefuture1; + } else { + return completablefuture == null ? PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE : completablefuture; + } } - public boolean isDone() { return e(); } // Paper - OBFHELPER - public boolean e() { - return this.done; + private void a(CompletableFuture> completablefuture) { + this.chunkSave = this.chunkSave.thenCombine(completablefuture, (ichunkaccess, either) -> { + return (IChunkAccess) either.map((ichunkaccess1) -> { + return ichunkaccess1; + }, (playerchunk_failure) -> { + return ichunkaccess; + }); + }); } - @Nullable - public Chunk f() { - return this.chunk; + public ChunkCoordIntPair i() { + return this.location; } - public double g() { - double d0 = Double.MAX_VALUE; - Iterator iterator = this.players.iterator(); + public int getTicketLevel() { + return this.ticketLevel; + } - while (iterator.hasNext()) { - EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - double d1 = this.location.a(entityplayer); + public int k() { + return this.n; + } - if (d1 < d0) { - d0 = d1; + private void d(int i) { + this.n = i; + } + + public void a(int i) { + this.ticketLevel = i; + } + + protected void a(PlayerChunkMap playerchunkmap) { + ChunkStatus chunkstatus = getChunkStatus(this.oldTicketLevel); + ChunkStatus chunkstatus1 = getChunkStatus(this.ticketLevel); + boolean flag = this.oldTicketLevel <= PlayerChunkMap.GOLDEN_TICKET; + boolean flag1 = this.ticketLevel <= PlayerChunkMap.GOLDEN_TICKET; // Paper - diff on change: (flag1 = new ticket level is in loadable range) + PlayerChunk.State playerchunk_state = getChunkState(this.oldTicketLevel); + PlayerChunk.State playerchunk_state1 = getChunkState(this.ticketLevel); + // CraftBukkit start + // ChunkUnloadEvent: Called before the chunk is unloaded: isChunkLoaded is still true and chunk can still be modified by plugins. + if (playerchunk_state.isAtLeast(PlayerChunk.State.BORDER) && !playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER)) { + this.getStatusFutureUnchecked(ChunkStatus.FULL).thenAcceptAsync((either) -> { + either.ifLeft((chunkAccess) -> { + Chunk chunk = (Chunk) chunkAccess; + // Minecraft will apply the chunks tick lists to the world once the chunk got loaded, and then store the tick + // lists again inside the chunk once the chunk becomes inaccessible and set the chunk's needsSaving flag. + // These actions may however happen deferred, so we manually set the needsSaving flag already here. + chunk.setNeedsSaving(true); + chunk.unloadCallback(); + }); + }, playerchunkmap.callbackExecutor); + + // Run callback right away if the future was already done + playerchunkmap.callbackExecutor.run(); + } + // CraftBukkit end + CompletableFuture completablefuture; + + if (flag) { + Either either = Either.right(new PlayerChunk.Failure() { + public String toString() { + return "Unloaded ticket level " + PlayerChunk.this.location.toString(); + } + }); + + // Paper start + if (!flag1) { + playerchunkmap.world.asyncChunkTaskManager.cancelChunkLoad(this.location.x, this.location.z); + } + // Paper end + + for (int i = flag1 ? chunkstatus1.c() + 1 : 0; i <= chunkstatus.c(); ++i) { + completablefuture = (CompletableFuture) this.statusFutures.get(i); + if (completablefuture != null) { + completablefuture.complete(either); + } else { + this.statusFutures.set(i, CompletableFuture.completedFuture(either)); + } } } - return d0; + boolean flag2 = playerchunk_state.isAtLeast(PlayerChunk.State.BORDER); + boolean flag3 = playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER); + + this.hasBeenLoaded |= flag3; + if (!flag2 && flag3) { + this.fullChunkFuture = playerchunkmap.b(this); + this.a(this.fullChunkFuture); + } + + if (flag2 && !flag3) { + completablefuture = this.fullChunkFuture; + this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; + this.a(((CompletableFuture>) completablefuture).thenApply((either1) -> { // CraftBukkit - decompile error + playerchunkmap.getClass(); + return either1.ifLeft(playerchunkmap::a); + })); + } + + boolean flag4 = playerchunk_state.isAtLeast(PlayerChunk.State.TICKING); + boolean flag5 = playerchunk_state1.isAtLeast(PlayerChunk.State.TICKING); + + if (!flag4 && flag5) { + this.tickingFuture = playerchunkmap.a(this); + this.a(this.tickingFuture); + } + + if (flag4 && !flag5) { + this.tickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); + this.tickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; + } + + boolean flag6 = playerchunk_state.isAtLeast(PlayerChunk.State.ENTITY_TICKING); + boolean flag7 = playerchunk_state1.isAtLeast(PlayerChunk.State.ENTITY_TICKING); + + if (!flag6 && flag7) { + if (this.entityTickingFuture != PlayerChunk.UNLOADED_CHUNK_FUTURE) { + throw new IllegalStateException(); + } + + this.entityTickingFuture = playerchunkmap.b(this.location); + this.a(this.entityTickingFuture); + } + + if (flag6 && !flag7) { + this.entityTickingFuture.complete(PlayerChunk.UNLOADED_CHUNK); + this.entityTickingFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE; + } + + this.w.a(this.location, this::k, this.ticketLevel, this::d); + this.oldTicketLevel = this.ticketLevel; + // CraftBukkit start + // ChunkLoadEvent: Called after the chunk is loaded: isChunkLoaded returns true and chunk is ready to be modified by plugins. + if (!playerchunk_state.isAtLeast(PlayerChunk.State.BORDER) && playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER)) { + this.getStatusFutureUnchecked(ChunkStatus.FULL).thenAcceptAsync((either) -> { + either.ifLeft((chunkAccess) -> { + Chunk chunk = (Chunk) chunkAccess; + chunk.loadCallback(); + }); + }, playerchunkmap.callbackExecutor); + + // Run callback right away if the future was already done + playerchunkmap.callbackExecutor.run(); + } + // CraftBukkit end + } + + public static ChunkStatus getChunkStatus(int i) { + return i < 33 ? ChunkStatus.FULL : ChunkStatus.a(i - 33); + } + + public static PlayerChunk.State getChunkState(int i) { + return PlayerChunk.CHUNK_STATES[MathHelper.clamp(33 - i + 1, 0, PlayerChunk.CHUNK_STATES.length - 1)]; + } + + public boolean hasBeenLoaded() { + return this.hasBeenLoaded; + } + + public void m() { + this.hasBeenLoaded = getChunkState(this.ticketLevel).isAtLeast(PlayerChunk.State.BORDER); + } + + public void a(ProtoChunkExtension protochunkextension) { + for (int i = 0; i < this.statusFutures.length(); ++i) { + CompletableFuture> completablefuture = (CompletableFuture) this.statusFutures.get(i); + + if (completablefuture != null) { + Optional optional = ((Either) completablefuture.getNow(PlayerChunk.UNLOADED_CHUNK_ACCESS)).left(); + + if (optional.isPresent() && optional.get() instanceof ProtoChunk) { + this.statusFutures.set(i, CompletableFuture.completedFuture(Either.left(protochunkextension))); + } + } + } + + this.a(CompletableFuture.completedFuture(Either.left(protochunkextension.u()))); + } + + public interface d { + + Stream a(ChunkCoordIntPair chunkcoordintpair, boolean flag); + } + + public interface c { + + void a(ChunkCoordIntPair chunkcoordintpair, IntSupplier intsupplier, int i, IntConsumer intconsumer); + } + + public interface Failure { + + PlayerChunk.Failure b = new PlayerChunk.Failure() { + public String toString() { + return "UNLOADED"; + } + }; + } + + public static enum State { + + INACCESSIBLE, BORDER, TICKING, ENTITY_TICKING; + + private State() {} + + public boolean isAtLeast(PlayerChunk.State playerchunk_state) { + return this.ordinal() >= playerchunk_state.ordinal(); + } } } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java index 46cf1e464..59e74900f 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -1,561 +1,1690 @@ package net.minecraft.server; -import co.aikar.timings.Timing; -import com.google.common.collect.AbstractIterator; -import com.google.common.collect.ComparisonChain; +import co.aikar.timings.Timing; // Paper +import com.destroystokyo.paper.PaperWorldConfig; // Paper +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.ComparisonChain; // Paper import com.google.common.collect.Lists; +import com.google.common.collect.Queues; import com.google.common.collect.Sets; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import java.util.Collections; +import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.util.Either; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry; +import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator; +import it.unimi.dsi.fastutil.objects.ObjectIterator; +import java.io.File; +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; // Paper import java.util.Iterator; import java.util.List; +import java.util.Map; // Paper +import java.util.Objects; +import java.util.Optional; +import java.util.Queue; import java.util.Set; -import java.util.function.Predicate; +import java.util.concurrent.CancellationException; +import java.util.UUID; // Paper +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.IntFunction; +import java.util.function.IntSupplier; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nullable; +import org.apache.commons.lang3.mutable.MutableBoolean; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.entity.Player; // CraftBukkit -// CraftBukkit start -import java.util.LinkedList; -// CraftBukkit end +public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { -public class PlayerChunkMap { + private static final Logger LOGGER = LogManager.getLogger(); + public static final int GOLDEN_TICKET = 33 + ChunkStatus.b(); + public final Long2ObjectLinkedOpenHashMap updatingChunks = new Long2ObjectLinkedOpenHashMap(); + public volatile Long2ObjectLinkedOpenHashMap visibleChunks; + private final Long2ObjectLinkedOpenHashMap pendingUnload; + final LongSet loadedChunks; // Paper - private -> package + public final WorldServer world; + private final LightEngineThreaded lightEngine; + private final IAsyncTaskHandler executor; + public final ChunkGenerator chunkGenerator; + private final Supplier m; public final Supplier getWorldPersistentDataSupplier() { return this.m; } // Paper - OBFHELPER + private final VillagePlace n; + public final LongSet unloadQueue; + private boolean updatingChunksModified; + private final ChunkTaskQueueSorter q; + private final Mailbox> mailboxWorldGen; + private final Mailbox> mailboxMain; + public final WorldLoadListener worldLoadListener; + public final PlayerChunkMap.a chunkDistanceManager; public final PlayerChunkMap.a getChunkMapDistanceManager() { return this.chunkDistanceManager; } // Paper - OBFHELPER + private final AtomicInteger v; + public final DefinedStructureManager definedStructureManager; // Paper - private -> public + private final File x; + private final PlayerMap playerMap; + public final Int2ObjectMap trackedEntities; + private final Queue A; + int viewDistance; // Paper - private -> package private + public final com.destroystokyo.paper.util.PlayerMobDistanceMap playerMobDistanceMap; // Paper - private static final Predicate a = (entityplayer) -> { - return entityplayer != null && !entityplayer.isSpectator(); - }; - private static final Predicate b = (entityplayer) -> { - return entityplayer != null && (!entityplayer.isSpectator() || entityplayer.getWorldServer().getGameRules().getBoolean("spectatorsGenerateChunks")); - }; static final Predicate CAN_GEN_CHUNKS = b; // Paper - OBFHELPER - private final WorldServer world; - private final List managedPlayers = Lists.newArrayList(); - private final Long2ObjectMap e = new Long2ObjectOpenHashMap(4096); Long2ObjectMap getChunks() { return e; } // Paper - OBFHELPER - private final Set f = Sets.newHashSet(); - private final List g = Lists.newLinkedList(); - private final List h = Lists.newLinkedList(); - private final List i = Lists.newArrayList(); - private int j;public int getViewDistance() { return j; } // Paper OBFHELPER - private long k; - private boolean l = true; - private boolean m = true; - private boolean wasNotEmpty; // CraftBukkit - add field + // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() + public final CallbackExecutor callbackExecutor = new CallbackExecutor(); + public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable { - public PlayerChunkMap(WorldServer worldserver) { - this.world = worldserver; - this.a(worldserver.spigotConfig.viewDistance); // Spigot - } + private Runnable queued; - public WorldServer getWorld() { - return this.world; - } - - public Iterator b() { - final Iterator iterator = this.i.iterator(); - - return new AbstractIterator() { - protected Chunk computeNext() { - while (true) { - if (iterator.hasNext()) { - PlayerChunk playerchunk = (PlayerChunk) iterator.next(); - Chunk chunk = playerchunk.f(); - - if (chunk == null) { - continue; - } - - if (!chunk.v()) { - return chunk; - } - - if (!playerchunk.a(128.0D, PlayerChunkMap.a)) { - continue; - } - - return chunk; - } - - return (Chunk) this.endOfData(); - } + @Override + public void execute(Runnable runnable) { + if (queued != null) { + throw new IllegalStateException("Already queued"); } - }; + queued = runnable; + } + + @Override + public void run() { + Runnable task = queued; + queued = null; + if (task != null) { + task.run(); + } + } + }; + // CraftBukkit end + + public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier supplier, int i) { + super(new File(worldserver.getWorldProvider().getDimensionManager().a(file), "region"), datafixer); + this.visibleChunks = this.updatingChunks.clone(); + this.pendingUnload = new Long2ObjectLinkedOpenHashMap(); + this.loadedChunks = new LongOpenHashSet(); + this.unloadQueue = new LongOpenHashSet(); + this.v = new AtomicInteger(); + this.playerMap = new PlayerMap(); + this.trackedEntities = new Int2ObjectOpenHashMap(); + this.A = new com.destroystokyo.paper.utils.CachedSizeConcurrentLinkedQueue<>(); // Paper + this.definedStructureManager = definedstructuremanager; + this.x = worldserver.getWorldProvider().getDimensionManager().a(file); + this.world = worldserver; + this.chunkGenerator = chunkgenerator; + this.executor = iasynctaskhandler; + ThreadedMailbox threadedmailbox = ThreadedMailbox.a(executor, "worldgen"); + + iasynctaskhandler.getClass(); + Mailbox mailbox = Mailbox.a("main", iasynctaskhandler::a); + + this.worldLoadListener = worldloadlistener; + ThreadedMailbox threadedmailbox1 = ThreadedMailbox.a(executor, "light"); + + this.q = new ChunkTaskQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), executor, Integer.MAX_VALUE); + this.mailboxWorldGen = this.q.a(threadedmailbox, false); + this.mailboxMain = this.q.a(mailbox, false); + this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().g(), threadedmailbox1, this.q.a(threadedmailbox1, false)); + this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); + this.m = supplier; + this.n = new VillagePlace(new File(this.x, "poi"), datafixer, this.world); // Paper + this.setViewDistance(i); + this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper } - public void flush() { - long i = this.world.getTime(); - PlayerChunk playerchunk; + public void updatePlayerMobTypeMap(Entity entity) { + if (!this.world.paperConfig.perPlayerMobSpawns) { + return; + } + int chunkX = (int)Math.floor(entity.locX) >> 4; + int chunkZ = (int)Math.floor(entity.locZ) >> 4; + int index = entity.getEntityType().getEnumCreatureType().ordinal(); + + for (EntityPlayer player : this.playerMobDistanceMap.getPlayersInRange(chunkX, chunkZ)) { + ++player.mobCounts[index]; + } + } + + public int getMobCountNear(EntityPlayer entityPlayer, EnumCreatureType enumCreatureType) { + return entityPlayer.mobCounts[enumCreatureType.ordinal()]; + } + + private static double a(ChunkCoordIntPair chunkcoordintpair, Entity entity) { + double d0 = (double) (chunkcoordintpair.x * 16 + 8); + double d1 = (double) (chunkcoordintpair.z * 16 + 8); + double d2 = d0 - entity.locX; + double d3 = d1 - entity.locZ; + + return d2 * d2 + d3 * d3; + } + + private static int b(ChunkCoordIntPair chunkcoordintpair, EntityPlayer entityplayer, boolean flag) { + int i; int j; - if (i - this.k > 8000L) { - try (Timing ignored = world.timings.doChunkMapUpdate.startTimingUnsafe()) { // Paper // Akarin - this.k = i; + if (flag) { + SectionPosition sectionposition = entityplayer.M(); - for (j = 0; j < this.i.size(); ++j) { - playerchunk = (PlayerChunk) this.i.get(j); - playerchunk.d(); - playerchunk.c(); - } - } // Paper timing - } - - if (!this.f.isEmpty()) { - try (Timing ignored = world.timings.doChunkMapToUpdate.startTimingUnsafe()) { // Paper // Akarin - Iterator iterator = this.f.iterator(); - - while (iterator.hasNext()) { - playerchunk = (PlayerChunk) iterator.next(); - playerchunk.d(); - } - - this.f.clear(); - } // Paper timing - } - - if (this.l && i % 4L == 0L) { - this.l = false; - try (Timing ignored = world.timings.doChunkMapSortMissing.startTimingUnsafe()) { // Paper // Akarin - Collections.sort(this.h, (playerchunk1, playerchunk2) -> { - return ComparisonChain.start().compare(playerchunk1.g(), playerchunk2.g()).result(); - }); - } // Paper timing - } - - if (this.m && i % 4L == 2L) { - this.m = false; - try (Timing ignored = world.timings.doChunkMapSortSendToPlayers.startTimingUnsafe()) { // Paper // Akarin - Collections.sort(this.g, (playerchunk1, playerchunk2) -> { - return ComparisonChain.start().compare(playerchunk1.g(), playerchunk2.g()).result(); - }); - } // Paper timing - } - - if (!this.h.isEmpty()) { - try (Timing ignored = world.timings.doChunkMapPlayersNeedingChunks.startTimingUnsafe()) { // Paper // Akarin - // Spigot start - org.spigotmc.SlackActivityAccountant activityAccountant = this.world.getMinecraftServer().slackActivityAccountant; - activityAccountant.startActivity(0.5); - int chunkGensAllowed = world.paperConfig.maxChunkGensPerTick; // Paper - // Spigot end - - Iterator iterator1 = this.h.iterator(); - - while (iterator1.hasNext()) { - PlayerChunk playerchunk1 = (PlayerChunk) iterator1.next(); - - if (playerchunk1.f() == null) { - boolean flag = playerchunk1.a(PlayerChunkMap.b); - // Paper start - if (flag && !playerchunk1.chunkExists && chunkGensAllowed-- <= 0) { - continue; - } - // Paper end - - if (playerchunk1.a(flag)) { - iterator1.remove(); - if (playerchunk1.b()) { - this.g.remove(playerchunk1); - } - - if (activityAccountant.activityTimeIsExhausted()) { // Spigot - break; - } - } - // CraftBukkit start - SPIGOT-2891: remove once chunk has been provided - } else { - iterator1.remove(); - } - // CraftBukkit end - } - - activityAccountant.endActivity(); // Spigot - } // Paper timing - } - - if (!this.g.isEmpty()) { - j = world.paperConfig.maxChunkSendsPerTick; // Paper - try (Timing ignored = world.timings.doChunkMapPendingSendToPlayers.startTimingUnsafe()) { // Paper // Akarin - Iterator iterator2 = this.g.iterator(); - - while (iterator2.hasNext()) { - PlayerChunk playerchunk2 = (PlayerChunk) iterator2.next(); - - if (playerchunk2.b()) { - iterator2.remove(); - --j; - if (j < 0) { - break; - } - } - } - } // Paper timing - } - - if (this.managedPlayers.isEmpty()) { - try (Timing ignored = world.timings.doChunkMapUnloadChunks.startTimingUnsafe()) { // Paper // Akarin - WorldProvider worldprovider = this.world.worldProvider; - - if (!worldprovider.canRespawn() && !this.world.savingDisabled) { // Paper - respect saving disabled setting - this.world.getChunkProvider().b(); - } - } // Paper timing + i = sectionposition.a(); + j = sectionposition.c(); + } else { + i = MathHelper.floor(entityplayer.locX / 16.0D); + j = MathHelper.floor(entityplayer.locZ / 16.0D); } + return a(chunkcoordintpair, i, j); } - public boolean a(int i, int j) { - long k = d(i, j); + private static int a(ChunkCoordIntPair chunkcoordintpair, int i, int j) { + int k = chunkcoordintpair.x - i; + int l = chunkcoordintpair.z - j; - return this.e.get(k) != null; + return Math.max(Math.abs(k), Math.abs(l)); + } + + protected LightEngineThreaded a() { + return this.lightEngine; } @Nullable - public PlayerChunk getChunk(int i, int j) { - return (PlayerChunk) this.e.get(d(i, j)); + protected PlayerChunk getUpdatingChunk(long i) { + return (PlayerChunk) this.updatingChunks.get(i); } - private PlayerChunk c(int i, int j) { - long k = d(i, j); - PlayerChunk playerchunk = (PlayerChunk) this.e.get(k); + @Nullable + public PlayerChunk getVisibleChunk(long i) { // Paper - protected -> public + return (PlayerChunk) this.visibleChunks.get(i); + } - if (playerchunk == null) { - playerchunk = new PlayerChunk(this, i, j); - this.e.put(k, playerchunk); - this.i.add(playerchunk); - if (playerchunk.f() == null) { - this.h.add(playerchunk); - } + protected IntSupplier c(long i) { + return () -> { + PlayerChunk playerchunk = this.getVisibleChunk(i); - if (!playerchunk.b()) { - this.g.add(playerchunk); + return playerchunk == null ? ChunkTaskQueue.a - 1 : Math.min(playerchunk.k(), ChunkTaskQueue.a - 1); + }; + } + + private CompletableFuture, PlayerChunk.Failure>> a(ChunkCoordIntPair chunkcoordintpair, int i, IntFunction intfunction) { + List>> list = Lists.newArrayList(); + int j = chunkcoordintpair.x; + int k = chunkcoordintpair.z; + + for (int l = -i; l <= i; ++l) { + for (int i1 = -i; i1 <= i; ++i1) { + int j1 = Math.max(Math.abs(i1), Math.abs(l)); + final ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(j + i1, k + l); + long k1 = chunkcoordintpair1.pair(); + PlayerChunk playerchunk = this.getUpdatingChunk(k1); + + if (playerchunk == null) { + return CompletableFuture.completedFuture(Either.right(new PlayerChunk.Failure() { + public String toString() { + return "Unloaded " + chunkcoordintpair1.toString(); + } + })); + } + + ChunkStatus chunkstatus = (ChunkStatus) intfunction.apply(j1); + CompletableFuture> completablefuture = playerchunk.a(chunkstatus, this); + + list.add(completablefuture); } } - return playerchunk; - } + CompletableFuture>> completablefuture1 = SystemUtils.b(list); - // CraftBukkit start - add method - public final boolean isChunkInUse(int x, int z) { - PlayerChunk pi = getChunk(x, z); - if (pi != null) { - return (pi.players.size() > 0); - } - return false; - } - // CraftBukkit end + return completablefuture1.thenApply((list1) -> { + List list2 = Lists.newArrayList(); + // CraftBukkit start - decompile error + int cnt = 0; - public void flagDirty(BlockPosition blockposition) { - int i = blockposition.getX() >> 4; - int j = blockposition.getZ() >> 4; - PlayerChunk playerchunk = this.getChunk(i, j); + for (Iterator iterator = list1.iterator(); iterator.hasNext(); ++cnt) { + final int l1 = cnt; + // CraftBukkit end + final Either either = (Either) iterator.next(); + Optional optional = either.left(); - if (playerchunk != null) { - playerchunk.a(blockposition.getX() & 15, blockposition.getY(), blockposition.getZ() & 15); - } + if (!optional.isPresent()) { + return Either.right(new PlayerChunk.Failure() { + public String toString() { + return "Unloaded " + new ChunkCoordIntPair(j + l1 % (i * 2 + 1), k + l1 / (i * 2 + 1)) + " " + ((PlayerChunk.Failure) either.right().get()).toString(); + } + }); + } - } - - public void addPlayer(EntityPlayer entityplayer) { - int i = (int) entityplayer.locX >> 4; - int j = (int) entityplayer.locZ >> 4; - - entityplayer.d = entityplayer.locX; - entityplayer.e = entityplayer.locZ; - - - // CraftBukkit start - Load nearby chunks first - List chunkList = new LinkedList(); - - // Paper start - Player view distance API - int viewDistance = entityplayer.getViewDistance(); - for (int k = i - viewDistance; k <= i + viewDistance; ++k) { - for (int l = j - viewDistance; l <= j + viewDistance; ++l) { - // Paper end - chunkList.add(new ChunkCoordIntPair(k, l)); + list2.add(optional.get()); } - } - Collections.sort(chunkList, new ChunkCoordComparator(entityplayer)); - for (ChunkCoordIntPair pair : chunkList) { - this.c(pair.x, pair.z).a(entityplayer); - } - // CraftBukkit end - - this.managedPlayers.add(entityplayer); - this.e(); + return Either.left(list2); + }); } - public void removePlayer(EntityPlayer entityplayer) { - int i = (int) entityplayer.d >> 4; - int j = (int) entityplayer.e >> 4; + public CompletableFuture> b(ChunkCoordIntPair chunkcoordintpair) { + return this.a(chunkcoordintpair, 2, (i) -> { + return ChunkStatus.FULL; + }).thenApplyAsync((either) -> { + return either.mapLeft((list) -> { + return (Chunk) list.get(list.size() / 2); + }); + }, this.executor); + } - // Paper start - Player view distance API - int viewDistance = entityplayer.getViewDistance(); - for (int k = i - viewDistance; k <= i + viewDistance; ++k) { - for (int l = j - viewDistance; l <= j + viewDistance; ++l) { - // Paper end - PlayerChunk playerchunk = this.getChunk(k, l); + @Nullable + private PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k) { + if (k > PlayerChunkMap.GOLDEN_TICKET && j > PlayerChunkMap.GOLDEN_TICKET) { + return playerchunk; + } else { + if (playerchunk != null) { + playerchunk.a(j); + } - if (playerchunk != null) { - playerchunk.b(entityplayer); + if (playerchunk != null) { + if (j > PlayerChunkMap.GOLDEN_TICKET) { + this.unloadQueue.add(i); + } else { + this.unloadQueue.remove(i); } } + + if (j <= PlayerChunkMap.GOLDEN_TICKET && playerchunk == null) { + playerchunk = (PlayerChunk) this.pendingUnload.remove(i); + if (playerchunk != null) { + playerchunk.a(j); + } else { + playerchunk = new PlayerChunk(new ChunkCoordIntPair(i), j, this.lightEngine, this.q, this); + } + + this.updatingChunks.put(i, playerchunk); + this.updatingChunksModified = true; + } + + return playerchunk; } - - this.managedPlayers.remove(entityplayer); - this.e(); } - private boolean a(int i, int j, int k, int l, int i1) { - int j1 = i - k; - int k1 = j - l; - - return j1 >= -i1 && j1 <= i1 ? k1 >= -i1 && k1 <= i1 : false; + @Override + public void close() throws IOException { + this.q.close(); + this.world.asyncChunkTaskManager.close(true); // Paper - Required since we're closing regionfiles in the next line + this.n.close(); + super.close(); } - public void movePlayer(EntityPlayer entityplayer) { - int i = (int) entityplayer.locX >> 4; - int j = (int) entityplayer.locZ >> 4; - double d0 = entityplayer.d - entityplayer.locX; - double d1 = entityplayer.e - entityplayer.locZ; - double d2 = d0 * d0 + d1 * d1; + // Paper start - derived from below + protected void saveIncrementally() { + int savedThisTick = 0; + for (PlayerChunk playerchunk : visibleChunks.values()) { + if (playerchunk.hasBeenLoaded()) { - if (d2 >= 64.0D) { - int k = (int) entityplayer.d >> 4; - int l = (int) entityplayer.e >> 4; - int i1 = entityplayer.getViewDistance(); // Paper - Player view distance API + IChunkAccess ichunkaccess = (IChunkAccess) playerchunk.getChunkSave().getNow(null); // CraftBukkit - decompile error - int j1 = i - k; - int k1 = j - l; - List chunksToLoad = new LinkedList(); // CraftBukkit + if (ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk) { + boolean shouldSave = true; - if (j1 != 0 || k1 != 0) { - for (int l1 = i - i1; l1 <= i + i1; ++l1) { - for (int i2 = j - i1; i2 <= j + i1; ++i2) { - if (!this.a(l1, i2, k, l, i1)) { - // this.c(l1, i2).a(entityplayer); - chunksToLoad.add(new ChunkCoordIntPair(l1, i2)); // CraftBukkit - } + if (ichunkaccess instanceof Chunk) { + shouldSave = ((Chunk) ichunkaccess).lastSaved + world.paperConfig.autoSavePeriod <= world.getTime(); + } - if (!this.a(l1 - j1, i2 - k1, i, j, i1)) { - PlayerChunk playerchunk = this.getChunk(l1 - j1, i2 - k1); - - if (playerchunk != null) { - playerchunk.b(entityplayer); - } - } else { // Paper start - PlayerChunk playerchunk = this.getChunk(l1 - j1, i2 - k1); - if (playerchunk != null) { - playerchunk.checkHighPriority(entityplayer); // Paper - } - } - // Paper end + if (shouldSave && this.saveChunk(ichunkaccess, true)) { // Paper - async chunk io + ++savedThisTick; + playerchunk.m(); } } - entityplayer.d = entityplayer.locX; - entityplayer.e = entityplayer.locZ; - this.e(); - - // CraftBukkit start - send nearest chunks first - Collections.sort(chunksToLoad, new ChunkCoordComparator(entityplayer)); - for (ChunkCoordIntPair pair : chunksToLoad) { - // Paper start - PlayerChunk c = this.c(pair.x, pair.z); - c.checkHighPriority(entityplayer); - c.a(entityplayer); - // Paper end + if (savedThisTick >= world.paperConfig.maxAutoSaveChunksPerTick) { + return; + } + } + } + } + // paper end + + protected void save(boolean flag) { + if (flag) { + List list = (List) this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).peek(PlayerChunk::m).collect(Collectors.toList()); + MutableBoolean mutableboolean = new MutableBoolean(); + + do { + mutableboolean.setFalse(); + list.stream().map((playerchunk) -> { + CompletableFuture completablefuture; + + do { + completablefuture = playerchunk.getChunkSave(); + this.executor.awaitTasks(completablefuture::isDone); + } while (completablefuture != playerchunk.getChunkSave()); + + return (IChunkAccess) completablefuture.join(); + }).filter((ichunkaccess) -> { + return ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk; + }).filter((chunk) -> this.saveChunk(chunk, true)).forEach((ichunkaccess) -> { // Paper - async io for chunk save + mutableboolean.setTrue(); + }); + } while (mutableboolean.isTrue()); + + this.b(() -> { + return true; + }); + this.world.asyncChunkTaskManager.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour + PlayerChunkMap.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.x.getName()); + } else { + this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).forEach((playerchunk) -> { + IChunkAccess ichunkaccess = (IChunkAccess) playerchunk.getChunkSave().getNow(null); // CraftBukkit - decompile error + + if (ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk) { + this.saveChunk(ichunkaccess, true); // Paper + playerchunk.m(); + } + + }); + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour + } + + } + + private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.96; // Spigot + + protected void unloadChunks(BooleanSupplier booleansupplier) { + GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler(); + + try (Timing ignored = this.world.timings.poiUnload.startTiming()) { // Paper + gameprofilerfiller.enter("poi"); + this.n.a(booleansupplier); + } // Paper + gameprofilerfiller.exitEnter("chunk_unload"); + if (!this.world.isSavingDisabled()) { + try (Timing ignored = this.world.timings.chunkUnload.startTiming()) { // Paper + this.b(booleansupplier); + }// Paper + } + + gameprofilerfiller.exit(); + } + + private void b(BooleanSupplier booleansupplier) { + LongIterator longiterator = this.unloadQueue.iterator(); + // Spigot start + org.spigotmc.SlackActivityAccountant activityAccountant = this.world.getMinecraftServer().slackActivityAccountant; + activityAccountant.startActivity(0.5); + int targetSize = Math.min(this.unloadQueue.size() - 100, (int) (this.unloadQueue.size() * UNLOAD_QUEUE_RESIZE_FACTOR)); // Paper - Make more aggressive + // Spigot end + while (longiterator.hasNext()) { // Spigot + long j = longiterator.nextLong(); + longiterator.remove(); // Spigot + PlayerChunk playerchunk = (PlayerChunk) this.updatingChunks.remove(j); + + if (playerchunk != null) { + this.pendingUnload.put(j, playerchunk); + this.updatingChunksModified = true; + // Spigot start + if (!booleansupplier.getAsBoolean() && this.unloadQueue.size() <= targetSize && activityAccountant.activityTimeIsExhausted()) { + break; + } + // Spigot end + this.a(j, playerchunk); + } + } + activityAccountant.endActivity(); // Spigot + + Runnable runnable; + + int queueTarget = Math.min(this.A.size() - 100, (int) (this.A.size() * UNLOAD_QUEUE_RESIZE_FACTOR)); // Paper - Target this queue as well + + while ((booleansupplier.getAsBoolean() || this.A.size() > queueTarget) && (runnable = (Runnable) this.A.poll()) != null) { // Paper - Target this queue as well + runnable.run(); + } + + } + + // Paper start - async chunk save for unload + // Note: This is very unsafe to call if the chunk is still in use. + // This is also modeled after PlayerChunkMap#saveChunk(IChunkAccess, boolean), with the intentional difference being + // serializing the chunk is left to a worker thread. + private void asyncSave(IChunkAccess chunk) { + ChunkCoordIntPair chunkPos = chunk.getPos(); + NBTTagCompound poiData; + try (Timing ignored = this.world.timings.chunkUnloadPOISerialization.startTiming()) { + poiData = this.getVillagePlace().getData(chunk.getPos()); + } + + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkPos.x, chunkPos.z, + poiData, null, com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY); + + if (!chunk.isNeedsSaving()) { + return; + } + + ChunkStatus chunkstatus = chunk.getChunkStatus(); + + // Copied from PlayerChunkMap#saveChunk(IChunkAccess, boolean) + if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) { + try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveOverwriteCheck.startTiming()) { // Paper + // Paper start - Optimize save by using status cache + try { + ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkPos); + if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) { + // Paper end + return; + } + + if (chunkstatus == ChunkStatus.EMPTY && chunk.h().values().stream().noneMatch(StructureStart::e)) { + return; + } + } catch (IOException ex) { + ex.printStackTrace(); + return; + } + } + } + + ChunkRegionLoader.AsyncSaveData asyncSaveData; + try (Timing ignored = this.world.timings.chunkUnloadPrepareSave.startTiming()) { + asyncSaveData = ChunkRegionLoader.getAsyncSaveData(this.world, chunk); + } + + this.world.asyncChunkTaskManager.scheduleChunkSave(chunkPos.x, chunkPos.z, com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY, + asyncSaveData, chunk); + + chunk.setLastSaved(this.world.getTime()); + chunk.setNeedsSaving(false); + } + // Paper end + + private void a(long i, PlayerChunk playerchunk) { + CompletableFuture completablefuture = playerchunk.getChunkSave(); + Consumer consumer = (ichunkaccess) -> { // CraftBukkit - decompile error + CompletableFuture completablefuture1 = playerchunk.getChunkSave(); + + if (completablefuture1 != completablefuture) { + this.a(i, playerchunk); + } else { + if (this.pendingUnload.remove(i, playerchunk) && ichunkaccess != null) { + if (ichunkaccess instanceof Chunk) { + ((Chunk) ichunkaccess).setLoaded(false); + } + + //this.saveChunk(ichunkaccess);// Paper - delay + if (this.loadedChunks.remove(i) && ichunkaccess instanceof Chunk) { + Chunk chunk = (Chunk) ichunkaccess; + + this.world.unloadChunk(chunk); + } + + try { + this.asyncSave(ichunkaccess); // Paper - async chunk saving + } catch (Throwable ex) { + LOGGER.fatal("Failed to prepare async save, attempting synchronous save", ex); + this.saveChunk(ichunkaccess, true); + } + + this.lightEngine.a(ichunkaccess.getPos()); + this.lightEngine.queueUpdate(); + this.worldLoadListener.a(ichunkaccess.getPos(), (ChunkStatus) null); + } + + } + }; + Queue queue = this.A; + + this.A.getClass(); + completablefuture.thenAcceptAsync(consumer, queue::add).whenComplete((ovoid, throwable) -> { + if (throwable != null) { + PlayerChunkMap.LOGGER.error("Failed to save chunk " + playerchunk.i(), throwable); + } + + }); + } + + protected boolean b() { + if (!this.updatingChunksModified) { + return false; + } else { + this.visibleChunks = this.updatingChunks.clone(); + this.updatingChunksModified = false; + return true; + } + } + + public CompletableFuture> a(PlayerChunk playerchunk, ChunkStatus chunkstatus) { + ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + + if (chunkstatus == ChunkStatus.EMPTY) { + return this.f(chunkcoordintpair); + } else { + CompletableFuture> completablefuture = playerchunk.a(chunkstatus.e(), this); + + return completablefuture.thenComposeAsync((either) -> { + Optional optional = either.left(); + + if (!optional.isPresent()) { + return CompletableFuture.completedFuture(either); + } else { + if (chunkstatus == ChunkStatus.LIGHT) { + this.chunkDistanceManager.a(TicketType.LIGHT, chunkcoordintpair, 33 + ChunkStatus.a(ChunkStatus.FEATURES), chunkcoordintpair); + } + + IChunkAccess ichunkaccess = (IChunkAccess) optional.get(); + + if (ichunkaccess.getChunkStatus().b(chunkstatus)) { + CompletableFuture completablefuture1; + + if (chunkstatus == ChunkStatus.LIGHT) { + completablefuture1 = this.b(playerchunk, chunkstatus); + } else { + completablefuture1 = chunkstatus.a(this.world, this.definedStructureManager, this.lightEngine, (ichunkaccess1) -> { + return this.c(playerchunk); + }, ichunkaccess); + } + + this.worldLoadListener.a(chunkcoordintpair, chunkstatus); + return completablefuture1; + } else { + return this.b(playerchunk, chunkstatus); + } + } + }, this.executor); + } + } + + // Paper start - Async chunk io + public NBTTagCompound completeChunkData(NBTTagCompound compound, ChunkCoordIntPair chunkcoordintpair) throws IOException { + return compound == null ? null : this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.getWorldPersistentDataSupplier(), compound, chunkcoordintpair, this.world); + } + // Paper end + + private CompletableFuture> f(ChunkCoordIntPair chunkcoordintpair) { + // Paper start - Async chunk io + final java.util.function.BiFunction> syncLoadComplete = (chunkHolder, ioThrowable) -> { + try (Timing ignored = this.world.timings.syncChunkLoadTimer.startTimingIfSync()) { // Paper + if (ioThrowable != null) { + com.destroystokyo.paper.io.IOUtil.rethrow(ioThrowable); + } + this.getVillagePlace().loadInData(chunkcoordintpair, chunkHolder.poiData); + chunkHolder.tasks.forEach(Runnable::run); + // Paper - async load completes this + // Paper end + + // Paper start - This is done async + if (chunkHolder.protoChunk != null) { + chunkHolder.protoChunk.setLastSaved(this.world.getTime()); + return Either.left(chunkHolder.protoChunk); + } + // Paper end + } catch (ReportedException reportedexception) { + Throwable throwable = reportedexception.getCause(); + + if (!(throwable instanceof IOException)) { + throw reportedexception; + } + + PlayerChunkMap.LOGGER.error("Couldn't load chunk {}", chunkcoordintpair, throwable); + } catch (Exception exception) { + PlayerChunkMap.LOGGER.error("Couldn't load chunk {}", chunkcoordintpair, exception); + } + + return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.world)); // Paper - Anti-Xray + // Paper start - Async chunk io + }; + CompletableFuture> ret = new CompletableFuture<>(); + + Consumer chunkHolderConsumer = (ChunkRegionLoader.InProgressChunkHolder holder) -> { + PlayerChunkMap.this.executor.addTask(() -> { + ret.complete(syncLoadComplete.apply(holder, null)); + }); + }; + + CompletableFuture chunkSaveFuture = this.world.asyncChunkTaskManager.getChunkSaveFuture(chunkcoordintpair.x, chunkcoordintpair.z); + if (chunkSaveFuture != null) { + this.world.asyncChunkTaskManager.scheduleChunkLoad(chunkcoordintpair.x, chunkcoordintpair.z, + com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY, chunkHolderConsumer, false, chunkSaveFuture); + this.world.asyncChunkTaskManager.raisePriority(chunkcoordintpair.x, chunkcoordintpair.z, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY); + } else { + this.world.asyncChunkTaskManager.scheduleChunkLoad(chunkcoordintpair.x, chunkcoordintpair.z, + com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY, chunkHolderConsumer, false); + } + return ret; + // Paper end + } + + private CompletableFuture> b(PlayerChunk playerchunk, ChunkStatus chunkstatus) { + ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + CompletableFuture, PlayerChunk.Failure>> completablefuture = this.a(chunkcoordintpair, chunkstatus.f(), (i) -> { + return this.a(chunkstatus, i); + }); + + return completablefuture.thenComposeAsync((either) -> { + return either.map((list) -> { // Paper - Shut up. + try { + CompletableFuture> completablefuture1 = chunkstatus.a(this.world, this.chunkGenerator, this.definedStructureManager, this.lightEngine, (ichunkaccess) -> { + return this.c(playerchunk); + }, list); + + this.worldLoadListener.a(chunkcoordintpair, chunkstatus); + return completablefuture1; + } catch (Exception exception) { + CrashReport crashreport = CrashReport.a(exception, "Exception generating new chunk"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Chunk to be generated"); + + crashreportsystemdetails.a("Location", (Object) String.format("%d,%d", chunkcoordintpair.x, chunkcoordintpair.z)); + crashreportsystemdetails.a("Position hash", (Object) ChunkCoordIntPair.pair(chunkcoordintpair.x, chunkcoordintpair.z)); + crashreportsystemdetails.a("Generator", (Object) this.chunkGenerator); + throw new ReportedException(crashreport); + } + }, (playerchunk_failure) -> { + this.c(chunkcoordintpair); + return CompletableFuture.completedFuture(Either.right(playerchunk_failure)); + }); + }, (runnable) -> { + this.mailboxWorldGen.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error + }); + } + + protected void c(ChunkCoordIntPair chunkcoordintpair) { + this.executor.a(SystemUtils.a(() -> { + this.chunkDistanceManager.b(TicketType.LIGHT, chunkcoordintpair, 33 + ChunkStatus.a(ChunkStatus.FEATURES), chunkcoordintpair); + }, () -> { + return "release light ticket " + chunkcoordintpair; + })); + } + + private ChunkStatus a(ChunkStatus chunkstatus, int i) { + ChunkStatus chunkstatus1; + + if (i == 0) { + chunkstatus1 = chunkstatus.e(); + } else { + chunkstatus1 = ChunkStatus.a(ChunkStatus.a(chunkstatus) + i); + } + + return chunkstatus1; + } + + private CompletableFuture> c(PlayerChunk playerchunk) { + CompletableFuture> completablefuture = playerchunk.getStatusFutureUnchecked(ChunkStatus.FULL.e()); + + return completablefuture.thenApplyAsync((either) -> { + ChunkStatus chunkstatus = PlayerChunk.getChunkStatus(playerchunk.getTicketLevel()); + + return !chunkstatus.b(ChunkStatus.FULL) ? PlayerChunk.UNLOADED_CHUNK_ACCESS : either.mapLeft((ichunkaccess) -> { + try (Timing ignored = world.timings.chunkIOStage2.startTimingIfSync()) { // Paper + ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + Chunk chunk; + + if (ichunkaccess instanceof ProtoChunkExtension) { + chunk = ((ProtoChunkExtension) ichunkaccess).u(); + } else { + chunk = new Chunk(this.world, (ProtoChunk) ichunkaccess); + playerchunk.a(new ProtoChunkExtension(chunk)); + } + + chunk.a(() -> { + return PlayerChunk.getChunkState(playerchunk.getTicketLevel()); + }); + chunk.addEntities(); + if (this.loadedChunks.add(chunkcoordintpair.pair())) { + chunk.setLoaded(true); + this.world.a(chunk.getTileEntities().values()); + List list = null; + List[] aentityslice = chunk.getEntitySlices(); // Spigot + int i = aentityslice.length; + + for (int j = 0; j < i; ++j) { + List entityslice = aentityslice[j]; // Spigot + + // Paper start + PaperWorldConfig.DuplicateUUIDMode mode = world.paperConfig.duplicateUUIDMode; + if (mode == PaperWorldConfig.DuplicateUUIDMode.WARN || mode == PaperWorldConfig.DuplicateUUIDMode.DELETE || mode == PaperWorldConfig.DuplicateUUIDMode.SAFE_REGEN) { + Map thisChunk = new HashMap<>(); + for (Iterator iterator = ((List) entityslice).iterator(); iterator.hasNext(); ) { + Entity entity = iterator.next(); + if (entity.dead || entity.valid) continue; + Entity other = ((WorldServer) world).getEntity(entity.uniqueID); + if (other == null || other.dead) { + other = thisChunk.get(entity.uniqueID); + } + + if (mode == PaperWorldConfig.DuplicateUUIDMode.SAFE_REGEN && other != null && !other.dead + && java.util.Objects.equals(other.getSaveID(), entity.getSaveID()) + && entity.getBukkitEntity().getLocation().distance(other.getBukkitEntity().getLocation()) < world.paperConfig.duplicateUUIDDeleteRange + ) { + if (World.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + " because it was near the duplicate and likely an actual duplicate. See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); + entity.dead = true; + iterator.remove(); + continue; + } + if (other != null && !other.dead) { + switch (mode) { + case SAFE_REGEN: { + entity.setUUID(UUID.randomUUID()); + if (World.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", regenerated UUID for " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); + break; + } + case DELETE: { + if (World.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", deleted entity " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); + entity.dead = true; + iterator.remove(); + break; + } + default: + if (World.DEBUG_ENTITIES) LOGGER.warn("[DUPE-UUID] Duplicate UUID found used by " + other + ", doing nothing to " + entity + ". See https://github.com/PaperMC/Paper/issues/1223 for discussion on what this is about."); + break; + } + } + + + if (!(entity instanceof EntityHuman) && (entity.dead || !this.world.addEntityChunk(entity))) { // Paper + if (list == null) { + list = Lists.newArrayList(new Entity[]{entity}); + } else { + list.add(entity); + } + } + } + } // Paper + } + + if (list != null) { + list.forEach(chunk::b); + } + } + + return chunk; + } // Paper + }); + }, (runnable) -> { + Mailbox mailbox = this.mailboxMain; + long i = playerchunk.i().pair(); + + playerchunk.getClass(); + mailbox.a(ChunkTaskQueueSorter.a(runnable, i, playerchunk::getTicketLevel)); // CraftBukkit - decompile error + }); + } + + public CompletableFuture> a(PlayerChunk playerchunk) { + ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + CompletableFuture, PlayerChunk.Failure>> completablefuture = this.a(chunkcoordintpair, 1, (i) -> { + return ChunkStatus.FULL; + }); + CompletableFuture> completablefuture1 = completablefuture.thenApplyAsync((either) -> { + return either.flatMap((list) -> { + Chunk chunk = (Chunk) list.get(list.size() / 2); + + chunk.A(); + return Either.left(chunk); + }); + }, (runnable) -> { + this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error + }); + + completablefuture1.thenAcceptAsync((either) -> { + either.mapLeft((chunk) -> { + this.v.getAndIncrement(); + Packet[] apacket = new Packet[2]; + + this.a(chunkcoordintpair, false).forEach((entityplayer) -> { + this.a(entityplayer, apacket, chunk); + }); + return Either.left(chunk); + }); + }, (runnable) -> { + this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error + }); + return completablefuture1; + } + + public CompletableFuture> b(PlayerChunk playerchunk) { + return playerchunk.a(ChunkStatus.FULL, this).thenApplyAsync((either) -> { + return either.mapLeft((ichunkaccess) -> { + Chunk chunk = (Chunk) ichunkaccess; + + chunk.B(); + return chunk; + }); + }, (runnable) -> { + this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error + }); + } + + public int c() { + return this.v.get(); + } + + // Paper start - async chunk io + private boolean writeDataAsync(ChunkCoordIntPair chunkPos, NBTTagCompound poiData, NBTTagCompound chunkData, boolean async) { + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkPos.x, chunkPos.z, + poiData, chunkData, !async ? com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY : com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY); + + if (async) { + return true; + } + + try (co.aikar.timings.Timing ignored = this.world.timings.chunkSaveIOWait.startTiming()) { // Paper + Boolean successPoi = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, chunkPos.x, chunkPos.z, true, true); + Boolean successChunk = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, chunkPos.x, chunkPos.z, true, false); + + if (successPoi == Boolean.FALSE || successChunk == Boolean.FALSE) { + return false; + } + + // null indicates no task existed, which means our write completed before we waited on it + + return true; + } // Paper + } + // Paper end + + public boolean saveChunk(IChunkAccess ichunkaccess) { + // Paper start - async param + return this.saveChunk(ichunkaccess, false); + } + public boolean saveChunk(IChunkAccess ichunkaccess, boolean async) { + try (co.aikar.timings.Timing ignored = this.world.timings.chunkSave.startTiming()) { + NBTTagCompound poiData = this.getVillagePlace().getData(ichunkaccess.getPos()); // Paper + //this.n.a(ichunkaccess.getPos()); // Delay + // Paper end + if (!ichunkaccess.isNeedsSaving()) { + return false; + } else { + // Paper - The save session check is performed on the IO thread + + ichunkaccess.setLastSaved(this.world.getTime()); + ichunkaccess.setNeedsSaving(false); + ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos(); + + try { + ChunkStatus chunkstatus = ichunkaccess.getChunkStatus(); + NBTTagCompound nbttagcompound; + + if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) { + try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveOverwriteCheck.startTiming()) { // Paper + // Paper start - Optimize save by using status cache + ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkcoordintpair); + if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) { + // Paper end + this.writeDataAsync(ichunkaccess.getPos(), poiData, null, async); // Paper - Async chunk io + return false; + } + + if (chunkstatus == ChunkStatus.EMPTY && ichunkaccess.h().values().stream().noneMatch(StructureStart::e)) { + this.writeDataAsync(ichunkaccess.getPos(), poiData, null, async); // Paper - Async chunk io + return false; + } + } + } // Paper + try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveDataSerialization.startTiming()) { // Paper + nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess); + } // Paper + return this.writeDataAsync(ichunkaccess.getPos(), poiData, nbttagcompound, async); // Paper - Async chunk io + //return true; // Paper + } catch (Exception exception) { + PlayerChunkMap.LOGGER.error("Failed to save chunk {},{}", chunkcoordintpair.x, chunkcoordintpair.z, exception); + com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper + return false; + } + } + } // Paper + } + + protected void setViewDistance(int i) { + int j = MathHelper.clamp(i + 1, 3, 33); + + if (j != this.viewDistance) { + int k = this.viewDistance; + + this.viewDistance = j; + this.chunkDistanceManager.a(this.viewDistance); + ObjectIterator objectiterator = this.updatingChunks.values().iterator(); + + while (objectiterator.hasNext()) { + PlayerChunk playerchunk = (PlayerChunk) objectiterator.next(); + ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); + Packet[] apacket = new Packet[2]; + + this.a(chunkcoordintpair, false).forEach((entityplayer) -> { + int l = b(chunkcoordintpair, entityplayer, true); + boolean flag = l <= k; + boolean flag1 = l <= this.viewDistance; + + this.sendChunk(entityplayer, chunkcoordintpair, apacket, flag, flag1); + }); + } + } + + } + + protected void sendChunk(EntityPlayer entityplayer, ChunkCoordIntPair chunkcoordintpair, Packet[] apacket, boolean flag, boolean flag1) { + if (entityplayer.world == this.world) { + if (flag1 && !flag) { + PlayerChunk playerchunk = this.getVisibleChunk(chunkcoordintpair.pair()); + + if (playerchunk != null) { + Chunk chunk = playerchunk.getChunk(); + + if (chunk != null) { + this.a(entityplayer, apacket, chunk); + } + + PacketDebug.a(this.world, chunkcoordintpair); + } + } + + if (!flag1 && flag) { + entityplayer.a(chunkcoordintpair); + } + + } + } + + public int d() { + return this.visibleChunks.size(); + } + + protected PlayerChunkMap.a e() { + return this.chunkDistanceManager; + } + + protected Iterable f() { + return Iterables.unmodifiableIterable(this.visibleChunks.values()); + } + + void a(Writer writer) throws IOException { + CSVWriter csvwriter = CSVWriter.a().a("x").a("z").a("level").a("in_memory").a("status").a("full_status").a("accessible_ready").a("ticking_ready").a("entity_ticking_ready").a("ticket").a("spawning").a("entity_count").a("block_entity_count").a(writer); + ObjectBidirectionalIterator objectbidirectionaliterator = this.visibleChunks.long2ObjectEntrySet().iterator(); + + while (objectbidirectionaliterator.hasNext()) { + Entry entry = (Entry) objectbidirectionaliterator.next(); + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(entry.getLongKey()); + PlayerChunk playerchunk = (PlayerChunk) entry.getValue(); + Optional optional = Optional.ofNullable(playerchunk.f()); + Optional optional1 = optional.flatMap((ichunkaccess) -> { + return ichunkaccess instanceof Chunk ? Optional.of((Chunk) ichunkaccess) : Optional.empty(); + }); + + // Craftbukkit - decompile error + csvwriter.a(chunkcoordintpair.x, chunkcoordintpair.z, playerchunk.getTicketLevel(), optional.isPresent(), optional.map(IChunkAccess::getChunkStatus).orElse(null), optional1.map(Chunk::getState).orElse(null), a(playerchunk.c()), a(playerchunk.a()), a(playerchunk.b()), this.chunkDistanceManager.c(entry.getLongKey()), !this.isOutsideOfRange(chunkcoordintpair), optional1.map((chunk) -> { + return Stream.of(chunk.getEntitySlices()).mapToInt(List::size).sum(); // Spigot + }).orElse(0), optional1.map((chunk) -> { + return chunk.getTileEntities().size(); + }).orElse(0)); + } + + } + + private static String a(CompletableFuture> completablefuture) { + try { + Either either = (Either) completablefuture.getNow(null); // Craftbukkit - decompile error + + return either != null ? (String) either.map((chunk) -> { + return "done"; + }, (playerchunk_failure) -> { + return "unloaded"; + }) : "not completed"; + } catch (CompletionException completionexception) { + return "failed " + completionexception.getCause().getMessage(); + } catch (CancellationException cancellationexception) { + return "cancelled"; + } + } + + // Paper start - Asynchronous chunk io + @Nullable + @Override + public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException { + if (Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) { + NBTTagCompound ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE + .loadChunkDataAsyncFuture(this.world, chunkcoordintpair.x, chunkcoordintpair.z, com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread(), + false, true, true).join().chunkData; + + if (ret == com.destroystokyo.paper.io.PaperFileIOThread.FAILURE_VALUE) { + throw new IOException("See logs for further detail"); + } + return ret; + } + return super.read(chunkcoordintpair); + } + + @Override + public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { + if (Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) { + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave( + this.world, chunkcoordintpair.x, chunkcoordintpair.z, null, nbttagcompound, + com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread()); + + Boolean ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, + chunkcoordintpair.x, chunkcoordintpair.z, true, false); + + if (ret == Boolean.FALSE) { + throw new IOException("See logs for further detail"); + } + return; + } + super.write(chunkcoordintpair, nbttagcompound); + } + // Paper end + + @Nullable + public NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException { // Paper - private -> public + NBTTagCompound nbttagcompound = this.read(chunkcoordintpair); + + // Paper start - Cache chunk status on disk + if (nbttagcompound == null) { + return null; + } + + nbttagcompound = this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.m, nbttagcompound, chunkcoordintpair, world); // CraftBukkit + if (nbttagcompound == null) { + return null; + } + + this.updateChunkStatusOnDisk(chunkcoordintpair, nbttagcompound); + + return nbttagcompound; + // Paper end + } + + // Paper start - chunk status cache "api" + public ChunkStatus getChunkStatusOnDiskIfCached(ChunkCoordIntPair chunkPos) { + // Paper start - async chunk save for unload + IChunkAccess unloadingChunk = this.world.asyncChunkTaskManager.getChunkInSaveProgress(chunkPos.x, chunkPos.z); + if (unloadingChunk != null) { + return unloadingChunk.getChunkStatus(); + } + // Paper end + // Paper start - async io + NBTTagCompound inProgressWrite = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE + .getPendingWrite(this.world, chunkPos.x, chunkPos.z, false); + + if (inProgressWrite != null) { + return ChunkRegionLoader.getStatus(inProgressWrite); + } + // Paper end + + RegionFile regionFile = this.getRegionFileIfLoaded(chunkPos); + + return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z); + } + + public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException { + // Paper start - async chunk save for unload + IChunkAccess unloadingChunk = this.world.asyncChunkTaskManager.getChunkInSaveProgress(chunkPos.x, chunkPos.z); + if (unloadingChunk != null) { + return unloadingChunk.getChunkStatus(); + } + // Paper end + // Paper start - async io + NBTTagCompound inProgressWrite = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE + .getPendingWrite(this.world, chunkPos.x, chunkPos.z, false); + + if (inProgressWrite != null) { + return ChunkRegionLoader.getStatus(inProgressWrite); + } + // Paper end + synchronized (this) { // Paper - async io + RegionFile regionFile = this.getRegionFile(chunkPos, false); + + if (!regionFile.chunkExists(chunkPos)) { + return null; + } + + ChunkStatus status = regionFile.getStatusIfCached(chunkPos.x, chunkPos.z); + + if (status != null) { + return status; + } + // Paper start - async io + } + + NBTTagCompound compound = this.readChunkData(chunkPos); + + return ChunkRegionLoader.getStatus(compound); + // Paper end + } + + public void updateChunkStatusOnDisk(ChunkCoordIntPair chunkPos, @Nullable NBTTagCompound compound) throws IOException { + synchronized (this) { // Paper - async io + RegionFile regionFile = this.getRegionFile(chunkPos, false); + + regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkRegionLoader.getStatus(compound)); + } // Paper - async io + } + + // Paper start - async io + // this function will not load chunk data off disk to check for status + // ret null for unknown, empty for empty status on disk or absent from disk + public ChunkStatus getStatusOnDiskNoLoad(int x, int z) { + // Paper start - async chunk save for unload + IChunkAccess unloadingChunk = this.world.asyncChunkTaskManager.getChunkInSaveProgress(x, z); + if (unloadingChunk != null) { + return unloadingChunk.getChunkStatus(); + } + // Paper end + // Paper start - async io + net.minecraft.server.NBTTagCompound inProgressWrite = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE + .getPendingWrite(this.world, x, z, false); + + if (inProgressWrite != null) { + return net.minecraft.server.ChunkRegionLoader.getStatus(inProgressWrite); + } + // Paper end + // variant of PlayerChunkMap#getChunkStatusOnDisk that does not load data off disk, but loads the region file + ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(x, z); + synchronized (world.getChunkProvider().playerChunkMap) { + net.minecraft.server.RegionFile file; + try { + file = world.getChunkProvider().playerChunkMap.getRegionFile(chunkPos, false); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + return !file.chunkExists(chunkPos) ? ChunkStatus.EMPTY : file.getStatusIfCached(x, z); + } + } + // Paper end + + public IChunkAccess getUnloadingChunk(int chunkX, int chunkZ) { + PlayerChunk chunkHolder = this.pendingUnload.get(ChunkCoordIntPair.pair(chunkX, chunkZ)); + return chunkHolder == null ? null : chunkHolder.getAvailableChunkNow(); + } + // Paper end + + boolean isOutsideOfRange(ChunkCoordIntPair chunkcoordintpair) { + // Spigot start + return isOutsideOfRange(chunkcoordintpair, false); + } + + boolean isOutsideOfRange(ChunkCoordIntPair chunkcoordintpair, boolean reducedRange) { + int chunkRange = world.spigotConfig.mobSpawnRange; + chunkRange = (chunkRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : chunkRange; + chunkRange = (chunkRange > 8) ? 8 : chunkRange; + + final int finalChunkRange = chunkRange; // Paper for lambda below + //double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; // Paper - use from event + // Spigot end + long i = chunkcoordintpair.pair(); + + return !this.chunkDistanceManager.d(i) ? true : this.playerMap.a(i).noneMatch((entityplayer) -> { + // Paper start - + com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event; + double blockRange = 16384.0D; + if (reducedRange) { + event = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityplayer.getBukkitEntity(), (byte) finalChunkRange); + event.callEvent(); + blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4)); + if (event.isCancelled()) return true; + } + + return (!entityplayer.isSpectator() && a(chunkcoordintpair, (Entity) entityplayer) < blockRange); // Spigot + // Paper end + }); + } + + private boolean b(EntityPlayer entityplayer) { + return entityplayer.isSpectator() && !this.world.getGameRules().getBoolean(GameRules.SPECTATORS_GENERATE_CHUNKS); + } + + void a(EntityPlayer entityplayer, boolean flag) { + boolean flag1 = this.b(entityplayer); + boolean flag2 = this.playerMap.c(entityplayer); + int i = MathHelper.floor(entityplayer.locX) >> 4; + int j = MathHelper.floor(entityplayer.locZ) >> 4; + + if (flag) { + this.playerMap.a(ChunkCoordIntPair.pair(i, j), entityplayer, flag1); + this.c(entityplayer); + if (!flag1) { + this.chunkDistanceManager.a(SectionPosition.a((Entity) entityplayer), entityplayer); + } + } else { + SectionPosition sectionposition = entityplayer.M(); + + this.playerMap.a(sectionposition.u().pair(), entityplayer); + if (!flag2) { + this.chunkDistanceManager.b(sectionposition, entityplayer); + } + } + + for (int k = i - this.viewDistance; k <= i + this.viewDistance; ++k) { + for (int l = j - this.viewDistance; l <= j + this.viewDistance; ++l) { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(k, l); + + this.sendChunk(entityplayer, chunkcoordintpair, new Packet[2], !flag, flag); + } + } + + } + + private SectionPosition c(EntityPlayer entityplayer) { + SectionPosition sectionposition = SectionPosition.a((Entity) entityplayer); + + entityplayer.a(sectionposition); + entityplayer.playerConnection.sendPacket(new PacketPlayOutViewCentre(sectionposition.a(), sectionposition.c())); + return sectionposition; + } + + public void movePlayer(EntityPlayer entityplayer) { + ObjectIterator objectiterator = this.trackedEntities.values().iterator(); + + while (objectiterator.hasNext()) { + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next(); + + if (playerchunkmap_entitytracker.tracker == entityplayer) { + playerchunkmap_entitytracker.track(this.world.getPlayers()); + } else { + playerchunkmap_entitytracker.updatePlayer(entityplayer); + } + } + + int i = MathHelper.floor(entityplayer.locX) >> 4; + int j = MathHelper.floor(entityplayer.locZ) >> 4; + SectionPosition sectionposition = entityplayer.M(); + SectionPosition sectionposition1 = SectionPosition.a((Entity) entityplayer); + long k = sectionposition.u().pair(); + long l = sectionposition1.u().pair(); + boolean flag = this.playerMap.d(entityplayer); + boolean flag1 = this.b(entityplayer); + boolean flag2 = sectionposition.v() != sectionposition1.v(); + + if (flag2 || flag != flag1) { + this.c(entityplayer); + if (!flag) { + this.chunkDistanceManager.b(sectionposition, entityplayer); + } + + if (!flag1) { + this.chunkDistanceManager.a(sectionposition1, entityplayer); + } + + if (!flag && flag1) { + this.playerMap.a(entityplayer); + } + + if (flag && !flag1) { + this.playerMap.b(entityplayer); + } + + if (k != l) { + this.playerMap.a(k, l, entityplayer); + } + } + + int i1 = sectionposition.a(); + int j1 = sectionposition.c(); + int k1; + int l1; + + if (Math.abs(i1 - i) <= this.viewDistance * 2 && Math.abs(j1 - j) <= this.viewDistance * 2) { + k1 = Math.min(i, i1) - this.viewDistance; + l1 = Math.min(j, j1) - this.viewDistance; + int i2 = Math.max(i, i1) + this.viewDistance; + int j2 = Math.max(j, j1) + this.viewDistance; + + for (int k2 = k1; k2 <= i2; ++k2) { + for (int l2 = l1; l2 <= j2; ++l2) { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(k2, l2); + boolean flag3 = a(chunkcoordintpair, i1, j1) <= this.viewDistance; + boolean flag4 = a(chunkcoordintpair, i, j) <= this.viewDistance; + + this.sendChunk(entityplayer, chunkcoordintpair, new Packet[2], flag3, flag4); + } + } + } else { + ChunkCoordIntPair chunkcoordintpair1; + boolean flag5; + boolean flag6; + + for (k1 = i1 - this.viewDistance; k1 <= i1 + this.viewDistance; ++k1) { + for (l1 = j1 - this.viewDistance; l1 <= j1 + this.viewDistance; ++l1) { + chunkcoordintpair1 = new ChunkCoordIntPair(k1, l1); + flag5 = true; + flag6 = false; + this.sendChunk(entityplayer, chunkcoordintpair1, new Packet[2], true, false); + } + } + + for (k1 = i - this.viewDistance; k1 <= i + this.viewDistance; ++k1) { + for (l1 = j - this.viewDistance; l1 <= j + this.viewDistance; ++l1) { + chunkcoordintpair1 = new ChunkCoordIntPair(k1, l1); + flag5 = false; + flag6 = true; + this.sendChunk(entityplayer, chunkcoordintpair1, new Packet[2], false, true); + } + } + } + + } + + @Override + public Stream a(ChunkCoordIntPair chunkcoordintpair, boolean flag) { + return this.playerMap.a(chunkcoordintpair.pair()).filter((entityplayer) -> { + int i = b(chunkcoordintpair, entityplayer, true); + + return i > this.viewDistance ? false : !flag || i == this.viewDistance; + }); + } + + protected void addEntity(Entity entity) { + org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot + if (!(entity instanceof EntityComplexPart)) { + if (!(entity instanceof EntityLightning)) { + EntityTypes entitytypes = entity.getEntityType(); + int i = entitytypes.getChunkRange() * 16; + i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i); // Spigot + int j = entitytypes.getUpdateInterval(); + + if (this.trackedEntities.containsKey(entity.getId())) { + throw new IllegalStateException("Entity is already tracked!"); + } else { + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = new PlayerChunkMap.EntityTracker(entity, i, j, entitytypes.isDeltaTracking()); + + entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker + this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker); + playerchunkmap_entitytracker.track(this.world.getPlayers()); + if (entity instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entity; + + this.a(entityplayer, true); + ObjectIterator objectiterator = this.trackedEntities.values().iterator(); + + while (objectiterator.hasNext()) { + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker1 = (PlayerChunkMap.EntityTracker) objectiterator.next(); + + if (playerchunkmap_entitytracker1.tracker != entityplayer) { + playerchunkmap_entitytracker1.updatePlayer(entityplayer); + } + } + } + } - // CraftBukkit end } } } - public boolean a(EntityPlayer entityplayer, int i, int j) { - PlayerChunk playerchunk = this.getChunk(i, j); + protected void removeEntity(Entity entity) { + org.spigotmc.AsyncCatcher.catchOp("entity untrack"); // Spigot + if (entity instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entity; - return playerchunk != null && playerchunk.d(entityplayer) && playerchunk.e(); + this.a(entityplayer, false); + ObjectIterator objectiterator = this.trackedEntities.values().iterator(); + + while (objectiterator.hasNext()) { + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next(); + + playerchunkmap_entitytracker.clear(entityplayer); + } + } + + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker1 = (PlayerChunkMap.EntityTracker) this.trackedEntities.remove(entity.getId()); + + if (playerchunkmap_entitytracker1 != null) { + playerchunkmap_entitytracker1.a(); + } + entity.tracker = null; // Paper - We're no longer tracked } - public final void setViewDistanceForAll(int viewDistance) { this.a(viewDistance); } // Paper - OBFHELPER - // Paper start - Separate into two methods - public void a(int i) { - i = MathHelper.clamp(i, 3, 32); - if (i != this.j) { - int j = i - this.j; - List list = Lists.newArrayList(this.managedPlayers); + protected void g() { + List list = Lists.newArrayList(); + List list1 = this.world.getPlayers(); + + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker; + ObjectIterator objectiterator; + world.timings.tracker1.startTiming(); // Paper + + for (objectiterator = this.trackedEntities.values().iterator(); objectiterator.hasNext(); playerchunkmap_entitytracker.trackerEntry.a()) { + playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next(); + SectionPosition sectionposition = playerchunkmap_entitytracker.e; + SectionPosition sectionposition1 = SectionPosition.a(playerchunkmap_entitytracker.tracker); + + if (!Objects.equals(sectionposition, sectionposition1)) { + playerchunkmap_entitytracker.track(list1); + Entity entity = playerchunkmap_entitytracker.tracker; + + if (entity instanceof EntityPlayer) { + list.add((EntityPlayer) entity); + } + + playerchunkmap_entitytracker.e = sectionposition1; + } + } + world.timings.tracker1.stopTiming(); // Paper + + objectiterator = this.trackedEntities.values().iterator(); + + world.timings.tracker2.startTiming(); // Paper + while (objectiterator.hasNext()) { + playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next(); + playerchunkmap_entitytracker.track(list); + } + world.timings.tracker2.stopTiming(); // Paper + + } + + protected void broadcast(Entity entity, Packet packet) { + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) this.trackedEntities.get(entity.getId()); + + if (playerchunkmap_entitytracker != null) { + playerchunkmap_entitytracker.broadcast(packet); + } + + } + + protected void broadcastIncludingSelf(Entity entity, Packet packet) { + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) this.trackedEntities.get(entity.getId()); + + if (playerchunkmap_entitytracker != null) { + playerchunkmap_entitytracker.broadcastIncludingSelf(packet); + } + + } + + private void a(EntityPlayer entityplayer, Packet[] apacket, Chunk chunk) { + if (apacket[0] == null) { + apacket[0] = new PacketPlayOutMapChunk(chunk, 65535, true); // Paper - Anti-Xray + apacket[1] = new PacketPlayOutLightUpdate(chunk.getPos(), this.lightEngine); + } + + entityplayer.a(chunk.getPos(), apacket[0], apacket[1]); + PacketDebug.a(this.world, chunk.getPos()); + List list = Lists.newArrayList(); + List list1 = Lists.newArrayList(); + ObjectIterator objectiterator = this.trackedEntities.values().iterator(); + + while (objectiterator.hasNext()) { + PlayerChunkMap.EntityTracker playerchunkmap_entitytracker = (PlayerChunkMap.EntityTracker) objectiterator.next(); + Entity entity = playerchunkmap_entitytracker.tracker; + + if (entity != entityplayer && entity.chunkX == chunk.getPos().x && entity.chunkZ == chunk.getPos().z) { + playerchunkmap_entitytracker.updatePlayer(entityplayer); + if (entity instanceof EntityInsentient && ((EntityInsentient) entity).getLeashHolder() != null) { + list.add(entity); + } + + if (!entity.getPassengers().isEmpty()) { + list1.add(entity); + } + } + } + + Iterator iterator; + Entity entity1; + + if (!list.isEmpty()) { + iterator = list.iterator(); + + while (iterator.hasNext()) { + entity1 = (Entity) iterator.next(); + entityplayer.playerConnection.sendPacket(new PacketPlayOutAttachEntity(entity1, ((EntityInsentient) entity1).getLeashHolder())); + } + } + + if (!list1.isEmpty()) { + iterator = list1.iterator(); + + while (iterator.hasNext()) { + entity1 = (Entity) iterator.next(); + entityplayer.playerConnection.sendPacket(new PacketPlayOutMount(entity1)); + } + } + + } + + public VillagePlace getVillagePlace() { return this.h(); } // Paper - OBFHELPER + protected VillagePlace h() { + return this.n; + } + + public CompletableFuture a(Chunk chunk) { + return this.executor.e(() -> { + chunk.a(this.world); + }); + } + + public class EntityTracker { + + private final EntityTrackerEntry trackerEntry; + private final Entity tracker; + private final int trackingDistance; + private SectionPosition e; + // Paper start + // Replace trackedPlayers Set with a Map. The value is true until the player receives + // their first update (which is forced to have absolute coordinates), false afterward. + public java.util.Map trackedPlayerMap = new java.util.HashMap<>(); + public Set trackedPlayers = trackedPlayerMap.keySet(); + + public EntityTracker(Entity entity, int i, int j, boolean flag) { + this.trackerEntry = new EntityTrackerEntry(PlayerChunkMap.this.world, entity, j, flag, this::broadcast, trackedPlayerMap); // CraftBukkit // Paper + this.tracker = entity; + this.trackingDistance = i; + this.e = SectionPosition.a(entity); + } + + public boolean equals(Object object) { + return object instanceof PlayerChunkMap.EntityTracker ? ((PlayerChunkMap.EntityTracker) object).tracker.getId() == this.tracker.getId() : false; + } + + public int hashCode() { + return this.tracker.getId(); + } + + public void broadcast(Packet packet) { + Iterator iterator = this.trackedPlayers.iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + entityplayer.playerConnection.sendPacket(packet); + } + + } + + public void broadcastIncludingSelf(Packet packet) { + this.broadcast(packet); + if (this.tracker instanceof EntityPlayer) { + ((EntityPlayer) this.tracker).playerConnection.sendPacket(packet); + } + + } + + public void a() { + Iterator iterator = this.trackedPlayers.iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + this.trackerEntry.a(entityplayer); + } + + } + + public void clear(EntityPlayer entityplayer) { + org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot + if (this.trackedPlayers.remove(entityplayer)) { + this.trackerEntry.a(entityplayer); + } + + } + + public void updatePlayer(EntityPlayer entityplayer) { + org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot + if (entityplayer != this.tracker) { + Vec3D vec3d = (new Vec3D(entityplayer.locX, entityplayer.locY, entityplayer.locZ)).d(this.tracker.getPositionVector()); // MC-155077, SPIGOT-5113 + int i = Math.min(this.trackingDistance, (PlayerChunkMap.this.viewDistance - 1) * 16); + boolean flag = vec3d.x >= (double) (-i) && vec3d.x <= (double) i && vec3d.z >= (double) (-i) && vec3d.z <= (double) i && this.tracker.a(entityplayer); + + if (flag) { + boolean flag1 = this.tracker.attachedToPlayer; + + if (!flag1) { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ); + PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair.pair()); + + if (playerchunk != null && playerchunk.getChunk() != null) { + flag1 = PlayerChunkMap.b(chunkcoordintpair, entityplayer, false) <= PlayerChunkMap.this.viewDistance; + } + } + + // CraftBukkit start - respect vanish API + if (this.tracker instanceof EntityPlayer) { + Player player = ((EntityPlayer) this.tracker).getBukkitEntity(); + if (!entityplayer.getBukkitEntity().canSee(player)) { + flag1 = false; + } + } + + entityplayer.removeQueue.remove(Integer.valueOf(this.tracker.getId())); + // CraftBukkit end + + if (flag1 && this.trackedPlayerMap.putIfAbsent(entityplayer, true) == null) { // Paper + this.trackerEntry.b(entityplayer); + } + } else if (this.trackedPlayers.remove(entityplayer)) { + this.trackerEntry.a(entityplayer); + } + + } + } + + public void track(List list) { Iterator iterator = list.iterator(); while (iterator.hasNext()) { EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - this.setViewDistance(entityplayer, i, false); // Paper - Split, don't mark sort pending, we'll handle it after + + this.updatePlayer(entityplayer); } - this.j = i; - this.e(); } } - public void setViewDistance(EntityPlayer entityplayer, int i) { - this.setViewDistance(entityplayer, i, true); // Mark sort pending by default so we don't have to remember to do so all the time - } - - // Copied from above with minor changes - public void setViewDistance(EntityPlayer entityplayer, int i, boolean markSort) { - i = MathHelper.clamp(i, 3, 32); - int oldViewDistance = entityplayer.getViewDistance(); - if (i != oldViewDistance) { - int j = i - oldViewDistance; - - int k = (int) entityplayer.locX >> 4; - int l = (int) entityplayer.locZ >> 4; - int i1; - int j1; + class a extends ChunkMapDistance { - if (j > 0) { - for (i1 = k - i; i1 <= k + i; ++i1) { - for (j1 = l - i; j1 <= l + i; ++j1) { - PlayerChunk playerchunk = this.c(i1, j1); - - if (!playerchunk.d(entityplayer)) { - playerchunk.a(entityplayer); - } - } - } - } else { - for (i1 = k - oldViewDistance; i1 <= k + oldViewDistance; ++i1) { - for (j1 = l - oldViewDistance; j1 <= l + oldViewDistance; ++j1) { - if (!this.a(i1, j1, k, l, i)) { - this.c(i1, j1).b(entityplayer); - } - } - } - if (markSort) { - this.e(); - } - } - } - } - - void shutdown() { - getChunks().values().forEach(pchunk -> { - PaperAsyncChunkProvider.CancellableChunkRequest chunkRequest = pchunk.chunkRequest; - if (chunkRequest != null) { - chunkRequest.cancel(); - } - }); - } - // Paper end - - private void e() { - this.l = true; - this.m = true; - } - - public static int getFurthestViewableBlock(int i) { - return i * 16 - 16; - } - - private static long d(int i, int j) { - return (long) i + 2147483647L | (long) j + 2147483647L << 32; - } - - public void a(PlayerChunk playerchunk) { - //org.spigotmc.AsyncCatcher.catchOp("Async Player Chunk Add"); // Paper // Akarin - this.f.add(playerchunk); - } - - public void b(PlayerChunk playerchunk) { - org.spigotmc.AsyncCatcher.catchOp("Async Player Chunk Remove"); // Paper - ChunkCoordIntPair chunkcoordintpair = playerchunk.a(); - long i = d(chunkcoordintpair.x, chunkcoordintpair.z); - - playerchunk.c(); - this.e.remove(i); - this.i.remove(playerchunk); - this.f.remove(playerchunk); - this.g.remove(playerchunk); - this.h.remove(playerchunk); - Chunk chunk = playerchunk.f(); - - if (chunk != null) { - // Paper start - delay chunk unloads - if (world.paperConfig.delayChunkUnloadsBy <= 0) { - this.getWorld().getChunkProvider().unload(chunk); - } else { - chunk.scheduledForUnload = System.currentTimeMillis(); - } - // Paper end + protected a(Executor executor, Executor executor1) { + super(executor, executor1); } - } - - // CraftBukkit start - Sorter to load nearby chunks first - private static class ChunkCoordComparator implements java.util.Comparator { - private int x; - private int z; - - public ChunkCoordComparator (EntityPlayer entityplayer) { - x = (int) entityplayer.locX >> 4; - z = (int) entityplayer.locZ >> 4; + @Override + protected boolean a(long i) { + return PlayerChunkMap.this.unloadQueue.contains(i); } - public int compare(ChunkCoordIntPair a, ChunkCoordIntPair b) { - if (a.equals(b)) { - return 0; - } + @Nullable + @Override + protected PlayerChunk b(long i) { + return PlayerChunkMap.this.getUpdatingChunk(i); + } - // Subtract current position to set center point - int ax = a.x - this.x; - int az = a.z - this.z; - int bx = b.x - this.x; - int bz = b.z - this.z; - - int result = ((ax - bx) * (ax + bx)) + ((az - bz) * (az + bz)); - if (result != 0) { - return result; - } - - if (ax < 0) { - if (bx < 0) { - return bz - az; - } else { - return -1; - } - } else { - if (bx < 0) { - return 1; - } else { - return az - bz; - } - } + @Nullable + @Override + protected PlayerChunk a(long i, int j, @Nullable PlayerChunk playerchunk, int k) { + return PlayerChunkMap.this.a(i, j, playerchunk, k); } } - // CraftBukkit end - - // Paper start - Player view distance API - public void updateViewDistance(EntityPlayer player, int distanceIn) { - final int oldViewDistance = player.getViewDistance(); - - // This represents the view distance that we will set on the player - // It can exist as a negative value - int playerViewDistance = MathHelper.clamp(distanceIn, 3, 32); - - // This value is the one we actually use to update the chunk map - // We don't ever want this to be a negative - int toSet = playerViewDistance; - - if (distanceIn < 0) { - playerViewDistance = -1; - toSet = world.getPlayerChunkMap().getViewDistance(); - } - - if (toSet != oldViewDistance) { - // Order matters - this.setViewDistance(player, toSet); - player.setViewDistance(playerViewDistance); - - //Force update entity trackers - this.getWorld().getTracker().updatePlayer(player); - } - } - // Paper end } diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java index c91402522..ae17cdf23 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -1,36 +1,30 @@ package net.minecraft.server; -import com.google.common.collect.Lists; import com.google.common.primitives.Doubles; import com.google.common.primitives.Floats; -import com.google.common.util.concurrent.Futures; import com.mojang.brigadier.ParseResults; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.suggestion.Suggestions; - -import io.akarin.server.core.PacketType; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; - -import java.util.Arrays; +import it.unimi.dsi.fastutil.ints.Int2ShortMap; +import it.unimi.dsi.fastutil.ints.Int2ShortOpenHashMap; import java.util.Collections; import java.util.Iterator; +import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; - import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; // CraftBukkit start -import java.util.HashSet; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import org.bukkit.Location; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.event.CraftEventFactory; -import org.bukkit.craftbukkit.inventory.CraftInventoryView; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.craftbukkit.util.CraftMagicNumbers; @@ -69,9 +63,8 @@ import com.destroystokyo.paper.event.player.IllegalPacketEvent; // Paper import com.destroystokyo.paper.event.player.PlayerJumpEvent; // Paper import co.aikar.timings.MinecraftTimings; // Paper // CraftBukkit end -import co.aikar.timings.ThreadAssertion; -public class PlayerConnection implements PacketListenerPlayIn, ITickable { +public class PlayerConnection implements PacketListenerPlayIn { private static final Logger LOGGER = LogManager.getLogger(); public final NetworkManager networkManager; @@ -87,7 +80,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits // CraftBukkit end private int j; - private final IntHashMap k = new IntHashMap<>(); + private final Int2ShortMap k = new Int2ShortOpenHashMap(); private double l; private double m; private double n; @@ -166,14 +159,14 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } this.r = this.player.getRootVehicle(); - if (this.r != this.player && this.r.bO() == this.player) { + if (this.r != this.player && this.r.getRidingPassenger() == this.player) { this.s = this.r.locX; this.t = this.r.locY; this.u = this.r.locZ; this.v = this.r.locX; this.w = this.r.locY; this.x = this.r.locZ; - if (this.D && this.player.getRootVehicle().bO() == this.player) { + if (this.D && this.player.getRootVehicle().getRidingPassenger() == this.player) { if (++this.E > 80) { PlayerConnection.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getDisplayName().getString()); this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickVehicleMessage); // Paper - use configurable kick message @@ -189,7 +182,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.E = 0; } - //this.minecraftServer.methodProfiler.enter("keepAlive"); // Akarin + this.minecraftServer.getMethodProfiler().enter("keepAlive"); // Paper Start - give clients a longer time to respond to pings as per pre 1.12.2 timings // This should effectively place the keepalive handling back to "as it was" before 1.12.2 long currentTime = SystemUtils.getMonotonicMillis(); @@ -211,7 +204,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } // Paper end - //this.minecraftServer.methodProfiler.exit(); + this.minecraftServer.getMethodProfiler().exit(); // CraftBukkit start for (int spam; (spam = this.chatThrottle) > 0 && !chatSpamField.compareAndSet(this, spam, spam - 1); ) ; if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable @@ -242,10 +235,15 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.q = this.player.locZ; } + @Override public NetworkManager a() { return this.networkManager; } + private boolean isExemptPlayer() { + return this.minecraftServer.b(this.player.getProfile()); + } + // CraftBukkit start @Deprecated public void disconnect(IChatBaseComponent ichatbasecomponent) { @@ -285,9 +283,10 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.networkManager.getClass(); // CraftBukkit - Don't wait - minecraftserver.postToMainThread(networkmanager::handleDisconnection); + minecraftserver.scheduleOnMain(networkmanager::handleDisconnection); // Paper } + @Override public void a(PacketPlayInSteerVehicle packetplayinsteervehicle) { PlayerConnectionUtils.ensureMainThread(packetplayinsteervehicle, this, this.player.getWorldServer()); this.player.a(packetplayinsteervehicle.b(), packetplayinsteervehicle.c(), packetplayinsteervehicle.d(), packetplayinsteervehicle.e()); @@ -301,6 +300,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { return !Doubles.isFinite(packetplayinvehiclemove.getX()) || !Doubles.isFinite(packetplayinvehiclemove.getY()) || !Doubles.isFinite(packetplayinvehiclemove.getZ()) || !Floats.isFinite(packetplayinvehiclemove.getPitch()) || !Floats.isFinite(packetplayinvehiclemove.getYaw()); } + @Override public void a(PacketPlayInVehicleMove packetplayinvehiclemove) { PlayerConnectionUtils.ensureMainThread(packetplayinvehiclemove, this, this.player.getWorldServer()); if (b(packetplayinvehiclemove)) { @@ -308,7 +308,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } else { Entity entity = this.player.getRootVehicle(); - if (entity != this.player && entity.bO() == this.player && entity == this.r) { + if (entity != this.player && entity.getRidingPassenger() == this.player && entity == this.r) { WorldServer worldserver = this.player.getWorldServer(); double d0 = entity.locX; double d1 = entity.locY; @@ -321,7 +321,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { double d6 = d3 - this.s; double d7 = d4 - this.t; double d8 = d5 - this.u; - double d9 = entity.motX * entity.motX + entity.motY * entity.motY + entity.motZ * entity.motZ; + double d9 = entity.getMot().g(); double d10 = d6 * d6 + d7 * d7 + d8 * d8; @@ -351,13 +351,13 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { speed *= 2f; // TODO: Get the speed of the vehicle instead of the player // Paper start - Prevent moving into unloaded chunks - if (player.world.paperConfig.preventMovingIntoUnloadedChunks && !worldserver.isChunkLoaded((int) Math.floor(packetplayinvehiclemove.getX()) >> 4, (int) Math.floor(packetplayinvehiclemove.getZ()) >> 4, false)) { + if (player.world.paperConfig.preventMovingIntoUnloadedChunks && worldserver.getChunkIfLoadedImmediately((int) Math.floor(packetplayinvehiclemove.getX()) >> 4, (int) Math.floor(packetplayinvehiclemove.getZ()) >> 4) == null) { this.networkManager.sendPacket(new PacketPlayOutVehicleMove(entity)); return; } // Paper end - if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && (!this.minecraftServer.H() || !this.minecraftServer.G().equals(entity.getDisplayName().getString()))) { + if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isExemptPlayer()) { // CraftBukkit end PlayerConnection.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", entity.getDisplayName().getString(), this.player.getDisplayName().getString(), d6, d7, d8); this.networkManager.sendPacket(new PacketPlayOutVehicleMove(entity)); @@ -369,7 +369,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { d6 = d3 - this.v; d7 = d4 - this.w - 1.0E-6D; d8 = d5 - this.x; - entity.move(EnumMoveType.PLAYER, d6, d7, d8); + entity.move(EnumMoveType.PLAYER, new Vec3D(d6, d7, d8)); double d11 = d7; d6 = d3 - entity.locX; @@ -466,7 +466,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } // CraftBukkit end - this.minecraftServer.getPlayerList().updateChunks(this.player); + this.player.getWorldServer().getChunkProvider().movePlayer(this.player); this.player.checkMovement(this.player.locX - d0, this.player.locY - d1, this.player.locZ - d2); this.D = d11 >= -0.03125D && !this.minecraftServer.getAllowFlight() && !worldserver.a(entity.getBoundingBox().g(0.0625D).b(0.0D, -0.55D, 0.0D)); this.v = entity.locX; @@ -477,6 +477,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } } + @Override public void a(PacketPlayInTeleportAccept packetplayinteleportaccept) { PlayerConnectionUtils.ensureMainThread(packetplayinteleportaccept, this, this.player.getWorldServer()); if (packetplayinteleportaccept.b() == this.teleportAwait && this.teleportPos != null) { // CraftBukkit @@ -489,28 +490,33 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } this.teleportPos = null; - this.minecraftServer.getPlayerList().updateChunks(this.player); // CraftBukkit + this.player.getWorldServer().getChunkProvider().movePlayer(this.player); // CraftBukkit } } + @Override public void a(PacketPlayInRecipeDisplayed packetplayinrecipedisplayed) { PlayerConnectionUtils.ensureMainThread(packetplayinrecipedisplayed, this, this.player.getWorldServer()); if (packetplayinrecipedisplayed.b() == PacketPlayInRecipeDisplayed.Status.SHOWN) { - IRecipe irecipe = this.minecraftServer.getCraftingManager().a(packetplayinrecipedisplayed.c()); + Optional> optional = this.minecraftServer.getCraftingManager().a(packetplayinrecipedisplayed.c()); // CraftBukkit - decompile error + RecipeBookServer recipebookserver = this.player.B(); - if (irecipe != null) { - this.player.B().e(irecipe); - } + optional.ifPresent(recipebookserver::e); } else if (packetplayinrecipedisplayed.b() == PacketPlayInRecipeDisplayed.Status.SETTINGS) { this.player.B().a(packetplayinrecipedisplayed.d()); this.player.B().b(packetplayinrecipedisplayed.e()); this.player.B().c(packetplayinrecipedisplayed.f()); this.player.B().d(packetplayinrecipedisplayed.g()); + this.player.B().e(packetplayinrecipedisplayed.h()); + this.player.B().f(packetplayinrecipedisplayed.i()); + this.player.B().g(packetplayinrecipedisplayed.j()); + this.player.B().h(packetplayinrecipedisplayed.k()); } } + @Override public void a(PacketPlayInAdvancements packetplayinadvancements) { PlayerConnectionUtils.ensureMainThread(packetplayinadvancements, this, this.player.getWorldServer()); if (packetplayinadvancements.c() == PacketPlayInAdvancements.Status.OPENED_TAB) { @@ -524,11 +530,12 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } + @Override public void a(PacketPlayInTabComplete packetplayintabcomplete) { // PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.getWorldServer()); // Paper - run this async // CraftBukkit start if (tabSpamLimiter.addAndGet(com.destroystokyo.paper.PaperConfig.tabSpamIncrement) > com.destroystokyo.paper.PaperConfig.tabSpamLimit && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { // Paper start - split and make configurable - minecraftServer.postToMainThread(() -> this.disconnect(new ChatMessage("disconnect.spam", new Object[0]))); // Paper + minecraftServer.scheduleOnMain(() -> this.disconnect(new ChatMessage("disconnect.spam", new Object[0]))); // Paper return; } // CraftBukkit end @@ -550,12 +557,14 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { if (!event.isHandled()) { if (!event.isCancelled()) { // Paper end - async tab completion + this.minecraftServer.scheduleOnMain(() -> { // Paper - This needs to be on main ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener()); this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { if (((Suggestions) suggestions).isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [] from showing for plugins with nothing more to offer this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error }); + }); // Paper - This needs to be on main } // Paper start - async tab completion } else if (!completions.isEmpty()) { @@ -569,6 +578,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } + @Override public void a(PacketPlayInSetCommandBlock packetplayinsetcommandblock) { PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandblock, this, this.player.getWorldServer()); if (!this.minecraftServer.getEnableCommandBlock()) { @@ -594,21 +604,21 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { IBlockData iblockdata; switch (packetplayinsetcommandblock.g()) { - case SEQUENCE: - iblockdata = Blocks.CHAIN_COMMAND_BLOCK.getBlockData(); - this.player.world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) iblockdata.set(BlockCommand.a, enumdirection)).set(BlockCommand.b, packetplayinsetcommandblock.e()), 2); - break; - case AUTO: - iblockdata = Blocks.REPEATING_COMMAND_BLOCK.getBlockData(); - this.player.world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) iblockdata.set(BlockCommand.a, enumdirection)).set(BlockCommand.b, packetplayinsetcommandblock.e()), 2); - break; - case REDSTONE: - default: - iblockdata = Blocks.COMMAND_BLOCK.getBlockData(); - this.player.world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) iblockdata.set(BlockCommand.a, enumdirection)).set(BlockCommand.b, packetplayinsetcommandblock.e()), 2); + case SEQUENCE: + iblockdata = Blocks.CHAIN_COMMAND_BLOCK.getBlockData(); + this.player.world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) iblockdata.set(BlockCommand.a, enumdirection)).set(BlockCommand.b, packetplayinsetcommandblock.e()), 2); + break; + case AUTO: + iblockdata = Blocks.REPEATING_COMMAND_BLOCK.getBlockData(); + this.player.world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) iblockdata.set(BlockCommand.a, enumdirection)).set(BlockCommand.b, packetplayinsetcommandblock.e()), 2); + break; + case REDSTONE: + default: + iblockdata = Blocks.COMMAND_BLOCK.getBlockData(); + this.player.world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) iblockdata.set(BlockCommand.a, enumdirection)).set(BlockCommand.b, packetplayinsetcommandblock.e()), 2); } - tileentity.z(); + tileentity.n(); this.player.world.setTileEntity(blockposition, tileentity); commandblocklistenerabstract.setCommand(s); commandblocklistenerabstract.a(flag); @@ -619,13 +629,14 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { tileentitycommand.b(packetplayinsetcommandblock.f()); commandblocklistenerabstract.e(); if (!UtilColor.b(s)) { - this.player.sendMessage(new ChatMessage("advMode.setCommand.success", new Object[] { s})); + this.player.sendMessage(new ChatMessage("advMode.setCommand.success", new Object[]{s})); } } } } + @Override public void a(PacketPlayInSetCommandMinecart packetplayinsetcommandminecart) { PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandminecart, this, this.player.getWorldServer()); if (!this.minecraftServer.getEnableCommandBlock()) { @@ -643,20 +654,22 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } commandblocklistenerabstract.e(); - this.player.sendMessage(new ChatMessage("advMode.setCommand.success", new Object[] { packetplayinsetcommandminecart.b()})); + this.player.sendMessage(new ChatMessage("advMode.setCommand.success", new Object[]{packetplayinsetcommandminecart.b()})); } } } + @Override public void a(PacketPlayInPickItem packetplayinpickitem) { PlayerConnectionUtils.ensureMainThread(packetplayinpickitem, this, this.player.getWorldServer()); - this.player.inventory.d(packetplayinpickitem.b()); + this.player.inventory.c(packetplayinpickitem.b()); this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-2, this.player.inventory.itemInHandIndex, this.player.inventory.getItem(this.player.inventory.itemInHandIndex))); this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-2, packetplayinpickitem.b(), this.player.inventory.getItem(packetplayinpickitem.b()))); this.player.playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(this.player.inventory.itemInHandIndex)); } + @Override public void a(PacketPlayInItemName packetplayinitemname) { PlayerConnectionUtils.ensureMainThread(packetplayinitemname, this, this.player.getWorldServer()); if (this.player.activeContainer instanceof ContainerAnvil) { @@ -670,24 +683,16 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } + @Override public void a(PacketPlayInBeacon packetplayinbeacon) { PlayerConnectionUtils.ensureMainThread(packetplayinbeacon, this, this.player.getWorldServer()); if (this.player.activeContainer instanceof ContainerBeacon) { - ContainerBeacon containerbeacon = (ContainerBeacon) this.player.activeContainer; - Slot slot = containerbeacon.getSlot(0); - - if (slot.hasItem()) { - slot.a(1); - IInventory iinventory = containerbeacon.d(); - - iinventory.setProperty(1, packetplayinbeacon.b()); - iinventory.setProperty(2, packetplayinbeacon.c()); - iinventory.update(); - } + ((ContainerBeacon) this.player.activeContainer).c(packetplayinbeacon.b(), packetplayinbeacon.c()); } } + @Override public void a(PacketPlayInStruct packetplayinstruct) { PlayerConnectionUtils.ensureMainThread(packetplayinstruct, this, this.player.getWorldServer()); if (this.player.isCreativeAndOp()) { @@ -710,32 +715,32 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { tileentitystructure.f(packetplayinstruct.m()); tileentitystructure.a(packetplayinstruct.n()); tileentitystructure.a(packetplayinstruct.o()); - if (tileentitystructure.d()) { + if (tileentitystructure.f()) { String s = tileentitystructure.getStructureName(); if (packetplayinstruct.c() == TileEntityStructure.UpdateType.SAVE_AREA) { - if (tileentitystructure.q()) { - this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.save_success", new Object[] { s})), false); + if (tileentitystructure.C()) { + this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.save_success", new Object[]{s})), false); } else { - this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.save_failure", new Object[] { s})), false); + this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.save_failure", new Object[]{s})), false); } } else if (packetplayinstruct.c() == TileEntityStructure.UpdateType.LOAD_AREA) { - if (!tileentitystructure.D()) { - this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.load_not_found", new Object[] { s})), false); - } else if (tileentitystructure.r()) { - this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.load_success", new Object[] { s})), false); + if (!tileentitystructure.F()) { + this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.load_not_found", new Object[]{s})), false); + } else if (tileentitystructure.D()) { + this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.load_success", new Object[]{s})), false); } else { - this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.load_prepare", new Object[] { s})), false); + this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.load_prepare", new Object[]{s})), false); } } else if (packetplayinstruct.c() == TileEntityStructure.UpdateType.SCAN_AREA) { - if (tileentitystructure.p()) { - this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.size_success", new Object[] { s})), false); + if (tileentitystructure.B()) { + this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.size_success", new Object[]{s})), false); } else { this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.size_failure", new Object[0])), false); } } } else { - this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.invalid_structure_name", new Object[] { packetplayinstruct.e()})), false); + this.player.a((IChatBaseComponent) (new ChatMessage("structure_block.invalid_structure_name", new Object[]{packetplayinstruct.e()})), false); } tileentitystructure.update(); @@ -745,17 +750,44 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } } + @Override + public void a(PacketPlayInSetJigsaw packetplayinsetjigsaw) { + PlayerConnectionUtils.ensureMainThread(packetplayinsetjigsaw, this, this.player.getWorldServer()); + if (this.player.isCreativeAndOp()) { + BlockPosition blockposition = packetplayinsetjigsaw.b(); + IBlockData iblockdata = this.player.world.getType(blockposition); + TileEntity tileentity = this.player.world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityJigsaw) { + TileEntityJigsaw tileentityjigsaw = (TileEntityJigsaw) tileentity; + + tileentityjigsaw.a(packetplayinsetjigsaw.d()); + tileentityjigsaw.b(packetplayinsetjigsaw.c()); + tileentityjigsaw.a(packetplayinsetjigsaw.e()); + tileentityjigsaw.update(); + this.player.world.notify(blockposition, iblockdata, iblockdata, 3); + } + + } + } + + @Override public void a(PacketPlayInTrSel packetplayintrsel) { PlayerConnectionUtils.ensureMainThread(packetplayintrsel, this, this.player.getWorldServer()); int i = packetplayintrsel.b(); Container container = this.player.activeContainer; if (container instanceof ContainerMerchant) { - ((ContainerMerchant) container).d(i); + ContainerMerchant containermerchant = (ContainerMerchant) container; + CraftEventFactory.callTradeSelectEvent(this.player, i, containermerchant); // CraftBukkit + + containermerchant.d(i); + containermerchant.g(i); } } + @Override public void a(PacketPlayInBEdit packetplayinbedit) { // Paper start ItemStack testStack = packetplayinbedit.b(); @@ -788,7 +820,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { if (byteTotal > byteAllowed) { PlayerConnection.LOGGER.warn(this.player.getName() + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: "+ byteAllowed + " - Pages: " + pageList.size()); - minecraftServer.postToMainThread(() -> this.disconnect("Book too large!")); + minecraftServer.scheduleOnMain(() -> this.disconnect("Book too large!")); return; } } @@ -808,45 +840,46 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { if (ItemBookAndQuill.b(itemstack.getTag())) { ItemStack itemstack1 = this.player.b(packetplayinbedit.d()); - if (!itemstack1.isEmpty()) { - if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) { - if (packetplayinbedit.c()) { - ItemStack itemstack2 = new ItemStack(Items.WRITTEN_BOOK); + if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) { + if (packetplayinbedit.c()) { + ItemStack itemstack2 = new ItemStack(Items.WRITTEN_BOOK); + NBTTagCompound nbttagcompound = itemstack1.getTag(); - itemstack2.a("author", (NBTBase) (new NBTTagString(this.player.getDisplayName().getString()))); - itemstack2.a("title", (NBTBase) (new NBTTagString(itemstack.getTag().getString("title")))); - NBTTagList nbttaglist = itemstack.getTag().getList("pages", 8); - - for (int i = 0; i < nbttaglist.size(); ++i) { - String s = nbttaglist.getString(i); - ChatComponentText chatcomponenttext = new ChatComponentText(s); - - s = IChatBaseComponent.ChatSerializer.a((IChatBaseComponent) chatcomponenttext); - nbttaglist.set(i, (NBTBase) (new NBTTagString(s))); - } - - itemstack2.a("pages", (NBTBase) nbttaglist); - // EnumItemSlot enumitemslot = packetplayinbedit.d() == EnumHand.MAIN_HAND ? EnumItemSlot.MAINHAND : EnumItemSlot.OFFHAND; // CraftBukkit - Moved up - - this.player.setSlot(enumitemslot, CraftEventFactory.handleEditBookEvent(player, enumitemslot, itemstack1, itemstack2)); // CraftBukkit - } else { - // Paper start - dont mutate players current item, set it from the event - ItemStack newBook = itemstack1.cloneItemStack(); - newBook.getOrCreateTagAndSet("pages", (NBTBase) itemstack.getTag().getList("pages", 8)); - this.player.setSlot(enumitemslot, CraftEventFactory.handleEditBookEvent(player, enumitemslot, itemstack1, newBook)); - // Paper end + if (nbttagcompound != null) { + itemstack2.setTag(nbttagcompound.clone()); } - player.getBukkitEntity().updateInventory(); // Paper - fix client desync when event is cancelled - } + itemstack2.a("author", (NBTBase) (new NBTTagString(this.player.getDisplayName().getString()))); + itemstack2.a("title", (NBTBase) (new NBTTagString(itemstack.getTag().getString("title")))); + NBTTagList nbttaglist = itemstack.getTag().getList("pages", 8); + + for (int i = 0; i < nbttaglist.size(); ++i) { + String s = nbttaglist.getString(i); + ChatComponentText chatcomponenttext = new ChatComponentText(s); + + s = IChatBaseComponent.ChatSerializer.a((IChatBaseComponent) chatcomponenttext); + nbttaglist.set(i, (NBTBase) (new NBTTagString(s))); + } + + itemstack2.a("pages", (NBTBase) nbttaglist); + this.player.a(packetplayinbedit.d(), CraftEventFactory.handleEditBookEvent(player, enumitemslot, itemstack1, itemstack2)); // CraftBukkit + } else { + // Paper start - dont mutate players current item, set it from the event + ItemStack newBook = itemstack1.cloneItemStack(); + newBook.getOrCreateTagAndSet("pages", (NBTBase)itemstack.getTag().getList("pages", 8)); + this.player.setSlot(enumitemslot, CraftEventFactory.handleEditBookEvent(player, enumitemslot, itemstack1, newBook)); + // Paper end + } } + } } } + @Override public void a(PacketPlayInEntityNBTQuery packetplayinentitynbtquery) { PlayerConnectionUtils.ensureMainThread(packetplayinentitynbtquery, this, this.player.getWorldServer()); - if (this.player.j(2)) { + if (this.player.k(2)) { Entity entity = this.player.getWorldServer().getEntity(packetplayinentitynbtquery.c()); if (entity != null) { @@ -858,9 +891,10 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } } + @Override public void a(PacketPlayInTileNBTQuery packetplayintilenbtquery) { PlayerConnectionUtils.ensureMainThread(packetplayintilenbtquery, this, this.player.getWorldServer()); - if (this.player.j(2)) { + if (this.player.k(2)) { TileEntity tileentity = this.player.getWorldServer().getTileEntity(packetplayintilenbtquery.c()); NBTTagCompound nbttagcompound = tileentity != null ? tileentity.save(new NBTTagCompound()) : null; @@ -868,6 +902,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } } + @Override public void a(PacketPlayInFlying packetplayinflying) { PlayerConnectionUtils.ensureMainThread(packetplayinflying, this, this.player.getWorldServer()); if (b(packetplayinflying)) { @@ -890,7 +925,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.A = this.e; if (this.player.isPassenger()) { this.player.setLocation(this.player.locX, this.player.locY, this.player.locZ, packetplayinflying.a(this.player.yaw), packetplayinflying.b(this.player.pitch)); - this.minecraftServer.getPlayerList().updateChunks(this.player); + this.player.getWorldServer().getChunkProvider().movePlayer(this.player); this.allowedPlayerTicks = 20; // CraftBukkit } else { // CraftBukkit - Make sure the move is valid but then reset it for plugins to modify @@ -912,7 +947,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { double d7 = d4 - this.l; double d8 = d5 - this.m; double d9 = d6 - this.n; - double d10 = this.player.motX * this.player.motX + this.player.motY * this.player.motY + this.player.motZ * this.player.motZ; + double d10 = this.player.getMot().g(); double d11 = d7 * d7 + d8 * d8 + d9 * d9; if (this.player.isSleeping()) { @@ -945,18 +980,17 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } else { speed = player.abilities.walkSpeed * 10f; } - // Paper start - Prevent moving into unloaded chunks - if (player.world.paperConfig.preventMovingIntoUnloadedChunks && (this.player.locX != toX || this.player.locZ != toZ) && !worldserver.isChunkLoaded((int) Math.floor(toX) >> 4, (int) Math.floor(toZ) >> 4, false)) { + if (player.world.paperConfig.preventMovingIntoUnloadedChunks && (this.player.locX != toX || this.player.locZ != toZ) && worldserver.getChunkIfLoadedImmediately((int) Math.floor(toX) >> 4, (int) Math.floor(toZ) >> 4) == null) { // Paper - use getIfLoadedImmediately this.internalTeleport(this.player.locX, this.player.locY, this.player.locZ, this.player.yaw, this.player.pitch, Collections.emptySet()); return; } // Paper end - if (!this.player.H() && (!this.player.getWorldServer().getGameRules().getBoolean("disableElytraMovementCheck") || !this.player.dc())) { - float f2 = this.player.dc() ? 300.0F : 100.0F; + if (!this.player.H() && (!this.player.getWorldServer().getGameRules().getBoolean(GameRules.DISABLE_ELYTRA_MOVEMENT_CHECK) || !this.player.isGliding())) { + float f2 = this.player.isGliding() ? 300.0F : 100.0F; - if (d11 - d10 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && (!this.minecraftServer.H() || !this.minecraftServer.G().equals(this.player.getProfile().getName()))) { + if (d11 - d10 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isExemptPlayer()) { // CraftBukkit end PlayerConnection.LOGGER.warn("{} moved too quickly! {},{},{}", this.player.getDisplayName().getString(), d7, d8, d9); this.a(this.player.locX, this.player.locY, this.player.locZ, this.player.yaw, this.player.pitch); @@ -964,7 +998,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } } - boolean flag = worldserver.getCubes(this.player, this.player.getBoundingBox().shrink(0.0625D)); + boolean flag = this.a((IWorldReader) worldserver); d7 = d4 - this.o; d8 = d5 - this.p; @@ -1000,7 +1034,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { // Paper end } - this.player.move(EnumMoveType.PLAYER, d7, d8, d9); + this.player.move(EnumMoveType.PLAYER, new Vec3D(d7, d8, d9)); this.player.onGround = packetplayinflying.b(); double d12 = d8; @@ -1022,7 +1056,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.player.setLocation(d4, d5, d6, f, f1); this.player.checkMovement(this.player.locX - d0, this.player.locY - d1, this.player.locZ - d2); if (!this.player.noclip && !this.player.isSleeping()) { - boolean flag2 = worldserver.getCubes(this.player, this.player.getBoundingBox().shrink(0.0625D)); + boolean flag2 = this.a((IWorldReader) worldserver); if (flag && (flag1 || !flag2)) { this.a(d0, d1, d2, f, f1); @@ -1093,11 +1127,9 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.player.setLocation(d4, d5, d6, f, f1); // Copied from above // CraftBukkit end - this.B = d12 >= -0.03125D; - this.B &= !this.minecraftServer.getAllowFlight() && !this.player.abilities.canFly; - this.B &= !this.player.hasEffect(MobEffects.LEVITATION) && !this.player.dc() && !worldserver.a(this.player.getBoundingBox().g(0.0625D).b(0.0D, -0.55D, 0.0D)); + this.B = d12 >= -0.03125D && this.player.playerInteractManager.getGameMode() != EnumGamemode.SPECTATOR && !this.minecraftServer.getAllowFlight() && !this.player.abilities.canFly && !this.player.hasEffect(MobEffects.LEVITATION) && !this.player.isGliding() && !worldserver.a(this.player.getBoundingBox().g(0.0625D).b(0.0D, -0.55D, 0.0D)); this.player.onGround = packetplayinflying.b(); - this.minecraftServer.getPlayerList().updateChunks(this.player); + this.player.getWorldServer().getChunkProvider().movePlayer(this.player); this.player.a(this.player.locY - d3, packetplayinflying.b()); this.o = this.player.locX; this.p = this.player.locY; @@ -1109,6 +1141,10 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } } + private boolean a(IWorldReader iworldreader) { + return iworldreader.getCubes(this.player, this.player.getBoundingBox().shrink(9.999999747378752E-6D)); + } + public void a(double d0, double d1, double d2, float f, float f1) { this.a(d0, d1, d2, f, f1, Collections.emptySet()); } @@ -1133,6 +1169,12 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { float pitch = f1; Location to = new Location(this.getPlayer().getWorld(), x, y, z, yaw, pitch); + // SPIGOT-5171: Triggered on join + if (from.equals(to)) { + this.internalTeleport(d0, d1, d2, f, f1, set); + return; + } + PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause); this.server.getPluginManager().callEvent(event); @@ -1188,122 +1230,85 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.player.playerConnection.sendPacket(new PacketPlayOutPosition(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.teleportAwait)); } + @Override public void a(PacketPlayInBlockDig packetplayinblockdig) { PlayerConnectionUtils.ensureMainThread(packetplayinblockdig, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit - WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); BlockPosition blockposition = packetplayinblockdig.b(); this.player.resetIdleTimer(); - switch (packetplayinblockdig.d()) { - case SWAP_HELD_ITEMS: - if (!this.player.isSpectator()) { - ItemStack itemstack = this.player.b(EnumHand.OFF_HAND); + PacketPlayInBlockDig.EnumPlayerDigType packetplayinblockdig_enumplayerdigtype = packetplayinblockdig.d(); - // CraftBukkit start - inspiration taken from DispenserRegistry (See SpigotCraft#394) - CraftItemStack mainHand = CraftItemStack.asCraftMirror(itemstack); - CraftItemStack offHand = CraftItemStack.asCraftMirror(this.player.b(EnumHand.MAIN_HAND)); - PlayerSwapHandItemsEvent swapItemsEvent = new PlayerSwapHandItemsEvent(getPlayer(), mainHand.clone(), offHand.clone()); - this.server.getPluginManager().callEvent(swapItemsEvent); - if (swapItemsEvent.isCancelled()) { - return; - } - if (swapItemsEvent.getOffHandItem().equals(offHand)) { - this.player.a(EnumHand.OFF_HAND, this.player.b(EnumHand.MAIN_HAND)); - } else { - this.player.a(EnumHand.OFF_HAND, CraftItemStack.asNMSCopy(swapItemsEvent.getOffHandItem())); - } - if (swapItemsEvent.getMainHandItem().equals(mainHand)) { - this.player.a(EnumHand.MAIN_HAND, itemstack); - } else { - this.player.a(EnumHand.MAIN_HAND, CraftItemStack.asNMSCopy(swapItemsEvent.getMainHandItem())); - } - // CraftBukkit end - } + switch (packetplayinblockdig_enumplayerdigtype) { + case SWAP_HELD_ITEMS: + if (!this.player.isSpectator()) { + ItemStack itemstack = this.player.b(EnumHand.OFF_HAND); - return; - case DROP_ITEM: - if (!this.player.isSpectator()) { - // limit how quickly items can be dropped - // If the ticks aren't the same then the count starts from 0 and we update the lastDropTick. - if (this.lastDropTick != MinecraftServer.currentTick) { - this.dropCount = 0; - this.lastDropTick = MinecraftServer.currentTick; - } else { - // Else we increment the drop count and check the amount. - this.dropCount++; - if (this.dropCount >= 20) { - LOGGER.warn(this.player.getName() + " dropped their items too quickly!"); - this.disconnect("You dropped your items too quickly (Hacking?)"); + // CraftBukkit start - inspiration taken from DispenserRegistry (See SpigotCraft#394) + CraftItemStack mainHand = CraftItemStack.asCraftMirror(itemstack); + CraftItemStack offHand = CraftItemStack.asCraftMirror(this.player.b(EnumHand.MAIN_HAND)); + PlayerSwapHandItemsEvent swapItemsEvent = new PlayerSwapHandItemsEvent(getPlayer(), mainHand.clone(), offHand.clone()); + this.server.getPluginManager().callEvent(swapItemsEvent); + if (swapItemsEvent.isCancelled()) { return; } - } - // CraftBukkit end - this.player.a(false); - } - - return; - case DROP_ALL_ITEMS: - if (!this.player.isSpectator()) { - this.player.a(true); - } - - return; - case RELEASE_USE_ITEM: - this.player.clearActiveItem(); - return; - case START_DESTROY_BLOCK: - case ABORT_DESTROY_BLOCK: - case STOP_DESTROY_BLOCK: - // Paper start - Don't allow digging in unloaded chunks - if (!worldserver.isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4, true)) { - return; - } - // Paper end - Don't allow digging in unloaded chunks - double d0 = this.player.locX - ((double) blockposition.getX() + 0.5D); - double d1 = this.player.locY - ((double) blockposition.getY() + 0.5D) + 1.5D; - double d2 = this.player.locZ - ((double) blockposition.getZ() + 0.5D); - double d3 = d0 * d0 + d1 * d1 + d2 * d2; - - if (d3 > 36.0D) { - if (worldserver.isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4, true)) // Paper - Fix block break desync - Don't send for unloaded chunks - this.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); // Paper - Fix block break desync - return; - } else if (blockposition.getY() >= this.minecraftServer.getMaxBuildHeight()) { - return; - } else { - if (packetplayinblockdig.d() == PacketPlayInBlockDig.EnumPlayerDigType.START_DESTROY_BLOCK) { - if (!this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { - this.player.playerInteractManager.a(blockposition, packetplayinblockdig.c()); + if (swapItemsEvent.getOffHandItem().equals(offHand)) { + this.player.a(EnumHand.OFF_HAND, this.player.b(EnumHand.MAIN_HAND)); } else { - // CraftBukkit start - fire PlayerInteractEvent - CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, packetplayinblockdig.c(), this.player.inventory.getItemInHand(), EnumHand.MAIN_HAND); - this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); - // Update any tile entity data for this block - TileEntity tileentity = worldserver.getTileEntity(blockposition); - if (tileentity != null) { - this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); - } - // CraftBukkit end + this.player.a(EnumHand.OFF_HAND, CraftItemStack.asNMSCopy(swapItemsEvent.getOffHandItem())); } - } else { - if (packetplayinblockdig.d() == PacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) { - this.player.playerInteractManager.a(blockposition); - } else if (packetplayinblockdig.d() == PacketPlayInBlockDig.EnumPlayerDigType.ABORT_DESTROY_BLOCK) { - this.player.playerInteractManager.e(); - } - - if (!worldserver.getType(blockposition).isAir()) { - this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); + if (swapItemsEvent.getMainHandItem().equals(mainHand)) { + this.player.a(EnumHand.MAIN_HAND, itemstack); + } else { + this.player.a(EnumHand.MAIN_HAND, CraftItemStack.asNMSCopy(swapItemsEvent.getMainHandItem())); } + // CraftBukkit end } return; - } - default: - throw new IllegalArgumentException("Invalid player action"); + case DROP_ITEM: + if (!this.player.isSpectator()) { + // limit how quickly items can be dropped + // If the ticks aren't the same then the count starts from 0 and we update the lastDropTick. + if (this.lastDropTick != MinecraftServer.currentTick) { + this.dropCount = 0; + this.lastDropTick = MinecraftServer.currentTick; + } else { + // Else we increment the drop count and check the amount. + this.dropCount++; + if (this.dropCount >= 20) { + LOGGER.warn(this.player.getName() + " dropped their items too quickly!"); + this.disconnect("You dropped your items too quickly (Hacking?)"); + return; + } + } + // CraftBukkit end + this.player.n(false); + } + + return; + case DROP_ALL_ITEMS: + if (!this.player.isSpectator()) { + this.player.n(true); + } + + return; + case RELEASE_USE_ITEM: + this.player.clearActiveItem(); + return; + case START_DESTROY_BLOCK: + case ABORT_DESTROY_BLOCK: + case STOP_DESTROY_BLOCK: + // Paper start - Don't allow digging in unloaded chunks + if (this.player.world.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) == null) { + return; + } + // Paper end - Don't allow digging in unloaded chunks + this.player.playerInteractManager.a(blockposition, packetplayinblockdig_enumplayerdigtype, packetplayinblockdig.c(), this.minecraftServer.getMaxBuildHeight()); + return; + default: + throw new IllegalArgumentException("Invalid player action"); } - // CraftBukkit end } // Spigot start - limit place/interactions @@ -1326,37 +1331,41 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } // Spigot end + @Override public void a(PacketPlayInUseItem packetplayinuseitem) { PlayerConnectionUtils.ensureMainThread(packetplayinuseitem, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit if (!checkLimit(packetplayinuseitem.timestamp)) return; // Spigot - check limit WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); - EnumHand enumhand = packetplayinuseitem.d(); + EnumHand enumhand = packetplayinuseitem.b(); ItemStack itemstack = this.player.b(enumhand); - BlockPosition blockposition = packetplayinuseitem.b(); - EnumDirection enumdirection = packetplayinuseitem.c(); + MovingObjectPositionBlock movingobjectpositionblock = packetplayinuseitem.c(); + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition(); + EnumDirection enumdirection = movingobjectpositionblock.getDirection(); IBlockData clickedBlock = worldserver.getType(blockposition); // Spigot this.player.resetIdleTimer(); if (blockposition.getY() >= this.minecraftServer.getMaxBuildHeight() - 1 && ((enumdirection == EnumDirection.UP && !(clickedBlock.getBlock() instanceof BlockStepAbstract && clickedBlock.get(BlockStepAbstract.a) == BlockPropertySlabType.BOTTOM)) || blockposition.getY() >= this.minecraftServer.getMaxBuildHeight())) { // Spigot - IChatBaseComponent ichatbasecomponent = (new ChatMessage("build.tooHigh", new Object[] { this.minecraftServer.getMaxBuildHeight()})).a(EnumChatFormat.RED); + IChatBaseComponent ichatbasecomponent = (new ChatMessage("build.tooHigh", new Object[]{this.minecraftServer.getMaxBuildHeight()})).a(EnumChatFormat.RED); this.player.playerConnection.sendPacket(new PacketPlayOutChat(ichatbasecomponent, ChatMessageType.GAME_INFO)); - } else if (this.teleportPos == null && this.player.d((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && !this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { + } else if (this.teleportPos == null && this.player.e((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && worldserver.a((EntityHuman) this.player, blockposition)) { // CraftBukkit start - Check if we can actually do something over this large a distance Location eyeLoc = this.getPlayer().getEyeLocation(); double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ()); if (reachDistance > (this.getPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) { return; } + this.player.clearActiveItem(); // SPIGOT-4706 // CraftBukkit end - this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand, blockposition, enumdirection, packetplayinuseitem.e(), packetplayinuseitem.f(), packetplayinuseitem.g()); + this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock); } this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition.shift(enumdirection))); } + @Override public void a(PacketPlayInBlockPlace packetplayinblockplace) { PlayerConnectionUtils.ensureMainThread(packetplayinblockplace, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit @@ -1384,10 +1393,10 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { float f8 = f3 * f5; double d3 = player.playerInteractManager.getGameMode()== EnumGamemode.CREATIVE ? 5.0D : 4.5D; Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); - MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1); + MovingObjectPosition movingobjectposition = this.player.world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.OUTLINE, RayTrace.FluidCollisionOption.NONE, player)); boolean cancelled; - if (movingobjectposition == null || movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.BLOCK) { + if (movingobjectposition == null || movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.BLOCK) { org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack, enumhand); cancelled = event.useItemInHand() == Event.Result.DENY; } else { @@ -1395,7 +1404,8 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { player.playerInteractManager.firedInteract = false; cancelled = player.playerInteractManager.interactResult; } else { - org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, movingobjectposition.getBlockPosition(), movingobjectposition.direction, itemstack, true, enumhand); + MovingObjectPositionBlock movingobjectpositionblock = (MovingObjectPositionBlock) movingobjectposition; + org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, movingobjectpositionblock.getBlockPosition(), movingobjectpositionblock.getDirection(), itemstack, true, enumhand); cancelled = event.useItemInHand() == Event.Result.DENY; } } @@ -1409,28 +1419,26 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } } + @Override public void a(PacketPlayInSpectate packetplayinspectate) { PlayerConnectionUtils.ensureMainThread(packetplayinspectate, this, this.player.getWorldServer()); if (this.player.isSpectator()) { - Entity entity = null; Iterator iterator = this.minecraftServer.getWorlds().iterator(); while (iterator.hasNext()) { WorldServer worldserver = (WorldServer) iterator.next(); + Entity entity = packetplayinspectate.a(worldserver); - entity = packetplayinspectate.a(worldserver); if (entity != null) { - break; + this.player.a(worldserver, entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit + return; } } - - if (entity != null) { - this.player.a((WorldServer) entity.world, entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit - } } } + @Override // CraftBukkit start public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) { PlayerConnectionUtils.ensureMainThread(packetplayinresourcepackstatus, this, this.player.getWorldServer()); @@ -1442,6 +1450,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } // CraftBukkit end + @Override public void a(PacketPlayInBoatMove packetplayinboatmove) { PlayerConnectionUtils.ensureMainThread(packetplayinboatmove, this, this.player.getWorldServer()); Entity entity = this.player.getVehicle(); @@ -1452,7 +1461,8 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } - public final void a(IChatBaseComponent ichatbasecomponent) { // Akarin - add final + @Override + public void a(IChatBaseComponent ichatbasecomponent) { // CraftBukkit start - Rarely it would send a disconnect line twice if (this.processedDisconnect) { return; @@ -1463,8 +1473,8 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { PlayerConnection.LOGGER.info("{} lost connection: {}", this.player.getDisplayName().getString(), ichatbasecomponent.getString()); // CraftBukkit start - Replace vanilla quit message handling with our own. /* - this.minecraftServer.at(); - this.minecraftServer.getPlayerList().sendMessage((new ChatMessage("multiplayer.player.left", new Object[] { this.player.getScoreboardDisplayName()})).a(EnumChatFormat.YELLOW)); + this.minecraftServer.invalidatePingSample(); + this.minecraftServer.getPlayerList().sendMessage((new ChatMessage("multiplayer.player.left", new Object[]{this.player.getScoreboardDisplayName()})).a(EnumChatFormat.YELLOW)); */ this.player.n(); @@ -1473,9 +1483,9 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.minecraftServer.getPlayerList().sendMessage(CraftChatMessage.fromString(quitMessage)); } // CraftBukkit end - if (this.minecraftServer.H() && this.player.getDisplayName().getString().equals(this.minecraftServer.G())) { + if (this.isExemptPlayer()) { PlayerConnection.LOGGER.info("Stopping singleplayer server as player logged out"); - this.minecraftServer.safeShutdown(); + this.minecraftServer.safeShutdown(false); } } @@ -1483,97 +1493,25 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { public void sendPacket(Packet packet) { this.a(packet, (GenericFutureListener) null); } - // Akarin start - public final void sendPackets(Packet packet0, Packet packet1) { - if (this.processedDisconnect) - return; - - if (packet0.getType() == PacketType.PLAY_OUT_SPAWN_POSITION) { - PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet0; - this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); - } else if (packet1.getType() == PacketType.PLAY_OUT_SPAWN_POSITION) { - PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet1; - this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); - } - - try { - this.networkManager.sendPackets(packet0, packet1); - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Sending packet"); - CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Packet being sent"); - - crashreportsystemdetails.a("Packet classes", () -> { - return Lists.newArrayList(packet0.getClass().getName(), packet1.getClass().getName()).toString(); - }); - throw new ReportedException(crashreport); - } - } - - public final void sendPackets(Packet packet0, Packet packet1, Packet packet2) { - if (this.processedDisconnect) - return; - - if (packet0 .getType() == PacketType.PLAY_OUT_SPAWN_POSITION) { - PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet0; - this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); - } else if (packet1.getType() == PacketType.PLAY_OUT_SPAWN_POSITION) { - PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet1; - this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); - } else if (packet2.getType() == PacketType.PLAY_OUT_SPAWN_POSITION) { - PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet2; - this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); - } - - try { - this.networkManager.sendPackets(packet0, packet1, packet2); - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Sending packet"); - CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Packet being sent"); - - crashreportsystemdetails.a("Packet classes", () -> { - return Lists.newArrayList(packet0.getClass().getName(), packet1.getClass().getName(), packet2.getClass().getName()).toString(); - }); - throw new ReportedException(crashreport); - } - } - - public final void sendPackets(Packet packet0, Packet packet1, Packet packet2, Packet packet3, Packet packet4, Packet packet5, Packet packet6) { - if (this.processedDisconnect) - return; - - try { - this.networkManager.sendPackets(packet0, packet1, packet2, packet3, packet4, packet5, packet6); - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Sending packet"); - CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Packet being sent"); - - crashreportsystemdetails.a("Packet classes", () -> { - return Lists.newArrayList(packet0.getClass().getName(), packet1.getClass().getName(), packet2.getClass().getName(), packet3.getClass().getName(), packet4.getClass().getName(), packet5.getClass().getName(), packet6.getClass().getName()).toString(); - }); - throw new ReportedException(crashreport); - } - } - // Akarin end public void a(Packet packet, @Nullable GenericFutureListener> genericfuturelistener) { - if (packet == null) return; // Akarin - GH-72 - if (packet.getType() == PacketType.PLAY_OUT_CHAT) { // Akarin + if (packet instanceof PacketPlayOutChat) { PacketPlayOutChat packetplayoutchat = (PacketPlayOutChat) packet; - EntityHuman.EnumChatVisibility entityhuman_enumchatvisibility = this.player.getChatFlags(); + EnumChatVisibility enumchatvisibility = this.player.getChatFlags(); - if (entityhuman_enumchatvisibility == EntityHuman.EnumChatVisibility.HIDDEN && packetplayoutchat.d() != ChatMessageType.GAME_INFO) { + if (enumchatvisibility == EnumChatVisibility.HIDDEN && packetplayoutchat.d() != ChatMessageType.GAME_INFO) { return; } - if (entityhuman_enumchatvisibility == EntityHuman.EnumChatVisibility.SYSTEM && !packetplayoutchat.c()) { + if (enumchatvisibility == EnumChatVisibility.SYSTEM && !packetplayoutchat.c()) { return; } } // CraftBukkit start - if (/*packet == null ||*/ this.processedDisconnect) { // Spigot // Akarin + if (packet == null || this.processedDisconnect) { // Spigot return; - } else if (packet.getType() == PacketType.PLAY_OUT_SPAWN_POSITION) { // Akarin + } else if (packet instanceof PacketPlayOutSpawnPosition) { PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet; this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); } @@ -1592,6 +1530,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } } + @Override public void a(PacketPlayInHeldItemSlot packetplayinhelditemslot) { PlayerConnectionUtils.ensureMainThread(packetplayinhelditemslot, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit @@ -1612,6 +1551,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } } + @Override public void a(PacketPlayInChat packetplayinchat) { // CraftBukkit start - async chat // SPIGOT-3638 @@ -1624,7 +1564,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.getWorldServer()); } // CraftBukkit end - if (this.player.dead || this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { // CraftBukkit - dead men tell no tales + if (this.player.dead || this.player.getChatFlags() == EnumChatVisibility.HIDDEN) { // CraftBukkit - dead men tell no tales this.sendPacket(new PacketPlayOutChat((new ChatMessage("chat.cannotSend", new Object[0])).a(EnumChatFormat.RED))); } else { this.player.resetIdleTimer(); @@ -1679,7 +1619,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { getPlayer().acceptConversationInput(conversationInput); } }); - } else if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.SYSTEM) { // Re-add "Command Only" flag check + } else if (this.player.getChatFlags() == EnumChatVisibility.SYSTEM) { // Re-add "Command Only" flag check ChatMessage chatmessage = new ChatMessage("chat.cannotSend", new Object[0]); chatmessage.getChatModifier().setColor(EnumChatFormat.RED); @@ -1688,7 +1628,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.chat(s, true); // CraftBukkit end - the below is for reference. :) } else { - ChatMessage chatmessage = new ChatMessage("chat.type.text", new Object[] { this.player.getScoreboardDisplayName(), s}); + ChatMessage chatmessage = new ChatMessage("chat.type.text", new Object[]{this.player.getScoreboardDisplayName(), s}); this.minecraftServer.getPlayerList().sendMessage(chatmessage, false); } @@ -1736,15 +1676,15 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { // CraftBukkit start - add method public void chat(String s, boolean async) { - if (s.isEmpty() || this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { + if (s.isEmpty() || this.player.getChatFlags() == EnumChatVisibility.HIDDEN) { return; } if (!async && s.startsWith("/")) { // Paper Start - if (!org.spigotmc.AsyncCatcher.shuttingDown && !ThreadAssertion.is() && !org.bukkit.Bukkit.isPrimaryThread()) { + if (!org.spigotmc.AsyncCatcher.shuttingDown && !org.bukkit.Bukkit.isPrimaryThread()) { final String fCommandLine = s; - MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Command Dispatched Async: " + fCommandLine); // Akarin + MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Command Dispatched Async: " + fCommandLine); MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable()); Waitable wait = new Waitable() { @Override @@ -1754,8 +1694,6 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } }; minecraftServer.processQueue.add(wait); - // Akarin start - /* try { wait.get(); return; @@ -1764,12 +1702,10 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } catch (Exception e) { throw new RuntimeException("Exception processing chat command", e.getCause()); } - */ - // Akarin end } // Paper End this.handleCommand(s); - } else if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.SYSTEM) { + } else if (this.player.getChatFlags() == EnumChatVisibility.SYSTEM) { // Do nothing, this is coming from a plugin } else { Player player = this.getPlayer(); @@ -1845,7 +1781,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { // CraftBukkit end private void handleCommand(String s) { - MinecraftTimings.playerCommandTimer.startTimingUnsafe(); // Paper + MinecraftTimings.playerCommandTimer.startTiming(); // Paper // CraftBukkit start - whole method if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot this.LOGGER.info(this.player.getName() + " issued server command: " + s); @@ -1869,12 +1805,13 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { java.util.logging.Logger.getLogger(PlayerConnection.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); return; } finally { - MinecraftTimings.playerCommandTimer.stopTimingUnsafe(); // Paper + MinecraftTimings.playerCommandTimer.stopTiming(); // Paper } // this.minecraftServer.getCommandDispatcher().a(this.player.getCommandListener(), s); // CraftBukkit end } + @Override public void a(PacketPlayInArmAnimation packetplayinarmanimation) { PlayerConnectionUtils.ensureMainThread(packetplayinarmanimation, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit @@ -1895,9 +1832,9 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { float f8 = f3 * f5; double d3 = player.playerInteractManager.getGameMode()== EnumGamemode.CREATIVE ? 5.0D : 4.5D; Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); - MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1); + MovingObjectPosition movingobjectposition = this.player.world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.OUTLINE, RayTrace.FluidCollisionOption.NONE, player)); - if (movingobjectposition == null || movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.BLOCK) { + if (movingobjectposition == null || movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.BLOCK) { CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.inventory.getItemInHand(), EnumHand.MAIN_HAND); } @@ -1910,6 +1847,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.player.a(packetplayinarmanimation.b()); } + @Override public void a(PacketPlayInEntityAction packetplayinentityaction) { PlayerConnectionUtils.ensureMainThread(packetplayinentityaction, this, this.player.getWorldServer()); // CraftBukkit start @@ -1939,8 +1877,8 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { IJumpable ijumpable; switch (packetplayinentityaction.c()) { - case START_SNEAKING: - this.player.setSneaking(true); + case START_SNEAKING: + this.player.setSneaking(true); // Paper start - Hang on! if (this.player.world.paperConfig.parrotsHangOnBetter) { @@ -1948,60 +1886,61 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } // Paper end - break; - case STOP_SNEAKING: - this.player.setSneaking(false); - break; - case START_SPRINTING: - this.player.setSprinting(true); - break; - case STOP_SPRINTING: - this.player.setSprinting(false); - break; - case STOP_SLEEPING: - if (this.player.isSleeping()) { - this.player.a(false, true, true); - this.teleportPos = new Vec3D(this.player.locX, this.player.locY, this.player.locZ); - } - break; - case START_RIDING_JUMP: - if (this.player.getVehicle() instanceof IJumpable) { - ijumpable = (IJumpable) this.player.getVehicle(); - int i = packetplayinentityaction.d(); - - if (ijumpable.G_() && i > 0) { - ijumpable.b(i); + break; + case STOP_SNEAKING: + this.player.setSneaking(false); + break; + case START_SPRINTING: + this.player.setSprinting(true); + break; + case STOP_SPRINTING: + this.player.setSprinting(false); + break; + case STOP_SLEEPING: + if (this.player.isSleeping()) { + this.player.wakeup(false, true, true); + this.teleportPos = new Vec3D(this.player.locX, this.player.locY, this.player.locZ); } - } - break; - case STOP_RIDING_JUMP: - if (this.player.getVehicle() instanceof IJumpable) { - ijumpable = (IJumpable) this.player.getVehicle(); - ijumpable.I_(); - } - break; - case OPEN_INVENTORY: - if (this.player.getVehicle() instanceof EntityHorseAbstract) { - ((EntityHorseAbstract) this.player.getVehicle()).c((EntityHuman) this.player); - } - break; - case START_FALL_FLYING: - if (!this.player.onGround && this.player.motY < 0.0D && !this.player.dc() && !this.player.isInWater()) { - ItemStack itemstack = this.player.getEquipment(EnumItemSlot.CHEST); + break; + case START_RIDING_JUMP: + if (this.player.getVehicle() instanceof IJumpable) { + ijumpable = (IJumpable) this.player.getVehicle(); + int i = packetplayinentityaction.d(); - if (itemstack.getItem() == Items.ELYTRA && ItemElytra.e(itemstack)) { - this.player.J(); + if (ijumpable.F_() && i > 0) { + ijumpable.b(i); + } } - } else { - this.player.K(); - } - break; - default: - throw new IllegalArgumentException("Invalid client command!"); + break; + case STOP_RIDING_JUMP: + if (this.player.getVehicle() instanceof IJumpable) { + ijumpable = (IJumpable) this.player.getVehicle(); + ijumpable.c(); + } + break; + case OPEN_INVENTORY: + if (this.player.getVehicle() instanceof EntityHorseAbstract) { + ((EntityHorseAbstract) this.player.getVehicle()).e((EntityHuman) this.player); + } + break; + case START_FALL_FLYING: + if (!this.player.onGround && this.player.getMot().y < 0.0D && !this.player.isGliding() && !this.player.isInWater()) { + ItemStack itemstack = this.player.getEquipment(EnumItemSlot.CHEST); + + if (itemstack.getItem() == Items.ELYTRA && ItemElytra.e(itemstack)) { + this.player.J(); + } + } else { + this.player.K(); + } + break; + default: + throw new IllegalArgumentException("Invalid client command!"); } } + @Override public void a(PacketPlayInUseEntity packetplayinuseentity) { PlayerConnectionUtils.ensureMainThread(packetplayinuseentity, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit @@ -2076,7 +2015,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { // CraftBukkit end } else if (packetplayinuseentity.b() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) { enumhand = packetplayinuseentity.c(); - entity.a(this.player, packetplayinuseentity.d(), enumhand); + entity.a((EntityHuman) this.player, packetplayinuseentity.d(), enumhand); // CraftBukkit start if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) { this.player.updateInventory(this.player.activeContainer); @@ -2112,36 +2051,37 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } + @Override public void a(PacketPlayInClientCommand packetplayinclientcommand) { PlayerConnectionUtils.ensureMainThread(packetplayinclientcommand, this, this.player.getWorldServer()); this.player.resetIdleTimer(); PacketPlayInClientCommand.EnumClientCommand packetplayinclientcommand_enumclientcommand = packetplayinclientcommand.b(); switch (packetplayinclientcommand_enumclientcommand) { - case PERFORM_RESPAWN: - if (this.player.viewingCredits) { - this.player.viewingCredits = false; - // this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, DimensionManager.OVERWORLD, true); - this.minecraftServer.getPlayerList().changeDimension(this.player, DimensionManager.OVERWORLD, PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit - reroute logic through custom portal management - CriterionTriggers.v.a(this.player, DimensionManager.THE_END, DimensionManager.OVERWORLD); - } else { - if (this.player.getHealth() > 0.0F) { - return; - } + case PERFORM_RESPAWN: + if (this.player.viewingCredits) { + this.player.viewingCredits = false; + this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, DimensionManager.OVERWORLD, true); + CriterionTriggers.v.a(this.player, DimensionManager.THE_END, DimensionManager.OVERWORLD); + } else { + if (this.player.getHealth() > 0.0F) { + return; + } - this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, DimensionManager.OVERWORLD, false); - if (this.minecraftServer.isHardcore()) { - this.player.a(EnumGamemode.SPECTATOR); - this.player.getWorldServer().getGameRules().set("spectatorsGenerateChunks", "false", this.minecraftServer); + this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, DimensionManager.OVERWORLD, false); + if (this.minecraftServer.isHardcore()) { + this.player.a(EnumGamemode.SPECTATOR); + ((GameRules.GameRuleBoolean) this.player.getWorldServer().getGameRules().get(GameRules.SPECTATORS_GENERATE_CHUNKS)).a(false, this.minecraftServer); + } } - } - break; - case REQUEST_STATS: - this.player.getStatisticManager().a(this.player); + break; + case REQUEST_STATS: + this.player.getStatisticManager().a(this.player); } } + @Override public void a(PacketPlayInCloseWindow packetplayinclosewindow) { PlayerConnectionUtils.ensureMainThread(packetplayinclosewindow, this, this.player.getWorldServer()); @@ -2151,6 +2091,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.player.m(); } + @Override public void a(PacketPlayInWindowClick packetplayinwindowclick) { PlayerConnectionUtils.ensureMainThread(packetplayinwindowclick, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit @@ -2283,7 +2224,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { case CLONE: if (packetplayinwindowclick.d() == 2) { click = ClickType.MIDDLE; - if (packetplayinwindowclick.c() < 0) { // Paper - GH-404 + if (packetplayinwindowclick.c() < 0) { action = InventoryAction.NOTHING; } else { Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.c()); @@ -2436,12 +2377,12 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { // CraftBukkit end if (ItemStack.matches(packetplayinwindowclick.f(), itemstack)) { this.player.playerConnection.sendPacket(new PacketPlayOutTransaction(packetplayinwindowclick.b(), packetplayinwindowclick.e(), true)); - this.player.f = true; - this.player.activeContainer.b(); + this.player.e = true; + this.player.activeContainer.c(); this.player.broadcastCarriedItem(); - this.player.f = false; + this.player.e = false; } else { - this.k.a(this.player.activeContainer.windowId, packetplayinwindowclick.e()); + this.k.put(this.player.activeContainer.windowId, packetplayinwindowclick.e()); this.player.playerConnection.sendPacket(new PacketPlayOutTransaction(packetplayinwindowclick.b(), packetplayinwindowclick.e(), false)); this.player.activeContainer.a(this.player, false); NonNullList nonnulllist1 = NonNullList.a(); @@ -2459,32 +2400,30 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } + @Override public void a(PacketPlayInAutoRecipe packetplayinautorecipe) { PlayerConnectionUtils.ensureMainThread(packetplayinautorecipe, this, this.player.getWorldServer()); this.player.resetIdleTimer(); - if (!this.player.isSpectator() && this.player.activeContainer.windowId == packetplayinautorecipe.b() && this.player.activeContainer.c(this.player)) { - IRecipe irecipe = this.minecraftServer.getCraftingManager().a(packetplayinautorecipe.c()); - - if (this.player.activeContainer instanceof ContainerFurnace) { - (new AutoRecipeFurnace()).a(this.player, irecipe, packetplayinautorecipe.d()); - } else { - (new AutoRecipe()).a(this.player, irecipe, packetplayinautorecipe.d()); - } - + if (!this.player.isSpectator() && this.player.activeContainer.windowId == packetplayinautorecipe.b() && this.player.activeContainer.c(this.player) && this.player.activeContainer instanceof ContainerRecipeBook) { + this.minecraftServer.getCraftingManager().a(packetplayinautorecipe.c()).ifPresent((irecipe) -> { + ((ContainerRecipeBook) this.player.activeContainer).a(packetplayinautorecipe.d(), irecipe, this.player); + }); } } + @Override public void a(PacketPlayInEnchantItem packetplayinenchantitem) { PlayerConnectionUtils.ensureMainThread(packetplayinenchantitem, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit this.player.resetIdleTimer(); if (this.player.activeContainer.windowId == packetplayinenchantitem.b() && this.player.activeContainer.c(this.player) && !this.player.isSpectator()) { - this.player.activeContainer.a(this.player, packetplayinenchantitem.c()); - this.player.activeContainer.b(); + this.player.activeContainer.a((EntityHuman) this.player, packetplayinenchantitem.c()); + this.player.activeContainer.c(); } } + @Override public void a(PacketPlayInSetCreativeSlot packetplayinsetcreativeslot) { PlayerConnectionUtils.ensureMainThread(packetplayinsetcreativeslot, this, this.player.getWorldServer()); if (this.player.playerInteractManager.isCreative()) { @@ -2554,6 +2493,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } this.player.defaultContainer.a(this.player, true); + this.player.defaultContainer.c(); } else if (flag && flag2 && this.j < 200) { this.j += 20; EntityItem entityitem = this.player.drop(itemstack, true); @@ -2566,17 +2506,19 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } + @Override public void a(PacketPlayInTransaction packetplayintransaction) { PlayerConnectionUtils.ensureMainThread(packetplayintransaction, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit - Short oshort = (Short) this.k.get(this.player.activeContainer.windowId); + int i = this.player.activeContainer.windowId; - if (oshort != null && packetplayintransaction.c() == oshort && this.player.activeContainer.windowId == packetplayintransaction.b() && !this.player.activeContainer.c(this.player) && !this.player.isSpectator()) { + if (i == packetplayintransaction.b() && this.k.getOrDefault(i, (short) (packetplayintransaction.c() + 1)) == packetplayintransaction.c() && !this.player.activeContainer.c(this.player) && !this.player.isSpectator()) { this.player.activeContainer.a(this.player, true); } } + @Override public void a(PacketPlayInUpdateSign packetplayinupdatesign) { PlayerConnectionUtils.ensureMainThread(packetplayinupdatesign, this, this.player.getWorldServer()); if (this.player.isFrozen()) return; // CraftBukkit @@ -2594,7 +2536,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { TileEntitySign tileentitysign = (TileEntitySign) tileentity; - if (!tileentitysign.d() || tileentitysign.signEditor == null || !tileentitysign.signEditor.equals(this.player.getUniqueID())) { // Paper + if (!tileentitysign.d() || tileentitysign.signEditor == null || !tileentitysign.signEditor.equals(this.player.getUniqueID())) { this.minecraftServer.warning("Player " + this.player.getDisplayName().getString() + " just tried to change non-editable sign"); this.sendPacket(tileentity.getUpdatePacket()); // CraftBukkit return; @@ -2614,7 +2556,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { if (MAX_SIGN_LINE_LENGTH > 0 && astring[i].length() > MAX_SIGN_LINE_LENGTH) { // This handles multibyte characters as 1 int offset = astring[i].codePoints().limit(MAX_SIGN_LINE_LENGTH).map(Character::charCount).sum(); - if (offset > astring.length) { + if (offset < astring[i].length()) { astring[i] = astring[i].substring(0, offset); } } @@ -2636,6 +2578,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { } + @Override public void a(PacketPlayInKeepAlive packetplayinkeepalive) { //PlayerConnectionUtils.ensureMainThread(packetplayinkeepalive, this, this.player.getWorldServer()); // CraftBukkit // Paper - This shouldn't be on the main thread if (this.awaitingKeepAlive && packetplayinkeepalive.b() == this.h) { @@ -2643,16 +2586,17 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { this.player.ping = (this.player.ping * 3 + i) / 4; this.awaitingKeepAlive = false; - } else if (!this.player.getDisplayName().getString().equals(this.minecraftServer.G())) { + } else if (!this.isExemptPlayer()) { // Paper start - This needs to be handled on the main thread for plugins - minecraftServer.postToMainThread(() -> { - this.disconnect(new ChatMessage("disconnect.timeout", new Object[0])); + minecraftServer.scheduleOnMain(() -> { + this.disconnect(new ChatMessage("disconnect.timeout")); }); // Paper end } } + @Override public void a(PacketPlayInAbilities packetplayinabilities) { PlayerConnectionUtils.ensureMainThread(packetplayinabilities, this, this.player.getWorldServer()); // CraftBukkit start @@ -2668,6 +2612,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { // CraftBukkit end } + @Override public void a(PacketPlayInSettings packetplayinsettings) { PlayerConnectionUtils.ensureMainThread(packetplayinsettings, this, this.player.getWorldServer()); this.player.a(packetplayinsettings); @@ -2677,6 +2622,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { private static final MinecraftKey CUSTOM_REGISTER = new MinecraftKey("register"); private static final MinecraftKey CUSTOM_UNREGISTER = new MinecraftKey("unregister"); + @Override public void a(PacketPlayInCustomPayload packetplayincustompayload) { PlayerConnectionUtils.ensureMainThread(packetplayincustompayload, this, this.player.getWorldServer()); if (packetplayincustompayload.tag.equals(CUSTOM_REGISTER)) { @@ -2716,4 +2662,20 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { return (!this.player.joining && !this.networkManager.isConnected()) || this.processedDisconnect; // Paper } // CraftBukkit end + + @Override + public void a(PacketPlayInDifficultyChange packetplayindifficultychange) { + PlayerConnectionUtils.ensureMainThread(packetplayindifficultychange, this, this.player.getWorldServer()); + if (this.player.k(2) || this.isExemptPlayer()) { + this.minecraftServer.a(packetplayindifficultychange.b(), false); + } + } + + @Override + public void a(PacketPlayInDifficultyLock packetplayindifficultylock) { + PlayerConnectionUtils.ensureMainThread(packetplayindifficultylock, this, this.player.getWorldServer()); + if (this.player.k(2) || this.isExemptPlayer()) { + this.minecraftServer.d(packetplayindifficultylock.b()); + } + } } diff --git a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java index cda91d6f7..e928525b8 100644 --- a/src/main/java/net/minecraft/server/PlayerConnectionUtils.java +++ b/src/main/java/net/minecraft/server/PlayerConnectionUtils.java @@ -1,19 +1,31 @@ package net.minecraft.server; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import co.aikar.timings.MinecraftTimings; // Paper import co.aikar.timings.Timing; // Paper public class PlayerConnectionUtils { - public static void ensureMainThread(Packet packet, T t0, IAsyncTaskHandler iasynctaskhandler) throws CancelledPacketHandleException { - if (!iasynctaskhandler.isMainThread()) { - Timing timing = MinecraftTimings.getPacketTiming(packet); // Paper + private static final Logger LOGGER = LogManager.getLogger(); + + public static void ensureMainThread(Packet packet, T t0, WorldServer worldserver) throws CancelledPacketHandleException { + ensureMainThread(packet, t0, (IAsyncTaskHandler) worldserver.getMinecraftServer()); + } + + public static void ensureMainThread(Packet packet, T t0, IAsyncTaskHandler iasynctaskhandler) throws CancelledPacketHandleException { + if (!iasynctaskhandler.isMainThread()) { + Timing timing = MinecraftTimings.getPacketTiming(packet); // Paper - timings + iasynctaskhandler.execute(() -> { + if (MinecraftServer.getServer().hasStopped() || (t0 instanceof PlayerConnection && ((PlayerConnection) t0).processedDisconnect)) return; // CraftBukkit, MC-142590 + if (t0.a().isConnected()) { + try (Timing ignored = timing.startTiming()) { // Paper - timings + packet.a(t0); + } // Paper - timings + } else { + PlayerConnectionUtils.LOGGER.debug("Ignoring packet due to disconnection: " + packet); + } - iasynctaskhandler.ensuresMainThread(() -> { - if (t0 instanceof PlayerConnection && ((PlayerConnection) t0).processedDisconnect) return; // CraftBukkit - try (Timing ignored = timing.startTimingUnsafe()) { // Paper - packet.a(t0); - } // Paper - timings }); throw CancelledPacketHandleException.INSTANCE; } diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java index 99e3856c0..bc03a82b7 100644 --- a/src/main/java/net/minecraft/server/PlayerInteractManager.java +++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; // CraftBukkit start import java.util.ArrayList; import org.bukkit.craftbukkit.block.CraftBlock; @@ -12,31 +14,32 @@ import org.bukkit.event.player.PlayerInteractEvent; public class PlayerInteractManager { - public World world; + private static final Logger LOGGER = LogManager.getLogger(); + public WorldServer world; public EntityPlayer player; private EnumGamemode gamemode; - private boolean d; + private boolean e; private int lastDigTick; - private BlockPosition f; + private BlockPosition g; private int currentTick; - private boolean h; - private BlockPosition i; - private int j; + private boolean i; + private BlockPosition j; private int k; + private int l; - public PlayerInteractManager(World world) { + public PlayerInteractManager(WorldServer worldserver) { this.gamemode = EnumGamemode.NOT_SET; - this.f = BlockPosition.ZERO; - this.i = BlockPosition.ZERO; - this.k = -1; - this.world = world; + this.g = BlockPosition.ZERO; + this.j = BlockPosition.ZERO; + this.l = -1; + this.world = worldserver; } public void setGameMode(EnumGamemode enumgamemode) { this.gamemode = enumgamemode; enumgamemode.a(this.player.abilities); this.player.updateAbilities(); - this.player.server.getPlayerList().sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_GAME_MODE, new EntityPlayer[] { this.player}), this.player); // CraftBukkit + this.player.server.getPlayerList().sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_GAME_MODE, new EntityPlayer[]{this.player}), this.player); // CraftBukkit this.world.everyoneSleeping(); } @@ -62,150 +65,192 @@ public class PlayerInteractManager { public void a() { this.currentTick = MinecraftServer.currentTick; // CraftBukkit; - float f; - int i; - - if (this.h) { - int j = this.currentTick - this.j; - IBlockData iblockdata = this.world.getType(this.i); + IBlockData iblockdata; + if (this.i) { + iblockdata = this.world.getType(this.j); if (iblockdata.isAir()) { - this.h = false; + this.i = false; } else { - f = iblockdata.getDamage(this.player, this.player.world, this.i) * (float) (j + 1); - i = (int) (f * 10.0F); - if (i != this.k) { - this.world.c(this.player.getId(), this.i, i); - this.k = i; - } + float f = this.a(iblockdata, this.j); if (f >= 1.0F) { - this.h = false; - this.breakBlock(this.i); + this.i = false; + this.breakBlock(this.j); } } - } else if (this.d) { - IBlockData iblockdata1 = this.world.getType(this.f); - - if (iblockdata1.isAir()) { - this.world.c(this.player.getId(), this.f, -1); - this.k = -1; - this.d = false; + } else if (this.e) { + iblockdata = this.world.getType(this.g); + if (iblockdata.isAir()) { + this.world.a(this.player.getId(), this.g, -1); + this.l = -1; + this.e = false; } else { - int k = this.currentTick - this.lastDigTick; - - f = iblockdata1.getDamage(this.player, this.player.world, this.i) * (float) (k + 1); - i = (int) (f * 10.0F); - if (i != this.k) { - this.world.c(this.player.getId(), this.f, i); - this.k = i; - } + this.a(iblockdata, this.g); } } } - public void a(BlockPosition blockposition, EnumDirection enumdirection) { - // CraftBukkit start - PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.inventory.getItemInHand(), EnumHand.MAIN_HAND); - if (event.isCancelled()) { - // Let the client know the block still exists - ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); - // Paper start - brute force neighbor blocks for any attached blocks - for (EnumDirection dir : EnumDirection.values()) { - ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition.shift(dir))); - } - // Paper end - // Update any tile entity data for this block - TileEntity tileentity = this.world.getTileEntity(blockposition); - if (tileentity != null) { - this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); - } - return; - } - // CraftBukkit end - boolean isCreative = this.isCreative(); - if (isCreative) { - if (!this.world.douseFire((EntityHuman) null, blockposition, enumdirection)) { - this.breakBlock(blockposition, isCreative, true); // Akarin - add parameters - } + private float a(IBlockData iblockdata, BlockPosition blockposition) { + int i = this.currentTick - this.k; + float f = iblockdata.getDamage(this.player, this.player.world, blockposition) * (float) (i + 1); + int j = (int) (f * 10.0F); + if (j != this.l) { + this.world.a(this.player.getId(), blockposition, j); + this.l = j; + } + + return f; + } + + public void a(BlockPosition blockposition, PacketPlayInBlockDig.EnumPlayerDigType packetplayinblockdig_enumplayerdigtype, EnumDirection enumdirection, int i) { + double d0 = this.player.locX - ((double) blockposition.getX() + 0.5D); + double d1 = this.player.locY - ((double) blockposition.getY() + 0.5D) + 1.5D; + double d2 = this.player.locZ - ((double) blockposition.getZ() + 0.5D); + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + + if (d3 > 36.0D) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, false)); + } else if (blockposition.getY() >= i) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, false)); } else { - if (this.gamemode.d()) { - if (this.gamemode == EnumGamemode.SPECTATOR) { + IBlockData iblockdata; + + if (packetplayinblockdig_enumplayerdigtype == PacketPlayInBlockDig.EnumPlayerDigType.START_DESTROY_BLOCK) { + if (!this.world.a((EntityHuman) this.player, blockposition)) { + // CraftBukkit start - fire PlayerInteractEvent + CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.inventory.getItemInHand(), EnumHand.MAIN_HAND); + this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, false)); + // Update any tile entity data for this block + TileEntity tileentity = world.getTileEntity(blockposition); + if (tileentity != null) { + this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); + } + // CraftBukkit end return; } - if (!this.player.dy()) { - ItemStack itemstack = this.player.getItemInMainHand(); + // CraftBukkit start + PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.inventory.getItemInHand(), EnumHand.MAIN_HAND); + if (event.isCancelled()) { + // Let the client know the block still exists + // Paper start - brute force neighbor blocks for any attached blocks + for (EnumDirection dir : EnumDirection.values()) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition.shift(dir))); + } + // Paper end + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + // Update any tile entity data for this block + TileEntity tileentity = this.world.getTileEntity(blockposition); + if (tileentity != null) { + this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); + } + return; + } + // CraftBukkit end - if (itemstack.isEmpty()) { - return; + if (this.isCreative()) { + if (!this.world.douseFire((EntityHuman) null, blockposition, enumdirection)) { + this.a(blockposition, packetplayinblockdig_enumplayerdigtype); + } else { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true)); } - ShapeDetectorBlock shapedetectorblock = new ShapeDetectorBlock(this.world, blockposition, false); + return; + } - if (!itemstack.a(this.world.F(), shapedetectorblock)) { - return; + if (this.player.a((World) this.world, blockposition, this.gamemode)) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, false)); + return; + } + + // this.world.douseFire((EntityHuman) null, blockposition, enumdirection); // CraftBukkit - Moved down + this.lastDigTick = this.currentTick; + float f = 1.0F; + + iblockdata = this.world.getType(blockposition); + // CraftBukkit start - Swings at air do *NOT* exist. + if (event.useInteractedBlock() == Event.Result.DENY) { + // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. + IBlockData data = this.world.getType(blockposition); + if (data.getBlock() instanceof BlockDoor) { + // For some reason *BOTH* the bottom/top part have to be marked updated. + boolean bottom = data.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.LOWER; + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, bottom ? blockposition.up() : blockposition.down())); + } else if (data.getBlock() instanceof BlockTrapdoor) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + } + } else if (!iblockdata.isAir()) { + iblockdata.attack(this.world, blockposition, this.player); + f = iblockdata.getDamage(this.player, this.player.world, blockposition); + // Allow fire punching to be blocked + this.world.douseFire((EntityHuman) null, blockposition, enumdirection); + } + + if (event.useItemInHand() == Event.Result.DENY) { + // If we 'insta destroyed' then the client needs to be informed. + if (f > 1.0f) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + } + return; + } + org.bukkit.event.block.BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.player, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.player.inventory.getItemInHand(), f >= 1.0f); + + if (blockEvent.isCancelled()) { + // Let the client know the block still exists + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + return; + } + + if (blockEvent.getInstaBreak()) { + f = 2.0f; + } + // CraftBukkit end + + if (!iblockdata.isAir() && f >= 1.0F) { + this.a(blockposition, packetplayinblockdig_enumplayerdigtype); + } else { + this.e = true; + this.g = blockposition; + int j = (int) (f * 10.0F); + + this.world.a(this.player.getId(), blockposition, j); + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); // Paper - fixes MC-156852 + this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true)); + this.l = j; + } + } else if (packetplayinblockdig_enumplayerdigtype == PacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) { + if (blockposition.equals(this.g)) { + int k = this.currentTick - this.lastDigTick; + + iblockdata = this.world.getType(blockposition); + if (!iblockdata.isAir()) { + float f1 = iblockdata.getDamage(this.player, this.player.world, blockposition) * (float) (k + 1); + + if (f1 >= 0.7F) { + this.e = false; + this.world.a(this.player.getId(), blockposition, -1); + this.a(blockposition, packetplayinblockdig_enumplayerdigtype); + return; + } + + if (!this.i) { + this.e = false; + this.i = true; + this.j = blockposition; + this.k = this.lastDigTick; + } } } - } - // this.world.douseFire((EntityHuman) null, blockposition, enumdirection); // CraftBukkit - Moved down - this.lastDigTick = this.currentTick; - float f = 1.0F; - IBlockData iblockdata = this.world.getType(blockposition); - - // CraftBukkit start - Swings at air do *NOT* exist. - if (event.useInteractedBlock() == Event.Result.DENY) { - // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. - IBlockData data = this.world.getType(blockposition); - if (data.getBlock() instanceof BlockDoor) { - // For some reason *BOTH* the bottom/top part have to be marked updated. - boolean bottom = data.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.LOWER; - ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); - ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, bottom ? blockposition.up() : blockposition.down())); - } else if (data.getBlock() instanceof BlockTrapdoor) { - ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); - } - } else if (!iblockdata.isAir()) { - iblockdata.attack(this.world, blockposition, this.player); - f = iblockdata.getDamage(this.player, this.player.world, blockposition); - // Allow fire punching to be blocked - this.world.douseFire((EntityHuman) null, blockposition, enumdirection); - } - - if (event.useItemInHand() == Event.Result.DENY) { - // If we 'insta destroyed' then the client needs to be informed. - if (false && f > 1.0f) { // Akarin - this does nothing - ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); - } - return; - } - org.bukkit.event.block.BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.player, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.player.inventory.getItemInHand(), f >= 1.0f); - - if (blockEvent.isCancelled()) { - // Let the client know the block still exists - //((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); // Akarin - unnecessary - return; - } - - boolean instaBreak = blockEvent.getInstaBreak(); // Akarin - if (instaBreak) { // Akarin - f = 2.0f; - } - // CraftBukkit end - - if (!iblockdata.isAir() && f >= 1.0F) { - this.breakBlock(blockposition, isCreative, instaBreak); // Akarin - add parameters - } else { - this.d = true; - this.f = blockposition; - int i = (int) (f * 10.0F); - - this.world.c(this.player.getId(), blockposition, i); - this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); - this.k = i; + this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true)); + } else if (packetplayinblockdig_enumplayerdigtype == PacketPlayInBlockDig.EnumPlayerDigType.ABORT_DESTROY_BLOCK) { + this.e = false; + this.world.a(this.player.getId(), this.g, -1); + this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true)); } } @@ -213,59 +258,16 @@ public class PlayerInteractManager { this.world.chunkPacketBlockController.onPlayerLeftClickBlock(this, blockposition, enumdirection); // Paper - Anti-Xray } - public void a(BlockPosition blockposition) { - if (blockposition.equals(this.f)) { - this.currentTick = MinecraftServer.currentTick; // CraftBukkit - int i = this.currentTick - this.lastDigTick; - IBlockData iblockdata = this.world.getType(blockposition); - - if (!iblockdata.isAir()) { - float f = iblockdata.getDamage(this.player, this.player.world, blockposition) * (float) (i + 1); - - if (f >= 0.7F) { - this.d = false; - this.world.c(this.player.getId(), blockposition, -1); - this.breakBlock(blockposition); - } else if (!this.h) { - this.d = false; - this.h = true; - this.i = blockposition; - this.j = this.lastDigTick; - } - } - // CraftBukkit start - Force block reset to client + public void a(BlockPosition blockposition, PacketPlayInBlockDig.EnumPlayerDigType packetplayinblockdig_enumplayerdigtype) { + if (this.breakBlock(blockposition)) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockBreak(blockposition, this.world.getType(blockposition), packetplayinblockdig_enumplayerdigtype, true)); } else { - this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); - // CraftBukkit end + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); // CraftBukkit - SPIGOT-5196 } } - public void e() { - this.d = false; - this.world.c(this.player.getId(), this.f, -1); - } - - private boolean c(BlockPosition blockposition) { - IBlockData iblockdata = this.world.getType(blockposition); - - iblockdata.getBlock().a(this.world, blockposition, iblockdata, (EntityHuman) this.player); - boolean flag = this.world.setAir(blockposition); - - if (flag) { - iblockdata.getBlock().postBreak(this.world, blockposition, iblockdata); - } - - return flag; - } - public boolean breakBlock(BlockPosition blockposition) { - // Akarin start - return breakBlock(blockposition, this.isCreative(), true); - } - - public boolean breakBlock(BlockPosition blockposition, boolean isCreative, boolean notifyCancel) { - // Akarin end IBlockData iblockdata = this.world.getType(blockposition); // CraftBukkit start - fire BlockBreakEvent org.bukkit.block.Block bblock = CraftBlock.at(world, blockposition); @@ -277,10 +279,10 @@ public class PlayerInteractManager { // Tell client the block is gone immediately then process events // Don't tell the client if its a creative sword break because its not broken! - if (false && world.getTileEntity(blockposition) == null && !isSwordNoBreak) { // Akarin - this does nothing + if (world.getTileEntity(blockposition) == null && !isSwordNoBreak) { PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(this.world, blockposition); packet.block = Blocks.AIR.getBlockData(); - ((EntityPlayer) this.player).playerConnection.sendPacket(packet); + this.player.playerConnection.sendPacket(packet); } event = new BlockBreakEvent(bblock, this.player.getBukkitEntity()); @@ -294,28 +296,22 @@ public class PlayerInteractManager { ItemStack itemstack = this.player.getEquipment(EnumItemSlot.MAINHAND); - if (nmsBlock != null && !event.isCancelled() && !isCreative && this.player.hasBlock(nmsBlock.getBlockData())) { // Akarin - // Copied from block.a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, @Nullable TileEntity tileentity, ItemStack itemstack) - // PAIL: checkme each update - if (!(nmsBlock.X_() && EnchantmentManager.getEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) > 0)) { - int bonusLevel = EnchantmentManager.getEnchantmentLevel(Enchantments.LOOT_BONUS_BLOCKS, itemstack); - - event.setExpToDrop(nmsBlock.getExpDrop(nmsData, this.world, blockposition, bonusLevel)); - } + if (nmsBlock != null && !event.isCancelled() && !this.isCreative() && this.player.hasBlock(nmsBlock.getBlockData())) { + event.setExpToDrop(nmsBlock.getExpDrop(nmsData, this.world, blockposition, itemstack)); } this.world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { - if (isSwordNoBreak || (!isCreative && !notifyCancel)) { // Akarin - only send back for insta breaks + if (isSwordNoBreak) { return false; } // Let the client know the block still exists - ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); // Akarin + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); // Brute force all possible updates for (EnumDirection dir : EnumDirection.values()) { - ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition.shift(dir))); + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(world, blockposition.shift(dir))); } // Update any tile entity data for this block @@ -328,7 +324,7 @@ public class PlayerInteractManager { } // CraftBukkit end - if (false && !this.player.getItemInMainHand().getItem().a(iblockdata, this.world, blockposition, (EntityHuman) this.player)) { // CraftBukkit - false + if (false && !this.player.getItemInMainHand().getItem().a(iblockdata, (World) this.world, blockposition, (EntityHuman) this.player)) { // CraftBukkit - false return false; } else { iblockdata = this.world.getType(blockposition); // CraftBukkit - update state from plugins @@ -336,82 +332,52 @@ public class PlayerInteractManager { TileEntity tileentity = this.world.getTileEntity(blockposition); Block block = iblockdata.getBlock(); - // CraftBukkit start - Special case skulls, their item data comes from a tile entity (Also check if block should drop items) - // And shulker boxes too for duplication on BlockPlaceEvent cancel reasons (Also check if block should drop items) - if (((iblockdata.getBlock() instanceof BlockSkullAbstract && !isCreative) || iblockdata.getBlock() instanceof BlockShulkerBox) && event.isDropItems()) { // Akarin - org.bukkit.block.BlockState state = bblock.getState(); - world.captureDrops = new ArrayList<>(); - - iblockdata.getBlock().dropNaturally(iblockdata, world, blockposition, 1.0F, 0); - boolean flag = this.c(blockposition); - - if (event.isDropItems()) { - org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, world.captureDrops); - } - - world.captureDrops = null; - return flag; - } - // CraftBukkit end - - if ((block instanceof BlockCommand || block instanceof BlockStructure) && !this.player.isCreativeAndOp()) { + if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp()) { this.world.notify(blockposition, iblockdata, iblockdata, 3); return false; + } else if (this.player.a((World) this.world, blockposition, this.gamemode)) { + return false; } else { - if (this.gamemode.d()) { - if (this.gamemode == EnumGamemode.SPECTATOR) { - return false; - } - - if (!this.player.dy()) { - ItemStack itemstack = this.player.getItemInMainHand(); - - if (itemstack.isEmpty()) { - return false; - } - - ShapeDetectorBlock shapedetectorblock = new ShapeDetectorBlock(this.world, blockposition, false); - - if (!itemstack.a(this.world.F(), shapedetectorblock)) { - return false; - } - } - } - // CraftBukkit start org.bukkit.block.BlockState state = bblock.getState(); world.captureDrops = new ArrayList<>(); // CraftBukkit end - boolean flag = this.c(blockposition); + block.a((World) this.world, blockposition, iblockdata, (EntityHuman) this.player); + boolean flag = this.world.a(blockposition, false); - if (!this.isCreative()) { - ItemStack itemstack1 = this.player.getItemInMainHand(); - boolean flag1 = this.player.hasBlock(iblockdata); - - ItemStack itemstack2 = flag && flag1 && event.isDropItems() && !itemstack1.isEmpty() ? itemstack1.cloneItemStack() : ItemStack.a; // Paper - MC-136865 - clone before use - itemstack1.a(this.world, iblockdata, blockposition, this.player); - // CraftBukkit start - Check if block should drop items - if (flag && flag1 && event.isDropItems()) { - //ItemStack itemstack2 = itemstack1.isEmpty() ? ItemStack.a : itemstack1.cloneItemStack(); // Paper - MC-136865 - move up - - iblockdata.getBlock().a(this.world, this.player, blockposition, iblockdata, tileentity, itemstack2); - } - // CraftBukkit end + if (flag) { + block.postBreak(this.world, blockposition, iblockdata); } + if (this.isCreative()) { + // return true; // CraftBukkit + } else { + ItemStack itemstack = this.player.getItemInMainHand(); + boolean flag1 = this.player.hasBlock(iblockdata); + + ItemStack itemstack1 = flag && flag1 && event.isDropItems() && !itemstack.isEmpty() ? itemstack.cloneItemStack() : ItemStack.a; // Paper - MC-136865 - clone before use + itemstack.a(this.world, iblockdata, blockposition, this.player); + if (flag && flag1 && event.isDropItems()) { // CraftBukkit - Check if block should drop items + //ItemStack itemstack1 = itemstack.isEmpty() ? ItemStack.a : itemstack.cloneItemStack(); // Paper - MC-136865 - move up + + block.a(this.world, this.player, blockposition, iblockdata, tileentity, itemstack1); + } + + // return true; // CraftBukkit + } + // CraftBukkit start if (event.isDropItems()) { org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, world.captureDrops); } world.captureDrops = null; - // CraftBukkit end - // CraftBukkit start - Drop event experience + // Drop event experience if (flag && event != null) { iblockdata.getBlock().dropExperience(this.world, blockposition, event.getExpToDrop(), this.player); // Paper } - // CraftBukkit end - return flag; + return true; + // CraftBukkit end } } } @@ -419,7 +385,7 @@ public class PlayerInteractManager { public EnumInteractionResult a(EntityHuman entityhuman, World world, ItemStack itemstack, EnumHand enumhand) { if (this.gamemode == EnumGamemode.SPECTATOR) { return EnumInteractionResult.PASS; - } else if (entityhuman.getCooldownTracker().a(itemstack.getItem())) { + } else if (entityhuman.getCooldownTracker().hasCooldown(itemstack.getItem())) { return EnumInteractionResult.PASS; } else { int i = itemstack.getCount(); @@ -456,22 +422,22 @@ public class PlayerInteractManager { // CraftBukkit start - whole method public boolean interactResult = false; public boolean firedInteract = false; - public EnumInteractionResult a(EntityHuman entityhuman, World world, ItemStack itemstack, EnumHand enumhand, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + public EnumInteractionResult a(EntityHuman entityhuman, World world, ItemStack itemstack, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) { + BlockPosition blockposition = movingobjectpositionblock.getBlockPosition(); IBlockData iblockdata = world.getType(blockposition); EnumInteractionResult enuminteractionresult = EnumInteractionResult.PASS; - if (iblockdata.isAir()) return enuminteractionresult; boolean cancelledBlock = false; if (this.gamemode == EnumGamemode.SPECTATOR) { - TileEntity tileentity = world.getTileEntity(blockposition); - cancelledBlock = !(tileentity instanceof ITileInventory || tileentity instanceof IInventory); + ITileInventory itileinventory = iblockdata.b(world, blockposition); + cancelledBlock = !(itileinventory instanceof ITileInventory); } - if (entityhuman.getCooldownTracker().a(itemstack.getItem())) { + if (entityhuman.getCooldownTracker().hasCooldown(itemstack.getItem())) { cancelledBlock = true; } - PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(entityhuman, Action.RIGHT_CLICK_BLOCK, blockposition, enumdirection, itemstack, cancelledBlock, enumhand); + PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(entityhuman, Action.RIGHT_CLICK_BLOCK, blockposition, movingobjectpositionblock.getDirection(), itemstack, cancelledBlock, enumhand); firedInteract = true; interactResult = event.useItemInHand() == Event.Result.DENY; @@ -484,9 +450,9 @@ public class PlayerInteractManager { ((EntityPlayer) entityhuman).getBukkitEntity().sendHealthUpdate(); // SPIGOT-1341 - reset health for cake // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method } else if (iblockdata.getBlock() instanceof BlockStructure) { - ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutCloseWindow()); + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutCloseWindow()); } else if (iblockdata.getBlock() instanceof BlockCommand) { - ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutCloseWindow()); + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutCloseWindow()); } else if (iblockdata.getBlock() instanceof BlockFlowerPot) { // Send a block change to air and then send back the correct block, just to make the client happy PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(this.world, blockposition); @@ -504,36 +470,24 @@ public class PlayerInteractManager { ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-2867 enuminteractionresult = (event.useItemInHand() != Event.Result.ALLOW) ? EnumInteractionResult.SUCCESS : EnumInteractionResult.PASS; } else if (this.gamemode == EnumGamemode.SPECTATOR) { - TileEntity tileentity = world.getTileEntity(blockposition); + ITileInventory itileinventory = iblockdata.b(world, blockposition); - if (tileentity instanceof ITileInventory) { - Block block = iblockdata.getBlock(); - ITileInventory itileinventory = (ITileInventory) tileentity; - - if (itileinventory instanceof TileEntityChest && block instanceof BlockChest) { - itileinventory = ((BlockChest) block).getInventory(iblockdata, world, blockposition, false); - } - - if (itileinventory != null) { - entityhuman.openContainer(itileinventory); - return EnumInteractionResult.SUCCESS; - } - } else if (tileentity instanceof IInventory) { - entityhuman.openContainer((IInventory) tileentity); + if (itileinventory != null) { + entityhuman.openContainer(itileinventory); return EnumInteractionResult.SUCCESS; + } else { + return EnumInteractionResult.PASS; } - - return EnumInteractionResult.PASS; } else { boolean flag = !entityhuman.getItemInMainHand().isEmpty() || !entityhuman.getItemInOffHand().isEmpty(); boolean flag1 = entityhuman.isSneaking() && flag; if (!flag1) { - enuminteractionresult = iblockdata.interact(world, blockposition, entityhuman, enumhand, enumdirection, f, f1, f2) ? EnumInteractionResult.SUCCESS : EnumInteractionResult.FAIL; + enuminteractionresult = iblockdata.interact(world, entityhuman, enumhand, movingobjectpositionblock) ? EnumInteractionResult.SUCCESS : EnumInteractionResult.FAIL; } if (!itemstack.isEmpty() && enuminteractionresult != EnumInteractionResult.SUCCESS && !interactResult) { // add !interactResult SPIGOT-764 - ItemActionContext itemactioncontext = new ItemActionContext(entityhuman, entityhuman.b(enumhand), blockposition, enumdirection, f, f1, f2); + ItemActionContext itemactioncontext = new ItemActionContext(entityhuman, enumhand, movingobjectpositionblock); if (this.isCreative()) { int i = itemstack.getCount(); diff --git a/src/main/java/net/minecraft/server/PlayerInventory.java b/src/main/java/net/minecraft/server/PlayerInventory.java index 988a36119..4aee712a6 100644 --- a/src/main/java/net/minecraft/server/PlayerInventory.java +++ b/src/main/java/net/minecraft/server/PlayerInventory.java @@ -4,25 +4,22 @@ import com.google.common.collect.ImmutableList; import java.util.Iterator; import java.util.List; import java.util.function.Predicate; -import javax.annotation.Nullable; // CraftBukkit start import java.util.ArrayList; -import java.util.List; import org.bukkit.Location; - import org.bukkit.craftbukkit.entity.CraftHumanEntity; import org.bukkit.entity.HumanEntity; // CraftBukkit end -public class PlayerInventory implements IInventory { +public class PlayerInventory implements IInventory, INamableTileEntity { public final NonNullList items; public final NonNullList armor; public final NonNullList extraSlots; private final List> f;List> getComponents() { return f; } // Paper - OBFHELPER public int itemInHandIndex; - public EntityHuman player; + public final EntityHuman player; private ItemStack carried; private int h; @@ -59,6 +56,11 @@ public class PlayerInventory implements IInventory { return this.player.getBukkitEntity(); } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; } @@ -79,7 +81,7 @@ public class PlayerInventory implements IInventory { } public ItemStack getItemInHand() { - return e(this.itemInHandIndex) ? (ItemStack) this.items.get(this.itemInHandIndex) : ItemStack.a; + return d(this.itemInHandIndex) ? (ItemStack) this.items.get(this.itemInHandIndex) : ItemStack.a; } public static int getHotbarSize() { @@ -106,6 +108,12 @@ public class PlayerInventory implements IInventory { } if (remains <= 0) return itemstack.getCount(); } + ItemStack offhandItemStack = this.getItem(this.items.size() + this.armor.size()); + if (this.a(offhandItemStack, itemstack)) { + remains -= (offhandItemStack.getMaxStackSize() < this.getMaxStackSize() ? offhandItemStack.getMaxStackSize() : this.getMaxStackSize()) - offhandItemStack.getCount(); + } + if (remains <= 0) return itemstack.getCount(); + return itemstack.getCount() - remains; } // CraftBukkit end @@ -120,15 +128,15 @@ public class PlayerInventory implements IInventory { return -1; } - public void d(int i) { - this.itemInHandIndex = this.l(); + public void c(int i) { + this.itemInHandIndex = this.i(); ItemStack itemstack = (ItemStack) this.items.get(this.itemInHandIndex); this.items.set(this.itemInHandIndex, this.items.get(i)); this.items.set(i, itemstack); } - public static boolean e(int i) { + public static boolean d(int i) { return i >= 0 && i < 9; } @@ -144,7 +152,7 @@ public class PlayerInventory implements IInventory { return -1; } - public int l() { + public int i() { int i; int j; @@ -268,7 +276,7 @@ public class PlayerInventory implements IInventory { } } - public void p() { + public void j() { Iterator iterator = this.f.iterator(); while (iterator.hasNext()) { @@ -365,6 +373,7 @@ public class PlayerInventory implements IInventory { } } + @Override public ItemStack splitStack(int i, int j) { List list = null; @@ -397,6 +406,7 @@ public class PlayerInventory implements IInventory { } + @Override public ItemStack splitWithoutUpdate(int i) { NonNullList nonnulllist = null; @@ -420,6 +430,7 @@ public class PlayerInventory implements IInventory { } } + @Override public void setItem(int i, ItemStack itemstack) { NonNullList nonnulllist = null; @@ -452,7 +463,7 @@ public class PlayerInventory implements IInventory { nbttagcompound = new NBTTagCompound(); nbttagcompound.setByte("Slot", (byte) i); ((ItemStack) this.items.get(i)).save(nbttagcompound); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); } } @@ -461,7 +472,7 @@ public class PlayerInventory implements IInventory { nbttagcompound = new NBTTagCompound(); nbttagcompound.setByte("Slot", (byte) (i + 100)); ((ItemStack) this.armor.get(i)).save(nbttagcompound); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); } } @@ -470,7 +481,7 @@ public class PlayerInventory implements IInventory { nbttagcompound = new NBTTagCompound(); nbttagcompound.setByte("Slot", (byte) (i + 150)); ((ItemStack) this.extraSlots.get(i)).save(nbttagcompound); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); } } @@ -500,11 +511,13 @@ public class PlayerInventory implements IInventory { } + @Override public int getSize() { return this.items.size() + this.armor.size() + this.extraSlots.size(); } - public boolean P_() { + @Override + public boolean isNotEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -540,6 +553,7 @@ public class PlayerInventory implements IInventory { return false; } + @Override public ItemStack getItem(int i) { List list = null; @@ -556,23 +570,11 @@ public class PlayerInventory implements IInventory { return list == null ? ItemStack.a : (ItemStack) list.get(i); } + @Override public IChatBaseComponent getDisplayName() { return new ChatMessage("container.inventory", new Object[0]); } - @Nullable - public IChatBaseComponent getCustomName() { - return null; - } - - public boolean hasCustomName() { - return false; - } - - public int getMaxStackSize() { - return maxStack; // CraftBukkit - } - public boolean b(IBlockData iblockdata) { return this.getItem(this.itemInHandIndex).b(iblockdata); } @@ -588,7 +590,10 @@ public class PlayerInventory implements IInventory { ItemStack itemstack = (ItemStack) this.armor.get(i); if (itemstack.getItem() instanceof ItemArmor) { - itemstack.damage((int) f, this.player); + int finalI = i; // CraftBukkit - decompile error + itemstack.damage((int) f, this.player, (entityhuman) -> { + entityhuman.c(EnumItemSlot.a(EnumItemSlot.Function.ARMOR, finalI)); // CraftBukkit - decompile error + }); } } @@ -613,6 +618,7 @@ public class PlayerInventory implements IInventory { } + @Override public void update() { ++this.h; } @@ -630,8 +636,9 @@ public class PlayerInventory implements IInventory { return this.carried; } + @Override public boolean a(EntityHuman entityhuman) { - return this.player.dead ? false : entityhuman.h(this.player) <= 64.0D; + return this.player.dead ? false : entityhuman.h((Entity) this.player) <= 64.0D; } public boolean h(ItemStack itemstack) { @@ -653,14 +660,6 @@ public class PlayerInventory implements IInventory { return false; } - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - - public boolean b(int i, ItemStack itemstack) { - return true; - } - public void a(PlayerInventory playerinventory) { for (int i = 0; i < this.getSize(); ++i) { this.setItem(i, playerinventory.getItem(i)); @@ -669,16 +668,7 @@ public class PlayerInventory implements IInventory { this.itemInHandIndex = playerinventory.itemInHandIndex; } - public int getProperty(int i) { - return 0; - } - - public void setProperty(int i, int j) {} - - public int h() { - return 0; - } - + @Override public void clear() { Iterator iterator = this.f.iterator(); diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index c98289f6d..3cb443c4f 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -5,10 +5,6 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.mojang.authlib.GameProfile; - -import io.akarin.server.core.AkarinAsyncExecutor; -import io.akarin.server.core.AkarinAsyncScheduler; -import io.akarin.server.core.AkarinGlobalConfig; import io.netty.buffer.Unpooled; import java.io.File; import java.net.SocketAddress; @@ -17,6 +13,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.UUID; import javax.annotation.Nullable; @@ -29,11 +26,9 @@ import com.google.common.collect.Iterables; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; -import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.TravelAgent; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerChangedWorldEvent; @@ -53,7 +48,7 @@ public abstract class PlayerList { public static final File b = new File("banned-ips.json"); public static final File c = new File("ops.json"); public static final File d = new File("whitelist.json"); - private static final Logger f = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final SimpleDateFormat g = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); private final MinecraftServer server; public final List players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety @@ -67,9 +62,9 @@ public abstract class PlayerList { // private final Map p; // CraftBukkit end public IPlayerFileData playerFileData; - //private boolean hasWhitelist; // Paper - moved to whitelist object so not duplicated - protected int maxPlayers; - private int s; + //private boolean hasWhitelist; + protected final int maxPlayers; + private int viewDistance; private EnumGamemode t; private boolean u; private int v; @@ -79,8 +74,8 @@ public abstract class PlayerList { private final Map playersByName = new java.util.HashMap<>(); @Nullable String collideRuleTeamName; // Paper - Team name used for collideRule - public PlayerList(MinecraftServer minecraftserver) { - this.cserver = minecraftserver.server = new CraftServer(minecraftserver, this); + public PlayerList(MinecraftServer minecraftserver, int i) { + this.cserver = minecraftserver.server = new CraftServer((DedicatedServer) minecraftserver, this); minecraftserver.console = new com.destroystokyo.paper.console.TerminalConsoleCommandSender(); // Paper // CraftBukkit end @@ -93,19 +88,21 @@ public abstract class PlayerList { // this.p = Maps.newHashMap(); // CraftBukkit end this.server = minecraftserver; + this.maxPlayers = i; this.getProfileBans().a(true); this.getIPBans().a(true); - this.maxPlayers = 8; } public void a(NetworkManager networkmanager, EntityPlayer entityplayer) { entityplayer.loginTime = System.currentTimeMillis(); // Paper GameProfile gameprofile = entityplayer.getProfile(); - AkarinUserCache usercache = this.server.getModernUserCache(); // Akarin - GameProfile gameprofile1 = usercache.peek(gameprofile.getName()); // Akarin + UserCache usercache = this.server.getUserCache(); + GameProfile gameprofile1 = usercache.a(gameprofile.getId()); String s = gameprofile1 == null ? gameprofile.getName() : gameprofile1.getName(); - usercache.offer(gameprofile); // Akarin + + usercache.a(gameprofile); NBTTagCompound nbttagcompound = this.a(entityplayer); + WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); // CraftBukkit start - Better rename detection if (nbttagcompound != null && nbttagcompound.hasKey("bukkit")) { NBTTagCompound bukkit = nbttagcompound.getCompound("bukkit"); @@ -125,10 +122,10 @@ public abstract class PlayerList { entityplayer.locZ = newLoc.getZ(); entityplayer.yaw = newLoc.getYaw(); entityplayer.pitch = newLoc.getPitch(); - entityplayer.dimension = ((CraftWorld) newLoc.getWorld()).getHandle().dimension; + entityplayer.dimension = ((CraftWorld) newLoc.getWorld()).getHandle().worldProvider.getDimensionManager(); // Paper end - entityplayer.spawnIn(this.server.getWorldServer(entityplayer.dimension)); + entityplayer.spawnIn(((CraftWorld) newLoc.getWorld()).getHandle()); entityplayer.playerInteractManager.a((WorldServer) entityplayer.world); String s1 = "local"; @@ -142,52 +139,100 @@ public abstract class PlayerList { Bukkit.getPluginManager().callEvent(ev); Location loc = ev.getSpawnLocation(); - WorldServer world = ((CraftWorld) loc.getWorld()).getHandle(); + worldserver = ((CraftWorld) loc.getWorld()).getHandle(); - entityplayer.spawnIn(world); + entityplayer.spawnIn(worldserver); entityplayer.setPosition(loc.getX(), loc.getY(), loc.getZ()); - entityplayer.setYawPitch(loc.getYaw(), loc.getPitch()); + entityplayer.setYawPitch(loc.getYaw(), loc.getPitch()); // Spigot end // CraftBukkit - Moved message to after join - // PlayerList.f.info("{}[{}] logged in with entity id {} at ({}, {}, {})", entityplayer.getDisplayName().getString(), s1, entityplayer.getId(), entityplayer.locX, entityplayer.locY, entityplayer.locZ); - WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); + // PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", entityplayer.getDisplayName().getString(), s1, entityplayer.getId(), entityplayer.locX, entityplayer.locY, entityplayer.locZ); WorldData worlddata = worldserver.getWorldData(); this.a(entityplayer, (EntityPlayer) null, worldserver); PlayerConnection playerconnection = new PlayerConnection(this.server, networkmanager, entityplayer); - playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), worlddata.isHardcore(), worldserver.worldProvider.getDimensionManager(), worldserver.getDifficulty(), this.getMaxPlayers(), worlddata.getType(), worldserver.getGameRules().getBoolean("reducedDebugInfo"))); + // CraftBukkit - getType() + // Spigot - view distance + playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), worlddata.isHardcore(), worldserver.worldProvider.getDimensionManager().getType(), this.getMaxPlayers(), worlddata.getType(), worldserver.spigotConfig.viewDistance, worldserver.getGameRules().getBoolean(GameRules.REDUCED_DEBUG_INFO))); entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit - // Akarin start - playerconnection.sendPackets( - new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.b, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName())), - new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked()), - new PacketPlayOutAbilities(entityplayer.abilities), - new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex), - new PacketPlayOutRecipeUpdate(this.server.getCraftingManager().b()), - new PacketPlayOutTags(this.server.getTagRegistry()), - new PacketPlayOutEntityStatus(entityplayer, (byte) (worldserver.getGameRules().getBoolean("reducedDebugInfo") ? 22 : 23))); // Paper - fix this rule not being initialized on the client - // Akarin end - this.f(entityplayer); + playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName()))); + playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); + playerconnection.sendPacket(new PacketPlayOutAbilities(entityplayer.abilities)); + playerconnection.sendPacket(new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex)); + playerconnection.sendPacket(new PacketPlayOutRecipeUpdate(this.server.getCraftingManager().b())); + playerconnection.sendPacket(new PacketPlayOutTags(this.server.getTagRegistry())); + playerconnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) (worldserver.getGameRules().getBoolean(GameRules.REDUCED_DEBUG_INFO) ? 22 : 23))); // Paper - fix this rule not being initialized on the client + this.d(entityplayer); entityplayer.getStatisticManager().c(); entityplayer.B().a(entityplayer); this.sendScoreboard(worldserver.getScoreboard(), entityplayer); - this.server.at(); + this.server.invalidatePingSample(); ChatMessage chatmessage; if (entityplayer.getProfile().getName().equalsIgnoreCase(s)) { - chatmessage = new ChatMessage("multiplayer.player.joined", new Object[] { entityplayer.getScoreboardDisplayName()}); + chatmessage = new ChatMessage("multiplayer.player.joined", new Object[]{entityplayer.getScoreboardDisplayName()}); } else { - chatmessage = new ChatMessage("multiplayer.player.joined.renamed", new Object[] { entityplayer.getScoreboardDisplayName(), s}); + chatmessage = new ChatMessage("multiplayer.player.joined.renamed", new Object[]{entityplayer.getScoreboardDisplayName(), s}); + } + // CraftBukkit start + chatmessage.a(EnumChatFormat.YELLOW); + String joinMessage = CraftChatMessage.fromComponent(chatmessage, EnumChatFormat.WHITE); + + playerconnection.a(entityplayer.locX, entityplayer.locY, entityplayer.locZ, entityplayer.yaw, entityplayer.pitch); + this.players.add(entityplayer); + this.playersByName.put(entityplayer.getName().toLowerCase(java.util.Locale.ROOT), entityplayer); // Spigot + this.j.put(entityplayer.getUniqueID(), entityplayer); + // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[]{entityplayer})); // CraftBukkit - replaced with loop below + + // CraftBukkit start + PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(entityplayer), joinMessage); + cserver.getPluginManager().callEvent(playerJoinEvent); + + if (!entityplayer.playerConnection.networkManager.isConnected()) { + return; } - chatmessage.a(EnumChatFormat.YELLOW); - this.onPlayerJoin(entityplayer, CraftChatMessage.fromComponent(chatmessage, EnumChatFormat.WHITE)); // Paper + joinMessage = playerJoinEvent.getJoinMessage(); + + if (joinMessage != null && joinMessage.length() > 0) { + for (IChatBaseComponent line : org.bukkit.craftbukkit.util.CraftChatMessage.fromString(joinMessage)) { + server.getPlayerList().sendAll(new PacketPlayOutChat(line)); + } + } // CraftBukkit end + + // CraftBukkit start - sendAll above replaced with this loop + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, entityplayer); + + for (int i = 0; i < this.players.size(); ++i) { + EntityPlayer entityplayer1 = (EntityPlayer) this.players.get(i); + + if (entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { + entityplayer1.playerConnection.sendPacket(packet); + } + + if (!entityplayer.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) { + continue; + } + + entityplayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[] { entityplayer1})); + } + entityplayer.sentListPacket = true; + // CraftBukkit end + + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityMetadata(entityplayer.getId(), entityplayer.datawatcher, true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn + + // CraftBukkit start - Only add if the player wasn't moved in the event + if (entityplayer.world == worldserver && !worldserver.getPlayers().contains(entityplayer)) { + worldserver.addPlayerJoin(entityplayer); + this.server.getBossBattleCustomData().a(entityplayer); + } + worldserver = server.getWorldServer(entityplayer.dimension); // CraftBukkit - Update in case join event changed it - playerconnection.a(entityplayer.locX, entityplayer.locY, entityplayer.locZ, entityplayer.yaw, entityplayer.pitch); - this.b(entityplayer, worldserver); + // CraftBukkit end + this.a(entityplayer, worldserver); if (!this.server.getResourcePack().isEmpty()) { entityplayer.setResourcePack(this.server.getResourcePack(), this.server.getResourcePackHash()); } @@ -202,7 +247,12 @@ public abstract class PlayerList { if (nbttagcompound != null && nbttagcompound.hasKeyOfType("RootVehicle", 10)) { NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); - Entity entity = ChunkRegionLoader.spawnEntity(nbttagcompound1.getCompound("Entity"), worldserver, true, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT); // Paper + // CraftBukkit start + WorldServer finalWorldServer = worldserver; + Entity entity = EntityTypes.a(nbttagcompound1.getCompound("Entity"), finalWorldServer, (entity1) -> { + return !finalWorldServer.addEntitySerialized(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; // Paper + // CraftBukkit end + }); if (entity != null) { UUID uuid = nbttagcompound1.a("Attach"); @@ -224,7 +274,7 @@ public abstract class PlayerList { } if (!entityplayer.isPassenger()) { - PlayerList.f.warn("Couldn't reattach entity to player"); + PlayerList.LOGGER.warn("Couldn't reattach entity to player"); worldserver.removeEntity(entity); iterator1 = entity.getAllPassengers().iterator(); @@ -245,7 +295,7 @@ public abstract class PlayerList { } // Paper end // CraftBukkit - Moved from above, added world - PlayerList.f.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", entityplayer.getDisplayName().getString(), s1, entityplayer.getId(), entityplayer.world.worldData.getName(), entityplayer.locX, entityplayer.locY, entityplayer.locZ); + PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", entityplayer.getDisplayName().getString(), s1, entityplayer.getId(), entityplayer.world.worldData.getName(), entityplayer.locX, entityplayer.locY, entityplayer.locZ); } public void sendScoreboard(ScoreboardServer scoreboardserver, EntityPlayer entityplayer) { @@ -279,65 +329,50 @@ public abstract class PlayerList { public void setPlayerFileData(WorldServer worldserver) { if (playerFileData != null) return; // CraftBukkit - this.playerFileData = worldserver.getDataManager().getPlayerFileData(); + this.playerFileData = worldserver.getDataManager(); worldserver.getWorldBorder().a(new IWorldBorderListener() { + @Override public void a(WorldBorder worldborder, double d0) { PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_SIZE), worldborder.world); } + @Override public void a(WorldBorder worldborder, double d0, double d1, long i) { PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.LERP_SIZE), worldborder.world); } + @Override public void a(WorldBorder worldborder, double d0, double d1) { PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_CENTER), worldborder.world); } + @Override public void a(WorldBorder worldborder, int i) { PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_WARNING_TIME), worldborder.world); } + @Override public void b(WorldBorder worldborder, int i) { PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_WARNING_BLOCKS), worldborder.world); } + @Override public void b(WorldBorder worldborder, double d0) {} + @Override public void c(WorldBorder worldborder, double d0) {} }); } - public void a(EntityPlayer entityplayer, @Nullable WorldServer worldserver) { - WorldServer worldserver1 = entityplayer.getWorldServer(); - - if (worldserver != null) { - worldserver.getPlayerChunkMap().removePlayer(entityplayer); - } - - worldserver1.getPlayerChunkMap().addPlayer(entityplayer); - worldserver1.getChunkProvider().getChunkAt((int) entityplayer.locX >> 4, (int) entityplayer.locZ >> 4, true, true); - if (worldserver != null) { - CriterionTriggers.v.a(entityplayer, worldserver.worldProvider.getDimensionManager(), worldserver1.worldProvider.getDimensionManager()); - if (worldserver.worldProvider.getDimensionManager() == DimensionManager.NETHER && entityplayer.world.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD && entityplayer.M() != null) { - CriterionTriggers.C.a(entityplayer, entityplayer.M()); - } - } - - } - - public int getFurthestViewableBlock() { - return PlayerChunkMap.getFurthestViewableBlock(this.getViewDistance()); - } - @Nullable public NBTTagCompound a(EntityPlayer entityplayer) { NBTTagCompound nbttagcompound = this.server.getWorldServer(DimensionManager.OVERWORLD).getWorldData().h(); NBTTagCompound nbttagcompound1; - if (entityplayer.getDisplayName().getString().equals(this.server.G()) && nbttagcompound != null) { + if (entityplayer.getDisplayName().getString().equals(this.server.getSinglePlayerName()) && nbttagcompound != null) { nbttagcompound1 = nbttagcompound; entityplayer.f(nbttagcompound); - PlayerList.f.debug("loading single player"); + PlayerList.LOGGER.debug("loading single player"); } else { nbttagcompound1 = this.playerFileData.load(entityplayer); } @@ -345,97 +380,21 @@ public abstract class PlayerList { return nbttagcompound1; } - // Akarin start protected void savePlayerFile(EntityPlayer entityplayer) { - savePlayerFile(entityplayer, true); - } - // Akarin end - protected void savePlayerFile(EntityPlayer entityplayer, boolean async) { if (!entityplayer.getBukkitEntity().isPersistent()) return; // CraftBukkit - entityplayer.lastSave = MinecraftServer.currentTick; // Paper - //this.playerFileData.save(entityplayer); // Akarin - moved down + this.playerFileData.save(entityplayer); ServerStatisticManager serverstatisticmanager = (ServerStatisticManager) entityplayer.getStatisticManager(); // CraftBukkit if (serverstatisticmanager != null) { - //serverstatisticmanager.a(); // Akarin - moved down + serverstatisticmanager.a(); } AdvancementDataPlayer advancementdataplayer = (AdvancementDataPlayer) entityplayer.getAdvancementData(); // CraftBukkit - Map advancements = advancementdataplayer.toSerializableMap(); // Akarin if (advancementdataplayer != null) { - //advancementdataplayer.c(); // Akarin - moved down - } - // Akarin start - AkarinAsyncExecutor.scheduleSingleAsyncTask(() -> { - this.playerFileData.save(entityplayer); - if (serverstatisticmanager != null) - serverstatisticmanager.a(); - if (advancementdataplayer != null) - advancementdataplayer.save(advancements); - }); - // Akarin end - - } - - public void onPlayerJoin(EntityPlayer entityplayer, String joinMessage) { // CraftBukkit added param - this.players.add(entityplayer); - this.playersByName.put(entityplayer.getName().toLowerCase(java.util.Locale.ROOT), entityplayer); // Spigot - this.j.put(entityplayer.getUniqueID(), entityplayer); - // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[] { entityplayer})); // CraftBukkit - replaced with loop below - WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); - - // CraftBukkit start - PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(entityplayer), joinMessage); - cserver.getPluginManager().callEvent(playerJoinEvent); - - if (!entityplayer.playerConnection.networkManager.isConnected()) { - return; + advancementdataplayer.c(); } - joinMessage = playerJoinEvent.getJoinMessage(); - - if (joinMessage != null && joinMessage.length() > 0) { - for (IChatBaseComponent line : org.bukkit.craftbukkit.util.CraftChatMessage.fromString(joinMessage)) { - server.getPlayerList().sendAll(new PacketPlayOutChat(line)); - } - } - - ChunkIOExecutor.adjustPoolSize(getPlayerCount()); - // CraftBukkit end - - // CraftBukkit start - sendAll above replaced with this loop - PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, entityplayer); - - for (int i = 0; i < this.players.size(); ++i) { - EntityPlayer entityplayer1 = (EntityPlayer) this.players.get(i); - - if (entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { - entityplayer1.playerConnection.sendPacket(packet); - } - - if (!entityplayer.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) { - continue; - } - - entityplayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[] { entityplayer1})); - } - entityplayer.sentListPacket = true; - // CraftBukkit end - - entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityMetadata(entityplayer.getId(), entityplayer.datawatcher, true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn - - // CraftBukkit start - Only add if the player wasn't moved in the event - if (entityplayer.world == worldserver && !worldserver.players.contains(entityplayer)) { - worldserver.addEntity(entityplayer); - this.a(entityplayer, (WorldServer) null); - this.server.getBossBattleCustomData().a(entityplayer); - } - // CraftBukkit end - } - - public void updateChunks(EntityPlayer entityplayer) { - entityplayer.getWorldServer().getPlayerChunkMap().movePlayer(entityplayer); } public String disconnect(EntityPlayer entityplayer) { // CraftBukkit - return string @@ -467,8 +426,8 @@ public abstract class PlayerList { if (entityplayer.isPassenger()) { Entity entity = entityplayer.getRootVehicle(); - if (entity.bR()) { - PlayerList.f.debug("Removing player mount"); + if (entity.hasSinglePlayerPassenger()) { + PlayerList.LOGGER.debug("Removing player mount"); entityplayer.stopRiding(); worldserver.removeEntity(entity); Iterator iterator = entity.getAllPassengers().iterator(); @@ -483,8 +442,8 @@ public abstract class PlayerList { } } - worldserver.kill(entityplayer); - worldserver.getPlayerChunkMap().removePlayer(entityplayer); + entityplayer.decouple(); + worldserver.removePlayer(entityplayer); entityplayer.getAdvancementData().a(); this.players.remove(entityplayer); this.playersByName.remove(entityplayer.getName().toLowerCase(java.util.Locale.ROOT)); // Spigot @@ -501,7 +460,7 @@ public abstract class PlayerList { } // CraftBukkit start - // this.sendAll(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[] { entityplayer})); + // this.sendAll(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer})); PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityplayer); for (int i = 0; i < players.size(); i++) { EntityPlayer entityplayer2 = (EntityPlayer) this.players.get(i); @@ -516,8 +475,6 @@ public abstract class PlayerList { cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); // CraftBukkit end - ChunkIOExecutor.adjustPoolSize(this.getPlayerCount()); // CraftBukkit - return playerQuitEvent.getQuitMessage(); // CraftBukkit } @@ -533,7 +490,7 @@ public abstract class PlayerList { for (int i = 0; i < this.players.size(); ++i) { entityplayer = (EntityPlayer) this.players.get(i); - if (AkarinUserCache.isOnlineMode() ? entityplayer.getUniqueID().equals(uuid) : entityplayer.getName().equalsIgnoreCase(gameprofile.getName())) { // Akarin - resolve offline servers + if (entityplayer.getUniqueID().equals(uuid)) { list.add(entityplayer); } } @@ -550,55 +507,19 @@ public abstract class PlayerList { // in the event, check with plugins to see if it's ok, and THEN kick // depending on the outcome. SocketAddress socketaddress = loginlistener.networkManager.getSocketAddress(); - // Akarin start - disallow before login event - if (AkarinGlobalConfig.disallowBeforeLogin) { - if (getProfileBans().isBanned(gameprofile) && !getProfileBans().get(gameprofile).hasExpired()) { - GameProfileBanEntry gameprofilebanentry = (GameProfileBanEntry) this.k.get(gameprofile); - - chatmessage = new ChatMessage("multiplayer.disconnect.banned.reason", new Object[] { gameprofilebanentry.getReason()}); - if (gameprofilebanentry.getExpires() != null) { - chatmessage.addSibling(new ChatMessage("multiplayer.disconnect.banned.expiration", new Object[] { PlayerList.g.format(gameprofilebanentry.getExpires())})); - } - - // return chatmessage; - if (!gameprofilebanentry.hasExpired()) CraftChatMessage.fromComponent(chatmessage); - return null; - } else if (!this.isWhitelisted(gameprofile)) { - //chatmessage = new ChatMessage("multiplayer.disconnect.not_whitelisted", new Object[0]); - //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot // Paper - moved to isWhitelisted - loginlistener.disconnect(org.spigotmc.SpigotConfig.whitelistMessage); - } else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) { - IpBanEntry ipbanentry = this.l.get(socketaddress); - - chatmessage = new ChatMessage("multiplayer.disconnect.banned_ip.reason", new Object[] { ipbanentry.getReason()}); - if (ipbanentry.getExpires() != null) { - chatmessage.addSibling(new ChatMessage("multiplayer.disconnect.banned_ip.expiration", new Object[] { PlayerList.g.format(ipbanentry.getExpires())})); - } - - // return chatmessage; - loginlistener.disconnect(chatmessage); - return null; - } else { - // return this.players.size() >= this.maxPlayers && !this.f(gameprofile) ? new ChatMessage("multiplayer.disconnect.server_full", new Object[0]) : null; - if (this.players.size() >= this.maxPlayers && !this.f(gameprofile)) { - loginlistener.disconnect(org.spigotmc.SpigotConfig.serverFullMessage); - return null; - } - } - } - // Akarin end EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(DimensionManager.OVERWORLD), gameprofile, new PlayerInteractManager(this.server.getWorldServer(DimensionManager.OVERWORLD))); Player player = entity.getBukkitEntity(); PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.networkManager.getRawAddress()).getAddress()); - if (!AkarinGlobalConfig.disallowBeforeLogin) {// Akarin - disallow before login event - if (getProfileBans().isBanned(gameprofile) && !getProfileBans().get(gameprofile).hasExpired()) { - GameProfileBanEntry gameprofilebanentry = (GameProfileBanEntry) this.k.get(gameprofile); + // Paper start - Fix MC-158900 + GameProfileBanEntry gameprofilebanentry; + if (getProfileBans().isBanned(gameprofile) && (gameprofilebanentry = getProfileBans().get(gameprofile)) != null) { + // Paper end - chatmessage = new ChatMessage("multiplayer.disconnect.banned.reason", new Object[] { gameprofilebanentry.getReason()}); + chatmessage = new ChatMessage("multiplayer.disconnect.banned.reason", new Object[]{gameprofilebanentry.getReason()}); if (gameprofilebanentry.getExpires() != null) { - chatmessage.addSibling(new ChatMessage("multiplayer.disconnect.banned.expiration", new Object[] { PlayerList.g.format(gameprofilebanentry.getExpires())})); + chatmessage.addSibling(new ChatMessage("multiplayer.disconnect.banned.expiration", new Object[]{PlayerList.g.format(gameprofilebanentry.getExpires())})); } // return chatmessage; @@ -609,9 +530,9 @@ public abstract class PlayerList { } else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) { IpBanEntry ipbanentry = this.l.get(socketaddress); - chatmessage = new ChatMessage("multiplayer.disconnect.banned_ip.reason", new Object[] { ipbanentry.getReason()}); + chatmessage = new ChatMessage("multiplayer.disconnect.banned_ip.reason", new Object[]{ipbanentry.getReason()}); if (ipbanentry.getExpires() != null) { - chatmessage.addSibling(new ChatMessage("multiplayer.disconnect.banned_ip.expiration", new Object[] { PlayerList.g.format(ipbanentry.getExpires())})); + chatmessage.addSibling(new ChatMessage("multiplayer.disconnect.banned_ip.expiration", new Object[]{PlayerList.g.format(ipbanentry.getExpires())})); } // return chatmessage; @@ -622,7 +543,6 @@ public abstract class PlayerList { event.disallow(PlayerLoginEvent.Result.KICK_FULL, org.spigotmc.SpigotConfig.serverFullMessage); // Spigot } } - } // Akarin - disallow before login event cserver.getPluginManager().callEvent(event); if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { @@ -661,7 +581,7 @@ public abstract class PlayerList { Object object; - if (this.server.L()) { + if (this.server.isDemoMode()) { object = new DemoPlayerInteractManager(this.server.getWorldServer(DimensionManager.OVERWORLD)); } else { object = new PlayerInteractManager(this.server.getWorldServer(DimensionManager.OVERWORLD)); @@ -680,12 +600,9 @@ public abstract class PlayerList { public EntityPlayer moveToWorld(EntityPlayer entityplayer, DimensionManager dimensionmanager, boolean flag, Location location, boolean avoidSuffocation) { entityplayer.stopRiding(); // CraftBukkit - entityplayer.getWorldServer().getTracker().untrackPlayer(entityplayer); - // entityplayer.getWorldServer().getTracker().untrackEntity(entityplayer); // CraftBukkit - entityplayer.getWorldServer().getPlayerChunkMap().removePlayer(entityplayer); this.players.remove(entityplayer); this.playersByName.remove(entityplayer.getName().toLowerCase(java.util.Locale.ROOT)); // Spigot - this.server.getWorldServer(entityplayer.dimension).removeEntity(entityplayer); + entityplayer.getWorldServer().removePlayer(entityplayer); BlockPosition blockposition = entityplayer.getBed(); boolean flag1 = entityplayer.isRespawnForced(); @@ -693,7 +610,7 @@ public abstract class PlayerList { entityplayer.dimension = dimensionmanager; Object object; - if (this.server.L()) { + if (this.server.isDemoMode()) { object = new DemoPlayerInteractManager(this.server.getWorldServer(entityplayer.dimension)); } else { object = new PlayerInteractManager(this.server.getWorldServer(entityplayer.dimension)); @@ -710,7 +627,6 @@ public abstract class PlayerList { entityplayer1.copyFrom(entityplayer, flag); entityplayer1.e(entityplayer.getId()); entityplayer1.a(entityplayer.getMainHand()); - synchronized (entityplayer.getScoreboardTags()) { // Akarin Iterator iterator = entityplayer.getScoreboardTags().iterator(); while (iterator.hasNext()) { @@ -718,12 +634,10 @@ public abstract class PlayerList { entityplayer1.addScoreboardTag(s); } - } // Akarin // WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); // CraftBukkit - handled later // this.a(entityplayer1, entityplayer, worldserver); // CraftBukkit - removed - BlockPosition blockposition1; // Paper start boolean isBedSpawn = false; @@ -735,10 +649,13 @@ public abstract class PlayerList { //boolean isBedSpawn = false; Paper - moved up CraftWorld cworld = (CraftWorld) this.server.server.getWorld(entityplayer.spawnWorld); if (cworld != null && blockposition != null) { - blockposition1 = EntityHuman.getBed(cworld.getHandle(), blockposition, flag1); - if (blockposition1 != null) { + Optional optional = EntityHuman.getBed(cworld.getHandle(), blockposition, flag1); + + if (optional.isPresent()) { + Vec3D vec3d = (Vec3D) optional.get(); + isBedSpawn = true; - location = new Location(cworld, (double) ((float) blockposition1.getX() + 0.5F), (double) ((float) blockposition1.getY() + 0.1F), (double) ((float) blockposition1.getZ() + 0.5F)); + location = new Location(cworld, vec3d.x, vec3d.y, vec3d.z); } else { entityplayer1.setRespawnPosition(null, true); entityplayer1.playerConnection.sendPacket(new PacketPlayOutGameStateChange(0, 0.0F)); @@ -761,7 +678,7 @@ public abstract class PlayerList { // Spigot End location = respawnEvent.getRespawnLocation(); - entityplayer.reset(); + if (!flag) entityplayer.reset(); // SPIGOT-4785 isRespawn = true; // Paper } else { location.setWorld(server.getWorldServer(dimensionmanager).getWorld()); @@ -770,30 +687,33 @@ public abstract class PlayerList { entityplayer1.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); // CraftBukkit end - worldserver.getChunkProvider().getChunkAt((int) entityplayer1.locX >> 4, (int) entityplayer1.locZ >> 4, true, true); - - while (avoidSuffocation && !worldserver.getCubes(entityplayer1, entityplayer1.getBoundingBox()) && entityplayer1.locY < 256.0D) { + while (avoidSuffocation && !worldserver.getCubes(entityplayer1) && entityplayer1.locY < 256.0D) { entityplayer1.setPosition(entityplayer1.locX, entityplayer1.locY + 1.0D, entityplayer1.locZ); } // CraftBukkit start // Force the client to refresh their chunk cache if (fromWorld.getEnvironment() == worldserver.getWorld().getEnvironment()) { - entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver.worldProvider.getDimensionManager().getDimensionID() >= 0 ? DimensionManager.NETHER : DimensionManager.OVERWORLD, worldserver.getDifficulty(), worldserver.getWorldData().getType(), entityplayer.playerInteractManager.getGameMode())); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver.worldProvider.getDimensionManager().getDimensionID() >= 0 ? DimensionManager.NETHER : DimensionManager.OVERWORLD, worldserver.getWorldData().getType(), entityplayer.playerInteractManager.getGameMode())); } - entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver.worldProvider.getDimensionManager(), worldserver.getDifficulty(), worldserver.getWorldData().getType(), entityplayer1.playerInteractManager.getGameMode())); + WorldData worlddata = worldserver.getWorldData(); + + entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver.worldProvider.getDimensionManager().getType(), worldserver.getWorldData().getType(), entityplayer1.playerInteractManager.getGameMode())); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver.spigotConfig.viewDistance)); // Spigot entityplayer1.spawnIn(worldserver); entityplayer1.dead = false; entityplayer1.playerConnection.teleport(new Location(worldserver.getWorld(), entityplayer1.locX, entityplayer1.locY, entityplayer1.locZ, entityplayer1.yaw, entityplayer1.pitch)); entityplayer1.setSneaking(false); - blockposition1 = worldserver.getSpawn(); + BlockPosition blockposition1 = worldserver.getSpawn(); + // entityplayer1.playerConnection.a(entityplayer1.locX, entityplayer1.locY, entityplayer1.locZ, entityplayer1.yaw, entityplayer1.pitch); - entityplayer1.playerConnection.sendPackets(new PacketPlayOutSpawnPosition(blockposition1), new PacketPlayOutExperience(entityplayer1.exp, entityplayer1.expTotal, entityplayer1.expLevel)); // Akarin - this.b(entityplayer1, worldserver); - this.f(entityplayer1); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutSpawnPosition(blockposition1)); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutExperience(entityplayer1.exp, entityplayer1.expTotal, entityplayer1.expLevel)); + this.a(entityplayer1, worldserver); + this.d(entityplayer1); if (!entityplayer.playerConnection.isDisconnected()) { - worldserver.getPlayerChunkMap().addPlayer(entityplayer1); - worldserver.addEntity(entityplayer1); + worldserver.addPlayerRespawn(entityplayer1); this.players.add(entityplayer1); this.playersByName.put(entityplayer1.getName().toLowerCase(java.util.Locale.ROOT), entityplayer1); // Spigot this.j.put(entityplayer1.getUniqueID(), entityplayer1); @@ -809,10 +729,7 @@ public abstract class PlayerList { } // Fire advancement trigger - CriterionTriggers.v.a(entityplayer, ((CraftWorld) fromWorld).getHandle().worldProvider.getDimensionManager(), worldserver.worldProvider.getDimensionManager()); - if (((CraftWorld) fromWorld).getHandle().worldProvider.getDimensionManager() == DimensionManager.NETHER && worldserver.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD && entityplayer.M() != null) { - CriterionTriggers.C.a(entityplayer, entityplayer.M()); - } + entityplayer.b(((CraftWorld) fromWorld).getHandle()); // Don't fire on respawn if (fromWorld != location.getWorld()) { @@ -835,268 +752,13 @@ public abstract class PlayerList { return entityplayer1; } - // CraftBukkit start - Replaced the standard handling of portals with a more customised method. - public void changeDimension(EntityPlayer entityplayer, DimensionManager dimensionManager, TeleportCause cause) { - WorldServer exitWorld = null; - if (entityplayer.dimension.getDimensionID() < CraftWorld.CUSTOM_DIMENSION_OFFSET) { // plugins must specify exit from custom Bukkit worlds - exitWorld = server.getWorldServer(dimensionManager); - } - - Location enter = entityplayer.getBukkitEntity().getLocation(); - Location exit = null; - boolean useTravelAgent = false; // don't use agent for custom worlds or return from THE_END - if (exitWorld != null) { - if ((cause == TeleportCause.END_PORTAL) && (dimensionManager == DimensionManager.OVERWORLD)) { - // THE_END -> NORMAL; use bed if available, otherwise default spawn - exit = ((org.bukkit.craftbukkit.entity.CraftPlayer) entityplayer.getBukkitEntity()).getBedSpawnLocation(); - if (exit == null || ((CraftWorld) exit.getWorld()).getHandle().dimension != DimensionManager.OVERWORLD) { - BlockPosition randomSpawn = entityplayer.getSpawnPoint(exitWorld); - exit = new Location(exitWorld.getWorld(), randomSpawn.getX(), randomSpawn.getY(), randomSpawn.getZ()); - } else { - exit = exit.add(0.5F, 0.1F, 0.5F); // SPIGOT-3879 - } - } else { - // NORMAL <-> NETHER or NORMAL -> THE_END - exit = this.calculateTarget(enter, exitWorld); - useTravelAgent = true; - } - } - - TravelAgent agent = exit != null ? (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().getTravelAgent() : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins - PlayerPortalEvent event = new PlayerPortalEvent(entityplayer.getBukkitEntity(), enter, exit, agent, cause); - event.useTravelAgent(useTravelAgent); - Bukkit.getServer().getPluginManager().callEvent(event); - if (event.isCancelled() || event.getTo() == null) { - return; - } - - exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo(); - if (exit == null) { - return; - } - exitWorld = ((CraftWorld) exit.getWorld()).getHandle(); - - org.bukkit.event.player.PlayerTeleportEvent tpEvent = new org.bukkit.event.player.PlayerTeleportEvent(entityplayer.getBukkitEntity(), enter, exit, cause); - Bukkit.getServer().getPluginManager().callEvent(tpEvent); - if (tpEvent.isCancelled() || tpEvent.getTo() == null) { - return; - } - - Vector velocity = entityplayer.getBukkitEntity().getVelocity(); - exitWorld.getTravelAgent().adjustExit(entityplayer, exit, velocity); - - entityplayer.worldChangeInvuln = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds - this.moveToWorld(entityplayer, exitWorld.dimension, true, exit, false); // Vanilla doesn't check for suffocation when handling portals, so neither should we - if (entityplayer.motX != velocity.getX() || entityplayer.motY != velocity.getY() || entityplayer.motZ != velocity.getZ()) { - entityplayer.getBukkitEntity().setVelocity(velocity); - } - } - - public void f(EntityPlayer entityplayer) { + public void d(EntityPlayer entityplayer) { GameProfile gameprofile = entityplayer.getProfile(); int i = this.server.a(gameprofile); this.a(entityplayer, i); } - public void a(EntityPlayer entityplayer, DimensionManager dimensionmanager) { - DimensionManager dimensionmanager1 = entityplayer.dimension; - WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); - - entityplayer.dimension = dimensionmanager; - WorldServer worldserver1 = this.server.getWorldServer(entityplayer.dimension); - - entityplayer.playerConnection.sendPacket(new PacketPlayOutRespawn(entityplayer.dimension, entityplayer.world.getDifficulty(), entityplayer.world.getWorldData().getType(), entityplayer.playerInteractManager.getGameMode())); - this.f(entityplayer); - worldserver.removeEntity(entityplayer); - entityplayer.dead = false; - this.changeWorld(entityplayer, dimensionmanager1, worldserver, worldserver1); - this.a(entityplayer, worldserver); - entityplayer.playerConnection.a(entityplayer.locX, entityplayer.locY, entityplayer.locZ, entityplayer.yaw, entityplayer.pitch); - entityplayer.playerInteractManager.a(worldserver1); - entityplayer.playerConnection.sendPacket(new PacketPlayOutAbilities(entityplayer.abilities)); - this.b(entityplayer, worldserver1); - this.updateClient(entityplayer); - Iterator iterator = entityplayer.getEffects().iterator(); - - while (iterator.hasNext()) { - MobEffect mobeffect = (MobEffect) iterator.next(); - - entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(entityplayer.getId(), mobeffect)); - } - - } - - public void changeWorld(Entity entity, DimensionManager dimensionmanager, WorldServer worldserver, WorldServer worldserver1) { - // CraftBukkit start - Split into modular functions - Location exit = calculateTarget(entity.getBukkitEntity().getLocation(), worldserver1); - repositionEntity(entity, exit, true); - } - - // Copy of original changeWorld(Entity, int, WorldServer, WorldServer) method with only location calculation logic - public Location calculateTarget(Location enter, World target) { - WorldServer worldserver = ((CraftWorld) enter.getWorld()).getHandle(); - WorldServer worldserver1 = ((CraftWorld) target.getWorld()).getHandle(); - DimensionManager dimensionmanager = worldserver.dimension; - - double y = enter.getY(); - float yaw = enter.getYaw(); - float pitch = enter.getPitch(); - double d0 = enter.getX(); - double d1 = enter.getZ(); - double d2 = 8.0D; - /* - double d0 = entity.locX; - double d1 = entity.locZ; - double d2 = 8.0D; - float f = entity.yaw; - */ - - //worldserver.methodProfiler.enter("moving"); // Akarin - if (worldserver1.dimension == DimensionManager.NETHER) { - d0 = MathHelper.a(d0 / 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); - d1 = MathHelper.a(d1 / 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); - /* - entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); - if (entity.isAlive()) { - worldserver.entityJoinedWorld(entity, false); - } - */ - } else if (worldserver1.dimension == DimensionManager.OVERWORLD) { - d0 = MathHelper.a(d0 * 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); - d1 = MathHelper.a(d1 * 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); - /* - entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); - if (entity.isAlive()) { - worldserver.entityJoinedWorld(entity, false); - } - */ - } else { - BlockPosition blockposition; - - if (dimensionmanager == DimensionManager.THE_END) { - // use default NORMAL world spawn instead of target - worldserver1 = this.server.getWorldServer(DimensionManager.OVERWORLD); - blockposition = worldserver1.getSpawn(); - } else { - blockposition = worldserver1.getDimensionSpawn(); - } - - d0 = (double) blockposition.getX(); - y = (double) blockposition.getY(); - d1 = (double) blockposition.getZ(); - /* - entity.setPositionRotation(d0, entity.locY, d1, 90.0F, 0.0F); - if (entity.isAlive()) { - worldserver.entityJoinedWorld(entity, false); - } - */ - } - - //worldserver.methodProfiler.exit(); // Akarin - remove caller - if (dimensionmanager != DimensionManager.THE_END) { - //worldserver.methodProfiler.enter("placing"); // Akarin - d0 = (double) MathHelper.clamp((int) d0, -29999872, 29999872); - d1 = (double) MathHelper.clamp((int) d1, -29999872, 29999872); - /* - if (entity.isAlive()) { - entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); - worldserver1.getTravelAgent().a(entity, f); - worldserver1.addEntity(entity); - worldserver1.entityJoinedWorld(entity, false); - } - */ - - //worldserver.methodProfiler.exit(); // Akarin - remove caller - } - - // entity.spawnIn(worldserver1); - return new Location(worldserver1.getWorld(), d0, y, d1, yaw, pitch); - } - - // copy of original a(Entity, int, WorldServer, WorldServer) method with only entity repositioning logic - public void repositionEntity(Entity entity, Location exit, boolean portal) { - WorldServer worldserver = (WorldServer) entity.world; - WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); - DimensionManager dimensionmanager = worldserver.dimension; - - /* - double d0 = entity.locX; - double d1 = entity.locZ; - double d2 = 8.0D; - float f = entity.yaw; - */ - - //worldserver.methodProfiler.enter("moving"); // Akarin - entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); - if (entity.isAlive()) { - worldserver.entityJoinedWorld(entity, false); - } - /* - if (entity.dimension == DimensionManager.NETHER) { - d0 = MathHelper.a(d0 / 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); - d1 = MathHelper.a(d1 / 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); - entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); - if (entity.isAlive()) { - worldserver.entityJoinedWorld(entity, false); - } - } else if (entity.dimension == DimensionManager.OVERWORLD) { - d0 = MathHelper.a(d0 * 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); - d1 = MathHelper.a(d1 * 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); - entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); - if (entity.isAlive()) { - worldserver.entityJoinedWorld(entity, false); - } - } else { - BlockPosition blockposition; - - if (dimensionmanager == DimensionManager.THE_END) { - // use default NORMAL world spawn instead of target - worldserver1 = this.server.worlds.get(0); - blockposition = worldserver1.getSpawn(); - } else { - blockposition = worldserver1.getDimensionSpawn(); - } - - d0 = (double) blockposition.getX(); - entity.locY = (double) blockposition.getY(); - d1 = (double) blockposition.getZ(); - entity.setPositionRotation(d0, entity.locY, d1, 90.0F, 0.0F); - if (entity.isAlive()) { - worldserver.entityJoinedWorld(entity, false); - } - } - */ - - //worldserver.methodProfiler.exit(); // Akarin - remove caller - if (dimensionmanager != DimensionManager.THE_END) { - //worldserver.methodProfiler.enter("placing"); // Akarin - /* - d0 = (double) MathHelper.clamp((int) d0, -29999872, 29999872); - d1 = (double) MathHelper.clamp((int) d1, -29999872, 29999872); - */ - if (entity.isAlive()) { - // entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); - // worldserver1.getTravelAgent().a(entity, f); - if (portal) { - Vector velocity = entity.getBukkitEntity().getVelocity(); - worldserver1.getTravelAgent().adjustExit(entity, exit, velocity); - entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); - if (entity.motX != velocity.getX() || entity.motY != velocity.getY() || entity.motZ != velocity.getZ()) { - entity.getBukkitEntity().setVelocity(velocity); - } - } - // worldserver1.addEntity(entity); - worldserver1.entityJoinedWorld(entity, false); - } - - //worldserver.methodProfiler.exit(); // Akarin - remove caller - } - - entity.spawnIn(worldserver1); - // CraftBukkit end - } - public void tick() { if (++this.v > 600) { // CraftBukkit start @@ -1117,15 +779,14 @@ public abstract class PlayerList { } public void sendAll(Packet packet) { - for (EntityHuman player : this.players) { // Akarin - iterate safety - ((EntityPlayer) player).playerConnection.sendPacket(packet); // Akarin + for (int i = 0; i < this.players.size(); ++i) { + ((EntityPlayer) this.players.get(i)).playerConnection.sendPacket(packet); } } // CraftBukkit start - add a world/entity limited version public void sendAll(Packet packet, EntityHuman entityhuman) { - AkarinAsyncExecutor.scheduleAsyncTask(() -> { // Akarin for (int i = 0; i < this.players.size(); ++i) { EntityPlayer entityplayer = this.players.get(i); if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { @@ -1133,15 +794,12 @@ public abstract class PlayerList { } ((EntityPlayer) this.players.get(i)).playerConnection.sendPacket(packet); } - }); // Akarin } public void sendAll(Packet packet, World world) { - AkarinAsyncExecutor.scheduleAsyncTask(() -> { // Akarin - for (EntityHuman player : world.players) { // Akarin - iterate safety - ((EntityPlayer) player).playerConnection.sendPacket(packet); // Akarin + for (int i = 0; i < world.getPlayers().size(); ++i) { + ((EntityPlayer) world.getPlayers().get(i)).playerConnection.sendPacket(packet); } - }); // Akarin } // CraftBukkit end @@ -1193,7 +851,7 @@ public abstract class PlayerList { } } - public String[] f() { + public String[] e() { String[] astring = new String[this.players.size()]; for (int i = 0; i < this.players.size(); ++i) { @@ -1216,7 +874,7 @@ public abstract class PlayerList { EntityPlayer entityplayer = this.a(gameprofile.getId()); if (entityplayer != null) { - this.f(entityplayer); + this.d(entityplayer); } } @@ -1226,7 +884,7 @@ public abstract class PlayerList { EntityPlayer entityplayer = this.a(gameprofile.getId()); if (entityplayer != null) { - this.f(entityplayer); + this.d(entityplayer); } } @@ -1271,7 +929,7 @@ public abstract class PlayerList { // Paper end public boolean isOp(GameProfile gameprofile) { - return this.operators.d(gameprofile) || this.server.H() && this.server.getWorldServer(DimensionManager.OVERWORLD).getWorldData().u() && this.server.G().equalsIgnoreCase(gameprofile.getName()) || this.u; + return this.operators.d(gameprofile) || this.server.b(gameprofile) && this.server.getWorldServer(DimensionManager.OVERWORLD).getWorldData().t() || this.u; } @Nullable @@ -1285,7 +943,7 @@ public abstract class PlayerList { } public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, WorldServer world, Packet packet) { - sendPacketNearby(entityhuman, d0, d1, d2, d3, world.dimension, world, packet); + sendPacketNearby(entityhuman, d0, d1, d2, d3, world.worldProvider.getDimensionManager(), world, packet); } public void sendPacketNearby(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, double d3, DimensionManager dimensionmanager, @Nullable WorldServer world, Packet packet) { @@ -1294,8 +952,8 @@ public abstract class PlayerList { } List players1 = world == null ? players : world.players; - for (EntityHuman entity : players1) { // Akarin - iterate safety - //EntityHuman entity = players1.get(j); // Akarin + for (int j = 0; j < players1.size(); ++j) { + EntityHuman entity = players1.get(j); if (!(entity instanceof EntityPlayer)) continue; EntityPlayer entityplayer = (EntityPlayer) entity; // Paper end @@ -1319,27 +977,15 @@ public abstract class PlayerList { } - // Paper start public void savePlayers() { - savePlayers(null); - } - - public void savePlayers(Integer interval) { - //MCUtil.ensureMain("Save Players", () -> { // Paper - ensure main // Akarin - long now = MinecraftServer.currentTick; - //MinecraftTimings.savePlayers.startTiming(); // Paper // Akarin - int numSaved = 0; // Paper + MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main + MinecraftTimings.savePlayers.startTiming(); // Paper for (int i = 0; i < this.players.size(); ++i) { - EntityPlayer entityplayer = this.players.get(i); - if (interval == null || now - entityplayer.lastSave >= interval) { - this.savePlayerFile(entityplayer, false); - if (interval != null && ++numSaved <= com.destroystokyo.paper.PaperConfig.maxPlayerAutoSavePerTick) { break; } // Paper - } + this.savePlayerFile((EntityPlayer) this.players.get(i)); } - //MinecraftTimings.savePlayers.stopTiming(); // Paper // Akarin - //return null; }); // Paper - ensure main // Akarin + MinecraftTimings.savePlayers.stopTiming(); // Paper + return null; }); // Paper - ensure main } - // Paper end public WhiteList getWhitelist() { return this.whitelist; @@ -1353,29 +999,27 @@ public abstract class PlayerList { return this.operators; } - public String[] n() { + public String[] m() { return this.operators.getEntries(); } public void reloadWhitelist() {} - public void b(EntityPlayer entityplayer, WorldServer worldserver) { + public void a(EntityPlayer entityplayer, WorldServer worldserver) { WorldBorder worldborder = entityplayer.world.getWorldBorder(); // CraftBukkit - // Akarin start + entityplayer.playerConnection.sendPacket(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.INITIALIZE)); + entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean(GameRules.DO_DAYLIGHT_CYCLE))); BlockPosition blockposition = worldserver.getSpawn(); - entityplayer.playerConnection.sendPackets( - new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.INITIALIZE), - new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), - new PacketPlayOutSpawnPosition(blockposition)); - // Akarin end + + entityplayer.playerConnection.sendPacket(new PacketPlayOutSpawnPosition(blockposition)); if (worldserver.isRaining()) { // CraftBukkit start - handle player weather // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(1, 0.0F)); - // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, worldserver.i(1.0F))); - // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, worldserver.g(1.0F))); + // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, worldserver.h(1.0F))); + // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, worldserver.f(1.0F))); entityplayer.setPlayerWeather(org.bukkit.WeatherType.DOWNFALL, false); - entityplayer.updateWeather(-worldserver.o, worldserver.o, -worldserver.q, worldserver.q); + entityplayer.updateWeather(-worldserver.rainLevel, worldserver.rainLevel, -worldserver.thunderLevel, worldserver.thunderLevel); // CraftBukkit end } @@ -1385,12 +1029,11 @@ public abstract class PlayerList { entityplayer.updateInventory(entityplayer.defaultContainer); // entityplayer.triggerHealthUpdate(); entityplayer.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange - // Akarin start - int i = entityplayer.world.getGameRules().get("reducedDebugInfo").b() ? 22 : 23; - entityplayer.playerConnection.sendPackets( - new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex), - new PacketPlayOutEntityStatus(entityplayer, (byte) i)); - // Akarin end + entityplayer.playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex)); + // CraftBukkit start - from GameRules + int i = entityplayer.world.getGameRules().getBoolean(GameRules.REDUCED_DEBUG_INFO) ? 22 : 23; + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) i)); + // CraftBukkit end } public int getPlayerCount() { @@ -1401,10 +1044,6 @@ public abstract class PlayerList { return this.maxPlayers; } - public String[] getSeenPlayers() { - return this.server.getWorldServer(DimensionManager.OVERWORLD).getDataManager().getPlayerFileData().getSeenPlayers(); - } - public boolean getHasWhitelist() { return this.whitelist.isEnabled(); // Paper } @@ -1430,14 +1069,14 @@ public abstract class PlayerList { } public int getViewDistance() { - return this.s; + return this.viewDistance; } public MinecraftServer getServer() { return this.server; } - public NBTTagCompound t() { + public NBTTagCompound r() { return null; } @@ -1452,11 +1091,11 @@ public abstract class PlayerList { } // Paper start - Extract method to allow for restarting flag - public void u() { - u(false); + public void shutdown() { + this.shutdown(false); } - public void u(boolean isRestarting) { + public void shutdown(boolean isRestarting) { // CraftBukkit start - disconnect safely for (EntityPlayer player : this.players) { player.playerConnection.disconnect(!isRestarting ? this.server.server.getShutdownMessage() : org.spigotmc.SpigotConfig.restartMessage); // CraftBukkit - add custom shutdown message // Paper - add isRestarting flag @@ -1517,7 +1156,7 @@ public abstract class PlayerList { return serverstatisticmanager; } - public AdvancementDataPlayer h(EntityPlayer entityplayer) { + public AdvancementDataPlayer f(EntityPlayer entityplayer) { UUID uuid = entityplayer.getUniqueID(); AdvancementDataPlayer advancementdataplayer = (AdvancementDataPlayer) entityplayer.getAdvancementData(); // CraftBukkit @@ -1534,21 +1173,21 @@ public abstract class PlayerList { } public void a(int i) { - this.s = i; + this.viewDistance = i; + this.sendAll(new PacketPlayOutViewDistance(i)); Iterator iterator = this.server.getWorlds().iterator(); while (iterator.hasNext()) { WorldServer worldserver = (WorldServer) iterator.next(); if (worldserver != null) { - worldserver.getPlayerChunkMap().a(i); - worldserver.getTracker().a(i); + worldserver.getChunkProvider().setViewDistance(i); } } } - public List v() { + public List getPlayers() { return this.players; } @@ -1590,7 +1229,7 @@ public abstract class PlayerList { } - public boolean x() { + public boolean v() { return this.u; } } diff --git a/src/main/java/net/minecraft/server/PortalTravelAgent.java b/src/main/java/net/minecraft/server/PortalTravelAgent.java index 40bd8dd88..2f0a8e4bb 100644 --- a/src/main/java/net/minecraft/server/PortalTravelAgent.java +++ b/src/main/java/net/minecraft/server/PortalTravelAgent.java @@ -1,312 +1,137 @@ package net.minecraft.server; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectIterator; +import com.google.common.collect.Maps; +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.objects.Object2LongMap; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; +import java.util.Iterator; +import java.util.Map; import java.util.Random; -// CraftBukkit start -import org.bukkit.Location; -import org.bukkit.event.entity.EntityPortalExitEvent; -import org.bukkit.util.Vector; -// CraftBukkit end +import java.util.Map.Entry; +import javax.annotation.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.util.Supplier; public class PortalTravelAgent { - private static final BlockPortal a = (BlockPortal) Blocks.NETHER_PORTAL; - public final WorldServer world; // Paper - private -> public - private final Random c; - private final Long2ObjectMap d = new Long2ObjectOpenHashMap(4096); + private static final Logger LOGGER = LogManager.getLogger(); + private static final BlockPortal b = (BlockPortal) Blocks.NETHER_PORTAL; + private final WorldServer world; + private final Random d; + private final Map e = Maps.newHashMapWithExpectedSize(4096); + private final Object2LongMap f = new Object2LongOpenHashMap(); public PortalTravelAgent(WorldServer worldserver) { this.world = worldserver; - this.c = new Random(worldserver.getSeed()); + this.d = new Random(worldserver.getSeed()); } - public void a(Entity entity, float f) { - if (this.world.worldProvider.getDimensionManager() != DimensionManager.THE_END) { - if (!this.b(entity, f)) { - this.a(entity); - this.b(entity, f); - } - } else { - int i = MathHelper.floor(entity.locX); - int j = MathHelper.floor(entity.locY) - 1; - int k = MathHelper.floor(entity.locZ); - // CraftBukkit start - Modularize end portal creation - BlockPosition created = this.createEndPortal(entity.locX, entity.locY, entity.locZ); - entity.setPositionRotation((double) created.getX(), (double) created.getY(), (double) created.getZ(), entity.yaw, 0.0F); - entity.motX = entity.motY = entity.motZ = 0.0D; - } - } + public boolean a(Entity entity, float f) { + Vec3D vec3d = entity.getPortalOffset(); + EnumDirection enumdirection = entity.getPortalDirection(); + ShapeDetector.Shape shapedetector_shape = this.a(new BlockPosition(entity), entity.getMot(), enumdirection, vec3d.x, vec3d.y, entity instanceof EntityHuman); - // Split out from original a(Entity, double, double, double, float) method in order to enable being called from createPortal - private BlockPosition createEndPortal(double x, double y, double z) { - int i = MathHelper.floor(x); - int j = MathHelper.floor(y) - 1; - int k = MathHelper.floor(z); - // CraftBukkit end - byte b0 = 1; - byte b1 = 0; - - java.util.Collection bukkitBlocks = new java.util.HashSet<>(); // Paper - java.util.Map nmsBlocks = new java.util.LinkedHashMap<>(); // Paper - - for (int l = -2; l <= 2; ++l) { - for (int i1 = -2; i1 <= 2; ++i1) { - for (int j1 = -1; j1 < 3; ++j1) { - int k1 = i + i1 * 1 + l * 0; - int l1 = j + j1; - int i2 = k + i1 * 0 - l * 1; - boolean flag2 = j1 < 0; - - // Paper start - BlockPosition pos = new BlockPosition(k1, l1, i2); - nmsBlocks.put(pos, flag2 ? Blocks.OBSIDIAN.getBlockData() : Blocks.AIR.getBlockData()); - bukkitBlocks.add(this.world.getWorld().getBlockAt(pos)); // Akarin - // Paper end - } - } - } - - // Paper start - org.bukkit.event.world.PortalCreateEvent event = new org.bukkit.event.world.PortalCreateEvent(bukkitBlocks, this.world.getWorld(), org.bukkit.event.world.PortalCreateEvent.CreateReason.OBC_DESTINATION); - if (event.callEvent()) { - nmsBlocks.forEach(this.world::setTypeUpdate); - } - // Paper end - - // CraftBukkit start - return new BlockPosition(i, k, k); - } - - // use logic based on creation to verify end portal - private BlockPosition findEndPortal(BlockPosition portal) { - int i = portal.getX(); - int j = portal.getY() - 1; - int k = portal.getZ(); - byte b0 = 1; - byte b1 = 0; - - for (int l = -2; l <= 2; ++l) { - for (int i1 = -2; i1 <= 2; ++i1) { - for (int j1 = -1; j1 < 3; ++j1) { - int k1 = i + i1 * b0 + l * b1; - int l1 = j + j1; - int i2 = k + i1 * b1 - l * b0; - boolean flag = j1 < 0; - - if (this.world.getType(new BlockPosition(k1, l1, i2)).getBlock() != (flag ? Blocks.OBSIDIAN : Blocks.AIR)) { - return null; - } - } - } - } - return new BlockPosition(i, j, k); - } - // CraftBukkit end - - public boolean b(Entity entity, float f) { - // CraftBukkit start - Modularize portal search process and entity teleportation - BlockPosition found = this.findPortal(entity.locX, entity.locY, entity.locZ, world.paperConfig.portalSearchRadius); // Paper - Configurable search radius - if (found == null) { + if (shapedetector_shape == null) { return false; - } + } else { + Vec3D vec3d1 = shapedetector_shape.position; + Vec3D vec3d2 = shapedetector_shape.velocity; - Location exit = new Location(this.world.getWorld(), found.getX(), found.getY(), found.getZ(), f, entity.pitch); - Vector velocity = entity.getBukkitEntity().getVelocity(); - this.adjustExit(entity, exit, velocity); - entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); - if (entity.motX != velocity.getX() || entity.motY != velocity.getY() || entity.motZ != velocity.getZ()) { - entity.getBukkitEntity().setVelocity(velocity); + entity.setMot(vec3d2); + entity.yaw = f + (float) shapedetector_shape.yaw; + if (entity instanceof EntityPlayer) { + ((EntityPlayer) entity).playerConnection.a(vec3d1.x, vec3d1.y, vec3d1.z, entity.yaw, entity.pitch); + ((EntityPlayer) entity).playerConnection.syncPosition(); + } else { + entity.setPositionRotation(vec3d1.x, vec3d1.y, vec3d1.z, entity.yaw, entity.pitch); + } + + return true; } - return true; } - public BlockPosition findPortal(double x, double y, double z, int radius) { - if (this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { - return this.findEndPortal(this.world.worldProvider.d()); - } - // CraftBukkit end - double d0 = -1.0D; - // CraftBukkit start - int i = MathHelper.floor(x); - int j = MathHelper.floor(z); - // CraftBukkit end + @Nullable + public ShapeDetector.Shape a(BlockPosition blockposition, Vec3D vec3d, EnumDirection enumdirection, double d0, double d1, boolean flag) { boolean flag1 = true; - Object object = BlockPosition.ZERO; - long k = ChunkCoordIntPair.a(i, j); + boolean flag2 = true; + BlockPosition blockposition1 = null; + BlockPosition2D blockposition2d = new BlockPosition2D(blockposition); - if (this.d.containsKey(k)) { - PortalTravelAgent.ChunkCoordinatesPortal portaltravelagent_chunkcoordinatesportal = (PortalTravelAgent.ChunkCoordinatesPortal) this.d.get(k); - - d0 = 0.0D; - object = portaltravelagent_chunkcoordinatesportal; - portaltravelagent_chunkcoordinatesportal.b = this.world.getTime(); - flag1 = false; + if (!flag && this.f.containsKey(blockposition2d)) { + return null; } else { - BlockPosition blockposition = new BlockPosition(x, y, z); // CraftBukkit + PortalTravelAgent.ChunkCoordinatesPortal portaltravelagent_chunkcoordinatesportal = (PortalTravelAgent.ChunkCoordinatesPortal) this.e.get(blockposition2d); - for (int l = -radius; l <= radius; ++l) { - BlockPosition blockposition1; + if (portaltravelagent_chunkcoordinatesportal != null) { + blockposition1 = portaltravelagent_chunkcoordinatesportal.a; + portaltravelagent_chunkcoordinatesportal.b = this.world.getTime(); + flag2 = false; + } else { + double d2 = Double.MAX_VALUE; - for (int i1 = -radius; i1 <= radius; ++i1) { - for (BlockPosition blockposition2 = blockposition.a(l, this.world.ab() - 1 - blockposition.getY(), i1); blockposition2.getY() >= 0; blockposition2 = blockposition1) { - blockposition1 = blockposition2.down(); - if (this.world.getType(blockposition2).getBlock() == PortalTravelAgent.a) { - for (blockposition1 = blockposition2.down(); this.world.getType(blockposition1).getBlock() == PortalTravelAgent.a; blockposition1 = blockposition1.down()) { - blockposition2 = blockposition1; - } + int portalSearchRadius = world.paperConfig.portalSearchRadius; // Paper + for (int i = -portalSearchRadius; i <= portalSearchRadius; ++i) { // Paper + BlockPosition blockposition2; - double d1 = blockposition2.n(blockposition); + for (int j = -world.paperConfig.portalSearchRadius; j <= world.paperConfig.portalSearchRadius; ++j) { // Paper + for (BlockPosition blockposition3 = blockposition.b(i, this.world.getHeight() - 1 - blockposition.getY(), j); blockposition3.getY() >= 0; blockposition3 = blockposition2) { + blockposition2 = blockposition3.down(); + if (this.world.getType(blockposition3).getBlock() == PortalTravelAgent.b) { + for (blockposition2 = blockposition3.down(); this.world.getType(blockposition2).getBlock() == PortalTravelAgent.b; blockposition2 = blockposition2.down()) { + blockposition3 = blockposition2; + } - if (d0 < 0.0D || d1 < d0) { - d0 = d1; - object = blockposition2; + double d3 = blockposition3.m(blockposition); + + if (d2 < 0.0D || d3 < d2) { + d2 = d3; + blockposition1 = blockposition3; + } } } } } } - } - if (d0 >= 0.0D) { - if (flag1) { - this.d.put(k, new PortalTravelAgent.ChunkCoordinatesPortal((BlockPosition) object, this.world.getTime())); - } - // CraftBukkit start - Move entity teleportation logic into exit - return (BlockPosition) object; - } else { - return null; - } - } + if (blockposition1 == null) { + long k = this.world.getTime() + 300L; - // Entity repositioning logic split out from original b method and combined with repositioning logic for The End from original a method - public void adjustExit(Entity entity, Location position, Vector velocity) { - Location from = position.clone(); - Vector before = velocity.clone(); - BlockPosition object = new BlockPosition(position.getBlockX(), position.getBlockY(), position.getBlockZ()); - float f = position.getYaw(); - - if (this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END || entity.getBukkitEntity().getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END || entity.getPortalOffset() == null) { - // entity.setPositionRotation((double) i, (double) j, (double) k, entity.yaw, 0.0F); - // entity.motX = entity.motY = entity.motZ = 0.0D; - position.setPitch(0.0F); - velocity.setX(0); - velocity.setY(0); - velocity.setZ(0); - } else { - // CraftBukkit end - - double d2 = (double) ((BlockPosition) object).getX() + 0.5D; - double d3 = (double) ((BlockPosition) object).getZ() + 0.5D; - ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = PortalTravelAgent.a.c((GeneratorAccess) this.world, (BlockPosition) object); - boolean flag2 = shapedetector_shapedetectorcollection.getFacing().e().c() == EnumDirection.EnumAxisDirection.NEGATIVE; - double d4 = shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X ? (double) shapedetector_shapedetectorcollection.a().getZ() : (double) shapedetector_shapedetectorcollection.a().getX(); - double d5 = (double) (shapedetector_shapedetectorcollection.a().getY() + 1) - entity.getPortalOffset().y * (double) shapedetector_shapedetectorcollection.e(); - - if (flag2) { - ++d4; - } - - // Paper start - Prevent portal suffocation (and therefore getting teleported up in an attempt to avoid it) - // Based on work by CarpetMod - Licensed GPL-3.0 - double offset = (1.0D - entity.getPortalOffset().x) * (double) shapedetector_shapedetectorcollection.getWidth() * (double) shapedetector_shapedetectorcollection.getFacing().rotateY().getAxisDirection().getOffset(); - double adjustedRadius = 1.02 * entity.width / 2; - if (adjustedRadius >= shapedetector_shapedetectorcollection.getWidth() - adjustedRadius) { - // entity wider than portal, place it in the middle - adjustedRadius = (double) shapedetector_shapedetectorcollection.getWidth() / 2 - 0.001; - } - - if (offset >= 0) { - offset = MathHelper.clamp(offset, adjustedRadius, (double) shapedetector_shapedetectorcollection.getWidth() - adjustedRadius); + this.f.put(blockposition2d, k); + return null; } else { - offset = MathHelper.clamp(offset, (double) -shapedetector_shapedetectorcollection.getWidth() + adjustedRadius, -adjustedRadius); + if (flag2) { + this.e.put(blockposition2d, new PortalTravelAgent.ChunkCoordinatesPortal(blockposition1, this.world.getTime())); + Logger logger = PortalTravelAgent.LOGGER; + Supplier[] asupplier = new Supplier[2]; + WorldProvider worldprovider = this.world.getWorldProvider(); + + asupplier[0] = worldprovider::getDimensionManager; + asupplier[1] = () -> { + return blockposition2d; + }; + logger.debug("Adding nether portal ticket for {}:{}", asupplier); + this.world.getChunkProvider().addTicket(TicketType.PORTAL, new ChunkCoordIntPair(blockposition1), 3, blockposition2d); + } + + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = PortalTravelAgent.b.c((GeneratorAccess) this.world, blockposition1); + + return shapedetector_shapedetectorcollection.a(enumdirection, blockposition1, d1, vec3d, d0); } - - if (shapedetector_shapedetectorcollection.getFacing().k() == EnumDirection.EnumAxis.X) { - d3 = d4 + offset; - } else { - d2 = d4 + offset; - } - // Paper end - - float f1 = 0.0F; - float f2 = 0.0F; - float f3 = 0.0F; - float f4 = 0.0F; - - if (shapedetector_shapedetectorcollection.getFacing().opposite() == entity.getPortalDirection()) { - f1 = 1.0F; - f2 = 1.0F; - } else if (shapedetector_shapedetectorcollection.getFacing().opposite() == entity.getPortalDirection().opposite()) { - f1 = -1.0F; - f2 = -1.0F; - } else if (shapedetector_shapedetectorcollection.getFacing().opposite() == entity.getPortalDirection().e()) { - f3 = 1.0F; - f4 = -1.0F; - } else { - f3 = -1.0F; - f4 = 1.0F; - } - - // CraftBukkit start - double d6 = velocity.getX(); - double d7 = velocity.getZ(); - // CraftBukkit end - - // CraftBukkit start - Adjust position and velocity instances instead of entity - velocity.setX(d6 * (double) f1 + d7 * (double) f4); - velocity.setZ(d6 * (double) f3 + d7 * (double) f2); - f = f - (float) (entity.getPortalDirection().opposite().get2DRotationValue() * 90) + (float) (shapedetector_shapedetectorcollection.getFacing().get2DRotationValue() * 90); - // entity.setPositionRotation(d2, d5, d3, entity.yaw, entity.pitch); - position.setX(d2); - position.setY(d5); - position.setZ(d3); - position.setYaw(f); } - EntityPortalExitEvent event = new EntityPortalExitEvent(entity.getBukkitEntity(), from, position, before, velocity); - this.world.getServer().getPluginManager().callEvent(event); - Location to = event.getTo(); - if (event.isCancelled() || to == null || !entity.isAlive()) { - position.setX(from.getX()); - position.setY(from.getY()); - position.setZ(from.getZ()); - position.setYaw(from.getYaw()); - position.setPitch(from.getPitch()); - velocity.copy(before); - } else { - position.setX(to.getX()); - position.setY(to.getY()); - position.setZ(to.getZ()); - position.setYaw(to.getYaw()); - position.setPitch(to.getPitch()); - velocity.copy(event.getAfter()); // event.getAfter() will never be null, as setAfter() will cause an NPE if null is passed in - } - // CraftBukkit end } public boolean a(Entity entity) { - // CraftBukkit start - Allow for portal creation to be based on coordinates instead of entity - return this.createPortal(entity.locX, entity.locY, entity.locZ, 16); - } - - public boolean createPortal(double x, double y, double z, int b0) { - if (this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { - createEndPortal(x, y, z); - return true; - } - // CraftBukkit end + boolean flag = true; double d0 = -1.0D; - // CraftBukkit start - int i = MathHelper.floor(x); - int j = MathHelper.floor(y); - int k = MathHelper.floor(z); - // CraftBukkit end + int i = MathHelper.floor(entity.locX); + int j = MathHelper.floor(entity.locY); + int k = MathHelper.floor(entity.locZ); int l = i; int i1 = j; int j1 = k; int k1 = 0; - int l1 = this.c.nextInt(4); + int l1 = this.d.nextInt(4); BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); double d1; @@ -326,15 +151,15 @@ public class PortalTravelAgent { double d4; for (i2 = i - 16; i2 <= i + 16; ++i2) { - d1 = (double) i2 + 0.5D - x; // CraftBukkit + d1 = (double) i2 + 0.5D - entity.locX; for (j2 = k - 16; j2 <= k + 16; ++j2) { - d2 = (double) j2 + 0.5D - z; // CraftBukkit + d2 = (double) j2 + 0.5D - entity.locZ; label257: - for (k2 = this.world.ab() - 1; k2 >= 0; --k2) { - if (this.world.isEmpty(blockposition_mutableblockposition.c(i2, k2, j2))) { - while (k2 > 0 && this.world.isEmpty(blockposition_mutableblockposition.c(i2, k2 - 1, j2))) { + for (k2 = this.world.getHeight() - 1; k2 >= 0; --k2) { + if (this.world.isEmpty(blockposition_mutableblockposition.d(i2, k2, j2))) { + while (k2 > 0 && this.world.isEmpty(blockposition_mutableblockposition.d(i2, k2 - 1, j2))) { --k2; } @@ -353,7 +178,7 @@ public class PortalTravelAgent { j4 = k2 + k4; int l4 = j2 + (i4 - 1) * j3 - l3 * l2; - blockposition_mutableblockposition.c(k3, j4, l4); + blockposition_mutableblockposition.d(k3, j4, l4); if (k4 < 0 && !this.world.getType(blockposition_mutableblockposition).getMaterial().isBuildable() || k4 >= 0 && !this.world.isEmpty(blockposition_mutableblockposition)) { continue label257; } @@ -361,7 +186,7 @@ public class PortalTravelAgent { } } - d3 = (double) k2 + 0.5D - y; // CraftBukkit + d3 = (double) k2 + 0.5D - entity.locY; d4 = d1 * d1 + d3 * d3 + d2 * d2; if (d0 < 0.0D || d4 < d0) { d0 = d4; @@ -378,15 +203,15 @@ public class PortalTravelAgent { if (d0 < 0.0D) { for (i2 = i - 16; i2 <= i + 16; ++i2) { - d1 = (double) i2 + 0.5D - x; // CraftBukkit + d1 = (double) i2 + 0.5D - entity.locX; for (j2 = k - 16; j2 <= k + 16; ++j2) { - d2 = (double) j2 + 0.5D - z; // CraftBukkit + d2 = (double) j2 + 0.5D - entity.locZ; label205: - for (k2 = this.world.ab() - 1; k2 >= 0; --k2) { - if (this.world.isEmpty(blockposition_mutableblockposition.c(i2, k2, j2))) { - while (k2 > 0 && this.world.isEmpty(blockposition_mutableblockposition.c(i2, k2 - 1, j2))) { + for (k2 = this.world.getHeight() - 1; k2 >= 0; --k2) { + if (this.world.isEmpty(blockposition_mutableblockposition.d(i2, k2, j2))) { + while (k2 > 0 && this.world.isEmpty(blockposition_mutableblockposition.d(i2, k2 - 1, j2))) { --k2; } @@ -399,14 +224,14 @@ public class PortalTravelAgent { k4 = i2 + (l3 - 1) * l2; k3 = k2 + i4; j4 = j2 + (l3 - 1) * j3; - blockposition_mutableblockposition.c(k4, k3, j4); + blockposition_mutableblockposition.d(k4, k3, j4); if (i4 < 0 && !this.world.getType(blockposition_mutableblockposition).getMaterial().isBuildable() || i4 >= 0 && !this.world.isEmpty(blockposition_mutableblockposition)) { continue label205; } } } - d3 = (double) k2 + 0.5D - y; // CraftBukkit + d3 = (double) k2 + 0.5D - entity.locY; d4 = d1 * d1 + d3 * d3 + d2 * d2; if (d0 < 0.0D || d4 < d0) { d0 = d4; @@ -434,11 +259,9 @@ public class PortalTravelAgent { l5 = -l5; } - java.util.Collection bukkitBlocks = new java.util.HashSet<>(); // Paper - java.util.Map nmsBlocks = new java.util.LinkedHashMap<>(); // Paper - + org.bukkit.craftbukkit.util.BlockStateListPopulator blockList = new org.bukkit.craftbukkit.util.BlockStateListPopulator(this.world); // CraftBukkit - Use BlockStateListPopulator if (d0 < 0.0D) { - i1 = MathHelper.clamp(i1, 70, this.world.ab() - 10); + i1 = MathHelper.clamp(i1, 70, this.world.getHeight() - 10); j5 = i1; for (k2 = -1; k2 <= 1; ++k2) { @@ -449,11 +272,8 @@ public class PortalTravelAgent { i4 = j2 + (i3 - 1) * l5 - k2 * k5; boolean flag1 = l2 < 0; - // Paper start - BlockPosition pos = new BlockPosition(j3, l3, i4); - nmsBlocks.put(pos, flag1 ? Blocks.OBSIDIAN.getBlockData() : Blocks.AIR.getBlockData()); - bukkitBlocks.add(this.world.getWorld().getBlockAt(pos)); // Akarin - // Paper end + blockposition_mutableblockposition.d(j3, l3, i4); + blockList.setTypeAndData(blockposition_mutableblockposition, flag1 ? Blocks.OBSIDIAN.getBlockData() : Blocks.AIR.getBlockData(), 3); // CraftBukkit } } } @@ -462,62 +282,87 @@ public class PortalTravelAgent { for (k2 = -1; k2 < 3; ++k2) { for (i3 = -1; i3 < 4; ++i3) { if (k2 == -1 || k2 == 2 || i3 == -1 || i3 == 3) { - blockposition_mutableblockposition.c(i5 + k2 * k5, j5 + i3, j2 + k2 * l5); - // Paper start - BlockPosition pos = new BlockPosition(blockposition_mutableblockposition.getX(), blockposition_mutableblockposition.getY(), blockposition_mutableblockposition.getZ()); - nmsBlocks.put(pos, Blocks.OBSIDIAN.getBlockData()); - bukkitBlocks.add(this.world.getWorld().getBlockAt(pos)); // Akarin - // Paper end + blockposition_mutableblockposition.d(i5 + k2 * k5, j5 + i3, j2 + k2 * l5); + blockList.setTypeAndData(blockposition_mutableblockposition, Blocks.OBSIDIAN.getBlockData(), 3); // CraftBukkit } } } - IBlockData iblockdata = (IBlockData) PortalTravelAgent.a.getBlockData().set(BlockPortal.AXIS, k5 == 0 ? EnumDirection.EnumAxis.Z : EnumDirection.EnumAxis.X); + IBlockData iblockdata = (IBlockData) PortalTravelAgent.b.getBlockData().set(BlockPortal.AXIS, k5 == 0 ? EnumDirection.EnumAxis.Z : EnumDirection.EnumAxis.X); for (i3 = 0; i3 < 2; ++i3) { for (l2 = 0; l2 < 3; ++l2) { - blockposition_mutableblockposition.c(i5 + i3 * k5, j5 + l2, j2 + i3 * l5); - - // Paper start - BlockPosition pos = new BlockPosition(blockposition_mutableblockposition.getX(), blockposition_mutableblockposition.getY(), blockposition_mutableblockposition.getZ()); - nmsBlocks.put(pos, iblockdata); - bukkitBlocks.add(this.world.getWorld().getBlockAt(pos)); // Akarin - // Paper end + blockposition_mutableblockposition.d(i5 + i3 * k5, j5 + l2, j2 + i3 * l5); + blockList.setTypeAndData(blockposition_mutableblockposition, iblockdata, 18); // CraftBukkit } } - // Paper start - org.bukkit.event.world.PortalCreateEvent event = new org.bukkit.event.world.PortalCreateEvent(bukkitBlocks, this.world.getWorld(), org.bukkit.event.world.PortalCreateEvent.CreateReason.OBC_DESTINATION); - if (event.callEvent()) { - nmsBlocks.forEach((pos, data) -> this.world.setTypeAndData(pos, data, 18)); // keep flag in sync with removed call above - } - // Paper end + // CraftBukkit start + org.bukkit.World bworld = this.world.getWorld(); + org.bukkit.event.world.PortalCreateEvent event = new org.bukkit.event.world.PortalCreateEvent((java.util.List) (java.util.List) blockList.getList(), bworld, entity.getBukkitEntity(), org.bukkit.event.world.PortalCreateEvent.CreateReason.NETHER_PAIR); + this.world.getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) { + blockList.updateList(); + } + // CraftBukkit end return true; } public void a(long i) { if (i % 100L == 0L) { - long j = i - 300L; - ObjectIterator objectiterator = this.d.values().iterator(); + this.b(i); + this.c(i); + } - while (objectiterator.hasNext()) { - PortalTravelAgent.ChunkCoordinatesPortal portaltravelagent_chunkcoordinatesportal = (PortalTravelAgent.ChunkCoordinatesPortal) objectiterator.next(); + } - if (portaltravelagent_chunkcoordinatesportal == null || portaltravelagent_chunkcoordinatesportal.b < j) { - objectiterator.remove(); - } + private void b(long i) { + LongIterator longiterator = this.f.values().iterator(); + + while (longiterator.hasNext()) { + long j = longiterator.nextLong(); + + if (j <= i) { + longiterator.remove(); } } } - public class ChunkCoordinatesPortal extends BlockPosition { + private void c(long i) { + long j = i - 300L; + Iterator iterator = this.e.entrySet().iterator(); + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + PortalTravelAgent.ChunkCoordinatesPortal portaltravelagent_chunkcoordinatesportal = (PortalTravelAgent.ChunkCoordinatesPortal) entry.getValue(); + + if (portaltravelagent_chunkcoordinatesportal.b < j) { + BlockPosition2D blockposition2d = (BlockPosition2D) entry.getKey(); + Logger logger = PortalTravelAgent.LOGGER; + Supplier[] asupplier = new Supplier[2]; + WorldProvider worldprovider = this.world.getWorldProvider(); + + asupplier[0] = worldprovider::getDimensionManager; + asupplier[1] = () -> { + return blockposition2d; + }; + logger.debug("Removing nether portal ticket for {}:{}", asupplier); + this.world.getChunkProvider().removeTicket(TicketType.PORTAL, new ChunkCoordIntPair(portaltravelagent_chunkcoordinatesportal.a), 3, blockposition2d); + iterator.remove(); + } + } + + } + + static class ChunkCoordinatesPortal { + + public final BlockPosition a; public long b; public ChunkCoordinatesPortal(BlockPosition blockposition, long i) { - super(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + this.a = blockposition; this.b = i; } } diff --git a/src/main/java/net/minecraft/server/PotionUtil.java b/src/main/java/net/minecraft/server/PotionUtil.java index ea08c5a1c..bf4172be5 100644 --- a/src/main/java/net/minecraft/server/PotionUtil.java +++ b/src/main/java/net/minecraft/server/PotionUtil.java @@ -115,7 +115,7 @@ public class PotionUtil { MinecraftKey minecraftkey = IRegistry.POTION.getKey(potionregistry); if (potionregistry == Potions.EMPTY) { - itemstack.c("Potion"); + itemstack.removeTag("Potion"); } else { itemstack.getOrCreateTag().setString("Potion", minecraftkey.toString()); } @@ -134,7 +134,7 @@ public class PotionUtil { while (iterator.hasNext()) { MobEffect mobeffect = (MobEffect) iterator.next(); - nbttaglist.add((NBTBase) mobeffect.a(new NBTTagCompound())); + nbttaglist.add(mobeffect.a(new NBTTagCompound())); } nbttagcompound.set("CustomPotionEffects", nbttaglist); diff --git a/src/main/java/net/minecraft/server/PropertyManager.java b/src/main/java/net/minecraft/server/PropertyManager.java index 5055a4fb8..729455ce5 100644 --- a/src/main/java/net/minecraft/server/PropertyManager.java +++ b/src/main/java/net/minecraft/server/PropertyManager.java @@ -1,153 +1,249 @@ package net.minecraft.server; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; +import com.google.common.base.MoreObjects; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.util.Objects; import java.util.Properties; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; +import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import joptsimple.OptionSet; // CraftBukkit -public class PropertyManager { - - private static final Logger a = LogManager.getLogger(); - public final Properties properties = new Properties(); - private final File file; - - public PropertyManager(File file) { - this.file = file; - if (file.exists()) { - FileInputStream fileinputstream = null; - - try { - fileinputstream = new FileInputStream(file); - this.properties.load(fileinputstream); - } catch (Exception exception) { - PropertyManager.a.warn("Failed to load {}", file, exception); - this.a(); - } finally { - if (fileinputstream != null) { - try { - fileinputstream.close(); - } catch (IOException ioexception) { - ; - } - } - - } - } else { - PropertyManager.a.warn("{} does not exist", file); - this.a(); - } - - } +public abstract class PropertyManager> { + private static final Logger LOGGER = LogManager.getLogger(); + public final Properties properties; // CraftBukkit start private OptionSet options = null; - public PropertyManager(final OptionSet options) { - this((File) options.valueOf("config")); + public PropertyManager(Properties properties, final OptionSet options) { + this.properties = properties; this.options = options; } - private T getOverride(String name, T value) { + private String getOverride(String name, String value) { if ((this.options != null) && (this.options.has(name)) && !name.equals( "online-mode")) { // Spigot - return (T) this.options.valueOf(name); + return String.valueOf(this.options.valueOf(name)); } return value; } // CraftBukkit end - public void a() { - PropertyManager.a.info("Generating new properties file"); - this.savePropertiesFile(); - } - - public void savePropertiesFile() { - FileOutputStream fileoutputstream = null; + public static Properties loadPropertiesFile(java.nio.file.Path java_nio_file_path) { + Properties properties = new Properties(); + try { + InputStream inputstream = Files.newInputStream(java_nio_file_path); + Throwable throwable = null; + + try { + properties.load(inputstream); + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (inputstream != null) { + if (throwable != null) { + try { + inputstream.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + inputstream.close(); + } + } + + } + } catch (IOException ioexception) { + PropertyManager.LOGGER.error("Failed to load properties from file: " + java_nio_file_path); + } + + return properties; + } + + public void savePropertiesFile(java.nio.file.Path java_nio_file_path) { try { // CraftBukkit start - Don't attempt writing to file if it's read only - if (this.file.exists() && !this.file.canWrite()) { + if (java_nio_file_path.toFile().exists() && !java_nio_file_path.toFile().canWrite()) { return; } // CraftBukkit end + OutputStream outputstream = Files.newOutputStream(java_nio_file_path); + Throwable throwable = null; - fileoutputstream = new FileOutputStream(this.file); - this.properties.store(fileoutputstream, "Minecraft server properties"); - } catch (Exception exception) { - PropertyManager.a.warn("Failed to save {}", this.file, exception); - this.a(); - } finally { - if (fileoutputstream != null) { - try { - fileoutputstream.close(); - } catch (IOException ioexception) { - ; + try { + this.properties.store(outputstream, "Minecraft server properties"); + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (outputstream != null) { + if (throwable != null) { + try { + outputstream.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + outputstream.close(); + } } + } - + } catch (IOException ioexception) { + PropertyManager.LOGGER.error("Failed to store properties to file: " + java_nio_file_path); } } - public File c() { - return this.file; + private static Function a(Function function) { + return (s) -> { + try { + return (V) function.apply(s); // CraftBukkit - decompile error + } catch (NumberFormatException numberformatexception) { + return null; + } + }; } - public String getString(String s, String s1) { - if (!this.properties.containsKey(s)) { - this.properties.setProperty(s, s1); - this.savePropertiesFile(); - this.savePropertiesFile(); - } - - return getOverride(s, this.properties.getProperty(s, s1)); // CraftBukkit + protected static Function a(IntFunction intfunction, Function function) { + return (s) -> { + try { + return intfunction.apply(Integer.parseInt(s)); + } catch (NumberFormatException numberformatexception) { + return function.apply(s); + } + }; } - public int getInt(String s, int i) { - try { - return getOverride(s, Integer.parseInt(this.getString(s, "" + i))); // CraftBukkit - } catch (Exception exception) { - this.properties.setProperty(s, "" + i); - this.savePropertiesFile(); - return getOverride(s, i); // CraftBukkit + @Nullable String getSettingIfExists(final String path) { return this.c(path); } // Paper - OBFHELPER + @Nullable private String c(String s) { // Paper - OBFHELPER + return (String) getOverride(s, this.properties.getProperty(s)); // CraftBukkit + } + + @Nullable + protected V a(String s, Function function) { + String s1 = this.c(s); + + if (s1 == null) { + return null; + } else { + this.properties.remove(s); + return function.apply(s1); } } - public long getLong(String s, long i) { - try { - return getOverride(s, Long.parseLong(this.getString(s, "" + i))); // CraftBukkit - } catch (Exception exception) { - this.properties.setProperty(s, "" + i); - this.savePropertiesFile(); - return getOverride(s, i); // CraftBukkit + protected V a(String s, Function function, Function function1, V v0) { + String s1 = this.c(s); + V v1 = MoreObjects.firstNonNull(s1 != null ? function.apply(s1) : null, v0); + + this.properties.put(s, function1.apply(v1)); + return v1; + } + + protected PropertyManager.EditableProperty b(String s, Function function, Function function1, V v0) { + String s1 = this.c(s); + V v1 = MoreObjects.firstNonNull(s1 != null ? function.apply(s1) : null, v0); + + this.properties.put(s, function1.apply(v1)); + return new PropertyManager.EditableProperty(s, v1, function1); // CraftBukkit - decompile error + } + + protected V a(String s, Function function, UnaryOperator unaryoperator, Function function1, V v0) { + return this.a(s, (s1) -> { + V v1 = function.apply(s1); + + return v1 != null ? unaryoperator.apply(v1) : null; + }, function1, v0); + } + + protected V a(String s, Function function, V v0) { + return this.a(s, function, Objects::toString, v0); + } + + protected PropertyManager.EditableProperty b(String s, Function function, V v0) { + return this.b(s, function, Objects::toString, v0); + } + + protected String getString(String s, String s1) { + return (String) this.a(s, Function.identity(), Function.identity(), s1); + } + + @Nullable + protected String a(String s) { + return (String) this.a(s, Function.identity()); + } + + protected int getInt(String s, int i) { + return (Integer) this.a(s, a(Integer::parseInt), i); // CraftBukkit - decompile error + } + + protected PropertyManager.EditableProperty b(String s, int i) { + return this.b(s, a(Integer::parseInt), i); + } + + protected int a(String s, UnaryOperator unaryoperator, int i) { + return (Integer) this.a(s, a(Integer::parseInt), unaryoperator, Objects::toString, i); + } + + protected long getLong(String s, long i) { + return (Long) this.a(s, a(Long::parseLong), i); // CraftBukkit - decompile error + } + + protected boolean getBoolean(String s, boolean flag) { + return (Boolean) this.a(s, Boolean::valueOf, (Object) flag); + } + + protected PropertyManager.EditableProperty b(String s, boolean flag) { + return this.b(s, Boolean::valueOf, flag); + } + + @Nullable + protected Boolean b(String s) { + return (Boolean) this.a(s, Boolean::valueOf); + } + + protected Properties a() { + Properties properties = new Properties(); + + properties.putAll(this.properties); + return properties; + } + + protected abstract T reload(Properties properties, OptionSet optionset); // CraftBukkit + + public class EditableProperty implements Supplier { + + private final String b; + private final V c; + private final Function d; + + private EditableProperty(String s, V object, Function function) { // CraftBukkit - decompile error + this.b = s; + this.c = object; + this.d = function; } - } - public boolean getBoolean(String s, boolean flag) { - try { - return getOverride(s, Boolean.parseBoolean(this.getString(s, "" + flag))); //CraftBukkit - } catch (Exception exception) { - this.properties.setProperty(s, "" + flag); - this.savePropertiesFile(); - return getOverride(s, flag); // CraftBukkit + public V get() { + return this.c; } - } - public void setProperty(String s, Object object) { - this.properties.setProperty(s, "" + object); - } + public T set(V v0) { + Properties properties = PropertyManager.this.a(); - public boolean a(String s) { - return this.properties.containsKey(s); - } - - public void b(String s) { - this.properties.remove(s); + properties.put(this.b, this.d.apply(v0)); + return PropertyManager.this.reload(properties, PropertyManager.this.options); // CraftBukkit + } } } diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java index 77977687e..7bad12eb0 100644 --- a/src/main/java/net/minecraft/server/ProtoChunk.java +++ b/src/main/java/net/minecraft/server/ProtoChunk.java @@ -5,26 +5,29 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; -import it.unimi.dsi.fastutil.shorts.ShortArrayList; import it.unimi.dsi.fastutil.shorts.ShortList; import java.util.BitSet; +import java.util.Collection; import java.util.Collections; +import java.util.EnumSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.Map.Entry; +import java.util.stream.Stream; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class ProtoChunk implements IChunkAccess { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private final ChunkCoordIntPair b; - private boolean c; - private final AtomicInteger d; - private BiomeBase[] e; + private volatile boolean c; + private BiomeBase[] d; + @Nullable + private volatile LightEngine e; private final Map f; private volatile ChunkStatus g; private final Map h; @@ -40,26 +43,29 @@ public class ProtoChunk implements IChunkAccess { private final ProtoChunkTickList r; private long s; private final Map t; - private boolean u; - private GeneratorAccess world; // Paper - Anti-Xray - - // Paper start - Anti-Xray - Support default constructors - public ProtoChunk(int i, int j, ChunkConverter chunkconverter) { - this(new ChunkCoordIntPair(i, j), chunkconverter, null); - } + private volatile boolean u; + private final GeneratorAccess world; // Paper - Anti-Xray public ProtoChunk(ChunkCoordIntPair chunkcoordintpair, ChunkConverter chunkconverter) { - this(chunkcoordintpair, chunkconverter, null); + // Paper start - add world parameter + this(chunkcoordintpair, chunkconverter, (GeneratorAccess)null); } - - public ProtoChunk(int i, int j, ChunkConverter chunkconverter, GeneratorAccess world) { - this(new ChunkCoordIntPair(i, j), chunkconverter, world); - } - public ProtoChunk(ChunkCoordIntPair chunkcoordintpair, ChunkConverter chunkconverter, GeneratorAccess world) { + // Paper end + this(chunkcoordintpair, chunkconverter, (ChunkSection[]) null, new ProtoChunkTickList<>((block) -> { + return block == null || block.getBlockData().isAir(); + }, chunkcoordintpair), new ProtoChunkTickList<>((fluidtype) -> { + return fluidtype == null || fluidtype == FluidTypes.EMPTY; + }, chunkcoordintpair), world); // Paper - add world parameter + } + + public ProtoChunk(ChunkCoordIntPair chunkcoordintpair, ChunkConverter chunkconverter, @Nullable ChunkSection[] achunksection, ProtoChunkTickList protochunkticklist, ProtoChunkTickList protochunkticklist1) { + // Paper start - add world parameter + this(chunkcoordintpair, chunkconverter, achunksection, protochunkticklist, protochunkticklist1, (GeneratorAccess)null); + } + public ProtoChunk(ChunkCoordIntPair chunkcoordintpair, ChunkConverter chunkconverter, @Nullable ChunkSection[] achunksection, ProtoChunkTickList protochunkticklist, ProtoChunkTickList protochunkticklist1, GeneratorAccess world) { this.world = world; - // Paper end - this.d = new AtomicInteger(); + // Paper end this.f = Maps.newEnumMap(HeightMap.Type.class); this.g = ChunkStatus.EMPTY; this.h = Maps.newHashMap(); @@ -73,105 +79,159 @@ public class ProtoChunk implements IChunkAccess { this.t = Maps.newHashMap(); this.b = chunkcoordintpair; this.p = chunkconverter; - this.q = new ProtoChunkTickList<>((block) -> { - return block == null || block.getBlockData().isAir(); - }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::getOrDefault, chunkcoordintpair); - this.r = new ProtoChunkTickList<>((fluidtype) -> { - return fluidtype == null || fluidtype == FluidTypes.EMPTY; - }, IRegistry.FLUID::getKey, IRegistry.FLUID::getOrDefault, chunkcoordintpair); - } - - public static ShortList a(ShortList[] ashortlist, int i) { - if (ashortlist[i] == null) { - ashortlist[i] = new ShortArrayList(); + this.q = protochunkticklist; + this.r = protochunkticklist1; + if (achunksection != null) { + if (this.j.length == achunksection.length) { + System.arraycopy(achunksection, 0, this.j, 0, this.j.length); + } else { + ProtoChunk.LOGGER.warn("Could not set level chunk sections, array length is {} instead of {}", achunksection.length, this.j.length); + } } - return ashortlist[i]; } - @Nullable + // Paper start - If loaded util + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + return this.getFluid(blockposition); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + return this.getType(blockposition); + } + // Paper end + + @Override public IBlockData getType(BlockPosition blockposition) { - int i = blockposition.getX(); - int j = blockposition.getY(); - int k = blockposition.getZ(); + int i = blockposition.getY(); - return j >= 0 && j < 256 ? (this.j[j >> 4] == Chunk.a ? Blocks.AIR.getBlockData() : this.j[j >> 4].getType(i & 15, j & 15, k & 15)) : Blocks.VOID_AIR.getBlockData(); + if (World.b(i)) { + return Blocks.VOID_AIR.getBlockData(); + } else { + ChunkSection chunksection = this.getSections()[i >> 4]; + + return ChunkSection.a(chunksection) ? Blocks.AIR.getBlockData() : chunksection.getType(blockposition.getX() & 15, i & 15, blockposition.getZ() & 15); + } } + @Override public Fluid getFluid(BlockPosition blockposition) { - int i = blockposition.getX(); - int j = blockposition.getY(); - int k = blockposition.getZ(); + int i = blockposition.getY(); - return j >= 0 && j < 256 && this.j[j >> 4] != Chunk.a ? this.j[j >> 4].b(i & 15, j & 15, k & 15) : FluidTypes.EMPTY.i(); + if (World.b(i)) { + return FluidTypes.EMPTY.i(); + } else { + ChunkSection chunksection = this.getSections()[i >> 4]; + + return ChunkSection.a(chunksection) ? FluidTypes.EMPTY.i() : chunksection.b(blockposition.getX() & 15, i & 15, blockposition.getZ() & 15); + } } - public List j() { - return this.l; + @Override + public Stream m() { + return this.l.stream(); } - public ShortList[] p() { + public ShortList[] w() { ShortList[] ashortlist = new ShortList[16]; Iterator iterator = this.l.iterator(); while (iterator.hasNext()) { BlockPosition blockposition = (BlockPosition) iterator.next(); - a(ashortlist, blockposition.getY() >> 4).add(i(blockposition)); + IChunkAccess.a(ashortlist, blockposition.getY() >> 4).add(l(blockposition)); } return ashortlist; } - public void a(short short0, int i) { - this.h(a(short0, i, this.b)); + public void b(short short0, int i) { + this.k(a(short0, i, this.b)); } - public void h(BlockPosition blockposition) { - this.l.add(blockposition); + public void k(BlockPosition blockposition) { + this.l.add(blockposition.immutableCopy()); } @Nullable + @Override public IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag) { int i = blockposition.getX(); int j = blockposition.getY(); int k = blockposition.getZ(); if (j >= 0 && j < 256) { - if (iblockdata.e() > 0) { - this.l.add(new BlockPosition((i & 15) + this.getPos().d(), j, (k & 15) + this.getPos().e())); - } - - if (this.j[j >> 4] == Chunk.a) { - if (iblockdata.getBlock() == Blocks.AIR) { - return iblockdata; + if (this.j[j >> 4] == Chunk.a && iblockdata.getBlock() == Blocks.AIR) { + return iblockdata; + } else { + if (iblockdata.h() > 0) { + this.l.add(new BlockPosition((i & 15) + this.getPos().d(), j, (k & 15) + this.getPos().e())); } - this.j[j >> 4] = new ChunkSection(j >> 4 << 4, this.x(), this, this.world, true); // Paper - Anti-Xray + ChunkSection chunksection = this.a(j >> 4); + IBlockData iblockdata1 = chunksection.setType(i & 15, j & 15, k & 15, iblockdata); + + if (this.g.b(ChunkStatus.FEATURES) && iblockdata != iblockdata1 && (iblockdata.b((IBlockAccess) this, blockposition) != iblockdata1.b((IBlockAccess) this, blockposition) || iblockdata.h() != iblockdata1.h() || iblockdata.g() || iblockdata1.g())) { + LightEngine lightengine = this.e(); + + lightengine.a(blockposition); + } + + EnumSet enumset = this.getChunkStatus().h(); + EnumSet enumset1 = null; + Iterator iterator = enumset.iterator(); + + HeightMap.Type heightmap_type; + + while (iterator.hasNext()) { + heightmap_type = (HeightMap.Type) iterator.next(); + HeightMap heightmap = (HeightMap) this.f.get(heightmap_type); + + if (heightmap == null) { + if (enumset1 == null) { + enumset1 = EnumSet.noneOf(HeightMap.Type.class); + } + + enumset1.add(heightmap_type); + } + } + + if (enumset1 != null) { + HeightMap.a(this, enumset1); + } + + iterator = enumset.iterator(); + + while (iterator.hasNext()) { + heightmap_type = (HeightMap.Type) iterator.next(); + ((HeightMap) this.f.get(heightmap_type)).a(i & 15, j, k & 15, iblockdata); + } + + return iblockdata1; } - - IBlockData iblockdata1 = this.j[j >> 4].getType(i & 15, j & 15, k & 15); - - this.j[j >> 4].setType(i & 15, j & 15, k & 15, iblockdata); - if (this.u) { - this.c(HeightMap.Type.MOTION_BLOCKING).a(i & 15, j, k & 15, iblockdata); - this.c(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES).a(i & 15, j, k & 15, iblockdata); - this.c(HeightMap.Type.OCEAN_FLOOR).a(i & 15, j, k & 15, iblockdata); - this.c(HeightMap.Type.WORLD_SURFACE).a(i & 15, j, k & 15, iblockdata); - } - - return iblockdata1; } else { return Blocks.VOID_AIR.getBlockData(); } } - public void a(BlockPosition blockposition, TileEntity tileentity) { + public ChunkSection a(int i) { + if (this.j[i] == Chunk.a) { + this.j[i] = new ChunkSection(i << 4, this, this.world, true); // Paper - Anti-Xray + } + + return this.j[i]; + } + + @Override + public void setTileEntity(BlockPosition blockposition, TileEntity tileentity) { tileentity.setPosition(blockposition); this.h.put(blockposition, tileentity); } - public Set q() { + @Override + public Set c() { Set set = Sets.newHashSet(this.i.keySet()); set.addAll(this.h.keySet()); @@ -179,11 +239,12 @@ public class ProtoChunk implements IChunkAccess { } @Nullable + @Override public TileEntity getTileEntity(BlockPosition blockposition) { return (TileEntity) this.h.get(blockposition); } - public Map r() { + public Map x() { return this.h; } @@ -191,6 +252,7 @@ public class ProtoChunk implements IChunkAccess { this.k.add(nbttagcompound); } + @Override public void a(Entity entity) { NBTTagCompound nbttagcompound = new NBTTagCompound(); @@ -198,180 +260,120 @@ public class ProtoChunk implements IChunkAccess { this.b(nbttagcompound); } - public List s() { + public List y() { return this.k; } + @Override public void a(BiomeBase[] abiomebase) { - this.e = abiomebase; + this.d = abiomebase; } + @Override public BiomeBase[] getBiomeIndex() { - return this.e; + return this.d; } - public void a(boolean flag) { + @Override + public void setNeedsSaving(boolean flag) { this.c = flag; } - public boolean h() { + @Override + public boolean isNeedsSaving() { return this.c; } - public ChunkStatus i() { + @Override + public ChunkStatus getChunkStatus() { return this.g; } public void a(ChunkStatus chunkstatus) { this.g = chunkstatus; - this.a(true); - } - - public void c(String s) { - this.a(ChunkStatus.a(s)); + this.setNeedsSaving(true); } + @Override public ChunkSection[] getSections() { return this.j; } - public int a(EnumSkyBlock enumskyblock, BlockPosition blockposition, boolean flag) { - int i = blockposition.getX() & 15; - int j = blockposition.getY(); - int k = blockposition.getZ() & 15; - int l = j >> 4; - - if (l >= 0 && l <= this.j.length - 1) { - ChunkSection chunksection = this.j[l]; - - return chunksection == Chunk.a ? (this.c(blockposition) ? enumskyblock.c : 0) : (enumskyblock == EnumSkyBlock.SKY ? (!flag ? 0 : chunksection.c(i, j & 15, k)) : (enumskyblock == EnumSkyBlock.BLOCK ? chunksection.d(i, j & 15, k) : enumskyblock.c)); - } else { - return 0; - } - } - - public int a(BlockPosition blockposition, int i, boolean flag) { - int j = blockposition.getX() & 15; - int k = blockposition.getY(); - int l = blockposition.getZ() & 15; - int i1 = k >> 4; - - if (i1 >= 0 && i1 <= this.j.length - 1) { - ChunkSection chunksection = this.j[i1]; - - if (chunksection == Chunk.a) { - return this.x() && i < EnumSkyBlock.SKY.c ? EnumSkyBlock.SKY.c - i : 0; - } else { - int j1 = flag ? chunksection.c(j, k & 15, l) : 0; - - j1 -= i; - int k1 = chunksection.d(j, k & 15, l); - - if (k1 > j1) { - j1 = k1; - } - - return j1; - } - } else { - return 0; - } - } - - public boolean c(BlockPosition blockposition) { - int i = blockposition.getX() & 15; - int j = blockposition.getY(); - int k = blockposition.getZ() & 15; - - return j >= this.a(HeightMap.Type.MOTION_BLOCKING, i, k); - } - - public void a(ChunkSection[] achunksection) { - if (this.j.length != achunksection.length) { - ProtoChunk.a.warn("Could not set level chunk sections, array length is {} instead of {}", achunksection.length, this.j.length); - } else { - System.arraycopy(achunksection, 0, this.j, 0, this.j.length); - } - } - - public Set t() { - return this.f.keySet(); - } - @Nullable - public HeightMap b(HeightMap.Type heightmap_type) { - return (HeightMap) this.f.get(heightmap_type); + @Override + public LightEngine e() { + return this.e; } + @Override + public Collection> f() { + return Collections.unmodifiableSet(this.f.entrySet()); + } + + @Override public void a(HeightMap.Type heightmap_type, long[] along) { - this.c(heightmap_type).a(along); + this.b(heightmap_type).a(along); } - public void a(HeightMap.Type... aheightmap_type) { - HeightMap.Type[] aheightmap_type1 = aheightmap_type; - int i = aheightmap_type.length; - - for (int j = 0; j < i; ++j) { - HeightMap.Type heightmap_type = aheightmap_type1[j]; - - this.c(heightmap_type); - } - - } - - private HeightMap c(HeightMap.Type heightmap_type) { + @Override + public HeightMap b(HeightMap.Type heightmap_type) { return (HeightMap) this.f.computeIfAbsent(heightmap_type, (heightmap_type1) -> { - HeightMap heightmap = new HeightMap(this, heightmap_type1); - - heightmap.a(); - return heightmap; + return new HeightMap(this, heightmap_type1); }); } + @Override public int a(HeightMap.Type heightmap_type, int i, int j) { HeightMap heightmap = (HeightMap) this.f.get(heightmap_type); if (heightmap == null) { - this.a(heightmap_type); + HeightMap.a(this, EnumSet.of(heightmap_type)); heightmap = (HeightMap) this.f.get(heightmap_type); } return heightmap.a(i & 15, j & 15) - 1; } + @Override public ChunkCoordIntPair getPos() { return this.b; } + @Override public void setLastSaved(long i) {} @Nullable + @Override public StructureStart a(String s) { return (StructureStart) this.n.get(s); } + @Override public void a(String s, StructureStart structurestart) { this.n.put(s, structurestart); this.c = true; } - public Map e() { - return com.koloboke.collect.map.hash.HashObjObjMaps.newImmutableMap(this.n); // Akarin - koloboke + @Override + public Map h() { + return Collections.unmodifiableMap(this.n); } + @Override public void a(Map map) { this.n.clear(); this.n.putAll(map); this.c = true; } - @Nullable + @Override public LongSet b(String s) { return (LongSet) this.o.computeIfAbsent(s, (s1) -> { return new LongOpenHashSet(); }); } + @Override public void a(String s, long i) { ((LongSet) this.o.computeIfAbsent(s, (s1) -> { return new LongOpenHashSet(); @@ -379,43 +381,19 @@ public class ProtoChunk implements IChunkAccess { this.c = true; } - public Map f() { + @Override + public Map v() { return Collections.unmodifiableMap(this.o); } + @Override public void b(Map map) { this.o.clear(); this.o.putAll(map); this.c = true; } - public void a(EnumSkyBlock enumskyblock, boolean flag, BlockPosition blockposition, int i) { - int j = blockposition.getX() & 15; - int k = blockposition.getY(); - int l = blockposition.getZ() & 15; - int i1 = k >> 4; - - if (i1 < 16 && i1 >= 0) { - if (this.j[i1] == Chunk.a) { - if (i == enumskyblock.c) { - return; - } - - this.j[i1] = new ChunkSection(i1 << 4, this.x(), this, this.world, true); // Paper - Anti-Xray - } - - if (enumskyblock == EnumSkyBlock.SKY) { - if (flag) { - this.j[i1].a(j, k & 15, l, i); - } - } else if (enumskyblock == EnumSkyBlock.BLOCK) { - this.j[i1].b(j, k & 15, l, i); - } - - } - } - - public static short i(BlockPosition blockposition) { + public static short l(BlockPosition blockposition) { int i = blockposition.getX(); int j = blockposition.getY(); int k = blockposition.getZ(); @@ -434,62 +412,78 @@ public class ProtoChunk implements IChunkAccess { return new BlockPosition(j, k, l); } - public void e(BlockPosition blockposition) { - if (!World.k(blockposition)) { - a(this.m, blockposition.getY() >> 4).add(i(blockposition)); + @Override + public void f(BlockPosition blockposition) { + if (!World.isOutsideWorld(blockposition)) { + IChunkAccess.a(this.m, blockposition.getY() >> 4).add(l(blockposition)); } } - public ShortList[] u() { + @Override + public ShortList[] l() { return this.m; } - public void b(short short0, int i) { - a(this.m, i).add(short0); + @Override + public void a(short short0, int i) { + IChunkAccess.a(this.m, i).add(short0); } - public ProtoChunkTickList k() { + @Override + public ProtoChunkTickList n() { return this.q; } - public ProtoChunkTickList l() { + @Override + public ProtoChunkTickList o() { return this.r; } - private boolean x() { - return true; - } - - public ChunkConverter v() { + @Override + public ChunkConverter p() { return this.p; } + @Override public void b(long i) { this.s = i; } - public long m() { + @Override + public long q() { return this.s; } + @Override public void a(NBTTagCompound nbttagcompound) { this.i.put(new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")), nbttagcompound); } - public Map w() { - return com.koloboke.collect.map.hash.HashObjObjMaps.newImmutableMap(this.i); // Akarin - koloboke + public Map z() { + return Collections.unmodifiableMap(this.i); } - public NBTTagCompound g(BlockPosition blockposition) { + @Override + public NBTTagCompound i(BlockPosition blockposition) { return (NBTTagCompound) this.i.get(blockposition); } - public void d(BlockPosition blockposition) { + @Nullable + @Override + public NBTTagCompound j(BlockPosition blockposition) { + TileEntity tileentity = this.getTileEntity(blockposition); + + return tileentity != null ? tileentity.save(new NBTTagCompound()) : (NBTTagCompound) this.i.get(blockposition); + } + + @Override + public void removeTileEntity(BlockPosition blockposition) { this.h.remove(blockposition); this.i.remove(blockposition); } + @Override public BitSet a(WorldGenStage.Features worldgenstage_features) { return (BitSet) this.t.computeIfAbsent(worldgenstage_features, (worldgenstage_features1) -> { return new BitSet(65536); @@ -500,15 +494,19 @@ public class ProtoChunk implements IChunkAccess { this.t.put(worldgenstage_features, bitset); } - public void a(int i) { - this.d.addAndGet(i); + @Override + public void a(LightEngine lightengine) { + this.e = lightengine; } - public boolean ab_() { - return this.d.get() > 0; + @Override + public boolean r() { + return this.u; } + @Override public void b(boolean flag) { this.u = flag; + this.setNeedsSaving(true); } } diff --git a/src/main/java/net/minecraft/server/Raid.java b/src/main/java/net/minecraft/server/Raid.java new file mode 100644 index 000000000..fa15f20da --- /dev/null +++ b/src/main/java/net/minecraft/server/Raid.java @@ -0,0 +1,832 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.Random; +import java.util.Set; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class Raid { + + private static final ChatMessage a = new ChatMessage("event.minecraft.raid", new Object[0]); + private static final ChatMessage b = new ChatMessage("event.minecraft.raid.victory", new Object[0]); + private static final ChatMessage c = new ChatMessage("event.minecraft.raid.defeat", new Object[0]); + private static final IChatBaseComponent d = Raid.a.g().a(" - ").addSibling(Raid.b); + private static final IChatBaseComponent e = Raid.a.g().a(" - ").addSibling(Raid.c); + private final Map f = Maps.newHashMap(); + private final Map> g = Maps.newHashMap(); + public final Set h = Sets.newHashSet(); // PAIL rename heroes, private -> public + public long i; // PAIL rename activeTicks, private -> public + private BlockPosition j; + private final WorldServer k; + private boolean l; + private final int m; + public float n; // PAIL rename originTotalHealth, private -> public + public int o; // PAIL rename badOmenLevel, private -> public + private boolean p; + private int q; + private final BossBattleServer r; + private int s; + private int t; + private final Random u; + public final int v; // PAIL rename totalWaves, private -> public + private Raid.Status w; + private int x; + private Optional y; + + public Raid(int i, WorldServer worldserver, BlockPosition blockposition) { + this.r = new BossBattleServer(Raid.a, BossBattle.BarColor.RED, BossBattle.BarStyle.NOTCHED_10); + this.u = new Random(); + this.y = Optional.empty(); + this.m = i; + this.k = worldserver; + this.p = true; + this.t = 300; + this.r.setProgress(0.0F); + this.j = blockposition; + this.v = this.a(worldserver.getDifficulty()); + this.w = Raid.Status.ONGOING; + } + + public Raid(WorldServer worldserver, NBTTagCompound nbttagcompound) { + this.r = new BossBattleServer(Raid.a, BossBattle.BarColor.RED, BossBattle.BarStyle.NOTCHED_10); + this.u = new Random(); + this.y = Optional.empty(); + this.k = worldserver; + this.m = nbttagcompound.getInt("Id"); + this.l = nbttagcompound.getBoolean("Started"); + this.p = nbttagcompound.getBoolean("Active"); + this.i = nbttagcompound.getLong("TicksActive"); + this.o = nbttagcompound.getInt("BadOmenLevel"); + this.q = nbttagcompound.getInt("GroupsSpawned"); + this.t = nbttagcompound.getInt("PreRaidTicks"); + this.s = nbttagcompound.getInt("PostRaidTicks"); + this.n = nbttagcompound.getFloat("TotalHealth"); + this.j = new BlockPosition(nbttagcompound.getInt("CX"), nbttagcompound.getInt("CY"), nbttagcompound.getInt("CZ")); + this.v = nbttagcompound.getInt("NumGroups"); + this.w = Raid.Status.b(nbttagcompound.getString("Status")); + this.h.clear(); + if (nbttagcompound.hasKeyOfType("HeroesOfTheVillage", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("HeroesOfTheVillage", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); + UUID uuid = nbttagcompound1.a("UUID"); + + this.h.add(uuid); + } + } + + } + + public boolean a() { + return this.e() || this.f(); + } + + public boolean b() { + return this.c() && this.r() == 0 && this.t > 0; + } + + public boolean c() { + return this.q > 0; + } + + public boolean d() { + return this.w == Raid.Status.STOPPED; + } + + public boolean e() { + return this.w == Raid.Status.VICTORY; + } + + public boolean f() { + return this.w == Raid.Status.LOSS; + } + + // CraftBukkit start + public boolean isInProgress() { + return this.w == Status.ONGOING; + } + // CraftBukkit end + + public World i() { + return this.k; + } + + public boolean j() { + return this.l; + } + + public int k() { + return this.q; + } + + private Predicate x() { + return (entityplayer) -> { + BlockPosition blockposition = new BlockPosition(entityplayer); + + return entityplayer.isAlive() && this.k.c_(blockposition) == this; + }; + } + + private void y() { + Set set = Sets.newHashSet(this.r.getPlayers()); + List list = this.k.a(this.x()); + Iterator iterator = list.iterator(); + + EntityPlayer entityplayer; + + while (iterator.hasNext()) { + entityplayer = (EntityPlayer) iterator.next(); + if (!set.contains(entityplayer)) { + this.r.addPlayer(entityplayer); + } + } + + iterator = set.iterator(); + + while (iterator.hasNext()) { + entityplayer = (EntityPlayer) iterator.next(); + if (!list.contains(entityplayer)) { + this.r.removePlayer(entityplayer); + } + } + + } + + public int l() { + return 5; + } + + public int m() { + return this.o; + } + + public void a(EntityHuman entityhuman) { + if (entityhuman.hasEffect(MobEffects.BAD_OMEN)) { + this.o += entityhuman.getEffect(MobEffects.BAD_OMEN).getAmplifier() + 1; + this.o = MathHelper.clamp(this.o, 0, this.l()); + } + + entityhuman.removeEffect(MobEffects.BAD_OMEN); + } + + public void n() { + this.p = false; + this.r.b(); + this.w = Raid.Status.STOPPED; + } + + public void o() { + if (!this.d()) { + if (this.w == Raid.Status.ONGOING) { + boolean flag = this.p; + + this.p = this.k.isLoaded(this.j); + if (this.k.getDifficulty() == EnumDifficulty.PEACEFUL) { + org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(this, org.bukkit.event.raid.RaidStopEvent.Reason.PEACE); // CraftBukkit + this.n(); + return; + } + + if (flag != this.p) { + this.r.setVisible(this.p); + } + + if (!this.p) { + return; + } + + if (!this.k.b_(this.j)) { + this.z(); + } + + if (!this.k.b_(this.j)) { + if (this.q > 0) { + this.w = Raid.Status.LOSS; + org.bukkit.craftbukkit.event.CraftEventFactory.callRaidFinishEvent(this, new java.util.ArrayList<>()); // CraftBukkit + } else { + org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(this, org.bukkit.event.raid.RaidStopEvent.Reason.NOT_IN_VILLAGE); // CraftBukkit + this.n(); + } + } + + ++this.i; + if (this.i >= 48000L) { + org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(this, org.bukkit.event.raid.RaidStopEvent.Reason.TIMEOUT); // CraftBukkit + this.n(); + return; + } + + int i = this.r(); + boolean flag1; + + if (i == 0 && this.A()) { + if (this.t > 0) { + flag1 = this.y.isPresent(); + boolean flag2 = !flag1 && this.t % 5 == 0; + + if (flag1 && !this.k.getChunkProvider().a(new ChunkCoordIntPair((BlockPosition) this.y.get()))) { + flag2 = true; + } + + if (flag2) { + byte b0 = 0; + + if (this.t < 100) { + b0 = 1; + } else if (this.t < 40) { + b0 = 2; + } + + this.y = this.d(b0); + } + + if (this.t == 300 || this.t % 20 == 0) { + this.y(); + } + + --this.t; + this.r.setProgress(MathHelper.a((float) (300 - this.t) / 300.0F, 0.0F, 1.0F)); + } else if (this.t == 0 && this.q > 0) { + this.t = 300; + this.r.a((IChatBaseComponent) Raid.a); + return; + } + } + + if (this.i % 20L == 0L) { + this.y(); + this.F(); + if (i > 0) { + if (i <= 2) { + this.r.a(Raid.a.g().a(" - ").addSibling(new ChatMessage("event.minecraft.raid.raiders_remaining", new Object[]{i}))); + } else { + this.r.a((IChatBaseComponent) Raid.a); + } + } else { + this.r.a((IChatBaseComponent) Raid.a); + } + } + + flag1 = false; + int j = 0; + + while (this.G()) { + BlockPosition blockposition = this.y.isPresent() ? (BlockPosition) this.y.get() : this.a(j, 20); + + if (blockposition != null) { + this.l = true; + this.b(blockposition); + if (!flag1) { + this.a(blockposition); + flag1 = true; + } + } else { + ++j; + } + + if (j > 3) { + org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(this, org.bukkit.event.raid.RaidStopEvent.Reason.UNSPAWNABLE); // CraftBukkit + this.n(); + break; + } + } + + if (this.j() && !this.A() && i == 0) { + if (this.s < 40) { + ++this.s; + } else { + this.w = Raid.Status.VICTORY; + Iterator iterator = this.h.iterator(); + + List winners = new java.util.ArrayList<>(); // CraftBukkit + while (iterator.hasNext()) { + UUID uuid = (UUID) iterator.next(); + Entity entity = this.k.getEntity(uuid); + + if (entity instanceof EntityLiving && !entity.isSpectator()) { + EntityLiving entityliving = (EntityLiving) entity; + + entityliving.addEffect(new MobEffect(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.o - 1, false, false, true)); + if (entityliving instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entityliving; + + entityplayer.a(StatisticList.RAID_WIN); + CriterionTriggers.H.a(entityplayer); + winners.add(entityplayer.getBukkitEntity()); // CraftBukkit + } + } + } + org.bukkit.craftbukkit.event.CraftEventFactory.callRaidFinishEvent(this, winners); // CraftBukkit + } + } + + this.H(); + } else if (this.a()) { + ++this.x; + if (this.x >= 600) { + org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(this, org.bukkit.event.raid.RaidStopEvent.Reason.FINISHED); // CraftBukkit + this.n(); + return; + } + + if (this.x % 20 == 0) { + this.y(); + this.r.setVisible(true); + if (this.e()) { + this.r.setProgress(0.0F); + this.r.a(Raid.d); + } else { + this.r.a(Raid.e); + } + } + } + + } + } + + private void z() { + Stream stream = SectionPosition.a(SectionPosition.a(this.j), 2); + WorldServer worldserver = this.k; + + this.k.getClass(); + stream.filter(worldserver::a).map(SectionPosition::t).min(Comparator.comparingDouble((blockposition) -> { + return blockposition.m(this.j); + })).ifPresent(this::c); + } + + private Optional d(int i) { + for (int j = 0; j < 3; ++j) { + BlockPosition blockposition = this.a(i, 1); + + if (blockposition != null) { + return Optional.of(blockposition); + } + } + + return Optional.empty(); + } + + private boolean A() { + return this.C() ? !this.D() : !this.B(); + } + + private boolean B() { + return this.k() == this.v; + } + + private boolean C() { + return this.o > 1; + } + + private boolean D() { + return this.k() > this.v; + } + + private boolean E() { + return this.B() && this.r() == 0 && this.C(); + } + + private void F() { + Iterator> iterator = this.g.values().iterator(); + HashSet hashset = Sets.newHashSet(); + + while (iterator.hasNext()) { + Set set = (Set) iterator.next(); + Iterator iterator1 = set.iterator(); + + while (iterator1.hasNext()) { + EntityRaider entityraider = (EntityRaider) iterator1.next(); + BlockPosition blockposition = new BlockPosition(entityraider); + + if (!entityraider.dead && entityraider.dimension == this.k.getWorldProvider().getDimensionManager() && this.j.m(blockposition) < 12544.0D) { + if (entityraider.ticksLived > 600) { + if (this.k.getEntity(entityraider.getUniqueID()) == null) { + hashset.add(entityraider); + } + + if (!this.k.b_(blockposition) && entityraider.cw() > 2400) { + entityraider.b(entityraider.en() + 1); + } + + if (entityraider.en() >= 30) { + hashset.add(entityraider); + } + } + } else { + hashset.add(entityraider); + } + } + } + + Iterator iterator2 = hashset.iterator(); + + while (iterator2.hasNext()) { + EntityRaider entityraider1 = (EntityRaider) iterator2.next(); + + this.a(entityraider1, true); + } + + } + + private void a(BlockPosition blockposition) { + float f = 13.0F; + boolean flag = true; + Iterator iterator = this.k.getPlayers().iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + Vec3D vec3d = new Vec3D(entityhuman.locX, entityhuman.locY, entityhuman.locZ); + Vec3D vec3d1 = new Vec3D((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); + float f1 = MathHelper.sqrt((vec3d1.x - vec3d.x) * (vec3d1.x - vec3d.x) + (vec3d1.z - vec3d.z) * (vec3d1.z - vec3d.z)); + double d0 = vec3d.x + (double) (13.0F / f1) * (vec3d1.x - vec3d.x); + double d1 = vec3d.z + (double) (13.0F / f1) * (vec3d1.z - vec3d.z); + + if (f1 <= 64.0F || this.k.b_(new BlockPosition(entityhuman))) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(SoundEffects.EVENT_RAID_HORN, SoundCategory.NEUTRAL, d0, entityhuman.locY, d1, 64.0F, 1.0F)); + } + } + + } + + private void b(BlockPosition blockposition) { + boolean flag = false; + int i = this.q + 1; + + this.n = 0.0F; + DifficultyDamageScaler difficultydamagescaler = this.k.getDamageScaler(blockposition); + boolean flag1 = this.E(); + Raid.Wave[] araid_wave = Raid.Wave.f; + int j = araid_wave.length; + + // CraftBukkit start + EntityRaider leader = null; + List raiders = new java.util.ArrayList<>(); + // CraftBukkit end + for (int k = 0; k < j; ++k) { + Raid.Wave raid_wave = araid_wave[k]; + int l = this.a(raid_wave, i, flag1) + this.a(raid_wave, this.u, i, difficultydamagescaler, flag1); + int i1 = 0; + + for (int j1 = 0; j1 < l; ++j1) { + EntityRaider entityraider = (EntityRaider) raid_wave.g.a((World) this.k); + + if (!flag && entityraider.dX()) { + entityraider.setPatrolLeader(true); + this.a(i, entityraider); + flag = true; + leader = entityraider; // CraftBukkit + } + + this.a(i, entityraider, blockposition, false); + raiders.add(entityraider); // CraftBukkit + if (raid_wave.g == EntityTypes.RAVAGER) { + EntityRaider entityraider1 = null; + + if (i == this.a(EnumDifficulty.NORMAL)) { + entityraider1 = (EntityRaider) EntityTypes.PILLAGER.a((World) this.k); + } else if (i >= this.a(EnumDifficulty.HARD)) { + if (i1 == 0) { + entityraider1 = (EntityRaider) EntityTypes.EVOKER.a((World) this.k); + } else { + entityraider1 = (EntityRaider) EntityTypes.VINDICATOR.a((World) this.k); + } + } + + ++i1; + if (entityraider1 != null) { + this.a(i, entityraider1, blockposition, false); + entityraider1.setPositionRotation(blockposition, 0.0F, 0.0F); + entityraider1.startRiding(entityraider); + raiders.add(entityraider); // CraftBukkit + } + } + } + } + + this.y = Optional.empty(); + ++this.q; + this.p(); + this.H(); + org.bukkit.craftbukkit.event.CraftEventFactory.callRaidSpawnWaveEvent(this, leader, raiders); // CraftBukkit + } + + public void a(int i, EntityRaider entityraider, @Nullable BlockPosition blockposition, boolean flag) { + boolean flag1 = this.b(i, entityraider); + + if (flag1) { + entityraider.a(this); + entityraider.a(i); + entityraider.t(true); + entityraider.b(0); + if (!flag && blockposition != null) { + entityraider.setPosition((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 1.0D, (double) blockposition.getZ() + 0.5D); + entityraider.prepare(this.k, this.k.getDamageScaler(blockposition), EnumMobSpawn.EVENT, (GroupDataEntity) null, (NBTTagCompound) null); + entityraider.a(i, false); + entityraider.onGround = true; + this.k.addEntity(entityraider, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.RAID); // CraftBukkit + } + } + + } + + public void p() { + this.r.setProgress(MathHelper.a(this.q() / this.n, 0.0F, 1.0F)); + } + + public float q() { + float f = 0.0F; + Iterator iterator = this.g.values().iterator(); + + while (iterator.hasNext()) { + Set set = (Set) iterator.next(); + + EntityRaider entityraider; + + for (Iterator iterator1 = set.iterator(); iterator1.hasNext(); f += entityraider.getHealth()) { + entityraider = (EntityRaider) iterator1.next(); + } + } + + return f; + } + + private boolean G() { + return this.t == 0 && (this.q < this.v || this.E()) && this.r() == 0; + } + + public int r() { + return this.g.values().stream().mapToInt(Set::size).sum(); + } + + public void a(@Nonnull EntityRaider entityraider, boolean flag) { + Set set = (Set) this.g.get(entityraider.el()); + + if (set != null) { + boolean flag1 = set.remove(entityraider); + + if (flag1) { + if (flag) { + this.n -= entityraider.getHealth(); + } + + entityraider.a((Raid) null); + this.p(); + this.H(); + } + } + + } + + private void H() { + this.k.C().b(); + } + + public static ItemStack s() { + ItemStack itemstack = new ItemStack(Items.WHITE_BANNER); + NBTTagCompound nbttagcompound = itemstack.a("BlockEntityTag"); + NBTTagList nbttaglist = (new EnumBannerPatternType.a()).a(EnumBannerPatternType.RHOMBUS_MIDDLE, EnumColor.CYAN).a(EnumBannerPatternType.STRIPE_BOTTOM, EnumColor.LIGHT_GRAY).a(EnumBannerPatternType.STRIPE_CENTER, EnumColor.GRAY).a(EnumBannerPatternType.BORDER, EnumColor.LIGHT_GRAY).a(EnumBannerPatternType.STRIPE_MIDDLE, EnumColor.BLACK).a(EnumBannerPatternType.HALF_HORIZONTAL, EnumColor.LIGHT_GRAY).a(EnumBannerPatternType.CIRCLE_MIDDLE, EnumColor.LIGHT_GRAY).a(EnumBannerPatternType.BORDER, EnumColor.BLACK).a(); + + nbttagcompound.set("Patterns", nbttaglist); + itemstack.a((new ChatMessage("block.minecraft.ominous_banner", new Object[0])).a(EnumChatFormat.GOLD)); + return itemstack; + } + + @Nullable + public EntityRaider b(int i) { + return (EntityRaider) this.f.get(i); + } + + @Nullable + private BlockPosition a(int i, int j) { + int k = i == 0 ? 2 : 2 - i; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int l = 0; l < j; ++l) { + float f = this.k.random.nextFloat() * 6.2831855F; + int i1 = this.j.getX() + MathHelper.d(MathHelper.cos(f) * 32.0F * (float) k) + this.k.random.nextInt(5); + int j1 = this.j.getZ() + MathHelper.d(MathHelper.sin(f) * 32.0F * (float) k) + this.k.random.nextInt(5); + int k1 = this.k.a(HeightMap.Type.WORLD_SURFACE, i1, j1); + + blockposition_mutableblockposition.d(i1, k1, j1); + if ((!this.k.b_(blockposition_mutableblockposition) || i >= 2) && this.k.isAreaLoaded(blockposition_mutableblockposition.getX() - 10, blockposition_mutableblockposition.getY() - 10, blockposition_mutableblockposition.getZ() - 10, blockposition_mutableblockposition.getX() + 10, blockposition_mutableblockposition.getY() + 10, blockposition_mutableblockposition.getZ() + 10) && this.k.getChunkProvider().a(new ChunkCoordIntPair(blockposition_mutableblockposition)) && (SpawnerCreature.a(EntityPositionTypes.Surface.ON_GROUND, (IWorldReader) this.k, (BlockPosition) blockposition_mutableblockposition, EntityTypes.RAVAGER) || this.k.getType(blockposition_mutableblockposition.down()).getBlock() == Blocks.SNOW && this.k.getType(blockposition_mutableblockposition).isAir())) { + return blockposition_mutableblockposition; + } + } + + return null; + } + + private boolean b(int i, EntityRaider entityraider) { + return this.a(i, entityraider, true); + } + + public boolean a(int i, EntityRaider entityraider, boolean flag) { + this.g.computeIfAbsent(i, (integer) -> { + return Sets.newHashSet(); + }); + Set set = (Set) this.g.get(i); + EntityRaider entityraider1 = null; + Iterator iterator = set.iterator(); + + while (iterator.hasNext()) { + EntityRaider entityraider2 = (EntityRaider) iterator.next(); + + if (entityraider2.getUniqueID().equals(entityraider.getUniqueID())) { + entityraider1 = entityraider2; + break; + } + } + + if (entityraider1 != null) { + set.remove(entityraider1); + set.add(entityraider); + } + + set.add(entityraider); + if (flag) { + this.n += entityraider.getHealth(); + } + + this.p(); + this.H(); + return true; + } + + public void a(int i, EntityRaider entityraider) { + this.f.put(i, entityraider); + entityraider.setSlot(EnumItemSlot.HEAD, s()); + entityraider.a(EnumItemSlot.HEAD, 2.0F); + } + + public void c(int i) { + this.f.remove(i); + } + + public BlockPosition t() { + return this.j; + } + + private void c(BlockPosition blockposition) { + this.j = blockposition; + } + + public int u() { + return this.m; + } + + private int a(Raid.Wave raid_wave, int i, boolean flag) { + return flag ? raid_wave.h[this.v] : raid_wave.h[i]; + } + + private int a(Raid.Wave raid_wave, Random random, int i, DifficultyDamageScaler difficultydamagescaler, boolean flag) { + EnumDifficulty enumdifficulty = difficultydamagescaler.a(); + boolean flag1 = enumdifficulty == EnumDifficulty.EASY; + boolean flag2 = enumdifficulty == EnumDifficulty.NORMAL; + int j; + + switch (raid_wave) { + case WITCH: + if (flag1 || i <= 2 || i == 4) { + return 0; + } + + j = 1; + break; + case PILLAGER: + case VINDICATOR: + if (flag1) { + j = random.nextInt(2); + } else if (flag2) { + j = 1; + } else { + j = 2; + } + break; + case RAVAGER: + j = !flag1 && flag ? 1 : 0; + break; + default: + return 0; + } + + return j > 0 ? random.nextInt(j + 1) : 0; + } + + public boolean v() { + return this.p; + } + + public NBTTagCompound a(NBTTagCompound nbttagcompound) { + nbttagcompound.setInt("Id", this.m); + nbttagcompound.setBoolean("Started", this.l); + nbttagcompound.setBoolean("Active", this.p); + nbttagcompound.setLong("TicksActive", this.i); + nbttagcompound.setInt("BadOmenLevel", this.o); + nbttagcompound.setInt("GroupsSpawned", this.q); + nbttagcompound.setInt("PreRaidTicks", this.t); + nbttagcompound.setInt("PostRaidTicks", this.s); + nbttagcompound.setFloat("TotalHealth", this.n); + nbttagcompound.setInt("NumGroups", this.v); + nbttagcompound.setString("Status", this.w.a()); + nbttagcompound.setInt("CX", this.j.getX()); + nbttagcompound.setInt("CY", this.j.getY()); + nbttagcompound.setInt("CZ", this.j.getZ()); + NBTTagList nbttaglist = new NBTTagList(); + Iterator iterator = this.h.iterator(); + + while (iterator.hasNext()) { + UUID uuid = (UUID) iterator.next(); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.a("UUID", uuid); + nbttaglist.add(nbttagcompound1); + } + + nbttagcompound.set("HeroesOfTheVillage", nbttaglist); + return nbttagcompound; + } + + public int a(EnumDifficulty enumdifficulty) { + switch (enumdifficulty) { + case EASY: + return 3; + case NORMAL: + return 5; + case HARD: + return 7; + default: + return 0; + } + } + + public float w() { + int i = this.m(); + + return i == 2 ? 0.1F : (i == 3 ? 0.25F : (i == 4 ? 0.5F : (i == 5 ? 0.75F : 0.0F))); + } + + public void a(Entity entity) { + this.h.add(entity.getUniqueID()); + } + + // CraftBukkit start - a method to get all raiders + public java.util.Collection getRaiders() { + return this.g.values().stream().flatMap(Set::stream).collect(java.util.stream.Collectors.toSet()); + } + // CraftBukkit end + + static enum Wave { + + VINDICATOR(EntityTypes.VINDICATOR, new int[]{0, 0, 2, 0, 1, 4, 2, 5}), EVOKER(EntityTypes.EVOKER, new int[]{0, 0, 0, 0, 0, 1, 1, 2}), PILLAGER(EntityTypes.PILLAGER, new int[]{0, 4, 3, 3, 4, 4, 4, 2}), WITCH(EntityTypes.WITCH, new int[]{0, 0, 0, 0, 3, 0, 0, 1}), RAVAGER(EntityTypes.RAVAGER, new int[]{0, 0, 0, 1, 0, 1, 0, 2}); + + private static final Raid.Wave[] f = values(); + private final EntityTypes g; + private final int[] h; + + private Wave(EntityTypes entitytypes, int[] aint) { + this.g = entitytypes; + this.h = aint; + } + } + + static enum Status { + + ONGOING, VICTORY, LOSS, STOPPED; + + private static final Raid.Status[] e = values(); + + private Status() {} + + private static Raid.Status b(String s) { + Raid.Status[] araid_status = Raid.Status.e; + int i = araid_status.length; + + for (int j = 0; j < i; ++j) { + Raid.Status raid_status = araid_status[j]; + + if (s.equalsIgnoreCase(raid_status.name())) { + return raid_status; + } + } + + return Raid.Status.ONGOING; + } + + public String a() { + return this.name().toLowerCase(Locale.ROOT); + } + } +} diff --git a/src/main/java/net/minecraft/server/RandomPositionGenerator.java b/src/main/java/net/minecraft/server/RandomPositionGenerator.java index f2c4048c2..643dc0241 100644 --- a/src/main/java/net/minecraft/server/RandomPositionGenerator.java +++ b/src/main/java/net/minecraft/server/RandomPositionGenerator.java @@ -1,108 +1,118 @@ package net.minecraft.server; import java.util.Random; +import java.util.function.ToDoubleFunction; import javax.annotation.Nullable; public class RandomPositionGenerator { @Nullable public static Vec3D a(EntityCreature entitycreature, int i, int j) { - return c(entitycreature, i, j, (Vec3D) null); + return d(entitycreature, i, j, (Vec3D) null); } @Nullable public static Vec3D b(EntityCreature entitycreature, int i, int j) { - return a(entitycreature, i, j, (Vec3D) null, false, 0.0D); + entitycreature.getClass(); + return a(entitycreature, i, j, entitycreature::f); + } + + @Nullable + public static Vec3D a(EntityCreature entitycreature, int i, int j, ToDoubleFunction todoublefunction) { + return a(entitycreature, i, j, (Vec3D) null, false, 0.0D, todoublefunction); } @Nullable public static Vec3D a(EntityCreature entitycreature, int i, int j, Vec3D vec3d) { Vec3D vec3d1 = vec3d.a(entitycreature.locX, entitycreature.locY, entitycreature.locZ); - return c(entitycreature, i, j, vec3d1); + return d(entitycreature, i, j, vec3d1); } @Nullable public static Vec3D a(EntityCreature entitycreature, int i, int j, Vec3D vec3d, double d0) { Vec3D vec3d1 = vec3d.a(entitycreature.locX, entitycreature.locY, entitycreature.locZ); - return a(entitycreature, i, j, vec3d1, true, d0); + entitycreature.getClass(); + return a(entitycreature, i, j, vec3d1, true, d0, entitycreature::f); } @Nullable public static Vec3D b(EntityCreature entitycreature, int i, int j, Vec3D vec3d) { Vec3D vec3d1 = (new Vec3D(entitycreature.locX, entitycreature.locY, entitycreature.locZ)).d(vec3d); - return c(entitycreature, i, j, vec3d1); + entitycreature.getClass(); + return a(entitycreature, i, j, vec3d1, false, 1.5707963705062866D, entitycreature::f); } @Nullable - private static Vec3D c(EntityCreature entitycreature, int i, int j, @Nullable Vec3D vec3d) { - return a(entitycreature, i, j, vec3d, true, 1.5707963705062866D); + public static Vec3D c(EntityCreature entitycreature, int i, int j, Vec3D vec3d) { + Vec3D vec3d1 = (new Vec3D(entitycreature.locX, entitycreature.locY, entitycreature.locZ)).d(vec3d); + + return d(entitycreature, i, j, vec3d1); } @Nullable - private static Vec3D a(EntityCreature entitycreature, int i, int j, @Nullable Vec3D vec3d, boolean flag, double d0) { + private static Vec3D d(EntityCreature entitycreature, int i, int j, @Nullable Vec3D vec3d) { + entitycreature.getClass(); + return a(entitycreature, i, j, vec3d, true, 1.5707963705062866D, entitycreature::f); + } + + @Nullable + private static Vec3D a(EntityCreature entitycreature, int i, int j, @Nullable Vec3D vec3d, boolean flag, double d0, ToDoubleFunction todoublefunction) { NavigationAbstract navigationabstract = entitycreature.getNavigation(); Random random = entitycreature.getRandom(); boolean flag1; - if (entitycreature.dw()) { - double d1 = entitycreature.dt().distanceSquared((double) MathHelper.floor(entitycreature.locX), (double) MathHelper.floor(entitycreature.locY), (double) MathHelper.floor(entitycreature.locZ)) + 4.0D; - double d2 = (double) (entitycreature.du() + (float) i); - - flag1 = d1 < d2 * d2; + if (entitycreature.dL()) { + flag1 = entitycreature.dI().a((IPosition) entitycreature.getPositionVector(), (double) (entitycreature.dJ() + (float) i) + 1.0D); } else { flag1 = false; } boolean flag2 = false; - float f = -99999.0F; - int k = 0; - int l = 0; - int i1 = 0; + double d1 = Double.NEGATIVE_INFINITY; + BlockPosition blockposition = new BlockPosition(entitycreature); - for (int j1 = 0; j1 < 10; ++j1) { - BlockPosition blockposition = a(random, i, j, vec3d, d0); + for (int k = 0; k < 10; ++k) { + BlockPosition blockposition1 = a(random, i, j, vec3d, d0); - if (blockposition != null) { - int k1 = blockposition.getX(); - int l1 = blockposition.getY(); - int i2 = blockposition.getZ(); - BlockPosition blockposition1; + if (blockposition1 != null) { + int l = blockposition1.getX(); + int i1 = blockposition1.getY(); + int j1 = blockposition1.getZ(); + BlockPosition blockposition2; - if (entitycreature.dw() && i > 1) { - blockposition1 = entitycreature.dt(); - if (entitycreature.locX > (double) blockposition1.getX()) { - k1 -= random.nextInt(i / 2); + if (entitycreature.dL() && i > 1) { + blockposition2 = entitycreature.dI(); + if (entitycreature.locX > (double) blockposition2.getX()) { + l -= random.nextInt(i / 2); } else { - k1 += random.nextInt(i / 2); + l += random.nextInt(i / 2); } - if (entitycreature.locZ > (double) blockposition1.getZ()) { - i2 -= random.nextInt(i / 2); + if (entitycreature.locZ > (double) blockposition2.getZ()) { + j1 -= random.nextInt(i / 2); } else { - i2 += random.nextInt(i / 2); + j1 += random.nextInt(i / 2); } } - blockposition1 = new BlockPosition((double) k1 + entitycreature.locX, (double) l1 + entitycreature.locY, (double) i2 + entitycreature.locZ); - if (!entitycreature.world.isLoaded(blockposition1)) continue; // Paper - if ((!flag1 || entitycreature.f(blockposition1)) && navigationabstract.a(blockposition1)) { + blockposition2 = new BlockPosition((double) l + entitycreature.locX, (double) i1 + entitycreature.locY, (double) j1 + entitycreature.locZ); + if (!entitycreature.world.isLoaded(blockposition2)) continue; // Paper + if ((!flag1 || entitycreature.a(blockposition2)) && navigationabstract.a(blockposition2)) { if (!flag) { - blockposition1 = a(blockposition1, entitycreature); - if (b(blockposition1, entitycreature)) { + blockposition2 = a(blockposition2, entitycreature); + if (b(blockposition2, entitycreature)) { continue; } } - float f1 = entitycreature.a(blockposition1); + double d2 = todoublefunction.applyAsDouble(blockposition2); - if (f1 > f) { - f = f1; - k = k1; - l = l1; - i1 = i2; + if (d2 > d1) { + d1 = d2; + blockposition = blockposition2; flag2 = true; } } @@ -110,7 +120,7 @@ public class RandomPositionGenerator { } if (flag2) { - return new Vec3D((double) k + entitycreature.locX, (double) l + entitycreature.locY, (double) i1 + entitycreature.locZ); + return new Vec3D(blockposition); } else { return null; } @@ -119,7 +129,7 @@ public class RandomPositionGenerator { @Nullable private static BlockPosition a(Random random, int i, int j, @Nullable Vec3D vec3d, double d0) { if (vec3d != null && d0 < 3.141592653589793D) { - double d1 = MathHelper.c(vec3d.z, vec3d.x) - 1.5707963705062866D; + double d1 = MathHelper.d(vec3d.z, vec3d.x) - 1.5707963705062866D; double d2 = d1 + (double) (2.0F * random.nextFloat() - 1.0F) * d0; double d3 = Math.sqrt(random.nextDouble()) * (double) MathHelper.a * (double) i; double d4 = -d3 * Math.sin(d2); @@ -147,7 +157,7 @@ public class RandomPositionGenerator { } else { BlockPosition blockposition1; - for (blockposition1 = blockposition.up(); blockposition1.getY() < entitycreature.world.getHeight() && entitycreature.world.getType(blockposition1).getMaterial().isBuildable(); blockposition1 = blockposition1.up()) { + for (blockposition1 = blockposition.up(); blockposition1.getY() < entitycreature.world.getBuildHeight() && entitycreature.world.getType(blockposition1).getMaterial().isBuildable(); blockposition1 = blockposition1.up()) { ; } diff --git a/src/main/java/net/minecraft/server/RayTrace.java b/src/main/java/net/minecraft/server/RayTrace.java new file mode 100644 index 000000000..615c18277 --- /dev/null +++ b/src/main/java/net/minecraft/server/RayTrace.java @@ -0,0 +1,76 @@ +package net.minecraft.server; + +import java.util.function.Predicate; + +public class RayTrace { + + private final Vec3D a; + private final Vec3D b; + private final RayTrace.BlockCollisionOption c; + private final RayTrace.FluidCollisionOption d; + private final VoxelShapeCollision e; + + public RayTrace(Vec3D vec3d, Vec3D vec3d1, RayTrace.BlockCollisionOption raytrace_blockcollisionoption, RayTrace.FluidCollisionOption raytrace_fluidcollisionoption, Entity entity) { + this.a = vec3d; + this.b = vec3d1; + this.c = raytrace_blockcollisionoption; + this.d = raytrace_fluidcollisionoption; + this.e = (entity == null) ? VoxelShapeCollision.a() : VoxelShapeCollision.a(entity); // CraftBukkit + } + + public Vec3D a() { + return this.b; + } + + public Vec3D b() { + return this.a; + } + + public VoxelShape a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.c.get(iblockdata, iblockaccess, blockposition, this.e); + } + + public VoxelShape a(Fluid fluid, IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.d.a(fluid) ? fluid.d(iblockaccess, blockposition) : VoxelShapes.a(); + } + + public static enum FluidCollisionOption { + + NONE((fluid) -> { + return false; + }), SOURCE_ONLY(Fluid::isSource), ANY((fluid) -> { + return !fluid.isEmpty(); + }); + + private final Predicate predicate; + + private FluidCollisionOption(Predicate predicate) { // CraftBukkit - decompile error + this.predicate = predicate; + } + + public boolean a(Fluid fluid) { + return this.predicate.test(fluid); + } + } + + public interface c { + + VoxelShape get(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision); + } + + public static enum BlockCollisionOption implements RayTrace.c { + + COLLIDER(IBlockData::b), OUTLINE(IBlockData::a); + + private final RayTrace.c c; + + private BlockCollisionOption(RayTrace.c raytrace_c) { + this.c = raytrace_c; + } + + @Override + public VoxelShape get(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, VoxelShapeCollision voxelshapecollision) { + return this.c.get(iblockdata, iblockaccess, blockposition, voxelshapecollision); + } + } +} diff --git a/src/main/java/net/minecraft/server/RecipeArmorDye.java b/src/main/java/net/minecraft/server/RecipeArmorDye.java index d4f74044b..92bdd30c2 100644 --- a/src/main/java/net/minecraft/server/RecipeArmorDye.java +++ b/src/main/java/net/minecraft/server/RecipeArmorDye.java @@ -3,123 +3,76 @@ package net.minecraft.server; import com.google.common.collect.Lists; import java.util.List; -public class RecipeArmorDye extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipeArmorDye extends ShapelessRecipes { // CraftBukkit - added extends // CraftBukkit start - Delegate to new parent class with bogus info public RecipeArmorDye(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Items.LEATHER_HELMET, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.BONE_MEAL))); + super(minecraftkey, "", new ItemStack(Items.LEATHER_HELMET), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.BONE_MEAL))); } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - ItemStack itemstack = ItemStack.a; - List list = Lists.newArrayList(); + public boolean a(InventoryCrafting inventorycrafting, World world) { + ItemStack itemstack = ItemStack.a; + List list = Lists.newArrayList(); - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack1 = iinventory.getItem(i); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack1 = inventorycrafting.getItem(i); - if (!itemstack1.isEmpty()) { - if (itemstack1.getItem() instanceof ItemArmorColorable) { - if (!itemstack.isEmpty()) { - return false; - } - - itemstack = itemstack1; - } else { - if (!(itemstack1.getItem() instanceof ItemDye)) { - return false; - } - - list.add(itemstack1); + if (!itemstack1.isEmpty()) { + if (itemstack1.getItem() instanceof IDyeable) { + if (!itemstack.isEmpty()) { + return false; } + + itemstack = itemstack1; + } else { + if (!(itemstack1.getItem() instanceof ItemDye)) { + return false; + } + + list.add(itemstack1); } } - - return !itemstack.isEmpty() && !list.isEmpty(); } + + return !itemstack.isEmpty() && !list.isEmpty(); } - public ItemStack craftItem(IInventory iinventory) { + public ItemStack a(InventoryCrafting inventorycrafting) { + List list = Lists.newArrayList(); ItemStack itemstack = ItemStack.a; - int[] aint = new int[3]; - int i = 0; - int j = 0; - ItemArmorColorable itemarmorcolorable = null; - int k; - float f; - int l; - - for (k = 0; k < iinventory.getSize(); ++k) { - ItemStack itemstack1 = iinventory.getItem(k); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack1 = inventorycrafting.getItem(i); if (!itemstack1.isEmpty()) { Item item = itemstack1.getItem(); - if (item instanceof ItemArmorColorable) { - itemarmorcolorable = (ItemArmorColorable) item; + if (item instanceof IDyeable) { if (!itemstack.isEmpty()) { return ItemStack.a; } itemstack = itemstack1.cloneItemStack(); - itemstack.setCount(1); - if (itemarmorcolorable.e(itemstack1)) { - int i1 = itemarmorcolorable.f(itemstack); - - f = (float) (i1 >> 16 & 255) / 255.0F; - float f1 = (float) (i1 >> 8 & 255) / 255.0F; - float f2 = (float) (i1 & 255) / 255.0F; - - i = (int) ((float) i + Math.max(f, Math.max(f1, f2)) * 255.0F); - aint[0] = (int) ((float) aint[0] + f * 255.0F); - aint[1] = (int) ((float) aint[1] + f1 * 255.0F); - aint[2] = (int) ((float) aint[2] + f2 * 255.0F); - ++j; - } } else { if (!(item instanceof ItemDye)) { return ItemStack.a; } - float[] afloat = ((ItemDye) item).d().d(); - int j1 = (int) (afloat[0] * 255.0F); - - l = (int) (afloat[1] * 255.0F); - int k1 = (int) (afloat[2] * 255.0F); - - i += Math.max(j1, Math.max(l, k1)); - aint[0] += j1; - aint[1] += l; - aint[2] += k1; - ++j; + list.add((ItemDye) item); } } } - if (itemarmorcolorable == null) { - return ItemStack.a; + if (!itemstack.isEmpty() && !list.isEmpty()) { + return IDyeable.a(itemstack, list); } else { - k = aint[0] / j; - int l1 = aint[1] / j; - int i2 = aint[2] / j; - float f3 = (float) i / (float) j; - - f = (float) Math.max(k, Math.max(l1, i2)); - k = (int) ((float) k * f3 / f); - l1 = (int) ((float) l1 * f3 / f); - i2 = (int) ((float) i2 * f3 / f); - l = (k << 8) + l1; - l = (l << 8) + i2; - itemarmorcolorable.a(itemstack, l); - return itemstack; + return ItemStack.a; } } - public RecipeSerializer a() { - return RecipeSerializers.c; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.c; } } diff --git a/src/main/java/net/minecraft/server/RecipeBannerAdd.java b/src/main/java/net/minecraft/server/RecipeBannerAdd.java deleted file mode 100644 index 29ea581ba..000000000 --- a/src/main/java/net/minecraft/server/RecipeBannerAdd.java +++ /dev/null @@ -1,176 +0,0 @@ -package net.minecraft.server; - -import javax.annotation.Nullable; - -public class RecipeBannerAdd extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends - - // CraftBukkit start - Delegate to new parent class with bogus info - public RecipeBannerAdd(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Items.WHITE_BANNER, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.WHITE_BANNER))); - } - // CraftBukkit end - - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - boolean flag = false; - - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack = iinventory.getItem(i); - - if (itemstack.getItem() instanceof ItemBanner) { - if (flag) { - return false; - } - - if (TileEntityBanner.a(itemstack) >= 6) { - return false; - } - - flag = true; - } - } - - return flag && this.c(iinventory) != null; - } - } - - public ItemStack craftItem(IInventory iinventory) { - ItemStack itemstack = ItemStack.a; - - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack1 = iinventory.getItem(i); - - if (!itemstack1.isEmpty() && itemstack1.getItem() instanceof ItemBanner) { - itemstack = itemstack1.cloneItemStack(); - itemstack.setCount(1); - break; - } - } - - EnumBannerPatternType enumbannerpatterntype = this.c(iinventory); - - if (enumbannerpatterntype != null) { - EnumColor enumcolor = EnumColor.WHITE; - - for (int j = 0; j < iinventory.getSize(); ++j) { - Item item = iinventory.getItem(j).getItem(); - - if (item instanceof ItemDye) { - enumcolor = ((ItemDye) item).d(); - break; - } - } - - NBTTagCompound nbttagcompound = itemstack.a("BlockEntityTag"); - NBTTagList nbttaglist; - - if (nbttagcompound.hasKeyOfType("Patterns", 9)) { - nbttaglist = nbttagcompound.getList("Patterns", 10); - } else { - nbttaglist = new NBTTagList(); - nbttagcompound.set("Patterns", nbttaglist); - } - - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - - nbttagcompound1.setString("Pattern", enumbannerpatterntype.b()); - nbttagcompound1.setInt("Color", enumcolor.getColorIndex()); - nbttaglist.add((NBTBase) nbttagcompound1); - } - - return itemstack; - } - - @Nullable - private EnumBannerPatternType c(IInventory iinventory) { - EnumBannerPatternType[] aenumbannerpatterntype = EnumBannerPatternType.values(); - int i = aenumbannerpatterntype.length; - - for (int j = 0; j < i; ++j) { - EnumBannerPatternType enumbannerpatterntype = aenumbannerpatterntype[j]; - - if (enumbannerpatterntype.d()) { - boolean flag = true; - int k; - - if (enumbannerpatterntype.e()) { - boolean flag1 = false; - boolean flag2 = false; - - for (k = 0; k < iinventory.getSize() && flag; ++k) { - ItemStack itemstack = iinventory.getItem(k); - - if (!itemstack.isEmpty() && !(itemstack.getItem() instanceof ItemBanner)) { - if (itemstack.getItem() instanceof ItemDye) { - if (flag2) { - flag = false; - break; - } - - flag2 = true; - } else { - if (flag1 || !itemstack.doMaterialsMatch(enumbannerpatterntype.f())) { - flag = false; - break; - } - - flag1 = true; - } - } - } - - if (!flag1 || !flag2) { - flag = false; - } - } else if (iinventory.getSize() != enumbannerpatterntype.c().length * enumbannerpatterntype.c()[0].length()) { - flag = false; - } else { - EnumColor enumcolor = null; - - for (int l = 0; l < iinventory.getSize() && flag; ++l) { - k = l / 3; - int i1 = l % 3; - ItemStack itemstack1 = iinventory.getItem(l); - Item item = itemstack1.getItem(); - - if (!itemstack1.isEmpty() && !(item instanceof ItemBanner)) { - if (!(item instanceof ItemDye)) { - flag = false; - break; - } - - EnumColor enumcolor1 = ((ItemDye) item).d(); - - if (enumcolor != null && enumcolor != enumcolor1) { - flag = false; - break; - } - - if (enumbannerpatterntype.c()[k].charAt(i1) == ' ') { - flag = false; - break; - } - - enumcolor = enumcolor1; - } else if (enumbannerpatterntype.c()[k].charAt(i1) != ' ') { - flag = false; - break; - } - } - } - - if (flag) { - return enumbannerpatterntype; - } - } - } - - return null; - } - - public RecipeSerializer a() { - return RecipeSerializers.m; - } -} diff --git a/src/main/java/net/minecraft/server/RecipeBannerDuplicate.java b/src/main/java/net/minecraft/server/RecipeBannerDuplicate.java index 9e4d82279..3fb5c101a 100644 --- a/src/main/java/net/minecraft/server/RecipeBannerDuplicate.java +++ b/src/main/java/net/minecraft/server/RecipeBannerDuplicate.java @@ -1,80 +1,84 @@ package net.minecraft.server; -public class RecipeBannerDuplicate extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipeBannerDuplicate extends ShapelessRecipes { // CraftBukkit - added extends // CraftBukkit start - Delegate to new parent class with bogus info public RecipeBannerDuplicate(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Items.WHITE_BANNER, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.WHITE_BANNER))); + super(minecraftkey, "", new ItemStack(Items.WHITE_BANNER), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.WHITE_BANNER))); } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - EnumColor enumcolor = null; - ItemStack itemstack = null; - ItemStack itemstack1 = null; + public boolean a(InventoryCrafting inventorycrafting, World world) { + EnumColor enumcolor = null; + ItemStack itemstack = null; + ItemStack itemstack1 = null; - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack2 = iinventory.getItem(i); - Item item = itemstack2.getItem(); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack2 = inventorycrafting.getItem(i); + Item item = itemstack2.getItem(); - if (item instanceof ItemBanner) { - ItemBanner itembanner = (ItemBanner) item; + if (item instanceof ItemBanner) { + ItemBanner itembanner = (ItemBanner) item; - if (enumcolor == null) { - enumcolor = itembanner.b(); - } else if (enumcolor != itembanner.b()) { + if (enumcolor == null) { + enumcolor = itembanner.b(); + } else if (enumcolor != itembanner.b()) { + return false; + } + + int j = TileEntityBanner.a(itemstack2); + + if (j > 6) { + return false; + } + + if (j > 0) { + if (itemstack != null) { return false; } - boolean flag = TileEntityBanner.a(itemstack2) > 0; - - if (flag) { - if (itemstack != null) { - return false; - } - - itemstack = itemstack2; - } else { - if (itemstack1 != null) { - return false; - } - - itemstack1 = itemstack2; + itemstack = itemstack2; + } else { + if (itemstack1 != null) { + return false; } + + itemstack1 = itemstack2; } } - - return itemstack != null && itemstack1 != null; } + + return itemstack != null && itemstack1 != null; } - public ItemStack craftItem(IInventory iinventory) { - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack = iinventory.getItem(i); + public ItemStack a(InventoryCrafting inventorycrafting) { + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); - if (!itemstack.isEmpty() && TileEntityBanner.a(itemstack) > 0) { - ItemStack itemstack1 = itemstack.cloneItemStack(); + if (!itemstack.isEmpty()) { + int j = TileEntityBanner.a(itemstack); - itemstack1.setCount(1); - return itemstack1; + if (j > 0 && j <= 6) { + ItemStack itemstack1 = itemstack.cloneItemStack(); + + itemstack1.setCount(1); + return itemstack1; + } } } return ItemStack.a; } - public NonNullList b(IInventory iinventory) { - NonNullList nonnulllist = NonNullList.a(iinventory.getSize(), ItemStack.a); + public NonNullList b(InventoryCrafting inventorycrafting) { + NonNullList nonnulllist = NonNullList.a(inventorycrafting.getSize(), ItemStack.a); for (int i = 0; i < nonnulllist.size(); ++i) { - ItemStack itemstack = iinventory.getItem(i); + ItemStack itemstack = inventorycrafting.getItem(i); if (!itemstack.isEmpty()) { - if (itemstack.getItem().p()) { - nonnulllist.set(i, new ItemStack(itemstack.getItem().o())); + if (itemstack.getItem().o()) { + nonnulllist.set(i, new ItemStack(itemstack.getItem().n())); } else if (itemstack.hasTag() && TileEntityBanner.a(itemstack) > 0) { ItemStack itemstack1 = itemstack.cloneItemStack(); @@ -87,7 +91,8 @@ public class RecipeBannerDuplicate extends ShapelessRecipes implements IRecipe { return nonnulllist; } - public RecipeSerializer a() { - return RecipeSerializers.l; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.k; } } diff --git a/src/main/java/net/minecraft/server/RecipeBlasting.java b/src/main/java/net/minecraft/server/RecipeBlasting.java new file mode 100644 index 000000000..a2d76d597 --- /dev/null +++ b/src/main/java/net/minecraft/server/RecipeBlasting.java @@ -0,0 +1,33 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftBlastingRecipe; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftRecipe; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.Recipe; +// CraftBukkit end + +public class RecipeBlasting extends RecipeCooking { + + public RecipeBlasting(MinecraftKey minecraftkey, String s, RecipeItemStack recipeitemstack, ItemStack itemstack, float f, int i) { + super(Recipes.BLASTING, minecraftkey, s, recipeitemstack, itemstack, f, i); + } + + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.q; + } + + // CraftBukkit start + @Override + public Recipe toBukkitRecipe() { + CraftItemStack result = CraftItemStack.asCraftMirror(this.result); + + CraftBlastingRecipe recipe = new CraftBlastingRecipe(CraftNamespacedKey.fromMinecraft(this.key), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); + recipe.setGroup(this.group); + + return recipe; + } + // CraftBukkit end +} diff --git a/src/main/java/net/minecraft/server/RecipeBookClone.java b/src/main/java/net/minecraft/server/RecipeBookClone.java index 0069a067b..9feaad43a 100644 --- a/src/main/java/net/minecraft/server/RecipeBookClone.java +++ b/src/main/java/net/minecraft/server/RecipeBookClone.java @@ -1,50 +1,46 @@ package net.minecraft.server; -public class RecipeBookClone extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipeBookClone extends ShapelessRecipes { // CraftBukkit - added extends // CraftBukkit start - Delegate to new parent class with bogus info public RecipeBookClone(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Items.WRITTEN_BOOK, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.WRITABLE_BOOK))); + super(minecraftkey, "", new ItemStack(Items.WRITTEN_BOOK), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.WRITABLE_BOOK))); } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - int i = 0; - ItemStack itemstack = ItemStack.a; - - for (int j = 0; j < iinventory.getSize(); ++j) { - ItemStack itemstack1 = iinventory.getItem(j); - - if (!itemstack1.isEmpty()) { - if (itemstack1.getItem() == Items.WRITTEN_BOOK) { - if (!itemstack.isEmpty()) { - return false; - } - - itemstack = itemstack1; - } else { - if (itemstack1.getItem() != Items.WRITABLE_BOOK) { - return false; - } - - ++i; - } - } - } - - return !itemstack.isEmpty() && itemstack.hasTag() && i > 0; - } - } - - public ItemStack craftItem(IInventory iinventory) { + public boolean a(InventoryCrafting inventorycrafting, World world) { int i = 0; ItemStack itemstack = ItemStack.a; - for (int j = 0; j < iinventory.getSize(); ++j) { - ItemStack itemstack1 = iinventory.getItem(j); + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack1 = inventorycrafting.getItem(j); + + if (!itemstack1.isEmpty()) { + if (itemstack1.getItem() == Items.WRITTEN_BOOK) { + if (!itemstack.isEmpty()) { + return false; + } + + itemstack = itemstack1; + } else { + if (itemstack1.getItem() != Items.WRITABLE_BOOK) { + return false; + } + + ++i; + } + } + } + + return !itemstack.isEmpty() && itemstack.hasTag() && i > 0; + } + + public ItemStack a(InventoryCrafting inventorycrafting) { + int i = 0; + ItemStack itemstack = ItemStack.a; + + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack1 = inventorycrafting.getItem(j); if (!itemstack1.isEmpty()) { if (itemstack1.getItem() == Items.WRITTEN_BOOK) { @@ -75,14 +71,14 @@ public class RecipeBookClone extends ShapelessRecipes implements IRecipe { // Cr } } - public NonNullList b(IInventory iinventory) { - NonNullList nonnulllist = NonNullList.a(iinventory.getSize(), ItemStack.a); + public NonNullList b(InventoryCrafting inventorycrafting) { + NonNullList nonnulllist = NonNullList.a(inventorycrafting.getSize(), ItemStack.a); for (int i = 0; i < nonnulllist.size(); ++i) { - ItemStack itemstack = iinventory.getItem(i); + ItemStack itemstack = inventorycrafting.getItem(i); - if (itemstack.getItem().p()) { - nonnulllist.set(i, new ItemStack(itemstack.getItem().o())); + if (itemstack.getItem().o()) { + nonnulllist.set(i, new ItemStack(itemstack.getItem().n())); } else if (itemstack.getItem() instanceof ItemWrittenBook) { ItemStack itemstack1 = itemstack.cloneItemStack(); @@ -95,7 +91,8 @@ public class RecipeBookClone extends ShapelessRecipes implements IRecipe { // Cr return nonnulllist; } - public RecipeSerializer a() { - return RecipeSerializers.d; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.d; } } diff --git a/src/main/java/net/minecraft/server/RecipeBookServer.java b/src/main/java/net/minecraft/server/RecipeBookServer.java index 4d9f3d369..0e66bdda8 100644 --- a/src/main/java/net/minecraft/server/RecipeBookServer.java +++ b/src/main/java/net/minecraft/server/RecipeBookServer.java @@ -5,29 +5,31 @@ import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit public class RecipeBookServer extends RecipeBook { - private static final Logger g = LogManager.getLogger(); - private final CraftingManager h; + private static final Logger LOGGER = LogManager.getLogger(); + private final CraftingManager l; public RecipeBookServer(CraftingManager craftingmanager) { - this.h = craftingmanager; + this.l = craftingmanager; } - public int a(Collection collection, EntityPlayer entityplayer) { + public int a(Collection> collection, EntityPlayer entityplayer) { List list = Lists.newArrayList(); int i = 0; Iterator iterator = collection.iterator(); while (iterator.hasNext()) { - IRecipe irecipe = (IRecipe) iterator.next(); + IRecipe irecipe = (IRecipe) iterator.next(); MinecraftKey minecraftkey = irecipe.getKey(); - if (!this.a.contains(minecraftkey) && !irecipe.c() && CraftEventFactory.handlePlayerRecipeListUpdateEvent(entityplayer, minecraftkey)) { // CraftBukkit + if (!this.a.contains(minecraftkey) && !irecipe.isComplex() && CraftEventFactory.handlePlayerRecipeListUpdateEvent(entityplayer, minecraftkey)) { // CraftBukkit this.a(minecraftkey); this.c(minecraftkey); list.add(minecraftkey); @@ -40,13 +42,13 @@ public class RecipeBookServer extends RecipeBook { return i; } - public int b(Collection collection, EntityPlayer entityplayer) { + public int b(Collection> collection, EntityPlayer entityplayer) { List list = Lists.newArrayList(); int i = 0; Iterator iterator = collection.iterator(); while (iterator.hasNext()) { - IRecipe irecipe = (IRecipe) iterator.next(); + IRecipe irecipe = (IRecipe) iterator.next(); MinecraftKey minecraftkey = irecipe.getKey(); if (this.a.contains(minecraftkey)) { @@ -65,7 +67,7 @@ public class RecipeBookServer extends RecipeBook { entityplayer.playerConnection.sendPacket(new PacketPlayOutRecipes(packetplayoutrecipes_action, list, Collections.emptyList(), this.c, this.d, this.e, this.f)); } - public NBTTagCompound e() { + public NBTTagCompound save() { NBTTagCompound nbttagcompound = new NBTTagCompound(); nbttagcompound.setBoolean("isGuiOpen", this.c); @@ -77,12 +79,12 @@ public class RecipeBookServer extends RecipeBook { while (iterator.hasNext()) { MinecraftKey minecraftkey = (MinecraftKey) iterator.next(); - // Paper start - ignore missing recipes - IRecipe recipe = this.h.a(minecraftkey); - if (recipe == null) continue; + final Optional> recipe = this.l.a(minecraftkey); + if (!recipe.isPresent()) continue; // Paper end - nbttaglist.add((NBTBase) (new NBTTagString(minecraftkey.toString()))); + + nbttaglist.add(new NBTTagString(minecraftkey.toString())); } nbttagcompound.set("recipes", nbttaglist); @@ -91,12 +93,12 @@ public class RecipeBookServer extends RecipeBook { while (iterator1.hasNext()) { MinecraftKey minecraftkey1 = (MinecraftKey) iterator1.next(); - // Paper start - ignore missing recipes - IRecipe recipe = this.h.a(minecraftkey1); - if (recipe == null) continue; + final Optional> recipe = this.l.a(minecraftkey1); + if (!recipe.isPresent()) continue; // Paper end - nbttaglist1.add((NBTBase) (new NBTTagString(minecraftkey1.toString()))); + + nbttaglist1.add(new NBTTagString(minecraftkey1.toString())); } nbttagcompound.set("toBeDisplayed", nbttaglist1); @@ -110,27 +112,27 @@ public class RecipeBookServer extends RecipeBook { this.f = nbttagcompound.getBoolean("isFurnaceFilteringCraftable"); NBTTagList nbttaglist = nbttagcompound.getList("recipes", 8); - for (int i = 0; i < nbttaglist.size(); ++i) { - MinecraftKey minecraftkey = new MinecraftKey(nbttaglist.getString(i)); - IRecipe irecipe = this.h.a(minecraftkey); - - if (irecipe == null) { - RecipeBookServer.g.error("Tried to load unrecognized recipe: {} removed now.", minecraftkey); - } else { - this.a(irecipe); - } - } - + this.a(nbttaglist, this::a); NBTTagList nbttaglist1 = nbttagcompound.getList("toBeDisplayed", 8); - for (int j = 0; j < nbttaglist1.size(); ++j) { - MinecraftKey minecraftkey1 = new MinecraftKey(nbttaglist1.getString(j)); - IRecipe irecipe1 = this.h.a(minecraftkey1); + this.a(nbttaglist1, this::f); + } - if (irecipe1 == null) { - RecipeBookServer.g.error("Tried to load unrecognized recipe: {} removed now.", minecraftkey1); - } else { - this.f(irecipe1); + private void a(NBTTagList nbttaglist, Consumer> consumer) { + for (int i = 0; i < nbttaglist.size(); ++i) { + String s = nbttaglist.getString(i); + + try { + MinecraftKey minecraftkey = new MinecraftKey(s); + Optional> optional = this.l.a(minecraftkey); + + if (!optional.isPresent()) { + RecipeBookServer.LOGGER.error("Tried to load unrecognized recipe: {} removed now.", minecraftkey); + } else { + consumer.accept(optional.get()); + } + } catch (ResourceKeyInvalidException resourcekeyinvalidexception) { + RecipeBookServer.LOGGER.error("Tried to load improperly formatted recipe: {} removed now.", s); } } diff --git a/src/main/java/net/minecraft/server/RecipeCampfire.java b/src/main/java/net/minecraft/server/RecipeCampfire.java new file mode 100644 index 000000000..678f039cf --- /dev/null +++ b/src/main/java/net/minecraft/server/RecipeCampfire.java @@ -0,0 +1,33 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftCampfireRecipe; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftRecipe; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.Recipe; +// CraftBukkit end + +public class RecipeCampfire extends RecipeCooking { + + public RecipeCampfire(MinecraftKey minecraftkey, String s, RecipeItemStack recipeitemstack, ItemStack itemstack, float f, int i) { + super(Recipes.CAMPFIRE_COOKING, minecraftkey, s, recipeitemstack, itemstack, f, i); + } + + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.s; + } + + // CraftBukkit start + @Override + public Recipe toBukkitRecipe() { + CraftItemStack result = CraftItemStack.asCraftMirror(this.result); + + CraftCampfireRecipe recipe = new CraftCampfireRecipe(CraftNamespacedKey.fromMinecraft(this.key), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); + recipe.setGroup(this.group); + + return recipe; + } + // CraftBukkit end +} diff --git a/src/main/java/net/minecraft/server/RecipeFireworks.java b/src/main/java/net/minecraft/server/RecipeFireworks.java index a57f88aec..1602afb87 100644 --- a/src/main/java/net/minecraft/server/RecipeFireworks.java +++ b/src/main/java/net/minecraft/server/RecipeFireworks.java @@ -1,6 +1,6 @@ package net.minecraft.server; -public class RecipeFireworks extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipeFireworks extends ShapelessRecipes { // CraftBukkit - added extends private static final RecipeItemStack a = RecipeItemStack.a(Items.PAPER); private static final RecipeItemStack b = RecipeItemStack.a(Items.GUNPOWDER); @@ -8,50 +8,46 @@ public class RecipeFireworks extends ShapelessRecipes implements IRecipe { // Cr // CraftBukkit start - Delegate to new parent class with bogus info public RecipeFireworks(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Items.FIREWORK_ROCKET, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.GUNPOWDER))); + super(minecraftkey, "", new ItemStack(Items.FIREWORK_ROCKET, 3), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.GUNPOWDER))); } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - boolean flag = false; - int i = 0; + public boolean a(InventoryCrafting inventorycrafting, World world) { + boolean flag = false; + int i = 0; - for (int j = 0; j < iinventory.getSize(); ++j) { - ItemStack itemstack = iinventory.getItem(j); + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack = inventorycrafting.getItem(j); - if (!itemstack.isEmpty()) { - if (RecipeFireworks.a.test(itemstack)) { - if (flag) { - return false; - } - - flag = true; - } else if (RecipeFireworks.b.test(itemstack)) { - ++i; - if (i > 3) { - return false; - } - } else if (!RecipeFireworks.c.test(itemstack)) { + if (!itemstack.isEmpty()) { + if (RecipeFireworks.a.test(itemstack)) { + if (flag) { return false; } + + flag = true; + } else if (RecipeFireworks.b.test(itemstack)) { + ++i; + if (i > 3) { + return false; + } + } else if (!RecipeFireworks.c.test(itemstack)) { + return false; } } - - return flag && i >= 1; } + + return flag && i >= 1; } - public ItemStack craftItem(IInventory iinventory) { + public ItemStack a(InventoryCrafting inventorycrafting) { ItemStack itemstack = new ItemStack(Items.FIREWORK_ROCKET, 3); NBTTagCompound nbttagcompound = itemstack.a("Fireworks"); NBTTagList nbttaglist = new NBTTagList(); int i = 0; - for (int j = 0; j < iinventory.getSize(); ++j) { - ItemStack itemstack1 = iinventory.getItem(j); + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack1 = inventorycrafting.getItem(j); if (!itemstack1.isEmpty()) { if (RecipeFireworks.b.test(itemstack1)) { @@ -60,7 +56,7 @@ public class RecipeFireworks extends ShapelessRecipes implements IRecipe { // Cr NBTTagCompound nbttagcompound1 = itemstack1.b("Explosion"); if (nbttagcompound1 != null) { - nbttaglist.add((NBTBase) nbttagcompound1); + nbttaglist.add(nbttagcompound1); } } } @@ -74,11 +70,13 @@ public class RecipeFireworks extends ShapelessRecipes implements IRecipe { // Cr return itemstack; } - public ItemStack d() { + @Override + public ItemStack c() { return new ItemStack(Items.FIREWORK_ROCKET); } - public RecipeSerializer a() { - return RecipeSerializers.g; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.g; } } diff --git a/src/main/java/net/minecraft/server/RecipeFireworksFade.java b/src/main/java/net/minecraft/server/RecipeFireworksFade.java index c9af6b055..22875f3f2 100644 --- a/src/main/java/net/minecraft/server/RecipeFireworksFade.java +++ b/src/main/java/net/minecraft/server/RecipeFireworksFade.java @@ -3,53 +3,49 @@ package net.minecraft.server; import com.google.common.collect.Lists; import java.util.List; -public class RecipeFireworksFade extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipeFireworksFade extends ShapelessRecipes { // CraftBukkit - added extends private static final RecipeItemStack a = RecipeItemStack.a(Items.FIREWORK_STAR); // CraftBukkit start - Delegate to new parent class with bogus info public RecipeFireworksFade(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Items.FIREWORK_STAR, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.FIREWORK_STAR, Items.BONE_MEAL))); + super(minecraftkey, "", new ItemStack(Items.FIREWORK_STAR), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.FIREWORK_STAR, Items.BONE_MEAL))); } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - boolean flag = false; - boolean flag1 = false; + public boolean a(InventoryCrafting inventorycrafting, World world) { + boolean flag = false; + boolean flag1 = false; - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack = iinventory.getItem(i); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); - if (!itemstack.isEmpty()) { - if (itemstack.getItem() instanceof ItemDye) { - flag = true; - } else { - if (!RecipeFireworksFade.a.test(itemstack)) { - return false; - } - - if (flag1) { - return false; - } - - flag1 = true; + if (!itemstack.isEmpty()) { + if (itemstack.getItem() instanceof ItemDye) { + flag = true; + } else { + if (!RecipeFireworksFade.a.test(itemstack)) { + return false; } + + if (flag1) { + return false; + } + + flag1 = true; } } - - return flag1 && flag; } + + return flag1 && flag; } - public ItemStack craftItem(IInventory iinventory) { + public ItemStack a(InventoryCrafting inventorycrafting) { List list = Lists.newArrayList(); ItemStack itemstack = null; - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack1 = iinventory.getItem(i); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack1 = inventorycrafting.getItem(i); Item item = itemstack1.getItem(); if (item instanceof ItemDye) { @@ -68,7 +64,8 @@ public class RecipeFireworksFade extends ShapelessRecipes implements IRecipe { / } } - public RecipeSerializer a() { - return RecipeSerializers.i; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.i; } } diff --git a/src/main/java/net/minecraft/server/RecipeFireworksStar.java b/src/main/java/net/minecraft/server/RecipeFireworksStar.java index 3f4d7b303..7d75f0834 100644 --- a/src/main/java/net/minecraft/server/RecipeFireworksStar.java +++ b/src/main/java/net/minecraft/server/RecipeFireworksStar.java @@ -6,7 +6,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class RecipeFireworksStar extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipeFireworksStar extends ShapelessRecipes { // CraftBukkit - added extends private static final RecipeItemStack a = RecipeItemStack.a(Items.FIRE_CHARGE, Items.FEATHER, Items.GOLD_NUGGET, Items.SKELETON_SKULL, Items.WITHER_SKELETON_SKULL, Items.CREEPER_HEAD, Items.PLAYER_HEAD, Items.DRAGON_HEAD, Items.ZOMBIE_HEAD); private static final RecipeItemStack b = RecipeItemStack.a(Items.DIAMOND); @@ -26,70 +26,66 @@ public class RecipeFireworksStar extends ShapelessRecipes implements IRecipe { / // CraftBukkit start - Delegate to new parent class with bogus info public RecipeFireworksStar(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Items.FIREWORK_STAR, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.GUNPOWDER))); + super(minecraftkey, "", new ItemStack(Items.FIREWORK_STAR), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.GUNPOWDER))); } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - boolean flag = false; - boolean flag1 = false; - boolean flag2 = false; - boolean flag3 = false; - boolean flag4 = false; + public boolean a(InventoryCrafting inventorycrafting, World world) { + boolean flag = false; + boolean flag1 = false; + boolean flag2 = false; + boolean flag3 = false; + boolean flag4 = false; - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack = iinventory.getItem(i); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); - if (!itemstack.isEmpty()) { - if (RecipeFireworksStar.a.test(itemstack)) { - if (flag2) { - return false; - } - - flag2 = true; - } else if (RecipeFireworksStar.c.test(itemstack)) { - if (flag4) { - return false; - } - - flag4 = true; - } else if (RecipeFireworksStar.b.test(itemstack)) { - if (flag3) { - return false; - } - - flag3 = true; - } else if (RecipeFireworksStar.e.test(itemstack)) { - if (flag) { - return false; - } - - flag = true; - } else { - if (!(itemstack.getItem() instanceof ItemDye)) { - return false; - } - - flag1 = true; + if (!itemstack.isEmpty()) { + if (RecipeFireworksStar.a.test(itemstack)) { + if (flag2) { + return false; } + + flag2 = true; + } else if (RecipeFireworksStar.c.test(itemstack)) { + if (flag4) { + return false; + } + + flag4 = true; + } else if (RecipeFireworksStar.b.test(itemstack)) { + if (flag3) { + return false; + } + + flag3 = true; + } else if (RecipeFireworksStar.e.test(itemstack)) { + if (flag) { + return false; + } + + flag = true; + } else { + if (!(itemstack.getItem() instanceof ItemDye)) { + return false; + } + + flag1 = true; } } - - return flag && flag1; } + + return flag && flag1; } - public ItemStack craftItem(IInventory iinventory) { + public ItemStack a(InventoryCrafting inventorycrafting) { ItemStack itemstack = new ItemStack(Items.FIREWORK_STAR); NBTTagCompound nbttagcompound = itemstack.a("Explosion"); ItemFireworks.EffectType itemfireworks_effecttype = ItemFireworks.EffectType.SMALL_BALL; List list = Lists.newArrayList(); - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack1 = iinventory.getItem(i); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack1 = inventorycrafting.getItem(i); if (!itemstack1.isEmpty()) { if (RecipeFireworksStar.a.test(itemstack1)) { @@ -109,11 +105,13 @@ public class RecipeFireworksStar extends ShapelessRecipes implements IRecipe { / return itemstack; } - public ItemStack d() { + @Override + public ItemStack c() { return new ItemStack(Items.FIREWORK_STAR); } - public RecipeSerializer a() { - return RecipeSerializers.h; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.h; } } diff --git a/src/main/java/net/minecraft/server/RecipeItemStack.java b/src/main/java/net/minecraft/server/RecipeItemStack.java index a4932bec9..e339310dd 100644 --- a/src/main/java/net/minecraft/server/RecipeItemStack.java +++ b/src/main/java/net/minecraft/server/RecipeItemStack.java @@ -62,7 +62,7 @@ public final class RecipeItemStack implements Predicate { // CraftBukkit start if (exact) { - if (ItemStack.equals(itemstack, itemstack1)) { + if (itemstack1.getItem() == itemstack.getItem() && ItemStack.equals(itemstack, itemstack1)) { return true; } @@ -146,10 +146,10 @@ public final class RecipeItemStack implements Predicate { } public static RecipeItemStack b(PacketDataSerializer packetdataserializer) { - int i = packetdataserializer.g(); + int i = packetdataserializer.i(); return a(Stream.generate(() -> { - return new RecipeItemStack.StackProvider(packetdataserializer.k()); + return new RecipeItemStack.StackProvider(packetdataserializer.m()); }).limit((long) i)); } @@ -183,13 +183,11 @@ public final class RecipeItemStack implements Predicate { if (jsonobject.has("item")) { minecraftkey = new MinecraftKey(ChatDeserializer.h(jsonobject, "item")); - Item item = (Item) IRegistry.ITEM.get(minecraftkey); + Item item = (Item) IRegistry.ITEM.getOptional(minecraftkey).orElseThrow(() -> { + return new JsonSyntaxException("Unknown item '" + minecraftkey + "'"); + }); - if (item == null) { - throw new JsonSyntaxException("Unknown item '" + minecraftkey + "'"); - } else { - return new RecipeItemStack.StackProvider(new ItemStack(item)); - } + return new RecipeItemStack.StackProvider(new ItemStack(item)); } else if (jsonobject.has("tag")) { minecraftkey = new MinecraftKey(ChatDeserializer.h(jsonobject, "tag")); Tag tag = TagsItem.a().a(minecraftkey); @@ -213,6 +211,7 @@ public final class RecipeItemStack implements Predicate { this.a = tag; } + @Override public Collection a() { List list = Lists.newArrayList(); Iterator iterator = this.a.a().iterator(); @@ -226,6 +225,7 @@ public final class RecipeItemStack implements Predicate { return list; } + @Override public JsonObject b() { JsonObject jsonobject = new JsonObject(); @@ -242,10 +242,12 @@ public final class RecipeItemStack implements Predicate { this.a = itemstack; } + @Override public Collection a() { return Collections.singleton(this.a); } + @Override public JsonObject b() { JsonObject jsonobject = new JsonObject(); diff --git a/src/main/java/net/minecraft/server/RecipeMapClone.java b/src/main/java/net/minecraft/server/RecipeMapClone.java index 3e97edcd9..57f7b94d4 100644 --- a/src/main/java/net/minecraft/server/RecipeMapClone.java +++ b/src/main/java/net/minecraft/server/RecipeMapClone.java @@ -1,50 +1,46 @@ package net.minecraft.server; -public class RecipeMapClone extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipeMapClone extends ShapelessRecipes { // CraftBukkit - added extends // CraftBukkit start - Delegate to new parent class public RecipeMapClone(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Items.MAP, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.MAP))); + super(minecraftkey, "", new ItemStack(Items.MAP), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.MAP))); } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - int i = 0; - ItemStack itemstack = ItemStack.a; - - for (int j = 0; j < iinventory.getSize(); ++j) { - ItemStack itemstack1 = iinventory.getItem(j); - - if (!itemstack1.isEmpty()) { - if (itemstack1.getItem() == Items.FILLED_MAP) { - if (!itemstack.isEmpty()) { - return false; - } - - itemstack = itemstack1; - } else { - if (itemstack1.getItem() != Items.MAP) { - return false; - } - - ++i; - } - } - } - - return !itemstack.isEmpty() && i > 0; - } - } - - public ItemStack craftItem(IInventory iinventory) { + public boolean a(InventoryCrafting inventorycrafting, World world) { int i = 0; ItemStack itemstack = ItemStack.a; - for (int j = 0; j < iinventory.getSize(); ++j) { - ItemStack itemstack1 = iinventory.getItem(j); + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack1 = inventorycrafting.getItem(j); + + if (!itemstack1.isEmpty()) { + if (itemstack1.getItem() == Items.FILLED_MAP) { + if (!itemstack.isEmpty()) { + return false; + } + + itemstack = itemstack1; + } else { + if (itemstack1.getItem() != Items.MAP) { + return false; + } + + ++i; + } + } + } + + return !itemstack.isEmpty() && i > 0; + } + + public ItemStack a(InventoryCrafting inventorycrafting) { + int i = 0; + ItemStack itemstack = ItemStack.a; + + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack1 = inventorycrafting.getItem(j); if (!itemstack1.isEmpty()) { if (itemstack1.getItem() == Items.FILLED_MAP) { @@ -73,7 +69,8 @@ public class RecipeMapClone extends ShapelessRecipes implements IRecipe { // Cra } } - public RecipeSerializer a() { - return RecipeSerializers.e; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.e; } } diff --git a/src/main/java/net/minecraft/server/RecipeRepair.java b/src/main/java/net/minecraft/server/RecipeRepair.java index 91789e170..a674c53cd 100644 --- a/src/main/java/net/minecraft/server/RecipeRepair.java +++ b/src/main/java/net/minecraft/server/RecipeRepair.java @@ -2,9 +2,9 @@ package net.minecraft.server; import com.google.common.collect.Lists; import java.util.List; -import java.util.stream.Stream; +import java.util.stream.Stream; // CraftBukkit -public class RecipeRepair extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipeRepair extends ShapelessRecipes { // CraftBukkit - added extends // CraftBukkit start - Delegate to new parent class public RecipeRepair(MinecraftKey minecraftkey) { @@ -12,38 +12,34 @@ public class RecipeRepair extends ShapelessRecipes implements IRecipe { // Craft } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - List list = Lists.newArrayList(); + public boolean a(InventoryCrafting inventorycrafting, World world) { + List list = Lists.newArrayList(); - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack = iinventory.getItem(i); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); - if (!itemstack.isEmpty()) { - list.add(itemstack); - if (list.size() > 1) { - ItemStack itemstack1 = (ItemStack) list.get(0); + if (!itemstack.isEmpty()) { + list.add(itemstack); + if (list.size() > 1) { + ItemStack itemstack1 = (ItemStack) list.get(0); - if (itemstack.getItem() != itemstack1.getItem() || itemstack1.getCount() != 1 || itemstack.getCount() != 1 || !itemstack1.getItem().usesDurability()) { - return false; - } + if (itemstack.getItem() != itemstack1.getItem() || itemstack1.getCount() != 1 || itemstack.getCount() != 1 || !itemstack1.getItem().usesDurability()) { + return false; } } } - - return list.size() == 2; } + + return list.size() == 2; } - public ItemStack craftItem(IInventory iinventory) { + public ItemStack a(InventoryCrafting inventorycrafting) { List list = Lists.newArrayList(); ItemStack itemstack; - for (int i = 0; i < iinventory.getSize(); ++i) { - itemstack = iinventory.getItem(i); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + itemstack = inventorycrafting.getItem(i); if (!itemstack.isEmpty()) { list.add(itemstack); if (list.size() > 1) { @@ -75,15 +71,12 @@ public class RecipeRepair extends ShapelessRecipes implements IRecipe { // Craft itemstack3.setDamage(i1); // CraftBukkit start - Construct a dummy repair recipe - if (iinventory instanceof InventoryCrafting) { - InventoryCrafting inventorycrafting = (InventoryCrafting) iinventory; - NonNullList ingredients = NonNullList.a(); - ingredients.add(new RecipeItemStack(Stream.of(new RecipeItemStack.StackProvider(itemstack2.cloneItemStack())))); - ingredients.add(new RecipeItemStack(Stream.of(new RecipeItemStack.StackProvider(itemstack.cloneItemStack())))); - ShapelessRecipes recipe = new ShapelessRecipes(new MinecraftKey("repairitem"), "", itemstack3.cloneItemStack(), ingredients); - inventorycrafting.setCurrentRecipe(recipe); - itemstack3 = org.bukkit.craftbukkit.event.CraftEventFactory.callPreCraftEvent(inventorycrafting, inventorycrafting.resultInventory, itemstack3, inventorycrafting.container.getBukkitView(), true); - } + NonNullList ingredients = NonNullList.a(); + ingredients.add(new RecipeItemStack(Stream.of(new RecipeItemStack.StackProvider(itemstack2.cloneItemStack())))); + ingredients.add(new RecipeItemStack(Stream.of(new RecipeItemStack.StackProvider(itemstack.cloneItemStack())))); + ShapelessRecipes recipe = new ShapelessRecipes(new MinecraftKey("repairitem"), "", itemstack3.cloneItemStack(), ingredients); + inventorycrafting.setCurrentRecipe(recipe); + itemstack3 = org.bukkit.craftbukkit.event.CraftEventFactory.callPreCraftEvent(inventorycrafting, inventorycrafting.resultInventory, itemstack3, inventorycrafting.container.getBukkitView(), true); // CraftBukkit end return itemstack3; } @@ -92,7 +85,8 @@ public class RecipeRepair extends ShapelessRecipes implements IRecipe { // Craft return ItemStack.a; } - public RecipeSerializer a() { - return RecipeSerializers.j; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.o; } } diff --git a/src/main/java/net/minecraft/server/RecipeShulkerBox.java b/src/main/java/net/minecraft/server/RecipeShulkerBox.java index fe1c6e79b..905b49190 100644 --- a/src/main/java/net/minecraft/server/RecipeShulkerBox.java +++ b/src/main/java/net/minecraft/server/RecipeShulkerBox.java @@ -1,50 +1,46 @@ package net.minecraft.server; -public class RecipeShulkerBox extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipeShulkerBox extends ShapelessRecipes { // CraftBukkit - added extends // CraftBukkit start - Delegate to new parent class with bogus info public RecipeShulkerBox(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Blocks.WHITE_SHULKER_BOX, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.BONE_MEAL))); + super(minecraftkey, "", new ItemStack(Blocks.WHITE_SHULKER_BOX), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.BONE_MEAL))); } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - int i = 0; - int j = 0; + public boolean a(InventoryCrafting inventorycrafting, World world) { + int i = 0; + int j = 0; - for (int k = 0; k < iinventory.getSize(); ++k) { - ItemStack itemstack = iinventory.getItem(k); + for (int k = 0; k < inventorycrafting.getSize(); ++k) { + ItemStack itemstack = inventorycrafting.getItem(k); - if (!itemstack.isEmpty()) { - if (Block.asBlock(itemstack.getItem()) instanceof BlockShulkerBox) { - ++i; - } else { - if (!(itemstack.getItem() instanceof ItemDye)) { - return false; - } - - ++j; - } - - if (j > 1 || i > 1) { + if (!itemstack.isEmpty()) { + if (Block.asBlock(itemstack.getItem()) instanceof BlockShulkerBox) { + ++i; + } else { + if (!(itemstack.getItem() instanceof ItemDye)) { return false; } + + ++j; + } + + if (j > 1 || i > 1) { + return false; } } - - return i == 1 && j == 1; } + + return i == 1 && j == 1; } - public ItemStack craftItem(IInventory iinventory) { + public ItemStack a(InventoryCrafting inventorycrafting) { ItemStack itemstack = ItemStack.a; - ItemDye itemdye = (ItemDye) Items.BONE_MEAL; + ItemDye itemdye = (ItemDye) Items.WHITE_DYE; - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack1 = iinventory.getItem(i); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack1 = inventorycrafting.getItem(i); if (!itemstack1.isEmpty()) { Item item = itemstack1.getItem(); @@ -66,7 +62,8 @@ public class RecipeShulkerBox extends ShapelessRecipes implements IRecipe { // C return itemstack2; } - public RecipeSerializer a() { - return RecipeSerializers.o; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.m; } } diff --git a/src/main/java/net/minecraft/server/RecipeSmoking.java b/src/main/java/net/minecraft/server/RecipeSmoking.java new file mode 100644 index 000000000..0e436af10 --- /dev/null +++ b/src/main/java/net/minecraft/server/RecipeSmoking.java @@ -0,0 +1,33 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftRecipe; +import org.bukkit.craftbukkit.inventory.CraftSmokingRecipe; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.Recipe; +// CraftBukkit end + +public class RecipeSmoking extends RecipeCooking { + + public RecipeSmoking(MinecraftKey minecraftkey, String s, RecipeItemStack recipeitemstack, ItemStack itemstack, float f, int i) { + super(Recipes.SMOKING, minecraftkey, s, recipeitemstack, itemstack, f, i); + } + + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.r; + } + + // CraftBukkit start + @Override + public Recipe toBukkitRecipe() { + CraftItemStack result = CraftItemStack.asCraftMirror(this.result); + + CraftSmokingRecipe recipe = new CraftSmokingRecipe(CraftNamespacedKey.fromMinecraft(this.key), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); + recipe.setGroup(this.group); + + return recipe; + } + // CraftBukkit end +} diff --git a/src/main/java/net/minecraft/server/RecipeStonecutting.java b/src/main/java/net/minecraft/server/RecipeStonecutting.java new file mode 100644 index 000000000..2dc0954f6 --- /dev/null +++ b/src/main/java/net/minecraft/server/RecipeStonecutting.java @@ -0,0 +1,33 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftRecipe; +import org.bukkit.craftbukkit.inventory.CraftStonecuttingRecipe; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.Recipe; +// CraftBukkit end + +public class RecipeStonecutting extends RecipeSingleItem { + + public RecipeStonecutting(MinecraftKey minecraftkey, String s, RecipeItemStack recipeitemstack, ItemStack itemstack) { + super(Recipes.STONECUTTING, RecipeSerializer.t, minecraftkey, s, recipeitemstack, itemstack); + } + + @Override + public boolean a(IInventory iinventory, World world) { + return this.ingredient.test(iinventory.getItem(0)); + } + + // CraftBukkit start + @Override + public Recipe toBukkitRecipe() { + CraftItemStack result = CraftItemStack.asCraftMirror(this.result); + + CraftStonecuttingRecipe recipe = new CraftStonecuttingRecipe(CraftNamespacedKey.fromMinecraft(this.key), result, CraftRecipe.toBukkit(this.ingredient)); + recipe.setGroup(this.group); + + return recipe; + } + // CraftBukkit end +} diff --git a/src/main/java/net/minecraft/server/RecipeSuspiciousStew.java b/src/main/java/net/minecraft/server/RecipeSuspiciousStew.java new file mode 100644 index 000000000..21b55b852 --- /dev/null +++ b/src/main/java/net/minecraft/server/RecipeSuspiciousStew.java @@ -0,0 +1,68 @@ +package net.minecraft.server; + +public class RecipeSuspiciousStew extends ShapelessRecipes { // CraftBukkit - added extends + + // CraftBukkit start - Delegate to new parent class with bogus info + public RecipeSuspiciousStew(MinecraftKey minecraftkey) { + super(minecraftkey, "", new ItemStack(Items.SUSPICIOUS_STEW), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.BOWL))); + } + // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + boolean flag = false; + boolean flag1 = false; + boolean flag2 = false; + boolean flag3 = false; + + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (!itemstack.isEmpty()) { + if (itemstack.getItem() == Blocks.BROWN_MUSHROOM.getItem() && !flag2) { + flag2 = true; + } else if (itemstack.getItem() == Blocks.RED_MUSHROOM.getItem() && !flag1) { + flag1 = true; + } else if (itemstack.getItem().a(TagsItem.SMALL_FLOWERS) && !flag) { + flag = true; + } else { + if (itemstack.getItem() != Items.BOWL || flag3) { + return false; + } + + flag3 = true; + } + } + } + + return flag && flag2 && flag1 && flag3; + } + + public ItemStack a(InventoryCrafting inventorycrafting) { + ItemStack itemstack = ItemStack.a; + + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack1 = inventorycrafting.getItem(i); + + if (!itemstack1.isEmpty() && itemstack1.getItem().a(TagsItem.SMALL_FLOWERS)) { + itemstack = itemstack1; + break; + } + } + + ItemStack itemstack2 = new ItemStack(Items.SUSPICIOUS_STEW, 1); + + if (itemstack.getItem() instanceof ItemBlock && ((ItemBlock) itemstack.getItem()).getBlock() instanceof BlockFlowers) { + BlockFlowers blockflowers = (BlockFlowers) ((ItemBlock) itemstack.getItem()).getBlock(); + MobEffectList mobeffectlist = blockflowers.d(); + + ItemSuspiciousStew.a(itemstack2, mobeffectlist, blockflowers.e()); + } + + return itemstack2; + } + + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.n; + } +} diff --git a/src/main/java/net/minecraft/server/RecipeTippedArrow.java b/src/main/java/net/minecraft/server/RecipeTippedArrow.java index 09f6136b0..690f262d0 100644 --- a/src/main/java/net/minecraft/server/RecipeTippedArrow.java +++ b/src/main/java/net/minecraft/server/RecipeTippedArrow.java @@ -2,7 +2,7 @@ package net.minecraft.server; import java.util.Collection; -public class RecipeTippedArrow extends ShapedRecipes implements IRecipe { // CraftBukkit +public class RecipeTippedArrow extends ShapedRecipes { // CraftBukkit // CraftBukkit start public RecipeTippedArrow(MinecraftKey minecraftkey) { @@ -14,11 +14,11 @@ public class RecipeTippedArrow extends ShapedRecipes implements IRecipe { // Cra } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (iinventory.U_() == 3 && iinventory.n() == 3) { - for (int i = 0; i < iinventory.U_(); ++i) { - for (int j = 0; j < iinventory.n(); ++j) { - ItemStack itemstack = iinventory.getItem(i + j * iinventory.U_()); + public boolean a(InventoryCrafting inventorycrafting, World world) { + if (inventorycrafting.g() == 3 && inventorycrafting.f() == 3) { + for (int i = 0; i < inventorycrafting.g(); ++i) { + for (int j = 0; j < inventorycrafting.f(); ++j) { + ItemStack itemstack = inventorycrafting.getItem(i + j * inventorycrafting.g()); if (itemstack.isEmpty()) { return false; @@ -42,8 +42,8 @@ public class RecipeTippedArrow extends ShapedRecipes implements IRecipe { // Cra } } - public ItemStack craftItem(IInventory iinventory) { - ItemStack itemstack = iinventory.getItem(1 + iinventory.U_()); + public ItemStack a(InventoryCrafting inventorycrafting) { + ItemStack itemstack = inventorycrafting.getItem(1 + inventorycrafting.g()); if (itemstack.getItem() != Items.LINGERING_POTION) { return ItemStack.a; @@ -56,7 +56,8 @@ public class RecipeTippedArrow extends ShapedRecipes implements IRecipe { // Cra } } - public RecipeSerializer a() { - return RecipeSerializers.k; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.j; } } diff --git a/src/main/java/net/minecraft/server/RecipiesShield.java b/src/main/java/net/minecraft/server/RecipiesShield.java index 64dea7f07..60aa2524a 100644 --- a/src/main/java/net/minecraft/server/RecipiesShield.java +++ b/src/main/java/net/minecraft/server/RecipiesShield.java @@ -1,62 +1,58 @@ package net.minecraft.server; -public class RecipiesShield extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends +public class RecipiesShield extends ShapelessRecipes { // CraftBukkit - added extends // CraftBukkit start - Delegate to new parent class with bogus info public RecipiesShield(MinecraftKey minecraftkey) { - super(minecraftkey, "", new ItemStack(Items.SHIELD, 0), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.WHITE_BANNER))); + super(minecraftkey, "", new ItemStack(Items.SHIELD), NonNullList.a(RecipeItemStack.a, RecipeItemStack.a(Items.WHITE_BANNER))); } // CraftBukkit end - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - ItemStack itemstack = ItemStack.a; - ItemStack itemstack1 = ItemStack.a; - - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack2 = iinventory.getItem(i); - - if (!itemstack2.isEmpty()) { - if (itemstack2.getItem() instanceof ItemBanner) { - if (!itemstack1.isEmpty()) { - return false; - } - - itemstack1 = itemstack2; - } else { - if (itemstack2.getItem() != Items.SHIELD) { - return false; - } - - if (!itemstack.isEmpty()) { - return false; - } - - if (itemstack2.b("BlockEntityTag") != null) { - return false; - } - - itemstack = itemstack2; - } - } - } - - if (!itemstack.isEmpty() && !itemstack1.isEmpty()) { - return true; - } else { - return false; - } - } - } - - public ItemStack craftItem(IInventory iinventory) { + public boolean a(InventoryCrafting inventorycrafting, World world) { ItemStack itemstack = ItemStack.a; ItemStack itemstack1 = ItemStack.a; - for (int i = 0; i < iinventory.getSize(); ++i) { - ItemStack itemstack2 = iinventory.getItem(i); + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack2 = inventorycrafting.getItem(i); + + if (!itemstack2.isEmpty()) { + if (itemstack2.getItem() instanceof ItemBanner) { + if (!itemstack1.isEmpty()) { + return false; + } + + itemstack1 = itemstack2; + } else { + if (itemstack2.getItem() != Items.SHIELD) { + return false; + } + + if (!itemstack.isEmpty()) { + return false; + } + + if (itemstack2.b("BlockEntityTag") != null) { + return false; + } + + itemstack = itemstack2; + } + } + } + + if (!itemstack.isEmpty() && !itemstack1.isEmpty()) { + return true; + } else { + return false; + } + } + + public ItemStack a(InventoryCrafting inventorycrafting) { + ItemStack itemstack = ItemStack.a; + ItemStack itemstack1 = ItemStack.a; + + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack2 = inventorycrafting.getItem(i); if (!itemstack2.isEmpty()) { if (itemstack2.getItem() instanceof ItemBanner) { @@ -79,7 +75,8 @@ public class RecipiesShield extends ShapelessRecipes implements IRecipe { // Cra } } - public RecipeSerializer a() { - return RecipeSerializers.n; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.l; } } diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java index e5659980b..22144eb00 100644 --- a/src/main/java/net/minecraft/server/RegionFile.java +++ b/src/main/java/net/minecraft/server/RegionFile.java @@ -17,359 +17,370 @@ import java.util.zip.GZIPInputStream; import java.util.zip.InflaterInputStream; import javax.annotation.Nullable; -public class RegionFile { +public class RegionFile implements AutoCloseable { // Spigot start // Minecraft is limited to 256 sections per chunk. So 1MB. This can easily be overriden. // So we extend this to use the REAL size when the count is maxed by seeking to that section and reading the length. private static final boolean ENABLE_EXTENDED_SAVE = Boolean.parseBoolean(System.getProperty("net.minecraft.server.RegionFile.enableExtendedSave", "true")); + final File file; // Paper - private -> package // Spigot end private static final byte[] a = new byte[4096]; - private final File b;private File getFile() { return b; } // Paper - OBFHELPER - private RandomAccessFile c;private RandomAccessFile getDataFile() { return c; } // Paper - OBFHELPER - private final int[] d = new int[1024];private int[] offsets = d; // Paper - OBFHELPER - private final int[] e = new int[1024];private int[] timestamps = e; // Paper - OBFHELPER - private List f; private List getFreeSectors() { return this.f; } // Paper - OBFHELPER - private int g; - private long h; + private final RandomAccessFile b; private RandomAccessFile getDataFile() { return this.b; } // Paper - OBFHELPER // PAIL dataFile + private final int[] c = new int[1024]; private final int[] offsets = c; // Paper - OBFHELPER + private final int[] d = new int[1024]; private final int[] timestamps = d; // Paper - OBFHELPER + private final List e; // PAIL freeSectors - public RegionFile(File file) { - this.b = file; - this.g = 0; + // Paper start - Cache chunk status + private final ChunkStatus[] statuses = new ChunkStatus[32 * 32]; - try { - if (file.exists()) { - this.h = file.lastModified(); - } + private boolean closed; - this.c = new RandomAccessFile(file, "rw"); - if (this.c.length() < 8192L) { // Paper - headers should be 8192 - this.c.write(RegionFile.a); - this.c.write(RegionFile.a); - this.g += 8192; - } + // invoked on write/read + public void setStatus(int x, int z, ChunkStatus status) { + if (this.closed) { + // We've used an invalid region file. + throw new IllegalStateException("RegionFile is closed"); + } + this.statuses[this.getChunkLocation(new ChunkCoordIntPair(x, z))] = status; + } - int i; + public ChunkStatus getStatusIfCached(int x, int z) { + if (this.closed) { + // We've used an invalid region file. + throw new IllegalStateException("RegionFile is closed"); + } + final int location = this.getChunkLocation(new ChunkCoordIntPair(x, z)); + return this.statuses[location]; + } + // Paper end - if ((this.c.length() & 4095L) != 0L) { - for (i = 0; (long) i < (this.c.length() & 4095L); ++i) { - this.c.write(0); - } - } - - i = (int) this.c.length() / 4096; - this.f = Lists.newArrayListWithCapacity(i); - - int j; - - for (j = 0; j < i; ++j) { - this.f.add(true); - } - - this.f.set(0, false); - this.f.set(1, false); - this.c.seek(0L); - - int k; - // Paper Start - java.nio.ByteBuffer header = java.nio.ByteBuffer.allocate(8192); - while (header.hasRemaining()) { - if (this.c.getChannel().read(header) == -1) throw new java.io.EOFException(); - } - header.clear(); - java.nio.IntBuffer headerAsInts = header.asIntBuffer(); - initOversizedState(); - // Paper End - - for (j = 0; j < 1024; ++j) { - k = headerAsInts.get(); // Paper - this.d[j] = k; - // Spigot start - int length = k & 255; - if (length == 255) { - if ((k >> 8) <= this.f.size()) { - // We're maxed out, so we need to read the proper length from the section - this.c.seek((k >> 8) * 4096); - length = (this.c.readInt() + 4) / 4096 + 1; - this.c.seek(j * 4 + 4); // Go back to where we were - } - } - if (k > 0 && (k >> 8) > 1 && (k >> 8) + (length) <= this.f.size()) { // Paper >= 1 as 0/1 are the headers, and negative isnt valid - for (int l = 0; l < (length); ++l) { - // Spigot end - this.f.set((k >> 8) + l, false); - } - } - // Spigot start - else if (k != 0) { // Paper - org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Invalid chunk: ({0}, {1}) Offset: {2} Length: {3} runs off end file. {4}", new Object[]{j % 32, (int) (j / 32), k >> 8, length, file}); // Paper - deleteChunk(j); // Paper - } - // Spigot end - } - - for (j = 0; j < 1024; ++j) { - k = headerAsInts.get(); // Paper - if (offsets[j] != 0) this.timestamps[j] = k; // Paper - don't set timestamp if it got 0'd above due to corruption - } - } catch (IOException ioexception) { - ioexception.printStackTrace(); - ServerInternalException.reportInternalException(ioexception); // Paper + public RegionFile(File file) throws IOException { + this.b = new RandomAccessFile(file, "rw"); + this.file = file; // Spigot // Paper - We need this earlier + if (this.b.length() < 8192L) { // Paper - headers should be 8192 + this.b.write(RegionFile.a); + this.b.write(RegionFile.a); } - } + int i; - @Nullable - public synchronized DataInputStream getReadStream(int i, int j) { return a(i, j); } @Nullable public synchronized DataInputStream a(int i, int j) { // Paper - OBFHELPER - if (this.e(i, j)) { - return null; - } else { - try { - int k = this.getOffset(i, j); - - if (k == 0) { - return null; - } else { - int l = k >> 8; - int i1 = k & 255; - // Spigot start - if (i1 == 255) { - this.c.seek(l * 4096); - i1 = (this.c.readInt() + 4) / 4096 + 1; - } - // Spigot end - - if (l + i1 > this.f.size()) { - return null; - } else { - this.c.seek((long) (l * 4096)); - int j1 = this.c.readInt(); - - if (j1 > 4096 * i1) { - org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Invalid chunk: ({0}, {1}) Offset: {2} Invalid Size: {3}>{4} {5}", new Object[]{i, j, l, j1, i1 * 4096, this.b}); // Spigot - return null; - } else if (j1 <= 0) { - org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Invalid chunk: ({0}, {1}) Offset: {2} Invalid Size: {3} {4}", new Object[]{i, j, l, j1, this.b}); // Spigot - return null; - } else { - byte b0 = this.c.readByte(); - byte[] abyte; - - if (b0 == 1) { - abyte = new byte[j1 - 1]; - this.c.read(abyte); - return new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte)))); - } else if (b0 == 2) { - abyte = new byte[j1 - 1]; - this.c.read(abyte); - return new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte)))); - } else { - return null; - } - } - } - } - } catch (IOException ioexception) { - return null; + if ((this.b.length() & 4095L) != 0L) { + for (i = 0; (long) i < (this.b.length() & 4095L); ++i) { + this.b.write(0); } } - } - public boolean b(int i, int j) { - if (this.e(i, j)) { - return false; - } else { - int k = this.getOffset(i, j); + i = (int) this.b.length() / 4096; + this.e = Lists.newArrayListWithCapacity(i); - if (k == 0) { - return false; - } else { - int l = k >> 8; - int i1 = k & 255; + int j; - if (l + i1 > this.f.size()) { - return false; - } else { - try { - this.c.seek((long) (l * 4096)); - int j1 = this.c.readInt(); - - return j1 > 4096 * i1 ? false : j1 > 0; - } catch (IOException ioexception) { - return false; - } - } - } + for (j = 0; j < i; ++j) { + this.e.add(true); } - } - @Nullable - public DataOutputStream getWriteStream(int i, int j) { return c(i, j); } @Nullable public DataOutputStream c(int i, int j) { // Paper - OBFHELPER - return this.e(i, j) ? null : new DataOutputStream(new RegionFile.ChunkBuffer(i, j)); // Paper - remove middleware, move deflate to .close() for dynamic levels - } + this.e.set(0, false); + this.e.set(1, false); + this.b.seek(0L); - protected synchronized void a(int i, int j, byte[] abyte, int k) { - try { - int l = this.getOffset(i, j); - int i1 = l >> 8; final int oldSectorOffset = i1; // Paper - store variable for later - int j1 = l & 255; final int oldSectorCount; // Paper - store variable for later + // Paper Start + java.nio.ByteBuffer header = java.nio.ByteBuffer.allocate(8192); + while (header.hasRemaining()) { + if (this.getDataFile().getChannel().read(header) == -1) throw new java.io.EOFException(); + } + ((java.nio.Buffer) header).clear(); + java.nio.IntBuffer headerAsInts = header.asIntBuffer(); + initOversizedState(); + // Paper End + + int k; + + for (j = 0; j < 1024; ++j) { + k = headerAsInts.get(); // Paper + this.c[j] = k; // Spigot start - if (j1 == 255) { - this.c.seek(i1 * 4096); - j1 = (this.c.readInt() + 4) / 4096 + 1; + int length = k & 255; + if (length == 255) { + if ((k >> 8) <= this.e.size()) { + // We're maxed out, so we need to read the proper length from the section + this.b.seek((k >> 8) * 4096); + length = (this.b.readInt() + 4) / 4096 + 1; + this.b.seek(j * 4 + 4); // Go back to where we were + } + } + if (k > 0 && (k >> 8) > 1 && (k >> 8) + (length) <= this.e.size()) { // Paper >= 1 as 0/1 are the headers, and negative isnt valid + for (int l = 0; l < (length); ++l) { + // Spigot end + this.e.set((k >> 8) + l, false); + } + } + // Spigot start + else if (length > 0) { + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Invalid chunk: ({0}, {1}) Offset: {2} Length: {3} runs off end file. {4}", new Object[]{j % 32, (int) (j / 32), k >> 8, length, file}); + deleteChunk(j); // Paper } // Spigot end - oldSectorCount = j1; // Paper - store variable for later (watch out for re-assignments of j1) - int k1 = (k + 5) / 4096 + 1; + } - if (k1 >= 256) { + for (j = 0; j < 1024; ++j) { + k = headerAsInts.get(); // Paper + if (this.offsets[j] != 0) this.timestamps[j] = k; // Paper - don't set timestamp if it got 0'd above due to corruption + } + + // Paper - we need this earlier + } + + @Nullable + public synchronized DataInputStream getReadStream(ChunkCoordIntPair chunkcoordintpair) { return this.a(chunkcoordintpair); } public synchronized DataInputStream a(ChunkCoordIntPair chunkcoordintpair) { // Paper - OBFHELPER + try { + int i = this.getOffset(chunkcoordintpair); + + if (i == 0) { + return null; + } else { + int j = i >> 8; + int k = i & 255; // Spigot start - if (!USE_SPIGOT_OVERSIZED_METHOD && !RegionFileCache.isOverzealous()) throw new ChunkTooLargeException(i, j, k1); // Paper - throw error instead - org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING,"Large Chunk Detected: ({0}, {1}) Size: {2} {3}", new Object[]{i, j, k1, this.b}); - if (!ENABLE_EXTENDED_SAVE) return; + if (k == 255) { + this.b.seek(j * 4096); + k = (this.b.readInt() + 4) / 4096 + 1; + } + // Spigot end + + if (j + k > this.e.size()) { + return null; + } else { + this.b.seek((long) (j * 4096)); + int l = this.b.readInt(); + + if (l > 4096 * k) { + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Invalid chunk: ({0}) Offset: {1} Invalid Size: {2}>{3} {4}", new Object[]{chunkcoordintpair, j, l, k * 4096, this.file}); // Spigot + return null; + } else if (l <= 0) { + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "Invalid chunk: ({0}) Offset: {1} Invalid Size: {2} {3}", new Object[]{chunkcoordintpair, j, l, this.file}); // Spigot + return null; + } else { + byte b0 = this.b.readByte(); + byte[] abyte; + + if (b0 == 1) { + abyte = new byte[l - 1]; + this.b.read(abyte); + return new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte)))); + } else if (b0 == 2) { + abyte = new byte[l - 1]; + this.b.read(abyte); + return new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte)))); + } else { + return null; + } + } + } + } + } catch (IOException ioexception) { + ServerInternalException.reportInternalException(ioexception); // Paper + return null; + } + } + + public boolean b(ChunkCoordIntPair chunkcoordintpair) { + int i = this.getOffset(chunkcoordintpair); + + if (i == 0) { + return false; + } else { + int j = i >> 8; + int k = i & 255; + + if (j + k > this.e.size()) { + return false; + } else { + try { + this.b.seek((long) (j * 4096)); + int l = this.b.readInt(); + + return l > 4096 * k ? false : l > 0; + } catch (IOException ioexception) { + return false; + } + } + } + } + + public DataOutputStream getWriteStream(ChunkCoordIntPair chunkcoordintpair) { return this.c(chunkcoordintpair); } public DataOutputStream c(ChunkCoordIntPair chunkcoordintpair) { // Paper - OBFHELPER + return new DataOutputStream(new RegionFile.ChunkBuffer(chunkcoordintpair)); // Paper - remove middleware, move deflate to .close() for dynamic levels + } + + protected synchronized void a(ChunkCoordIntPair chunkcoordintpair, byte[] abyte, int i) { + try { + int j = this.getOffset(chunkcoordintpair); + int k = j >> 8; final int oldSectorOffset = k; // Spigot - store variable for later + int l = j & 255; final int oldSectorCount; // Spigot - store variable for later + // Spigot start + if (l == 255) { + this.b.seek(k * 4096); + l = (this.b.readInt() + 4) / 4096 + 1; + } + // Spigot end + int i1 = (i + 5) / 4096 + 1; + oldSectorCount = l; // Spigot - store variable for later (watch out for re-assignments of l) + + if (i1 >= 256) { + // Spigot start + if (!USE_SPIGOT_OVERSIZED_METHOD && !RegionFileCache.isOverzealous()) throw new ChunkTooLargeException(chunkcoordintpair.x, chunkcoordintpair.z, l); // Paper - throw error instead + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING,"Large Chunk Detected: ({0}) Size: {1} {2}", new Object[]{chunkcoordintpair, i1, this.file}); + if (!ENABLE_EXTENDED_SAVE) throw new RuntimeException(String.format("Too big to save, %d > 1048576", i)); // Paper - move after our check // Spigot end } - if (false && i1 != 0 && j1 == k1) { // Paper - We never want to overrite old data - this.a(i1, abyte, k); + if (false && k != 0 && l == i1) { // Spigot - We never want to overrite old data + this.a(k, abyte, i); } else { + int j1; + + // Spigot start - We do not free old sectors until we are done writing the new chunk data + /* + for (j1 = 0; j1 < l; ++j1) { + this.e.set(k + j1, true); + } + */ + // Spigot end + + j1 = this.e.indexOf(true); + int k1 = 0; int l1; - // Paper - We do not free old sectors until we are done writing the new chunk data - - l1 = this.f.indexOf(true); - int i2 = 0; - int j2; - - if (l1 != -1) { - for (j2 = l1; j2 < this.f.size(); ++j2) { - if (i2 != 0) { - if ((Boolean) this.f.get(j2)) { - ++i2; + if (j1 != -1) { + for (l1 = j1; l1 < this.e.size(); ++l1) { + if (k1 != 0) { + if ((Boolean) this.e.get(l1)) { + ++k1; } else { - i2 = 0; + k1 = 0; } - } else if ((Boolean) this.f.get(j2)) { - l1 = j2; - i2 = 1; + } else if ((Boolean) this.e.get(l1)) { + j1 = l1; + k1 = 1; } - if (i2 >= k1) { + if (k1 >= i1) { break; } } } - if (i2 >= k1) { - i1 = l1; - //this.a(i, j, l1 << 8 | (k1 > 255 ? 255 : k1)); // Spigot // Paper - We only write to header after we've written chunk data + if (k1 >= i1) { + k = j1; + // this.a(chunkcoordintpair, j1 << 8 | (i1 > 255 ? 255 : i1)); // Spigot // Spigot - We only write to header after we've written chunk data - for (j2 = 0; j2 < k1; ++j2) { - this.f.set(i1 + j2, false); + for (l1 = 0; l1 < i1; ++l1) { + this.e.set(k + l1, false); } - this.writeChunk(i, j,i1 << 8 | (k1 > 255 ? 255 : k1), i1, abyte, k); // Paper - Ensure we do not corrupt region files + this.writeChunk(chunkcoordintpair, j1 << 8 | (i1 > 255 ? 255 : i1), k, abyte, i); // Spigot - Ensure we do not corrupt region files } else { - this.c.seek(this.c.length()); - i1 = this.f.size(); + this.b.seek(this.b.length()); + k = this.e.size(); - for (j2 = 0; j2 < k1; ++j2) { - this.c.write(RegionFile.a); - this.f.add(false); + for (l1 = 0; l1 < i1; ++l1) { + this.b.write(RegionFile.a); + this.e.add(false); } - this.g += 4096 * k1; - this.writeChunk(i, j, i1 << 8 | (k1 > 255 ? 255 : k1), i1, abyte, k); // Paper - Ensure we do not corrupt region files + this.writeChunk(chunkcoordintpair, k << 8 | (i1 > 255 ? 255 : i1), k, abyte, i); // Spigot - Ensure we do not corrupt region files } - // Paper start - Now that we've written the new chunk we can free the old data + // Spigot start - Now that we've written the new chunk we can free the old data for (int off = 0; off < oldSectorCount; ++off) { - this.getFreeSectors().set(oldSectorOffset + off, true); + this.e.set(oldSectorOffset + off, true); } - // Paper end + // Spigot end } - this.b(i, j, (int) (SystemUtils.getTimeMillis() / 1000L)); + // this.b(chunkcoordintpair, (int) (SystemUtils.getTimeMillis() / 1000L)); // Spigot - move this into writeChunk } catch (IOException ioexception) { com.destroystokyo.paper.util.SneakyThrow.sneaky(ioexception); // Paper - we want the upper try/catch to retry this } } - private void writeChunkData(final int sectorOffset, final byte[] data, final int dataLength) throws IOException { this.a(sectorOffset, data, dataLength); } // Paper - OBFHELPER - private void a(int i, byte[] abyte, int j) throws IOException { - this.c.seek((long) (i * 4096)); - this.writeIntAndByte(j + 1, (byte)2); // Paper - Avoid 4 io write calls - this.c.write(abyte, 0, j); + private void a(int i, byte[] abyte, int j) throws IOException { // PAIL writeChunkData + this.b.seek((long) (i * 4096)); + this.writeIntAndByte(j + 1, (byte)2); // Spigot - Avoid 4 io write calls + this.b.write(abyte, 0, j); } - private boolean e(int i, int j) { - return i < 0 || i >= 32 || j < 0 || j >= 32; + private int getOffset(ChunkCoordIntPair chunkcoordintpair) { + return this.c[this.f(chunkcoordintpair)]; } - private synchronized int getOffset(int i, int j) { - return this.d[i + j * 32]; + public final boolean chunkExists(ChunkCoordIntPair chunkPos) { return this.d(chunkPos); } // Paper - OBFHELPER + public boolean d(ChunkCoordIntPair chunkcoordintpair) { + return this.getOffset(chunkcoordintpair) != 0; } - public boolean d(int i, int j) { - return this.getOffset(i, j) != 0; + private void a(ChunkCoordIntPair chunkcoordintpair, int i) throws IOException { // PAIL updateChunkHeader + int j = this.f(chunkcoordintpair); + + //this.c[j] = i; // Spigot - move this to after the write + this.b.seek((long) (j * 4)); + this.writeInt(i); // Spigot - Avoid 3 io write calls + this.c[j] = i; // Spigot - move this to after the write } - private void updateChunkHeader(final int x, final int z, final int offset) throws IOException { this.a(x, z, offset); } // Paper - OBFHELPER - private void a(int i, int j, int k) throws IOException { - this.d[i + j * 32] = k; - this.c.seek((long) ((i + j * 32) * 4)); - this.writeInt(k); // Paper - Avoid 3 io write calls + private final int getChunkLocation(ChunkCoordIntPair chunkcoordintpair) { return this.f(chunkcoordintpair); } // Paper - OBFHELPER + private int f(ChunkCoordIntPair chunkcoordintpair) { + return chunkcoordintpair.j() + chunkcoordintpair.k() * 32; } - private void b(int i, int j, int k) throws IOException { - this.e[i + j * 32] = k; - this.c.seek((long) (4096 + (i + j * 32) * 4)); - this.writeInt(k); // Paper - Avoid 3 io write calls + private void b(ChunkCoordIntPair chunkcoordintpair, int i) throws IOException { // PAIL updateChunkTime + int j = this.f(chunkcoordintpair); + + // this.d[j] = i; // Spigot - move this to after the write + this.b.seek((long) (4096 + j * 4)); + this.writeInt(i); // Spigot - Avoid 3 io write calls + this.d[j] = i; // Spigot - move this to after the write } - public void close() throws IOException { - if (this.c != null) { - this.c.close(); - } - + public synchronized void close() throws IOException { // Paper - synchronize + this.closed = true; // Paper + this.b.close(); } - // Paper start - private static final boolean FLUSH_ON_SAVE = Boolean.getBoolean("paper.flush-on-save"); + // Spigot start - Make region files reliable + private static final boolean FLUSH_ON_SAVE = Boolean.getBoolean("spigot.flush-on-save") || Boolean.getBoolean("paper.flush-on-save"); // Paper - preserve old flag private void syncRegionFile() throws IOException { if (!FLUSH_ON_SAVE) { return; } - this.getDataFile().getFD().sync(); // rethrow exception as we want to avoid corrupting a regionfile + this.b.getFD().sync(); // rethrow exception as we want to avoid corrupting a regionfile } private final java.nio.ByteBuffer scratchBuffer = java.nio.ByteBuffer.allocate(8); private void writeInt(final int value) throws IOException { - synchronized (scratchBuffer) { - this.scratchBuffer.putInt(0, value); - this.getDataFile().write(this.scratchBuffer.array(), 0, 4); - } + this.scratchBuffer.putInt(0, value); + this.b.write(this.scratchBuffer.array(), 0, 4); } // writes v1 then v2 private void writeIntAndByte(final int v1, final byte v2) throws IOException { - synchronized (scratchBuffer) { - this.scratchBuffer.putInt(0, v1); - this.scratchBuffer.put(4, v2); - this.getDataFile().write(this.scratchBuffer.array(), 0, 5); - } + this.scratchBuffer.putInt(0, v1); + this.scratchBuffer.put(4, v2); + this.b.write(this.scratchBuffer.array(), 0, 5); } - private void writeChunk(final int x, final int z, final int chunkHeaderData, - final int chunkOffset, final byte[] chunkData, final int chunkDataLength) throws IOException { - this.writeChunkData(chunkOffset, chunkData, chunkDataLength); + private void writeChunk(final ChunkCoordIntPair chunk, final int chunkHeaderData, final int chunkOffset, final byte[] chunkData, final int chunkDataLength) throws IOException { + this.a(chunkOffset, chunkData, chunkDataLength); // chunk data this.syncRegionFile(); // Sync is required to ensure the previous data is written successfully - this.updateChunkHeader(x, z, chunkHeaderData); + this.b(chunk, (int) (SystemUtils.getTimeMillis() / 1000L)); // chunk time + this.a(chunk, chunkHeaderData); // chunk header this.syncRegionFile(); // Ensure header changes go through } + // Spigot end + // Paper start public synchronized void deleteChunk(int j1) { backup(); int k = offsets[j1]; @@ -387,10 +398,10 @@ public class RegionFile { // clear the timestamp file.seek(4096 + j1 * 4); file.writeInt(0); - org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Deleted corrupt chunk (" + debug + ") " + getFile().getAbsolutePath(), e); + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Deleted corrupt chunk (" + debug + ") " + this.file.getAbsolutePath(), e); } catch (IOException e) { - org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Error deleting corrupt chunk (" + debug + ") " + getFile().getAbsolutePath(), e); + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.SEVERE, "Error deleting corrupt chunk (" + debug + ") " + this.file.getAbsolutePath(), e); } } private boolean backedUp = false; @@ -399,7 +410,6 @@ public class RegionFile { return; } backedUp = true; - File file = this.getFile(); java.text.DateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd"); java.util.Date today = new java.util.Date(); File corrupt = new File(file.getParentFile(), file.getName() + "." + formatter.format(today) + ".corrupt"); @@ -468,11 +478,11 @@ public class RegionFile { } private File getOversizedMetaFile() { - return new File(getFile().getParentFile(), getFile().getName().replaceAll("\\.mca$", "") + ".oversized.nbt"); + return new File(this.file.getParentFile(), this.file.getName().replaceAll("\\.mca$", "") + ".oversized.nbt"); } private File getOversizedFile(int x, int z) { - return new File(this.getFile().getParentFile(), this.getFile().getName().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt"); + return new File(this.file.getParentFile(), this.file.getName().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt"); } void writeOversizedData(int x, int z, NBTTagCompound oversizedData) throws IOException { @@ -502,7 +512,7 @@ public class RegionFile { } public class ChunkTooLargeException extends RuntimeException { public ChunkTooLargeException(int x, int z, int sectors) { - super("Chunk " + x + "," + z + " of " + getFile().toString() + " is too large (" + sectors + "/256)"); + super("Chunk " + x + "," + z + " of " + RegionFile.this.file.toString() + " is too large (" + sectors + "/255)"); } } private static class DirectByteArrayOutputStream extends ByteArrayOutputStream { @@ -522,13 +532,11 @@ public class RegionFile { class ChunkBuffer extends ByteArrayOutputStream { - private final int b; - private final int c; + private final ChunkCoordIntPair b; - public ChunkBuffer(int i, int j) { + public ChunkBuffer(ChunkCoordIntPair chunkcoordintpair) { super(8096); - this.b = i; - this.c = j; + this.b = chunkcoordintpair; } public void close() throws IOException { @@ -539,7 +547,7 @@ public class RegionFile { byte[] bytes = out.getBuffer(); int length = out.size(); - RegionFile.this.a(this.b, this.c, bytes, length); // Paper - change to bytes/length + RegionFile.this.a(this.b, bytes, length); // Paper - change to bytes/length } } diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java index 17e76815a..d3d610742 100644 --- a/src/main/java/net/minecraft/server/RegionFileCache.java +++ b/src/main/java/net/minecraft/server/RegionFileCache.java @@ -1,89 +1,92 @@ package net.minecraft.server; -import com.destroystokyo.paper.exception.ServerInternalException; -import com.google.common.collect.Maps; +import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectIterator; import java.io.DataInputStream; +import java.io.DataOutput; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; -import java.util.Iterator; -import java.util.Map; import javax.annotation.Nullable; import com.destroystokyo.paper.PaperConfig; // Paper -import java.util.LinkedHashMap; // Paper -public class RegionFileCache { +import org.apache.logging.log4j.LogManager; - public static final Map cache = new LinkedHashMap(PaperConfig.regionFileCacheSize, 0.75f, true); // Paper - HashMap -> LinkedHashMap +public abstract class RegionFileCache implements AutoCloseable { - public static synchronized RegionFile getRegionFile(File file, int i, int j) { return a(file, i, j); } // Paper - OBFHELPER - public static synchronized RegionFile a(File file, int i, int j) { - File file1 = new File(file, "region"); - File file2 = new File(file1, "r." + (i >> 5) + "." + (j >> 5) + ".mca"); - RegionFile regionfile = (RegionFile) RegionFileCache.cache.get(file2); + public final Long2ObjectLinkedOpenHashMap cache = new Long2ObjectLinkedOpenHashMap(); + private final File a; + // Paper start + private final File templateWorld; + private final File actualWorld; + private boolean useAltWorld; + // Paper end + + + protected RegionFileCache(File file) { + this.a = file; + // Paper end + + this.actualWorld = file; + if (com.destroystokyo.paper.PaperConfig.useVersionedWorld) { + this.useAltWorld = true; + String name = file.getName(); + File container = file.getParentFile().getParentFile(); + if (name.equals("DIM-1") || name.equals("DIM1")) { + container = container.getParentFile(); + } + this.templateWorld = new File(container, name); + File region = new File(file, "region"); + if (!region.exists()) { + region.mkdirs(); + } + } else { + this.useAltWorld = false; + this.templateWorld = file; + } + // Paper start + } + + // Paper start + public synchronized RegionFile getRegionFileIfLoaded(ChunkCoordIntPair chunkcoordintpair) { // Paper - synchronize for async io + return this.cache.getAndMoveToFirst(ChunkCoordIntPair.pair(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ())); + } + // Paper end + + public RegionFile getRegionFile(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { return this.a(chunkcoordintpair, existingOnly); } // Paper - OBFHELPER + private synchronized RegionFile a(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - synchronize for async io + long i = ChunkCoordIntPair.pair(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()); + RegionFile regionfile = (RegionFile) this.cache.getAndMoveToFirst(i); if (regionfile != null) { return regionfile; } else { - if (!file1.exists()) { - file1.mkdirs(); + if (this.cache.size() >= PaperConfig.regionFileCacheSize) { // Paper - configurable + ((RegionFile) this.cache.removeLast()).close(); } - if (RegionFileCache.cache.size() >= 256) { - trimCache(); + if (!this.a.exists()) { + this.a.mkdirs(); } - RegionFile regionfile1 = new RegionFile(file2); + copyIfNeeded(chunkcoordintpair.x, chunkcoordintpair.z); // Paper + File file = new File(this.a, "r." + chunkcoordintpair.getRegionX() + "." + chunkcoordintpair.getRegionZ() + ".mca"); + if (existingOnly && !file.exists()) return null; // CraftBukkit + RegionFile regionfile1 = new RegionFile(file); - RegionFileCache.cache.put(file2, regionfile1); + this.cache.putAndMoveToFirst(i, regionfile1); return regionfile1; } } - // CraftBukkit start - public static synchronized RegionFile b(File file, int i, int j) { - File file1 = new File(file, "region"); - File file2 = new File(file1, "r." + (i >> 5) + "." + (j >> 5) + ".mca"); - RegionFile regionfile = (RegionFile) RegionFileCache.cache.get(file2); - - if (regionfile != null) { - return regionfile; - } else if (file1.exists() && file2.exists()) { - if (RegionFileCache.cache.size() >= 256) { - a(); - } - - RegionFile regionfile1 = new RegionFile(file2); - - RegionFileCache.cache.put(file2, regionfile1); - return regionfile1; - } else { - return null; - } - } - // CraftBukkit end - - // Paper Start - private static synchronized void trimCache() { - Iterator> itr = RegionFileCache.cache.entrySet().iterator(); - int count = RegionFileCache.cache.size() - PaperConfig.regionFileCacheSize; - while (count-- >= 0 && itr.hasNext()) { - try { - itr.next().getValue().close(); - } catch (IOException ioexception) { - ioexception.printStackTrace(); - ServerInternalException.reportInternalException(ioexception); - } - itr.remove(); - } - } - public static synchronized File getRegionFileName(File file, int i, int j) { + public static File getRegionFileName(File file, int i, int j) { File file1 = new File(file, "region"); return new File(file1, "r." + (i >> 5) + "." + (j >> 5) + ".mca"); } - public static synchronized boolean hasRegionFile(File file, int i, int j) { - return RegionFileCache.cache.containsKey(getRegionFileName(file, i, j)); + public synchronized boolean hasRegionFile(File file, int i, int j) { + return cache.containsKey(ChunkCoordIntPair.pair(i, j)); } + // Paper start private static void printOversizedLog(String msg, File file, int x, int z) { org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); } @@ -103,23 +106,27 @@ public class RegionFileCache { return SIZE_THRESHOLD == OVERZEALOUS_THRESHOLD; } - private static void writeRegion(File file, int x, int z, NBTTagCompound nbttagcompound) throws IOException { - RegionFile regionfile = getRegionFile(file, x, z); + private void writeRegion(ChunkCoordIntPair chunk, NBTTagCompound nbttagcompound) throws IOException { + RegionFile regionfile = getRegionFile(chunk, false); - DataOutputStream out = regionfile.getWriteStream(x & 31, z & 31); + int chunkX = chunk.x; + int chunkZ = chunk.z; + + DataOutputStream out = regionfile.getWriteStream(chunk); try { NBTCompressedStreamTools.writeNBT(nbttagcompound, out); out.close(); - regionfile.setOversized(x, z, false); + regionfile.setStatus(chunk.x, chunk.z, ChunkRegionLoader.getStatus(nbttagcompound)); // Paper - cache status on disk + regionfile.setOversized(chunkX, chunkZ, false); } catch (RegionFile.ChunkTooLargeException ignored) { - printOversizedLog("ChunkTooLarge! Someone is trying to duplicate.", file, x, z); + printOversizedLog("ChunkTooLarge! Someone is trying to duplicate.", regionfile.file, chunkX, chunkZ); // Clone as we are now modifying it, don't want to corrupt the pending save state nbttagcompound = nbttagcompound.clone(); // Filter out TileEntities and Entities NBTTagCompound oversizedData = filterChunkData(nbttagcompound); //noinspection SynchronizationOnLocalVariableOrMethodParameter synchronized (regionfile) { - out = regionfile.getWriteStream(x & 31, z & 31); + out = regionfile.getWriteStream(chunk); NBTCompressedStreamTools.writeNBT(nbttagcompound, out); try { out.close(); @@ -127,14 +134,15 @@ public class RegionFileCache { if (SIZE_THRESHOLD == OVERZEALOUS_THRESHOLD) { resetFilterThresholds(); } + regionfile.setStatus(chunk.x, chunk.z, ChunkRegionLoader.getStatus(nbttagcompound)); // Paper - cache status on disk } catch (RegionFile.ChunkTooLargeException e) { - printOversizedLog("ChunkTooLarge even after reduction. Trying in overzealous mode.", file, x, z); + printOversizedLog("ChunkTooLarge even after reduction. Trying in overzealous mode.", regionfile.file, chunkX, chunkZ); // Eek, major fail. We have retry logic, so reduce threshholds and fall back SIZE_THRESHOLD = OVERZEALOUS_THRESHOLD; throw e; } - regionfile.writeOversizedData(x, z, oversizedData); + regionfile.writeOversizedData(chunkX, chunkZ, oversizedData); } } } @@ -153,7 +161,7 @@ public class RegionFileCache { NBTTagList list = level.getList(key, 10); NBTTagList newList = extra.getList(key, 10); int totalSize = 0; - for (Iterator iterator = list.list.iterator(); iterator.hasNext(); ) { + for (java.util.Iterator iterator = list.list.iterator(); iterator.hasNext();) { NBTBase object = iterator.next(); int nbtSize = getNBTSize(object); if (nbtSize > SIZE_THRESHOLD || (SIZE_THRESHOLD == OVERZEALOUS_THRESHOLD && totalSize > OVERZEALOUS_TOTAL_THRESHOLD)) { @@ -168,11 +176,24 @@ public class RegionFileCache { } - private static NBTTagCompound readOversizedChunk(RegionFile regionfile, int i, int j) throws IOException { + private static NBTTagCompound readOversizedChunk(RegionFile regionfile, ChunkCoordIntPair chunkCoordinate) throws IOException { synchronized (regionfile) { - try (DataInputStream datainputstream = regionfile.getReadStream(i & 31, j & 31)) { - NBTTagCompound oversizedData = regionfile.getOversizedData(i, j); - NBTTagCompound chunk = NBTCompressedStreamTools.readNBT(datainputstream); + try (DataInputStream datainputstream = regionfile.getReadStream(chunkCoordinate)) { + // Paper start - Handle bad chunks more gracefully - also handle similarly with oversized data + NBTTagCompound oversizedData = null; + + try { + oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z); + } catch (Exception ex) {} + + NBTTagCompound chunk; + + try { + chunk = NBTCompressedStreamTools.readNBT(datainputstream); + } catch (final Exception ex) { + return null; + } + // Paper end if (oversizedData == null) { return chunk; } @@ -215,68 +236,89 @@ public class RegionFileCache { // Paper End - public static synchronized void a() { - Iterator iterator = RegionFileCache.cache.values().iterator(); + @Nullable + public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException { + RegionFile regionfile = this.a(chunkcoordintpair, false); // CraftBukkit + DataInputStream datainputstream = regionfile.a(chunkcoordintpair); + // Paper start + if (regionfile.isOversized(chunkcoordintpair.x, chunkcoordintpair.z)) { + printOversizedLog("Loading Oversized Chunk!", regionfile.file, chunkcoordintpair.x, chunkcoordintpair.z); + return readOversizedChunk(regionfile, chunkcoordintpair); + } + // Paper end + Throwable throwable = null; - while (iterator.hasNext()) { - RegionFile regionfile = (RegionFile) iterator.next(); + NBTTagCompound nbttagcompound; - try { - if (regionfile != null) { - regionfile.close(); + try { + if (datainputstream != null) { + // Paper start - Handle bad chunks more gracefully + try { + return NBTCompressedStreamTools.a(datainputstream); + } catch (Exception ex) { + return null; } - } catch (IOException ioexception) { - ioexception.printStackTrace(); - ServerInternalException.reportInternalException(ioexception); // Paper + // Paper end } + + nbttagcompound = null; + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (datainputstream != null) { + if (throwable != null) { + try { + datainputstream.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + datainputstream.close(); + } + } + } - RegionFileCache.cache.clear(); + return nbttagcompound; } - @Nullable - // CraftBukkit start - call sites hoisted for synchronization - public static NBTTagCompound read(File file, int i, int j) throws IOException { // Paper - remove synchronization - RegionFile regionfile = a(file, i, j); - // Paper start - if (regionfile.isOversized(i, j)) { - printOversizedLog("Loading Oversized Chunk!", file, i, j); - return readOversizedChunk(regionfile, i, j); - } - // Paper end - - DataInputStream datainputstream = regionfile.a(i & 31, j & 31); - - if (datainputstream == null) { - return null; - } - - return NBTCompressedStreamTools.a(datainputstream); - } - - @Nullable - public static void write(File file, int i, int j, NBTTagCompound nbttagcompound) throws IOException { + protected void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper - writeRegion(file, i, j, nbttagcompound); // Paper - moved to own method // Paper start -// RegionFile regionfile = a(file, i, j); + this.writeRegion(chunkcoordintpair, nbttagcompound); +// RegionFile regionfile = this.a(chunkcoordintpair, false); // CraftBukkit +// DataOutputStream dataoutputstream = regionfile.c(chunkcoordintpair); +// Throwable throwable = null; // -// DataOutputStream dataoutputstream = regionfile.c(i & 31, j & 31); -// NBTCompressedStreamTools.a(nbttagcompound, (java.io.DataOutput) dataoutputstream); -// dataoutputstream.close(); +// try { +// NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream); +// } catch (Throwable throwable1) { +// throwable = throwable1; +// throw throwable1; +// } finally { +// if (dataoutputstream != null) { +// if (throwable != null) { +// try { +// dataoutputstream.close(); +// } catch (Throwable throwable2) { +// throwable.addSuppressed(throwable2); +// } +// } else { +// dataoutputstream.close(); +// } +// } +// +// } // Paper end - // Paper start - laste = null; break; // Paper - } catch (Exception exception) { - //ChunkRegionLoader.a.error("Failed to save chunk", exception); // Paper - laste = exception; // Paper - } - try { - Thread.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - } + + // Paper start + return; + } catch (Exception ex) { + laste = ex; } + } + if (laste != null) { com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(laste); MinecraftServer.LOGGER.error("Failed to save chunk", laste); @@ -284,10 +326,46 @@ public class RegionFileCache { // Paper end } - public static boolean chunkExists(File file, int i, int j) { // Paper - remove synchronization - RegionFile regionfile = b(file, i, j); + public void close() throws IOException { + ObjectIterator objectiterator = this.cache.values().iterator(); - return regionfile != null ? regionfile.d(i & 31, j & 31) : false; + while (objectiterator.hasNext()) { + RegionFile regionfile = (RegionFile) objectiterator.next(); + + regionfile.close(); + } + + } + + // CraftBukkit start + public synchronized boolean chunkExists(ChunkCoordIntPair pos) throws IOException { // Paper - synchronize + copyIfNeeded(pos.x, pos.z); // Paper + RegionFile regionfile = a(pos, true); + + return regionfile != null ? regionfile.d(pos) : false; } // CraftBukkit end + + private void copyIfNeeded(int x, int z) { + if (!useAltWorld) { + return; + } + synchronized (RegionFileCache.class) { + if (hasRegionFile(this.actualWorld, x, z)) { + return; + } + File actual = RegionFileCache.getRegionFileName(this.actualWorld, x, z); + File template = RegionFileCache.getRegionFileName(this.templateWorld, x, z); + if (!actual.exists() && template.exists()) { + try { + net.minecraft.server.MinecraftServer.LOGGER.info("Copying" + template + " to " + actual); + java.nio.file.Files.copy(template.toPath(), actual.toPath(), java.nio.file.StandardCopyOption.COPY_ATTRIBUTES); + } catch (IOException e1) { + LogManager.getLogger().error("Error copying " + template + " to " + actual, e1); + MinecraftServer.getServer().safeShutdown(false); + com.destroystokyo.paper.util.SneakyThrow.sneaky(e1); + } + } + } + } } diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java new file mode 100644 index 000000000..04b7dab64 --- /dev/null +++ b/src/main/java/net/minecraft/server/RegionFileSection.java @@ -0,0 +1,242 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.OptionalDynamic; +import com.mojang.datafixers.types.DynamicOps; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.Optional; +import java.util.function.BiFunction; +import java.util.function.BooleanSupplier; +import java.util.function.Function; +import javax.annotation.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class RegionFileSection extends RegionFileCache { + + private static final Logger LOGGER = LogManager.getLogger(); + private final Long2ObjectMap> b = new Long2ObjectOpenHashMap(); + protected final LongLinkedOpenHashSet d = new LongLinkedOpenHashSet(); // Paper - private -> protected + private final BiFunction, R> e; + private final Function f; + private final DataFixer g; + private final DataFixTypes h; + + public RegionFileSection(File file, BiFunction, R> bifunction, Function function, DataFixer datafixer, DataFixTypes datafixtypes) { + super(file); + this.e = bifunction; + this.f = function; + this.g = datafixer; + this.h = datafixtypes; + } + + protected void a(BooleanSupplier booleansupplier) { + while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) { // Paper - conflict here to avoid obfhelpers + ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).u(); // Paper - conflict here to avoid obfhelpers + + this.d(chunkcoordintpair); + } + + } + + @Nullable + protected Optional c(long i) { + return (Optional) this.b.get(i); + } + + protected Optional d(long i) { + SectionPosition sectionposition = SectionPosition.a(i); + + if (this.b(sectionposition)) { + return Optional.empty(); + } else { + Optional optional = this.c(i); + + if (optional != null) { + return optional; + } else { + this.b(sectionposition.u()); + optional = this.c(i); + if (optional == null) { + throw new IllegalStateException(); + } else { + return optional; + } + } + } + } + + protected boolean b(SectionPosition sectionposition) { + return World.b(SectionPosition.c(sectionposition.b())); + } + + protected R e(long i) { + Optional optional = this.d(i); + + if (optional.isPresent()) { + return optional.get(); // Paper - decompile fix + } else { + R r0 = this.f.apply(() -> { // Paper - decompile fix + this.a(i); + }); + + this.b.put(i, Optional.of(r0)); + return r0; + } + } + + private void b(ChunkCoordIntPair chunkcoordintpair) { + // Paper start - load data in function + this.loadInData(chunkcoordintpair, this.c(chunkcoordintpair)); + } + public void loadInData(ChunkCoordIntPair chunkPos, NBTTagCompound compound) { + this.a(chunkPos, DynamicOpsNBT.a, compound); + // Paper end + } + + @Nullable + private NBTTagCompound c(ChunkCoordIntPair chunkcoordintpair) { + try { + return this.read(chunkcoordintpair); + } catch (IOException ioexception) { + RegionFileSection.LOGGER.error("Error reading chunk {} data from disk", chunkcoordintpair, ioexception); + return null; + } + } + + private void a(ChunkCoordIntPair chunkcoordintpair, DynamicOps dynamicops, @Nullable T t0) { + if (t0 == null) { + for (int i = 0; i < 16; ++i) { + this.b.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty()); + } + } else { + Dynamic dynamic = new Dynamic(dynamicops, t0); + int j = a(dynamic); + int k = SharedConstants.a().getWorldVersion(); + boolean flag = j != k; + Dynamic dynamic1 = this.g.update(this.h.a(), dynamic, j, k); + OptionalDynamic optionaldynamic = dynamic1.get("Sections"); + + for (int l = 0; l < 16; ++l) { + long i1 = SectionPosition.a(chunkcoordintpair, l).v(); + Optional optional = optionaldynamic.get(Integer.toString(l)).get().map((dynamic2) -> { + return this.e.apply(() -> { // Paper - decompile fix + this.a(i1); + }, dynamic2); + }); + + this.b.put(i1, optional); + optional.ifPresent((minecraftserializable) -> { + this.b(i1); + if (flag) { + this.a(i1); + } + + }); + } + } + + } + + private void d(ChunkCoordIntPair chunkcoordintpair) { + Dynamic dynamic = this.a(chunkcoordintpair, DynamicOpsNBT.a); // Paper - conflict here to avoid adding obfhelpers :) + NBTBase nbtbase = (NBTBase) dynamic.getValue(); + + if (nbtbase instanceof NBTTagCompound) { + try { + this.write(chunkcoordintpair, (NBTTagCompound) nbtbase); + } catch (IOException ioexception) { + RegionFileSection.LOGGER.error("Error writing data to disk", ioexception); + } + } else { + RegionFileSection.LOGGER.error("Expected compound tag, got {}", nbtbase); + } + + } + + // Paper start - internal get data function, copied from above + private NBTTagCompound getDataInternal(ChunkCoordIntPair chunkcoordintpair) { + Dynamic dynamic = this.a(chunkcoordintpair, DynamicOpsNBT.a); + NBTBase nbtbase = (NBTBase) dynamic.getValue(); + + if (nbtbase instanceof NBTTagCompound) { + return (NBTTagCompound)nbtbase; + } else { + RegionFileSection.LOGGER.error("Expected compound tag, got {}", nbtbase); + } + return null; + } + // Paper end + + private Dynamic a(ChunkCoordIntPair chunkcoordintpair, DynamicOps dynamicops) { + Map map = Maps.newHashMap(); + + for (int i = 0; i < 16; ++i) { + long j = SectionPosition.a(chunkcoordintpair, i).v(); + + this.d.remove(j); + Optional optional = (Optional) this.b.get(j); + + if (optional != null && optional.isPresent()) { + map.put(dynamicops.createString(Integer.toString(i)), ((MinecraftSerializable) optional.get()).a(dynamicops)); + } + } + + return new Dynamic(dynamicops, dynamicops.createMap(ImmutableMap.of(dynamicops.createString("Sections"), dynamicops.createMap(map), dynamicops.createString("DataVersion"), dynamicops.createInt(SharedConstants.a().getWorldVersion())))); + } + + protected void b(long i) {} + + protected void a(long i) { + Optional optional = (Optional) this.b.get(i); + + if (optional != null && optional.isPresent()) { + this.d.add(i); + } else { + RegionFileSection.LOGGER.warn("No data for position: {}", SectionPosition.a(i)); + } + } + + private static int a(Dynamic dynamic) { + return ((Number) dynamic.get("DataVersion").asNumber().orElse(1945)).intValue(); + } + + public void a(ChunkCoordIntPair chunkcoordintpair) { + if (!this.d.isEmpty()) { + for (int i = 0; i < 16; ++i) { + long j = SectionPosition.a(chunkcoordintpair, i).v(); // Paper - conflict here to avoid obfhelpers + + if (this.d.contains(j)) { // Paper - conflict here to avoid obfhelpers + this.d(chunkcoordintpair); + return; + } + } + } + + } + + // Paper start - get data function + public NBTTagCompound getData(ChunkCoordIntPair chunkcoordintpair) { + // Note: Copied from above + // This is checking if the data exists, then it builds it later in getDataInternal(ChunkCoordIntPair) + if (!this.d.isEmpty()) { + for (int i = 0; i < 16; ++i) { + long j = SectionPosition.a(chunkcoordintpair, i).v(); + + if (this.d.contains(j)) { + return this.getDataInternal(chunkcoordintpair); + } + } + } + return null; + } + // Paper end +} diff --git a/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java b/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java index da6df06d8..ac6687754 100644 --- a/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java +++ b/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java @@ -1,5 +1,7 @@ package net.minecraft.server; +import java.util.Collections; +import java.util.List; import java.util.Random; import java.util.function.Predicate; import javax.annotation.Nullable; @@ -8,39 +10,45 @@ import org.apache.logging.log4j.Logger; public class RegionLimitedWorldAccess implements GeneratorAccess { - private static final Logger a = LogManager.getLogger(); - private final ProtoChunk[] b; + private static final Logger LOGGER = LogManager.getLogger(); + private final List b; private final int c; private final int d; private final int e; - private final int f; - private final World g; - private final long h; - private final int i; - private final WorldData j; - private final Random k; - private final WorldProvider l; - private final GeneratorSettings m; - private final TickList n = new TickListWorldGen<>((blockposition) -> { - return this.y(blockposition).k(); + private final WorldServer f; + private final long g; + private final int h; + private final WorldData i; + private final Random j; + private final WorldProvider k; + private final GeneratorSettingsDefault l; + private final TickList m = new TickListWorldGen<>((blockposition) -> { + return this.w(blockposition).n(); }); - private final TickList o = new TickListWorldGen<>((blockposition) -> { - return this.y(blockposition).l(); + private final TickList n = new TickListWorldGen<>((blockposition) -> { + return this.w(blockposition).o(); }); - public RegionLimitedWorldAccess(ProtoChunk[] aprotochunk, int i, int j, int k, int l, World world) { - this.b = aprotochunk; - this.c = k; - this.d = l; - this.e = i; - this.f = j; - this.g = world.regionLimited(this); // Paper - this.h = world.getSeed(); - this.m = world.getChunkProvider().getChunkGenerator().getSettings(); - this.i = world.getSeaLevel(); - this.j = world.getWorldData(); - this.k = world.m(); - this.l = world.o(); + public RegionLimitedWorldAccess(WorldServer worldserver, List list) { + int i = MathHelper.floor(Math.sqrt((double) list.size())); + + if (i * i != list.size()) { + throw new IllegalStateException("Cache size is not a square."); + } else { + ChunkCoordIntPair chunkcoordintpair = ((IChunkAccess) list.get(list.size() / 2)).getPos(); + + this.b = list; + this.c = chunkcoordintpair.x; + this.d = chunkcoordintpair.z; + this.e = i; + this.f = worldserver; + this.g = worldserver.getSeed(); + this.l = worldserver.getChunkProvider().getChunkGenerator().getSettings(); + this.h = worldserver.getSeaLevel(); + this.i = worldserver.getWorldData(); + this.j = worldserver.getRandom(); + this.k = worldserver.getWorldProvider(); + } } public int a() { @@ -51,52 +59,97 @@ public class RegionLimitedWorldAccess implements GeneratorAccess { return this.d; } - public boolean a(int i, int j) { - ProtoChunk protochunk = this.b[0]; - ProtoChunk protochunk1 = this.b[this.b.length - 1]; - - return i >= protochunk.getPos().x && i <= protochunk1.getPos().x && j >= protochunk.getPos().z && j <= protochunk1.getPos().z; - } - + @Override public IChunkAccess getChunkAt(int i, int j) { - if (this.a(i, j)) { - int k = i - this.b[0].getPos().x; - int l = j - this.b[0].getPos().z; - - return this.b[k + l * this.e]; - } else { - ProtoChunk protochunk = this.b[0]; - ProtoChunk protochunk1 = this.b[this.b.length - 1]; - - RegionLimitedWorldAccess.a.error("Requested chunk : {} {}", i, j); - RegionLimitedWorldAccess.a.error("Region bounds : {} {} | {} {}", protochunk.getPos().x, protochunk.getPos().z, protochunk1.getPos().x, protochunk1.getPos().z); - throw new RuntimeException(String.format("We are asking a region for a chunk out of bound | %s %s", i, j)); - } - } - - public IBlockData getType(BlockPosition blockposition) { - return this.y(blockposition).getType(blockposition); - } - - public Fluid getFluid(BlockPosition blockposition) { - return this.y(blockposition).getFluid(blockposition); + return this.getChunkAt(i, j, ChunkStatus.EMPTY); } @Nullable + @Override + public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { + IChunkAccess ichunkaccess; + + if (this.isChunkLoaded(i, j)) { + ChunkCoordIntPair chunkcoordintpair = ((IChunkAccess) this.b.get(0)).getPos(); + int k = i - chunkcoordintpair.x; + int l = j - chunkcoordintpair.z; + + ichunkaccess = (IChunkAccess) this.b.get(k + l * this.e); + if (ichunkaccess.getChunkStatus().b(chunkstatus)) { + return ichunkaccess; + } + } else { + ichunkaccess = null; + } + + if (!flag) { + return null; + } else { + IChunkAccess ichunkaccess1 = (IChunkAccess) this.b.get(0); + IChunkAccess ichunkaccess2 = (IChunkAccess) this.b.get(this.b.size() - 1); + + RegionLimitedWorldAccess.LOGGER.error("Requested chunk : {} {}", i, j); + RegionLimitedWorldAccess.LOGGER.error("Region bounds : {} {} | {} {}", ichunkaccess1.getPos().x, ichunkaccess1.getPos().z, ichunkaccess2.getPos().x, ichunkaccess2.getPos().z); + if (ichunkaccess != null) { + throw new RuntimeException(String.format("Chunk is not of correct status. Expecting %s, got %s | %s %s", chunkstatus, ichunkaccess.getChunkStatus(), i, j)); + } else { + throw new RuntimeException(String.format("We are asking a region for a chunk out of bound | %s %s", i, j)); + } + } + } + + @Override + public boolean isChunkLoaded(int i, int j) { + IChunkAccess ichunkaccess = (IChunkAccess) this.b.get(0); + IChunkAccess ichunkaccess1 = (IChunkAccess) this.b.get(this.b.size() - 1); + + return i >= ichunkaccess.getPos().x && i <= ichunkaccess1.getPos().x && j >= ichunkaccess.getPos().z && j <= ichunkaccess1.getPos().z; + } + + // Paper start - if loaded util + @Nullable + @Override + public IChunkAccess getChunkIfLoadedImmediately(int x, int z) { + return this.getChunkAt(x, z, ChunkStatus.FULL, false); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + return chunk == null ? null : chunk.getType(blockposition); + } + + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + return chunk == null ? null : chunk.getFluid(blockposition); + } + // Paper end + + @Override + public IBlockData getType(BlockPosition blockposition) { + return this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4).getType(blockposition); + } + + @Override + public Fluid getFluid(BlockPosition blockposition) { + return this.w(blockposition).getFluid(blockposition); + } + + @Nullable + @Override public EntityHuman a(double d0, double d1, double d2, double d3, Predicate predicate) { return null; } + @Override public int c() { return 0; } - public boolean isEmpty(BlockPosition blockposition) { - return this.getType(blockposition).isAir(); - } - + @Override public BiomeBase getBiome(BlockPosition blockposition) { - BiomeBase biomebase = this.y(blockposition).getBiomeIndex()[blockposition.getX() & 15 | (blockposition.getZ() & 15) << 4]; + BiomeBase biomebase = this.w(blockposition).getBiomeIndex()[blockposition.getX() & 15 | (blockposition.getZ() & 15) << 4]; if (biomebase == null) { throw new RuntimeException(String.format("Biome is null @ %s", blockposition)); @@ -105,77 +158,85 @@ public class RegionLimitedWorldAccess implements GeneratorAccess { } } + @Override public int getBrightness(EnumSkyBlock enumskyblock, BlockPosition blockposition) { - IChunkAccess ichunkaccess = this.y(blockposition); - - return ichunkaccess.a(enumskyblock, blockposition, this.o().g()); + return this.getChunkProvider().getLightEngine().a(enumskyblock).b(blockposition); } + @Override public int getLightLevel(BlockPosition blockposition, int i) { - return this.y(blockposition).a(blockposition, i, this.o().g()); + return this.w(blockposition).a(blockposition, i, this.getWorldProvider().g()); } - public boolean isChunkLoaded(int i, int j, boolean flag) { - return this.a(i, j); - } - - public boolean setAir(BlockPosition blockposition, boolean flag) { + @Override + public boolean b(BlockPosition blockposition, boolean flag) { IBlockData iblockdata = this.getType(blockposition); if (iblockdata.isAir()) { return false; } else { if (flag) { - iblockdata.a(this.g, blockposition, 0); + TileEntity tileentity = iblockdata.getBlock().isTileEntity() ? this.getTileEntity(blockposition) : null; + + Block.a(iblockdata, (World) this.f, blockposition, tileentity); } return this.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); } } - public boolean e(BlockPosition blockposition) { - return this.y(blockposition).c(blockposition); - } - @Nullable + @Override public TileEntity getTileEntity(BlockPosition blockposition) { - IChunkAccess ichunkaccess = this.y(blockposition); + IChunkAccess ichunkaccess = this.w(blockposition); TileEntity tileentity = ichunkaccess.getTileEntity(blockposition); if (tileentity != null) { return tileentity; } else { - NBTTagCompound nbttagcompound = ichunkaccess.g(blockposition); + NBTTagCompound nbttagcompound = ichunkaccess.i(blockposition); if (nbttagcompound != null) { if ("DUMMY".equals(nbttagcompound.getString("id"))) { - tileentity = ((ITileEntity) this.getType(blockposition).getBlock()).a(this.g); + Block block = this.getType(blockposition).getBlock(); + + if (!(block instanceof ITileEntity)) { + return null; + } + + tileentity = ((ITileEntity) block).createTile(this.f); } else { tileentity = TileEntity.create(nbttagcompound); } if (tileentity != null) { - ichunkaccess.a(blockposition, tileentity); + ichunkaccess.setTileEntity(blockposition, tileentity); return tileentity; } } if (ichunkaccess.getType(blockposition).getBlock() instanceof ITileEntity) { - RegionLimitedWorldAccess.a.warn("Tried to access a block entity before it was created. {}", blockposition); + RegionLimitedWorldAccess.LOGGER.warn("Tried to access a block entity before it was created. {}", blockposition); } return null; } } + @Override public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { - IChunkAccess ichunkaccess = this.y(blockposition); + IChunkAccess ichunkaccess = this.w(blockposition); IBlockData iblockdata1 = ichunkaccess.setType(blockposition, iblockdata, false); + + if (iblockdata1 != null) { + this.f.a(blockposition, iblockdata1, iblockdata); + } + Block block = iblockdata.getBlock(); if (block.isTileEntity()) { - if (ichunkaccess.i().d() == ChunkStatus.Type.LEVELCHUNK) { - ichunkaccess.a(blockposition, ((ITileEntity) block).a(this)); + if (ichunkaccess.getChunkStatus().getType() == ChunkStatus.Type.LEVELCHUNK) { + ichunkaccess.setTileEntity(blockposition, ((ITileEntity) block).createTile(this)); } else { NBTTagCompound nbttagcompound = new NBTTagCompound(); @@ -186,10 +247,10 @@ public class RegionLimitedWorldAccess implements GeneratorAccess { ichunkaccess.a(nbttagcompound); } } else if (iblockdata1 != null && iblockdata1.getBlock().isTileEntity()) { - ichunkaccess.d(blockposition); + ichunkaccess.removeTileEntity(blockposition); } - if (iblockdata.l(this, blockposition)) { + if (iblockdata.n(this, blockposition)) { this.i(blockposition); } @@ -197,11 +258,12 @@ public class RegionLimitedWorldAccess implements GeneratorAccess { } private void i(BlockPosition blockposition) { - this.y(blockposition).e(blockposition); + this.w(blockposition).f(blockposition); } - // CraftBukkit start + @Override public boolean addEntity(Entity entity) { + // CraftBukkit start return addEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT); } @@ -215,95 +277,120 @@ public class RegionLimitedWorldAccess implements GeneratorAccess { return true; } - public boolean setAir(BlockPosition blockposition) { + @Override + public boolean a(BlockPosition blockposition, boolean flag) { return this.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); } - public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { - this.y(blockposition).a(enumskyblock, this.l.g(), blockposition, i); - } - + @Override public WorldBorder getWorldBorder() { - return this.g.getWorldBorder(); + return this.f.getWorldBorder(); } + @Override public boolean a(@Nullable Entity entity, VoxelShape voxelshape) { return true; } - public int a(BlockPosition blockposition, EnumDirection enumdirection) { - return this.getType(blockposition).b((IBlockAccess) this, blockposition, enumdirection); - } - + @Override public boolean e() { return false; } @Deprecated - public World getMinecraftWorld() { - return this.g; + @Override + public WorldServer getMinecraftWorld() { + return this.f; } + @Override public WorldData getWorldData() { - return this.j; - } - - public DifficultyDamageScaler getDamageScaler(BlockPosition blockposition) { - if (!this.a(blockposition.getX() >> 4, blockposition.getZ() >> 4)) { - throw new RuntimeException("We are asking a region for a chunk out of bound"); - } else { - return new DifficultyDamageScaler(this.g.getDifficulty(), this.g.getDayTime(), 0L, this.g.ah()); - } - } - - @Nullable - public PersistentCollection h() { - return this.g.h(); - } - - public IChunkProvider getChunkProvider() { - return this.g.getChunkProvider(); - } - - public IDataManager getDataManager() { - return this.g.getDataManager(); - } - - public long getSeed() { - return this.h; - } - - public TickList getBlockTickList() { - return this.n; - } - - public TickList getFluidTickList() { - return this.o; - } - - public int getSeaLevel() { return this.i; } - public Random m() { - return this.k; + @Override + public DifficultyDamageScaler getDamageScaler(BlockPosition blockposition) { + if (!this.isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4)) { + throw new RuntimeException("We are asking a region for a chunk out of bound"); + } else { + return new DifficultyDamageScaler(this.f.getDifficulty(), this.f.getDayTime(), 0L, this.f.aa()); + } } + @Override + public IChunkProvider getChunkProvider() { + return this.f.getChunkProvider(); + } + + @Override + public long getSeed() { + return this.g; + } + + @Override + public TickList getBlockTickList() { + return this.m; + } + + @Override + public TickList getFluidTickList() { + return this.n; + } + + @Override + public int getSeaLevel() { + return this.h; + } + + @Override + public Random getRandom() { + return this.j; + } + + @Override public void update(BlockPosition blockposition, Block block) {} + @Override public int a(HeightMap.Type heightmap_type, int i, int j) { return this.getChunkAt(i >> 4, j >> 4).a(heightmap_type, i & 15, j & 15) + 1; } - public void a(@Nullable EntityHuman entityhuman, BlockPosition blockposition, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) {} + @Override + public void playSound(@Nullable EntityHuman entityhuman, BlockPosition blockposition, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) {} + @Override public void addParticle(ParticleParam particleparam, double d0, double d1, double d2, double d3, double d4, double d5) {} - public BlockPosition getSpawn() { - return this.g.getSpawn(); + @Override + public void a(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j) {} + + @Override + public WorldProvider getWorldProvider() { + return this.k; } - public WorldProvider o() { - return this.l; + @Override + public boolean a(BlockPosition blockposition, Predicate predicate) { + return predicate.test(this.getType(blockposition)); + } + + @Override + public List a(Class oclass, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate) { + return Collections.emptyList(); + } + + @Override + public List getEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate) { + return Collections.emptyList(); + } + + @Override + public List getPlayers() { + return Collections.emptyList(); + } + + @Override + public BlockPosition getHighestBlockYAt(HeightMap.Type heightmap_type, BlockPosition blockposition) { + return new BlockPosition(blockposition.getX(), this.a(heightmap_type, blockposition.getX(), blockposition.getZ()), blockposition.getZ()); } } diff --git a/src/main/java/net/minecraft/server/Registry.java b/src/main/java/net/minecraft/server/Registry.java deleted file mode 100644 index 9efec49d6..000000000 --- a/src/main/java/net/minecraft/server/Registry.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.minecraft.server; - -import java.util.Iterator; -public interface Registry extends Iterable { // Paper - decompile fix - - @Override - Iterator iterator(); // Paper - decompile fix -} diff --git a/src/main/java/net/minecraft/server/RegistryBlockID.java b/src/main/java/net/minecraft/server/RegistryBlockID.java index ea1e5fe6b..60948afa4 100644 --- a/src/main/java/net/minecraft/server/RegistryBlockID.java +++ b/src/main/java/net/minecraft/server/RegistryBlockID.java @@ -3,7 +3,6 @@ package net.minecraft.server; import com.google.common.base.Predicates; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; - import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; @@ -12,7 +11,7 @@ import javax.annotation.Nullable; public class RegistryBlockID implements Registry { private int a; - private com.koloboke.collect.map.hash.HashObjIntMap b; // Akarin - IdentityHashMap -> HashObjIntMap + private final IdentityHashMap b; private final List c; public RegistryBlockID() { @@ -21,17 +20,11 @@ public class RegistryBlockID implements Registry { public RegistryBlockID(int i) { this.c = Lists.newArrayListWithExpectedSize(i); - this.b = com.koloboke.collect.map.hash.HashObjIntMaps.getDefaultFactory().withKeyEquivalence(com.koloboke.collect.Equivalence.identity()).newMutableMap(i); // Akarin - koloboke + this.b = new IdentityHashMap(i); } public void a(T t0, int i) { - // Akarin start - if (t0 == null) return; - com.koloboke.collect.map.hash.HashObjIntMap toImmutable = com.koloboke.collect.map.hash.HashObjIntMaps.newMutableMap(this.b); - toImmutable.put(t0, i); - this.b = com.koloboke.collect.map.hash.HashObjIntMaps.getDefaultFactory().withKeyEquivalence(com.koloboke.collect.Equivalence.identity()).newImmutableMap(toImmutable); - //this.b.put(t0, i); - // Akarin end + this.b.put(t0, i); while (this.c.size() <= i) { this.c.add(null); // Paper - decompile fix @@ -49,12 +42,13 @@ public class RegistryBlockID implements Registry { } public int getId(T t0) { - //Integer integer = this.b.get(t0); // Akarin + Integer integer = (Integer) this.b.get(t0); - return this.b.getOrDefault(t0, -1); // Akarin + return integer == null ? -1 : integer; } @Nullable + @Override public final T fromId(int i) { return i >= 0 && i < this.c.size() ? this.c.get(i) : null; } diff --git a/src/main/java/net/minecraft/server/RegistryID.java b/src/main/java/net/minecraft/server/RegistryID.java index 37641fa86..e8a48b9a4 100644 --- a/src/main/java/net/minecraft/server/RegistryID.java +++ b/src/main/java/net/minecraft/server/RegistryID.java @@ -29,6 +29,7 @@ public class RegistryID implements Registry { } @Nullable + @Override public K fromId(int i) { return i >= 0 && i < this.d.length ? this.d[i] : null; } diff --git a/src/main/java/net/minecraft/server/RegistryMaterials.java b/src/main/java/net/minecraft/server/RegistryMaterials.java index 2fffb6d66..fed38e6ef 100644 --- a/src/main/java/net/minecraft/server/RegistryMaterials.java +++ b/src/main/java/net/minecraft/server/RegistryMaterials.java @@ -5,6 +5,7 @@ import com.google.common.collect.HashBiMap; import java.util.Collection; import java.util.Collections; import java.util.Iterator; +import java.util.Optional; import java.util.Random; import java.util.Set; import javax.annotation.Nullable; @@ -12,77 +13,84 @@ import org.apache.commons.lang3.Validate; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -public class RegistryMaterials implements IRegistry { +public class RegistryMaterials extends IRegistryWritable { - protected static final Logger a = LogManager.getLogger(); - protected final RegistryID b = new RegistryID(2048); // Paper - use bigger expected size to reduce collisions - protected final BiMap c = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions - protected V[] d; // Paper - Decompile fix - private int x; + protected static final Logger LOGGER = LogManager.getLogger(); + protected final RegistryID b = new RegistryID<>(2048); // Paper - use bigger expected size to reduce collisions + protected final BiMap c = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions + protected T[] d; // Paper - Decompile fix + private int R; public RegistryMaterials() {} - public void a(int i, MinecraftKey minecraftkey, V v0) { + @Override + public V a(int i, MinecraftKey minecraftkey, V v0) { this.b.a(v0, i); Validate.notNull(minecraftkey); Validate.notNull(v0); this.d = null; if (this.c.containsKey(minecraftkey)) { - RegistryMaterials.a.debug("Adding duplicate key '{}' to registry", minecraftkey); + RegistryMaterials.LOGGER.debug("Adding duplicate key '{}' to registry", minecraftkey); } this.c.put(minecraftkey, v0); - if (this.x <= i) { - this.x = i + 1; + if (this.R <= i) { + this.R = i + 1; } + return v0; } - public void a(MinecraftKey minecraftkey, V v0) { - this.a(this.x, minecraftkey, v0); + @Override + public V a(MinecraftKey minecraftkey, V v0) { + return this.a(this.R, minecraftkey, v0); } @Nullable - public MinecraftKey getKey(V v0) { - return (MinecraftKey) this.c.inverse().get(v0); + @Override + public MinecraftKey getKey(T t0) { + return (MinecraftKey) this.c.inverse().get(t0); } - public V getOrDefault(@Nullable MinecraftKey minecraftkey) { - throw new UnsupportedOperationException("No default value"); - } - - public MinecraftKey b() { - throw new UnsupportedOperationException("No default key"); - } - - public int a(@Nullable V v0) { - return this.b.getId(v0); + @Override + public int a(@Nullable T t0) { + return this.b.getId(t0); } @Nullable - public V fromId(int i) { + @Override + public T fromId(int i) { return this.b.fromId(i); } - public Iterator iterator() { + public Iterator iterator() { return this.b.iterator(); } @Nullable - public V get(@Nullable MinecraftKey minecraftkey) { + @Override + public T get(@Nullable MinecraftKey minecraftkey) { return this.c.get(minecraftkey); } - public Set keySet() { - return com.koloboke.collect.set.hash.HashObjSets.newImmutableSet(this.c.keySet()); // Akarin - koloboke + @Override + public Optional getOptional(@Nullable MinecraftKey minecraftkey) { + return Optional.ofNullable(this.c.get(minecraftkey)); } - public boolean d() { + @Override + public Set keySet() { + return Collections.unmodifiableSet(this.c.keySet()); + } + + @Override + public boolean c() { return this.c.isEmpty(); } @Nullable - public V a(Random random) { + @Override + public T a(Random random) { if (this.d == null) { Collection collection = this.c.values(); @@ -90,13 +98,9 @@ public class RegistryMaterials implements IRegistry { return null; } - this.d = (V[]) collection.toArray(new Object[collection.size()]); // Paper - Decompile fix + this.d = (T[]) collection.toArray(new Object[collection.size()]); // Paper - Decompile fix } return this.d[random.nextInt(this.d.length)]; } - - public boolean c(MinecraftKey minecraftkey) { - return this.c.containsKey(minecraftkey); - } } diff --git a/src/main/java/net/minecraft/server/RemoteConnectionThread.java b/src/main/java/net/minecraft/server/RemoteConnectionThread.java index bcc36bbbf..d821ef9a7 100644 --- a/src/main/java/net/minecraft/server/RemoteConnectionThread.java +++ b/src/main/java/net/minecraft/server/RemoteConnectionThread.java @@ -12,15 +12,15 @@ import org.apache.logging.log4j.Logger; public abstract class RemoteConnectionThread implements Runnable { - private static final Logger h = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private static final AtomicInteger i = new AtomicInteger(0); protected boolean a; - protected IMinecraftServer b; protected IMinecraftServer getServer() { return b; } // Paper - OBFHELPER + protected final IMinecraftServer b; protected IMinecraftServer getServer() { return this.b; } // Paper - OBFHELPER protected final String c; protected Thread d; - protected int e = 5; - protected List f = Lists.newArrayList(); - protected List g = Lists.newArrayList(); + protected final int e = 5; + protected final List f = Lists.newArrayList(); + protected final List g = Lists.newArrayList(); protected RemoteConnectionThread(IMinecraftServer iminecraftserver, String s) { this.b = iminecraftserver; @@ -33,17 +33,53 @@ public abstract class RemoteConnectionThread implements Runnable { public synchronized void a() { this.d = new Thread(this, this.c + " #" + RemoteConnectionThread.i.incrementAndGet()); - this.d.setUncaughtExceptionHandler(new ThreadNamedUncaughtExceptionHandler(RemoteConnectionThread.h)); + this.d.setUncaughtExceptionHandler(new ThreadNamedUncaughtExceptionHandler(RemoteConnectionThread.LOGGER)); this.d.start(); this.a = true; } + public synchronized void b() { + this.a = false; + if (null != this.d) { + int i = 0; + + while (this.d.isAlive()) { + try { + this.d.join(1000L); + ++i; + if (5 <= i) { + this.c("Waited " + i + " seconds attempting force stop!"); + this.a(true); + } else if (this.d.isAlive()) { + this.c("Thread " + this + " (" + this.d.getState() + ") failed to exit after " + i + " second(s)"); + this.c("Stack:"); + StackTraceElement[] astacktraceelement = this.d.getStackTrace(); + int j = astacktraceelement.length; + + for (int k = 0; k < j; ++k) { + StackTraceElement stacktraceelement = astacktraceelement[k]; + + this.c(stacktraceelement.toString()); + } + + this.d.interrupt(); + } + } catch (InterruptedException interruptedexception) { + ; + } + } + + this.a(true); + this.d = null; + } + } + public boolean c() { return this.a; } protected void a(String s) { - this.b.g(s); + this.b.h(s); } protected void b(String s) { @@ -55,10 +91,10 @@ public abstract class RemoteConnectionThread implements Runnable { } protected void d(String s) { - this.b.f(s); + this.b.g(s); } - protected int getPlayerCount() { return d(); } // Paper - OBFHELPER + protected int getPlayerCount() { return this.d(); } // Paper - OBFHELPER protected int d() { return this.b.getPlayerCount(); } diff --git a/src/main/java/net/minecraft/server/RemoteControlCommandListener.java b/src/main/java/net/minecraft/server/RemoteControlCommandListener.java index b61766292..e32c475e1 100644 --- a/src/main/java/net/minecraft/server/RemoteControlCommandListener.java +++ b/src/main/java/net/minecraft/server/RemoteControlCommandListener.java @@ -2,51 +2,55 @@ package net.minecraft.server; public class RemoteControlCommandListener implements ICommandListener { - private final StringBuffer a = new StringBuffer(); - private final MinecraftServer b; + private final StringBuffer buffer = new StringBuffer(); + private final MinecraftServer server; public RemoteControlCommandListener(MinecraftServer minecraftserver) { - this.b = minecraftserver; + this.server = minecraftserver; } public void clearMessages() { - this.a.setLength(0); + this.buffer.setLength(0); } public String getMessages() { - return this.a.toString(); + return this.buffer.toString(); } - public CommandListenerWrapper f() { - WorldServer worldserver = this.b.getWorldServer(DimensionManager.OVERWORLD); + public CommandListenerWrapper getWrapper() { + WorldServer worldserver = this.server.getWorldServer(DimensionManager.OVERWORLD); - return new CommandListenerWrapper(this, new Vec3D(worldserver.getSpawn()), Vec2F.a, worldserver, 4, "Recon", new ChatComponentText("Rcon"), this.b, (Entity) null); + return new CommandListenerWrapper(this, new Vec3D(worldserver.getSpawn()), Vec2F.a, worldserver, 4, "Recon", new ChatComponentText("Rcon"), this.server, (Entity) null); } // CraftBukkit start - Send a String public void sendMessage(String message) { - this.a.append(message); + this.buffer.append(message); } @Override public org.bukkit.command.CommandSender getBukkitSender(CommandListenerWrapper wrapper) { - return b.remoteConsole; + return server.remoteConsole; } // CraftBukkit end + @Override public void sendMessage(IChatBaseComponent ichatbasecomponent) { - this.a.append(ichatbasecomponent.getString()); + this.buffer.append(ichatbasecomponent.getString()); } - public boolean a() { + @Override + public boolean shouldSendSuccess() { return true; } - public boolean b() { + @Override + public boolean shouldSendFailure() { return true; } - public boolean B_() { - return this.b.k(); + @Override + public boolean shouldBroadcastCommands() { + return this.server.l(); } } diff --git a/src/main/java/net/minecraft/server/RemoteControlListener.java b/src/main/java/net/minecraft/server/RemoteControlListener.java index 7b82c4dea..2ce490be0 100644 --- a/src/main/java/net/minecraft/server/RemoteControlListener.java +++ b/src/main/java/net/minecraft/server/RemoteControlListener.java @@ -13,44 +13,33 @@ import java.util.Map.Entry; public class RemoteControlListener extends RemoteConnectionThread { - private int h; - private final int i; - private String j; - private ServerSocket k; - private final String l; - private Map m; + private final int h; + private String i; + private ServerSocket j; + private final String k; + private Map l; public RemoteControlListener(IMinecraftServer iminecraftserver) { super(iminecraftserver, "RCON Listener"); - this.h = iminecraftserver.a("rcon.port", 0); - this.l = iminecraftserver.a("rcon.password", ""); - this.j = iminecraftserver.a("rcon.ip", ((DedicatedServer) iminecraftserver).getServerIp()); // Paper - this.i = iminecraftserver.e_(); - if (0 == this.h) { - this.h = this.i + 10; - this.b("Setting default rcon port to " + this.h); - iminecraftserver.a("rcon.port", (Object) this.h); - if (this.l.isEmpty()) { - iminecraftserver.a("rcon.password", (Object) ""); - } + DedicatedServerProperties dedicatedserverproperties = iminecraftserver.getDedicatedServerProperties(); - iminecraftserver.c_(); - } - - if (this.j.isEmpty()) { - this.j = "0.0.0.0"; + this.h = dedicatedserverproperties.rconPort; + this.k = dedicatedserverproperties.rconPassword; + this.i = dedicatedserverproperties.rconIp; // Paper - Configurable rcon ip + if (this.i.isEmpty()) { + this.i = "0.0.0.0"; } this.f(); - this.k = null; + this.j = null; } private void f() { - this.m = Maps.newHashMap(); + this.l = Maps.newHashMap(); } private void g() { - Iterator iterator = this.m.entrySet().iterator(); + Iterator iterator = this.l.entrySet().iterator(); while (iterator.hasNext()) { Entry entry = (Entry) iterator.next(); @@ -63,18 +52,18 @@ public class RemoteControlListener extends RemoteConnectionThread { } public void run() { - this.b("RCON running on " + this.j + ":" + this.h); + this.b("RCON running on " + this.i + ":" + this.h); try { while (this.a) { try { - Socket socket = this.k.accept(); + Socket socket = this.j.accept(); socket.setSoTimeout(500); - RemoteControlSession remotecontrolsession = new RemoteControlSession(this.b, socket); + RemoteControlSession remotecontrolsession = new RemoteControlSession(this.b, this.k, socket); remotecontrolsession.a(); - this.m.put(socket.getRemoteSocketAddress(), remotecontrolsession); + this.l.put(socket.getRemoteSocketAddress(), remotecontrolsession); this.g(); } catch (SocketTimeoutException sockettimeoutexception) { this.g(); @@ -85,27 +74,43 @@ public class RemoteControlListener extends RemoteConnectionThread { } } } finally { - this.b(this.k); + this.b(this.j); } } + @Override public void a() { - if (this.l.isEmpty()) { - this.c("No rcon password set in '" + this.b.d_() + "', rcon disabled!"); + if (this.k.isEmpty()) { + this.c("No rcon password set in server.properties, rcon disabled!"); } else if (0 < this.h && 65535 >= this.h) { if (!this.a) { try { - this.k = new ServerSocket(this.h, 0, InetAddress.getByName(this.j)); - this.k.setSoTimeout(500); + this.j = new ServerSocket(this.h, 0, InetAddress.getByName(this.i)); + this.j.setSoTimeout(500); super.a(); } catch (IOException ioexception) { - this.c("Unable to initialise rcon on " + this.j + ":" + this.h + " : " + ioexception.getMessage()); + this.c("Unable to initialise rcon on " + this.i + ":" + this.h + " : " + ioexception.getMessage()); } } } else { - this.c("Invalid rcon port " + this.h + " found in '" + this.b.d_() + "', rcon disabled!"); + this.c("Invalid rcon port " + this.h + " found in server.properties, rcon disabled!"); } } + + @Override + public void b() { + super.b(); + Iterator iterator = this.l.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + + ((RemoteControlSession) entry.getValue()).b(); + } + + this.b(this.j); + this.f(); + } } diff --git a/src/main/java/net/minecraft/server/RemoteStatusListener.java b/src/main/java/net/minecraft/server/RemoteStatusListener.java index fd981931b..67e94a6f0 100644 --- a/src/main/java/net/minecraft/server/RemoteStatusListener.java +++ b/src/main/java/net/minecraft/server/RemoteStatusListener.java @@ -20,28 +20,28 @@ import java.util.Map.Entry; public class RemoteStatusListener extends RemoteConnectionThread { private long h; - private int i; - private final int j; private int getServerPort() { return j; } // Paper - OBFHELPER - private final int k; private int getMaxPlayers() { return k; } // Paper - OBFHELPER - private final String l; private String getMotd() { return l; } // Paper - OBFHELPER - private final String m; private String getWorldName() { return m; } // Paper - OBFHELPER + private final int i; + private final int j; private int getServerPort() { return this.j; } // Paper - OBFHELPER + private final int k; private int getMaxPlayers() { return this.k; } // Paper - OBFHELPER + private final String l; private String getMotd() { return this.l; } // Paper - OBFHELPER + private final String m; private String getWorldName() { return this.m; } // Paper - OBFHELPER private DatagramSocket n; private final byte[] o = new byte[1460]; private DatagramPacket p; private final Map q; - private String r; private String getServerHost() { return r; } // Paper - OBFHELPER + private String r; private String getServerHost() { return this.r; } // Paper - OBFHELPER private String s; private final Map t; private final long u; - private final RemoteStatusReply v; private RemoteStatusReply getCachedFullResponse() { return v; } // Paper - OBFHELPER + private final RemoteStatusReply v; private RemoteStatusReply getCachedFullResponse() { return this.v; } // Paper - OBFHELPER private long w; public RemoteStatusListener(IMinecraftServer iminecraftserver) { super(iminecraftserver, "Query Listener"); - this.i = iminecraftserver.a("query.port", 0); - this.s = iminecraftserver.e(); - this.j = iminecraftserver.e_(); - this.l = iminecraftserver.m(); + this.i = iminecraftserver.getDedicatedServerProperties().queryPort; + this.s = iminecraftserver.e_(); + this.j = iminecraftserver.e(); + this.l = iminecraftserver.f_(); this.k = iminecraftserver.getMaxPlayers(); this.m = iminecraftserver.getWorld(); this.w = 0L; @@ -56,18 +56,10 @@ public class RemoteStatusListener extends RemoteConnectionThread { this.r = inetaddress.getHostAddress(); } catch (UnknownHostException unknownhostexception) { - this.c("Unable to determine local host IP, please set server-ip in '" + iminecraftserver.d_() + "' : " + unknownhostexception.getMessage()); + this.c("Unable to determine local host IP, please set server-ip in server.properties: " + unknownhostexception.getMessage()); } } - if (0 == this.i) { - this.i = this.j; - this.b("Setting default query port to " + this.i); - iminecraftserver.a("query.port", (Object) this.i); - iminecraftserver.a("debug", (Object) false); - iminecraftserver.c_(); - } - this.q = Maps.newHashMap(); this.v = new RemoteStatusReply(1460); this.t = Maps.newHashMap(); @@ -87,26 +79,26 @@ public class RemoteStatusListener extends RemoteConnectionThread { if (3 <= i && -2 == abyte[0] && -3 == abyte[1]) { this.a("Packet '" + StatusChallengeUtils.a(abyte[2]) + "' [" + socketaddress + "]"); switch (abyte[2]) { - case 0: - if (!this.c(datagrampacket)) { - this.a("Invalid challenge [" + socketaddress + "]"); - return false; - } else if (15 == i) { - this.a(this.b(datagrampacket), datagrampacket); - this.a("Rules [" + socketaddress + "]"); - } else { - RemoteStatusReply remotestatusreply = new RemoteStatusReply(1460); + case 0: + if (!this.c(datagrampacket)) { + this.a("Invalid challenge [" + socketaddress + "]"); + return false; + } else if (15 == i) { + this.a(this.b(datagrampacket), datagrampacket); + this.a("Rules [" + socketaddress + "]"); + } else { + RemoteStatusReply remotestatusreply = new RemoteStatusReply(1460); - remotestatusreply.a((int) 0); - remotestatusreply.a(this.a(datagrampacket.getSocketAddress())); + remotestatusreply.a((int) 0); + remotestatusreply.a(this.a(datagrampacket.getSocketAddress())); /* Paper start - GS4 Query event - remotestatusreply.a(this.l); - remotestatusreply.a("SMP"); - remotestatusreply.a(this.m); - remotestatusreply.a(Integer.toString(this.d())); - remotestatusreply.a(Integer.toString(this.k)); - remotestatusreply.a((short) this.j); - remotestatusreply.a(this.r); + remotestatusreply.a(this.l); + remotestatusreply.a("SMP"); + remotestatusreply.a(this.m); + remotestatusreply.a(Integer.toString(this.d())); + remotestatusreply.a(Integer.toString(this.k)); + remotestatusreply.a((short) this.j); + remotestatusreply.a(this.r); */ com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType queryType = com.destroystokyo.paper.event.server.GS4QueryEvent.QueryType.BASIC; @@ -132,15 +124,15 @@ public class RemoteStatusListener extends RemoteConnectionThread { remotestatusreply.writeShort((short) queryResponse.getPort()); remotestatusreply.writeString(queryResponse.getHostname()); // Paper end - this.a(remotestatusreply.a(), datagrampacket); - this.a("Status [" + socketaddress + "]"); - } - default: - return true; - case 9: - this.d(datagrampacket); - this.a("Challenge [" + socketaddress + "]"); - return true; + this.a(remotestatusreply.a(), datagrampacket); + this.a("Status [" + socketaddress + "]"); + } + default: + return true; + case 9: + this.d(datagrampacket); + this.a("Challenge [" + socketaddress + "]"); + return true; } } else { this.a("Invalid packet [" + socketaddress + "]"); @@ -349,6 +341,7 @@ public class RemoteStatusListener extends RemoteConnectionThread { } + @Override public void a() { if (!this.a) { if (0 < this.i && 65535 >= this.i) { @@ -357,7 +350,7 @@ public class RemoteStatusListener extends RemoteConnectionThread { } } else { - this.c("Invalid query port " + this.i + " found in '" + this.b.d_() + "' (queries disabled)"); + this.c("Invalid query port " + this.i + " found in server.properties (queries disabled)"); } } } diff --git a/src/main/java/net/minecraft/server/RemoteStatusReply.java b/src/main/java/net/minecraft/server/RemoteStatusReply.java index 9e8c8b3df..73efea7e1 100644 --- a/src/main/java/net/minecraft/server/RemoteStatusReply.java +++ b/src/main/java/net/minecraft/server/RemoteStatusReply.java @@ -18,7 +18,7 @@ public class RemoteStatusReply { this.b.write(abyte, 0, abyte.length); } - public void writeString(String string) throws IOException { a(string); } // Paper - OBFHELPER + public void writeString(String string) throws IOException { this.a(string); } // Paper - OBFHELPER public void a(String s) throws IOException { this.b.writeBytes(s); this.b.write(0); @@ -33,12 +33,12 @@ public class RemoteStatusReply { } // Paper end - public void writeInt(int i) throws IOException { a(i); } // Paper - OBFHELPER + public void writeInt(int i) throws IOException { this.a(i); } // Paper - OBFHELPER public void a(int i) throws IOException { this.b.write(i); } - public void writeShort(short i) throws IOException { a(i); } // Paper - OBFHELPER + public void writeShort(short i) throws IOException { this.a(i); } // Paper - OBFHELPER public void a(short short0) throws IOException { this.b.writeShort(Short.reverseBytes(short0)); } diff --git a/src/main/java/net/minecraft/server/SchedulerBatch.java b/src/main/java/net/minecraft/server/SchedulerBatch.java deleted file mode 100644 index f214a74a2..000000000 --- a/src/main/java/net/minecraft/server/SchedulerBatch.java +++ /dev/null @@ -1,70 +0,0 @@ -package net.minecraft.server; - -import java.util.concurrent.CompletableFuture; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -public class SchedulerBatch, R> { - - private static final Logger a = LogManager.getLogger(); - private final Scheduler b; - private boolean c; - private int d = 1000; - private final java.util.concurrent.locks.ReentrantLock lock = new java.util.concurrent.locks.ReentrantLock(true); // Paper - - public SchedulerBatch(Scheduler scheduler) { - this.b = scheduler; - } - - public void a() throws InterruptedException { - this.b.b(); - } - - public void startBatch() { b(); } // Paper - OBFHELPER - public void b() { - lock.lock(); // Paper - if (false && this.c) { // Paper - throw new RuntimeException("Batch already started."); - } else { - this.d = 1000; - this.c = true; - } - } - - public CompletableFuture add(K k0) { return a(k0); } // Paper - OBFHELPER - public CompletableFuture a(K k0) { - if (!this.c) { - throw new RuntimeException("Batch not properly started. Please use startBatch to create a new batch."); - } else { - CompletableFuture completablefuture = this.b.a(k0); - - --this.d; - if (this.d == 0) { - completablefuture = this.b.a(); - this.d = 1000; - } - - return completablefuture; - } - } - - public CompletableFuture executeBatch() { return c(); } // Paper - OBFHELPER - public CompletableFuture c() { - // Paper start - if (!lock.isHeldByCurrentThread()) { - throw new IllegalStateException("Current thread does not hold the write lock"); - } - try {// Paper end - if (false && !this.c) { // Paper - throw new RuntimeException("Batch not properly started. Please use startBatch to create a new batch."); - } else { - if (this.d != 1000) { - this.b.a(); - } - - this.c = false; - return this.b.c(); - } - } finally { lock.unlock(); } // Paper - } -} diff --git a/src/main/java/net/minecraft/server/Scoreboard.java b/src/main/java/net/minecraft/server/Scoreboard.java deleted file mode 100644 index e1ee14bea..000000000 --- a/src/main/java/net/minecraft/server/Scoreboard.java +++ /dev/null @@ -1,391 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -import javax.annotation.Nullable; - -public class Scoreboard { - - private final Map objectivesByName = Maps.newHashMap(); - private final Map> objectivesByCriteria = Maps.newHashMap(); - private final Map> playerScores = Maps.newHashMap(); - private final ScoreboardObjective[] displaySlots = new ScoreboardObjective[19]; - private final Map teamsByName = Maps.newHashMap(); - private final Map teamsByPlayer = Maps.newHashMap(); - private static String[] g; - - public Scoreboard() {} - - public ScoreboardObjective c(String s) { - return (ScoreboardObjective) this.objectivesByName.get(s); - } - - @Nullable - public ScoreboardObjective getObjective(@Nullable String s) { - return (ScoreboardObjective) this.objectivesByName.get(s); - } - - public ScoreboardObjective registerObjective(String s, IScoreboardCriteria iscoreboardcriteria, IChatBaseComponent ichatbasecomponent, IScoreboardCriteria.EnumScoreboardHealthDisplay iscoreboardcriteria_enumscoreboardhealthdisplay) { - if (s.length() > 16) { - throw new IllegalArgumentException("The objective name '" + s + "' is too long!"); - } else if (this.objectivesByName.containsKey(s)) { - throw new IllegalArgumentException("An objective with the name '" + s + "' already exists!"); - } else { - ScoreboardObjective scoreboardobjective = new ScoreboardObjective(this, s, iscoreboardcriteria, ichatbasecomponent, iscoreboardcriteria_enumscoreboardhealthdisplay); - - ((List) this.objectivesByCriteria.computeIfAbsent(iscoreboardcriteria, (iscoreboardcriteria1) -> { - return Lists.newArrayList(); - })).add(scoreboardobjective); - this.objectivesByName.put(s, scoreboardobjective); - this.handleObjectiveAdded(scoreboardobjective); - return scoreboardobjective; - } - } - - public final void getObjectivesForCriteria(IScoreboardCriteria iscoreboardcriteria, String s, Consumer consumer) { - ((List) this.objectivesByCriteria.getOrDefault(iscoreboardcriteria, Collections.emptyList())).forEach((scoreboardobjective) -> { - consumer.accept(this.getPlayerScoreForObjective(s, (ScoreboardObjective) scoreboardobjective)); // Akarin - fixes decompile error - }); - } - - public boolean b(String s, ScoreboardObjective scoreboardobjective) { - Map map = (Map) this.playerScores.get(s); - - if (map == null) { - return false; - } else { - ScoreboardScore scoreboardscore = (ScoreboardScore) map.get(scoreboardobjective); - - return scoreboardscore != null; - } - } - - public ScoreboardScore getPlayerScoreForObjective(String s, ScoreboardObjective scoreboardobjective) { - if (s.length() > 40) { - throw new IllegalArgumentException("The player name '" + s + "' is too long!"); - } else { - Map map = (Map) this.playerScores.computeIfAbsent(s, (s1) -> { - return Maps.newHashMap(); - }); - - return (ScoreboardScore) map.computeIfAbsent(scoreboardobjective, (scoreboardobjective1) -> { - ScoreboardScore scoreboardscore = new ScoreboardScore(this, scoreboardobjective1, s); - - scoreboardscore.setScore(0); - return scoreboardscore; - }); - } - } - - public Collection getScoresForObjective(ScoreboardObjective scoreboardobjective) { - List list = Lists.newArrayList(); - Iterator iterator = this.playerScores.values().iterator(); - - while (iterator.hasNext()) { - Map map = (Map) iterator.next(); - ScoreboardScore scoreboardscore = (ScoreboardScore) map.get(scoreboardobjective); - - if (scoreboardscore != null) { - list.add(scoreboardscore); - } - } - - Collections.sort(list, ScoreboardScore.a); - return list; - } - - public Collection getObjectives() { - return this.objectivesByName.values(); - } - - public Collection d() { - return this.objectivesByName.keySet(); - } - - public Collection getPlayers() { - return Lists.newArrayList(this.playerScores.keySet()); - } - // Akarin start - public boolean containsPlayer(String playerName) { - return this.playerScores.containsKey(playerName); - } - // Akarin end - - public void resetPlayerScores(String s, @Nullable ScoreboardObjective scoreboardobjective) { - Map map; - - if (scoreboardobjective == null) { - map = (Map) this.playerScores.remove(s); - if (map != null) { - this.handlePlayerRemoved(s); - } - } else { - map = (Map) this.playerScores.get(s); - if (map != null) { - ScoreboardScore scoreboardscore = (ScoreboardScore) map.remove(scoreboardobjective); - - if (map.size() < 1) { - Map map1 = (Map) this.playerScores.remove(s); - - if (map1 != null) { - this.handlePlayerRemoved(s); - } - } else if (scoreboardscore != null) { - this.a(s, scoreboardobjective); - } - } - } - - } - - public Map getPlayerObjectives(String s) { - Map map = (Map) this.playerScores.get(s); - - if (map == null) { - map = Maps.newHashMap(); - } - - return (Map) map; - } - - public void unregisterObjective(ScoreboardObjective scoreboardobjective) { - this.objectivesByName.remove(scoreboardobjective.getName()); - - for (int i = 0; i < 19; ++i) { - if (this.getObjectiveForSlot(i) == scoreboardobjective) { - this.setDisplaySlot(i, (ScoreboardObjective) null); - } - } - - List list = (List) this.objectivesByCriteria.get(scoreboardobjective.getCriteria()); - - if (list != null) { - list.remove(scoreboardobjective); - } - - Iterator iterator = this.playerScores.values().iterator(); - - while (iterator.hasNext()) { - Map map = (Map) iterator.next(); - - map.remove(scoreboardobjective); - } - - this.handleObjectiveRemoved(scoreboardobjective); - } - - public void setDisplaySlot(int i, @Nullable ScoreboardObjective scoreboardobjective) { - this.displaySlots[i] = scoreboardobjective; - } - - @Nullable - public ScoreboardObjective getObjectiveForSlot(int i) { - return this.displaySlots[i]; - } - - public ScoreboardTeam getTeam(String s) { - return (ScoreboardTeam) this.teamsByName.get(s); - } - - public ScoreboardTeam createTeam(String s) { - if (s.length() > 16) { - throw new IllegalArgumentException("The team name '" + s + "' is too long!"); - } else { - ScoreboardTeam scoreboardteam = this.getTeam(s); - - if (scoreboardteam != null) { - throw new IllegalArgumentException("A team with the name '" + s + "' already exists!"); - } else { - scoreboardteam = new ScoreboardTeam(this, s); - this.teamsByName.put(s, scoreboardteam); - this.handleTeamAdded(scoreboardteam); - return scoreboardteam; - } - } - } - - public void removeTeam(ScoreboardTeam scoreboardteam) { - this.teamsByName.remove(scoreboardteam.getName()); - Iterator iterator = scoreboardteam.getPlayerNameSet().iterator(); - - while (iterator.hasNext()) { - String s = (String) iterator.next(); - - this.teamsByPlayer.remove(s); - } - - this.handleTeamRemoved(scoreboardteam); - } - - public boolean addPlayerToTeam(String s, ScoreboardTeam scoreboardteam) { - if (s.length() > 40) { - throw new IllegalArgumentException("The player name '" + s + "' is too long!"); - } else { - if (this.getPlayerTeam(s) != null) { - this.removePlayerFromTeam(s); - } - - this.teamsByPlayer.put(s, scoreboardteam); - return scoreboardteam.getPlayerNameSet().add(s); - } - } - - public boolean removePlayerFromTeam(String s) { - ScoreboardTeam scoreboardteam = this.getPlayerTeam(s); - - if (scoreboardteam != null) { - this.removePlayerFromTeam(s, scoreboardteam); - return true; - } else { - return false; - } - } - - public void removePlayerFromTeam(String s, ScoreboardTeam scoreboardteam) { - if (this.getPlayerTeam(s) != scoreboardteam) { - throw new IllegalStateException("Player is either on another team or not on any team. Cannot remove from team '" + scoreboardteam.getName() + "'."); - } else { - this.teamsByPlayer.remove(s); - scoreboardteam.getPlayerNameSet().remove(s); - } - } - - public Collection f() { - return this.teamsByName.keySet(); - } - - public Collection getTeams() { - return this.teamsByName.values(); - } - - @Nullable - public ScoreboardTeam getPlayerTeam(String s) { - return (ScoreboardTeam) this.teamsByPlayer.get(s); - } - - public void handleObjectiveAdded(ScoreboardObjective scoreboardobjective) {} - - public void handleObjectiveChanged(ScoreboardObjective scoreboardobjective) {} - - public void handleObjectiveRemoved(ScoreboardObjective scoreboardobjective) {} - - public void handleScoreChanged(ScoreboardScore scoreboardscore) {} - - public void handlePlayerRemoved(String s) {} - - public void a(String s, ScoreboardObjective scoreboardobjective) {} - - public void handleTeamAdded(ScoreboardTeam scoreboardteam) {} - - public void handleTeamChanged(ScoreboardTeam scoreboardteam) {} - - public void handleTeamRemoved(ScoreboardTeam scoreboardteam) {} - - public static String getSlotName(int i) { - switch (i) { - case 0: - return "list"; - case 1: - return "sidebar"; - case 2: - return "belowName"; - default: - if (i >= 3 && i <= 18) { - EnumChatFormat enumchatformat = EnumChatFormat.a(i - 3); - - if (enumchatformat != null && enumchatformat != EnumChatFormat.RESET) { - return "sidebar.team." + enumchatformat.g(); - } - } - - return null; - } - } - - public static int getSlotForName(String s) { - if ("list".equalsIgnoreCase(s)) { - return 0; - } else if ("sidebar".equalsIgnoreCase(s)) { - return 1; - } else if ("belowName".equalsIgnoreCase(s)) { - return 2; - } else { - if (s.startsWith("sidebar.team.")) { - String s1 = s.substring("sidebar.team.".length()); - EnumChatFormat enumchatformat = EnumChatFormat.c(s1); - - if (enumchatformat != null && enumchatformat.b() >= 0) { - return enumchatformat.b() + 3; - } - } - - return -1; - } - } - - public static String[] h() { - if (Scoreboard.g == null) { - Scoreboard.g = new String[19]; - - for (int i = 0; i < 19; ++i) { - Scoreboard.g[i] = getSlotName(i); - } - } - - return Scoreboard.g; - } - - public void a(Entity entity) { - if (entity != null && !(entity instanceof EntityHuman) && !entity.isAlive()) { - String s = entity.bu(); - - this.resetPlayerScores(s, (ScoreboardObjective) null); - this.removePlayerFromTeam(s); - } - } - - protected NBTTagList i() { - NBTTagList nbttaglist = new NBTTagList(); - - this.playerScores.values().stream().map(Map::values).forEach((collection) -> { - collection.stream().filter((scoreboardscore) -> { - return scoreboardscore.getObjective() != null; - }).forEach((scoreboardscore) -> { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - - nbttagcompound.setString("Name", scoreboardscore.getPlayerName()); - nbttagcompound.setString("Objective", scoreboardscore.getObjective().getName()); - nbttagcompound.setInt("Score", scoreboardscore.getScore()); - nbttagcompound.setBoolean("Locked", scoreboardscore.g()); - nbttaglist.add((NBTBase) nbttagcompound); - }); - }); - return nbttaglist; - } - - protected void a(NBTTagList nbttaglist) { - for (int i = 0; i < nbttaglist.size(); ++i) { - NBTTagCompound nbttagcompound = nbttaglist.getCompound(i); - ScoreboardObjective scoreboardobjective = this.c(nbttagcompound.getString("Objective")); - String s = nbttagcompound.getString("Name"); - - if (s.length() > 40) { - s = s.substring(0, 40); - } - - ScoreboardScore scoreboardscore = this.getPlayerScoreForObjective(s, scoreboardobjective); - - scoreboardscore.setScore(nbttagcompound.getInt("Score")); - if (nbttagcompound.hasKey("Locked")) { - scoreboardscore.a(nbttagcompound.getBoolean("Locked")); - } - } - - } -} diff --git a/src/main/java/net/minecraft/server/ScoreboardServer.java b/src/main/java/net/minecraft/server/ScoreboardServer.java index cf89c3287..929397a4c 100644 --- a/src/main/java/net/minecraft/server/ScoreboardServer.java +++ b/src/main/java/net/minecraft/server/ScoreboardServer.java @@ -18,6 +18,7 @@ public class ScoreboardServer extends Scoreboard { this.a = minecraftserver; } + @Override public void handleScoreChanged(ScoreboardScore scoreboardscore) { super.handleScoreChanged(scoreboardscore); if (this.b.contains(scoreboardscore.getObjective())) { @@ -27,12 +28,14 @@ public class ScoreboardServer extends Scoreboard { this.b(); } + @Override public void handlePlayerRemoved(String s) { super.handlePlayerRemoved(s); this.sendAll(new PacketPlayOutScoreboardScore(ScoreboardServer.Action.REMOVE, (String) null, s, 0)); this.b(); } + @Override public void a(String s, ScoreboardObjective scoreboardobjective) { super.a(s, scoreboardobjective); if (this.b.contains(scoreboardobjective)) { @@ -42,6 +45,7 @@ public class ScoreboardServer extends Scoreboard { this.b(); } + @Override public void setDisplaySlot(int i, @Nullable ScoreboardObjective scoreboardobjective) { ScoreboardObjective scoreboardobjective1 = this.getObjectiveForSlot(i); @@ -65,6 +69,7 @@ public class ScoreboardServer extends Scoreboard { this.b(); } + @Override public boolean addPlayerToTeam(String s, ScoreboardTeam scoreboardteam) { if (super.addPlayerToTeam(s, scoreboardteam)) { this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, Arrays.asList(s), 3)); @@ -75,17 +80,20 @@ public class ScoreboardServer extends Scoreboard { } } + @Override public void removePlayerFromTeam(String s, ScoreboardTeam scoreboardteam) { super.removePlayerFromTeam(s, scoreboardteam); this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, Arrays.asList(s), 4)); this.b(); } + @Override public void handleObjectiveAdded(ScoreboardObjective scoreboardobjective) { super.handleObjectiveAdded(scoreboardobjective); this.b(); } + @Override public void handleObjectiveChanged(ScoreboardObjective scoreboardobjective) { super.handleObjectiveChanged(scoreboardobjective); if (this.b.contains(scoreboardobjective)) { @@ -95,6 +103,7 @@ public class ScoreboardServer extends Scoreboard { this.b(); } + @Override public void handleObjectiveRemoved(ScoreboardObjective scoreboardobjective) { super.handleObjectiveRemoved(scoreboardobjective); if (this.b.contains(scoreboardobjective)) { @@ -104,18 +113,21 @@ public class ScoreboardServer extends Scoreboard { this.b(); } + @Override public void handleTeamAdded(ScoreboardTeam scoreboardteam) { super.handleTeamAdded(scoreboardteam); this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 0)); this.b(); } + @Override public void handleTeamChanged(ScoreboardTeam scoreboardteam) { super.handleTeamChanged(scoreboardteam); this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 2)); this.b(); } + @Override public void handleTeamRemoved(ScoreboardTeam scoreboardteam) { super.handleTeamRemoved(scoreboardteam); this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 1)); @@ -163,7 +175,7 @@ public class ScoreboardServer extends Scoreboard { public void e(ScoreboardObjective scoreboardobjective) { List> list = this.getScoreboardScorePacketsForObjective(scoreboardobjective); - Iterator iterator = this.a.getPlayerList().v().iterator(); + Iterator iterator = this.a.getPlayerList().getPlayers().iterator(); while (iterator.hasNext()) { EntityPlayer entityplayer = (EntityPlayer) iterator.next(); @@ -196,7 +208,7 @@ public class ScoreboardServer extends Scoreboard { public void g(ScoreboardObjective scoreboardobjective) { List> list = this.f(scoreboardobjective); - Iterator iterator = this.a.getPlayerList().v().iterator(); + Iterator iterator = this.a.getPlayerList().getPlayers().iterator(); while (iterator.hasNext()) { EntityPlayer entityplayer = (EntityPlayer) iterator.next(); diff --git a/src/main/java/net/minecraft/server/SecondaryWorldServer.java b/src/main/java/net/minecraft/server/SecondaryWorldServer.java index cca30db6d..e167b588e 100644 --- a/src/main/java/net/minecraft/server/SecondaryWorldServer.java +++ b/src/main/java/net/minecraft/server/SecondaryWorldServer.java @@ -1,62 +1,16 @@ package net.minecraft.server; +import java.util.concurrent.Executor; + public class SecondaryWorldServer extends WorldServer { // CraftBukkit start - Add WorldData, Environment and ChunkGenerator arguments - public SecondaryWorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, DimensionManager dimensionmanager, WorldServer worldserver, MethodProfiler methodprofiler, WorldData worldData, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { - super(minecraftserver, idatamanager, worldserver.h(), worldData, dimensionmanager, methodprofiler, env, gen); + public SecondaryWorldServer(WorldServer worldserver, MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, WorldData worldData, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + super(minecraftserver, executor, worldnbtstorage, worldData, dimensionmanager, gameprofilerfiller, worldloadlistener, env, gen); + // worldserver.getWorldBorder().a((IWorldBorderListener) (new IWorldBorderListener.a(this.getWorldBorder()))); // CraftBukkit end - /* CraftBukkit start - worldserver.getWorldBorder().a(new IWorldBorderListener() { - public void a(WorldBorder worldborder, double d0) { - SecondaryWorldServer.this.getWorldBorder().setSize(d0); - } - - public void a(WorldBorder worldborder, double d0, double d1, long i) { - SecondaryWorldServer.this.getWorldBorder().transitionSizeBetween(d0, d1, i); - } - - public void a(WorldBorder worldborder, double d0, double d1) { - SecondaryWorldServer.this.getWorldBorder().setCenter(d0, d1); - } - - public void a(WorldBorder worldborder, int i) { - SecondaryWorldServer.this.getWorldBorder().setWarningTime(i); - } - - public void b(WorldBorder worldborder, int i) { - SecondaryWorldServer.this.getWorldBorder().setWarningDistance(i); - } - - public void b(WorldBorder worldborder, double d0) { - SecondaryWorldServer.this.getWorldBorder().setDamageAmount(d0); - } - - public void c(WorldBorder worldborder, double d0) { - SecondaryWorldServer.this.getWorldBorder().setDamageBuffer(d0); - } - }); - // CraftBukkit end */ } + // @Override // CraftBukkit // protected void a() {} // CraftBukkit - - public SecondaryWorldServer i_() { - String s = PersistentVillage.a(this.worldProvider); - PersistentVillage persistentvillage = (PersistentVillage) this.a(DimensionManager.OVERWORLD, PersistentVillage::new, s); - - if (persistentvillage == null) { - this.villages = new PersistentVillage(this); - this.a(DimensionManager.OVERWORLD, s, (PersistentBase) this.villages); - } else { - this.villages = persistentvillage; - this.villages.a((World) this); - } - - return (SecondaryWorldServer) super.i_(); // CraftBukkit - } - - public void t_() { - this.worldProvider.k(); - } } diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java index 81b8aea2b..379c79272 100644 --- a/src/main/java/net/minecraft/server/ServerConnection.java +++ b/src/main/java/net/minecraft/server/ServerConnection.java @@ -1,7 +1,6 @@ package net.minecraft.server; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; @@ -13,9 +12,6 @@ import io.netty.channel.EventLoopGroup; import io.netty.channel.epoll.Epoll; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollServerSocketChannel; -import io.netty.channel.kqueue.KQueue; -import io.netty.channel.kqueue.KQueueEventLoopGroup; -import io.netty.channel.kqueue.KQueueServerSocketChannel; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.ServerSocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; @@ -23,46 +19,33 @@ import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.util.concurrent.Future; import java.io.IOException; import java.net.InetAddress; -import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; - import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class ServerConnection { - private static final Logger d = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public static final LazyInitVar a = new LazyInitVar<>(() -> { return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).build()); }); public static final LazyInitVar b = new LazyInitVar<>(() -> { return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Server IO #%d").setDaemon(true).build()); }); - // Akarin start - public static final LazyInitVar kQueue = new LazyInitVar<>(() -> { - return new KQueueEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty KQueue Server IO #%d").setDaemon(true).build()); - }); - // Akarin end private final MinecraftServer e; public volatile boolean c; private final List f = Collections.synchronizedList(Lists.newArrayList()); - private final List g = Collections.synchronizedList(Lists.newArrayList()); public final List getNetworkManagers() { return this.g; } // Akarin + private final List g = Collections.synchronizedList(Lists.newArrayList()); // Paper start - prevent blocking on adding a new network manager while the server is ticking - private final List pending = Collections.synchronizedList(Lists.newArrayList()); - // Akarin start - public final List pendingRemoval = Lists.newArrayList(); // Akarin - avoid same signature + private final List pending = Collections.synchronizedList(Lists.newArrayList()); private void addPending() { - /*synchronized (this.g)*/ { // Akarin + synchronized (pending) { this.g.addAll(pending); // Paper - OBFHELPER - List of network managers - //pending.clear(); // Akarin - move down + pending.clear(); } - pending.clear(); // Akarin - move from above - // Akarin end } // Paper end @@ -78,20 +61,14 @@ public class ServerConnection { Class oclass; LazyInitVar lazyinitvar; - if (Epoll.isAvailable() && this.e.V()) { + if (Epoll.isAvailable() && this.e.X()) { oclass = EpollServerSocketChannel.class; lazyinitvar = ServerConnection.b; - ServerConnection.d.info("Using epoll channel type"); - // Akarin start - } else if (KQueue.isAvailable()) { - oclass = KQueueServerSocketChannel.class; - lazyinitvar = ServerConnection.kQueue; - ServerConnection.d.info("Using kqueue channel type"); - // Akarin end + ServerConnection.LOGGER.info("Using epoll channel type"); } else { oclass = NioServerSocketChannel.class; lazyinitvar = ServerConnection.a; - ServerConnection.d.info("Using default channel type"); + ServerConnection.LOGGER.info("Using default channel type"); } this.f.add(((ServerBootstrap) ((ServerBootstrap) (new ServerBootstrap()).channel(oclass)).childHandler(new ChannelInitializer() { @@ -109,10 +86,20 @@ public class ServerConnection { channel.pipeline().addLast("packet_handler", networkmanager); networkmanager.setPacketListener(new HandshakeListener(ServerConnection.this.e, networkmanager)); } - }).group((EventLoopGroup) lazyinitvar.a()).localAddress(inetaddress, i)).bind().syncUninterruptibly()); + }).group((EventLoopGroup) lazyinitvar.a()).localAddress(inetaddress, i)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit } } + // CraftBukkit start + public void acceptConnections() { + synchronized (this.f) { // PAIL: listeningChannels + for (ChannelFuture f : this.f) { + f.channel().config().setAutoRead(true); + } + } + } + // CraftBukkit end + public void b() { this.c = false; Iterator iterator = this.f.iterator(); @@ -123,7 +110,7 @@ public class ServerConnection { try { channelfuture.channel().close().sync(); } catch (InterruptedException interruptedexception) { - ServerConnection.d.error("Interrupted whilst closing channel"); + ServerConnection.LOGGER.error("Interrupted whilst closing channel"); } } @@ -133,14 +120,8 @@ public class ServerConnection { List list = this.g; synchronized (this.g) { - // Akarin start - this.g.removeAll(pendingRemoval); - pendingRemoval.clear(); - addPending(); - } { - // Akarin end // Spigot Start - //addPending(); // Paper // Akarin - move above + addPending(); // Paper // This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % org.spigotmc.SpigotConfig.playerShuffle == 0 ) { @@ -165,7 +146,7 @@ public class ServerConnection { throw new ReportedException(crashreport); } - ServerConnection.d.warn("Failed to handle packet for {}", networkmanager.getSocketAddress(), exception); + ServerConnection.LOGGER.warn("Failed to handle packet for {}", networkmanager.getSocketAddress(), exception); ChatComponentText chatcomponenttext = new ChatComponentText("Internal server error"); networkmanager.sendPacket(new PacketPlayOutKickDisconnect(chatcomponenttext), (future) -> { @@ -178,7 +159,7 @@ public class ServerConnection { // Fix a race condition where a NetworkManager could be unregistered just before connection. if (networkmanager.preparing) continue; // Spigot End - pendingRemoval.add(networkmanager); // Akarin + iterator.remove(); networkmanager.handleDisconnection(); } } diff --git a/src/main/java/net/minecraft/server/ServerStatisticManager.java b/src/main/java/net/minecraft/server/ServerStatisticManager.java index d622983b2..1e911a889 100644 --- a/src/main/java/net/minecraft/server/ServerStatisticManager.java +++ b/src/main/java/net/minecraft/server/ServerStatisticManager.java @@ -8,7 +8,6 @@ import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.internal.Streams; import com.google.gson.stream.JsonReader; -import com.mojang.datafixers.DataFixTypes; import com.mojang.datafixers.DataFixer; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -18,16 +17,15 @@ import java.io.IOException; import java.io.StringReader; import java.util.Iterator; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.Map.Entry; -import javax.annotation.Nullable; -import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class ServerStatisticManager extends StatisticManager { - private static final Logger b = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private final MinecraftServer c; private final File d; private final Set> e = Sets.newHashSet(); @@ -45,11 +43,11 @@ public class ServerStatisticManager extends StatisticManager { // Spigot end if (file.isFile()) { try { - this.a(minecraftserver.az(), FileUtils.readFileToString(file)); + this.a(minecraftserver.aB(), org.apache.commons.io.FileUtils.readFileToString(file)); } catch (IOException ioexception) { - ServerStatisticManager.b.error("Couldn't read statistics file {}", file, ioexception); + ServerStatisticManager.LOGGER.error("Couldn't read statistics file {}", file, ioexception); } catch (JsonParseException jsonparseexception) { - ServerStatisticManager.b.error("Couldn't parse statistics file {}", file, jsonparseexception); + ServerStatisticManager.LOGGER.error("Couldn't parse statistics file {}", file, jsonparseexception); } } @@ -58,13 +56,14 @@ public class ServerStatisticManager extends StatisticManager { public void a() { if ( org.spigotmc.SpigotConfig.disableStatSaving ) return; // Spigot try { - FileUtils.writeStringToFile(this.d, this.b()); + org.apache.commons.io.FileUtils.writeStringToFile(this.d, this.b()); } catch (IOException ioexception) { - ServerStatisticManager.b.error("Couldn't save stats", ioexception); + ServerStatisticManager.LOGGER.error("Couldn't save stats", ioexception); } } + @Override public void setStatistic(EntityHuman entityhuman, Statistic statistic, int i) { if ( org.spigotmc.SpigotConfig.disableStatSaving ) return; // Spigot super.setStatistic(entityhuman, statistic, i); @@ -103,11 +102,7 @@ public class ServerStatisticManager extends StatisticManager { String s1 = (String) iterator.next(); if (nbttagcompound1.hasKeyOfType(s1, 10)) { - StatisticWrapper statisticwrapper = (StatisticWrapper) IRegistry.STATS.get(new MinecraftKey(s1)); - - if (statisticwrapper == null) { - ServerStatisticManager.b.warn("Invalid statistic type in {}: Don't know what {} is", this.d, s1); - } else { + SystemUtils.a(IRegistry.STATS.getOptional(new MinecraftKey(s1)), (statisticwrapper) -> { NBTTagCompound nbttagcompound2 = nbttagcompound1.getCompound(s1); Iterator iterator1 = nbttagcompound2.getKeys().iterator(); @@ -115,24 +110,27 @@ public class ServerStatisticManager extends StatisticManager { String s2 = (String) iterator1.next(); if (nbttagcompound2.hasKeyOfType(s2, 99)) { - Statistic statistic = this.a(statisticwrapper, s2); - - if (statistic == null) { - ServerStatisticManager.b.warn("Invalid statistic in {}: Don't know what {} is", this.d, s2); - } else { + SystemUtils.a(this.a(statisticwrapper, s2), (statistic) -> { this.a.put(statistic, nbttagcompound2.getInt(s2)); - } + }, () -> { + ServerStatisticManager.LOGGER.warn("Invalid statistic in {}: Don't know what {} is", this.d, s2); + }); } else { - ServerStatisticManager.b.warn("Invalid statistic value in {}: Don't know what {} is for key {}", this.d, nbttagcompound2.get(s2), s2); + ServerStatisticManager.LOGGER.warn("Invalid statistic value in {}: Don't know what {} is for key {}", this.d, nbttagcompound2.get(s2), s2); } } - } + + }, () -> { + ServerStatisticManager.LOGGER.warn("Invalid statistic type in {}: Don't know what {} is", this.d, s1); + }); } } } - } else { - ServerStatisticManager.b.error("Unable to parse Stat data from {}", this.d); + + return; } + + ServerStatisticManager.LOGGER.error("Unable to parse Stat data from {}", this.d); } catch (Throwable throwable1) { throwable = throwable1; throw throwable1; @@ -150,23 +148,20 @@ public class ServerStatisticManager extends StatisticManager { } } - } catch (IOException | JsonParseException jsonparseexception) { - ServerStatisticManager.b.error("Unable to parse Stat data from {}", this.d, jsonparseexception); - } + } catch (IOException | JsonParseException jsonparseexception) { + ServerStatisticManager.LOGGER.error("Unable to parse Stat data from {}", this.d, jsonparseexception); + } } - @Nullable - private Statistic a(StatisticWrapper statisticwrapper, String s) { - MinecraftKey minecraftkey = MinecraftKey.a(s); + private Optional> a(StatisticWrapper statisticwrapper, String s) { + Optional optional = Optional.ofNullable(MinecraftKey.a(s)); + IRegistry iregistry = statisticwrapper.getRegistry(); - if (minecraftkey == null) { - return null; - } else { - T t0 = statisticwrapper.a().get(minecraftkey); - - return t0 == null ? null : statisticwrapper.b(t0); - } + iregistry.getClass(); + Optional optional2 = optional.flatMap(iregistry::getOptional); + statisticwrapper.getClass(); + return optional2.map(statisticwrapper::b); } private static NBTTagCompound a(JsonObject jsonobject) { @@ -199,7 +194,7 @@ public class ServerStatisticManager extends StatisticManager { it.unimi.dsi.fastutil.objects.Object2IntMap.Entry> it_unimi_dsi_fastutil_objects_object2intmap_entry = (it.unimi.dsi.fastutil.objects.Object2IntMap.Entry) objectiterator.next(); Statistic statistic = (Statistic) it_unimi_dsi_fastutil_objects_object2intmap_entry.getKey(); - ((JsonObject) map.computeIfAbsent(statistic.a(), (statisticwrapper) -> { + ((JsonObject) map.computeIfAbsent(statistic.getWrapper(), (statisticwrapper) -> { return new JsonObject(); })).addProperty(b(statistic).toString(), it_unimi_dsi_fastutil_objects_object2intmap_entry.getIntValue()); } @@ -216,12 +211,12 @@ public class ServerStatisticManager extends StatisticManager { JsonObject jsonobject1 = new JsonObject(); jsonobject1.add("stats", jsonobject); - jsonobject1.addProperty("DataVersion", 1631); + jsonobject1.addProperty("DataVersion", SharedConstants.a().getWorldVersion()); return jsonobject1.toString(); } private static MinecraftKey b(Statistic statistic) { - return statistic.a().a().getKey(statistic.b()); + return statistic.getWrapper().getRegistry().getKey(statistic.b()); } public void c() { @@ -229,7 +224,7 @@ public class ServerStatisticManager extends StatisticManager { } public void a(EntityPlayer entityplayer) { - int i = this.c.ah(); + int i = this.c.aj(); Object2IntMap> object2intmap = new Object2IntOpenHashMap(); if (i - this.f > 300) { diff --git a/src/main/java/net/minecraft/server/ShapeDetector.java b/src/main/java/net/minecraft/server/ShapeDetector.java deleted file mode 100644 index 65d8f3624..000000000 --- a/src/main/java/net/minecraft/server/ShapeDetector.java +++ /dev/null @@ -1,175 +0,0 @@ -package net.minecraft.server; - -import com.google.common.base.MoreObjects; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import java.util.Iterator; -import java.util.function.Predicate; -import javax.annotation.Nullable; - -public class ShapeDetector { - - private final Predicate[][][] a; - private final int b; - private final int c; - private final int d; - - public ShapeDetector(Predicate[][][] apredicate) { - this.a = apredicate; - this.b = apredicate.length; - if (this.b > 0) { - this.c = apredicate[0].length; - if (this.c > 0) { - this.d = apredicate[0][0].length; - } else { - this.d = 0; - } - } else { - this.c = 0; - this.d = 0; - } - - } - - public int a() { - return this.b; - } - - public int b() { - return this.c; - } - - public int c() { - return this.d; - } - - @Nullable - private ShapeDetector.ShapeDetectorCollection a(BlockPosition blockposition, EnumDirection enumdirection, EnumDirection enumdirection1, com.github.benmanes.caffeine.cache.LoadingCache loadingcache) { // Akarin - caffeine - for (int i = 0; i < this.d; ++i) { - for (int j = 0; j < this.c; ++j) { - for (int k = 0; k < this.b; ++k) { - if (!this.a[k][j][i].test(loadingcache.get(a(blockposition, enumdirection, enumdirection1, i, j, k)))) { // Akarin - caffeine - return null; - } - } - } - } - - return new ShapeDetector.ShapeDetectorCollection(blockposition, enumdirection, enumdirection1, loadingcache, this.d, this.c, this.b); // Akarin - caffeine - } - - @Nullable - public ShapeDetector.ShapeDetectorCollection a(IWorldReader iworldreader, BlockPosition blockposition) { - com.github.benmanes.caffeine.cache.LoadingCache loadingcache = a(iworldreader, false); // Akarin - caffeine - int i = Math.max(Math.max(this.d, this.c), this.b); - Iterator iterator = BlockPosition.a(blockposition, blockposition.a(i - 1, i - 1, i - 1)).iterator(); - - while (iterator.hasNext()) { - BlockPosition blockposition1 = (BlockPosition) iterator.next(); - EnumDirection[] aenumdirection = EnumDirection.values(); - int j = aenumdirection.length; - - for (int k = 0; k < j; ++k) { - EnumDirection enumdirection = aenumdirection[k]; - EnumDirection[] aenumdirection1 = EnumDirection.values(); - int l = aenumdirection1.length; - - for (int i1 = 0; i1 < l; ++i1) { - EnumDirection enumdirection1 = aenumdirection1[i1]; - - if (enumdirection1 != enumdirection && enumdirection1 != enumdirection.opposite()) { - ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = this.a(blockposition1, enumdirection, enumdirection1, loadingcache); - - if (shapedetector_shapedetectorcollection != null) { - return shapedetector_shapedetectorcollection; - } - } - } - } - } - - return null; - } - - public static com.github.benmanes.caffeine.cache.LoadingCache a(IWorldReader iworldreader, boolean flag) { // Akarin - caffeine - return com.github.benmanes.caffeine.cache.Caffeine.newBuilder().build(new ShapeDetector.BlockLoader(iworldreader, flag)); // Akarin - caffeine - } - - protected static BlockPosition a(BlockPosition blockposition, EnumDirection enumdirection, EnumDirection enumdirection1, int i, int j, int k) { - if (enumdirection != enumdirection1 && enumdirection != enumdirection1.opposite()) { - BaseBlockPosition baseblockposition = new BaseBlockPosition(enumdirection.getAdjacentX(), enumdirection.getAdjacentY(), enumdirection.getAdjacentZ()); - BaseBlockPosition baseblockposition1 = new BaseBlockPosition(enumdirection1.getAdjacentX(), enumdirection1.getAdjacentY(), enumdirection1.getAdjacentZ()); - BaseBlockPosition baseblockposition2 = baseblockposition.d(baseblockposition1); - - return blockposition.a(baseblockposition1.getX() * -j + baseblockposition2.getX() * i + baseblockposition.getX() * k, baseblockposition1.getY() * -j + baseblockposition2.getY() * i + baseblockposition.getY() * k, baseblockposition1.getZ() * -j + baseblockposition2.getZ() * i + baseblockposition.getZ() * k); - } else { - throw new IllegalArgumentException("Invalid forwards & up combination"); - } - } - - public static class ShapeDetectorCollection { - - private final BlockPosition a; - private final EnumDirection b; - private final EnumDirection c; - private final com.github.benmanes.caffeine.cache.LoadingCache d; // Akarin - caffeine - private final int e; - private final int f; - private final int g; - - public ShapeDetectorCollection(BlockPosition blockposition, EnumDirection enumdirection, EnumDirection enumdirection1, com.github.benmanes.caffeine.cache.LoadingCache loadingcache, int i, int j, int k) { // Akarin - caffeine - this.a = blockposition; - this.b = enumdirection; - this.c = enumdirection1; - this.d = loadingcache; - this.e = i; - this.f = j; - this.g = k; - } - - public BlockPosition a() { - return this.a; - } - - public EnumDirection getFacing() { - return this.b; - } - - public EnumDirection c() { - return this.c; - } - - public final int getWidth() { return this.d(); } // Paper - OBFHELPER - public int d() { - return this.e; - } - - public int e() { - return this.f; - } - - public ShapeDetectorBlock a(int i, int j, int k) { - return (ShapeDetectorBlock) this.d.get(ShapeDetector.a(this.a, this.getFacing(), this.c(), i, j, k)); // Akarin - caffeine - } - - public String toString() { - return MoreObjects.toStringHelper(this).add("up", this.c).add("forwards", this.b).add("frontTopLeft", this.a).toString(); - } - } - - static class BlockLoader implements com.github.benmanes.caffeine.cache.CacheLoader { // Akarin - caffeine - - private final IWorldReader a; - private final boolean b; - - public BlockLoader(IWorldReader iworldreader, boolean flag) { - this.a = iworldreader; - this.b = flag; - } - - public ShapeDetectorBlock load(BlockPosition blockposition) throws Exception { - return new ShapeDetectorBlock(this.a, blockposition, this.b); - } - } -} diff --git a/src/main/java/net/minecraft/server/ShapedRecipes.java b/src/main/java/net/minecraft/server/ShapedRecipes.java index b8f4ddeb9..5942e89f9 100644 --- a/src/main/java/net/minecraft/server/ShapedRecipes.java +++ b/src/main/java/net/minecraft/server/ShapedRecipes.java @@ -22,7 +22,7 @@ import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.RecipeChoice; // CraftBukkit end -public class ShapedRecipes implements IRecipe { +public class ShapedRecipes implements RecipeCrafting { private final int width; private final int height; @@ -100,45 +100,45 @@ public class ShapedRecipes implements IRecipe { } // CraftBukkit end + @Override public MinecraftKey getKey() { return this.key; } - public RecipeSerializer a() { - return RecipeSerializers.a; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.a; } - public ItemStack d() { + @Override + public ItemStack c() { return this.result; } - public NonNullList e() { + @Override + public NonNullList a() { return this.items; } - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - for (int i = 0; i <= iinventory.U_() - this.width; ++i) { - for (int j = 0; j <= iinventory.n() - this.height; ++j) { - if (this.a(iinventory, i, j, true)) { - return true; - } + public boolean a(InventoryCrafting inventorycrafting, World world) { + for (int i = 0; i <= inventorycrafting.g() - this.width; ++i) { + for (int j = 0; j <= inventorycrafting.f() - this.height; ++j) { + if (this.a(inventorycrafting, i, j, true)) { + return true; + } - if (this.a(iinventory, i, j, false)) { - return true; - } + if (this.a(inventorycrafting, i, j, false)) { + return true; } } - - return false; } + + return false; } - private boolean a(IInventory iinventory, int i, int j, boolean flag) { - for (int k = 0; k < iinventory.U_(); ++k) { - for (int l = 0; l < iinventory.n(); ++l) { + private boolean a(InventoryCrafting inventorycrafting, int i, int j, boolean flag) { + for (int k = 0; k < inventorycrafting.g(); ++k) { + for (int l = 0; l < inventorycrafting.f(); ++l) { int i1 = k - i; int j1 = l - j; RecipeItemStack recipeitemstack = RecipeItemStack.a; @@ -151,7 +151,7 @@ public class ShapedRecipes implements IRecipe { } } - if (!recipeitemstack.test(iinventory.getItem(k + l * iinventory.U_()))) { + if (!recipeitemstack.test(inventorycrafting.getItem(k + l * inventorycrafting.g()))) { return false; } } @@ -160,15 +160,15 @@ public class ShapedRecipes implements IRecipe { return true; } - public ItemStack craftItem(IInventory iinventory) { - return this.d().cloneItemStack(); + public ItemStack a(InventoryCrafting inventorycrafting) { + return this.c().cloneItemStack(); } - public int g() { + public int i() { return this.width; } - public int h() { + public int j() { return this.height; } @@ -307,14 +307,14 @@ public class ShapedRecipes implements IRecipe { public static ItemStack a(JsonObject jsonobject) { String s = ChatDeserializer.h(jsonobject, "item"); - Item item = (Item) IRegistry.ITEM.get(new MinecraftKey(s)); + Item item = (Item) IRegistry.ITEM.getOptional(new MinecraftKey(s)).orElseThrow(() -> { + return new JsonSyntaxException("Unknown item '" + s + "'"); + }); - if (item == null) { - throw new JsonSyntaxException("Unknown item '" + s + "'"); - } else if (jsonobject.has("data")) { + if (jsonobject.has("data")) { throw new JsonParseException("Disallowed data tag found"); } else { - int i = ChatDeserializer.a(jsonobject, "count", 1); + int i = ChatDeserializer.a(jsonobject, "count", (int) 1); return new ItemStack(item, i); } @@ -324,6 +324,7 @@ public class ShapedRecipes implements IRecipe { public a() {} + @Override public ShapedRecipes a(MinecraftKey minecraftkey, JsonObject jsonobject) { String s = ChatDeserializer.a(jsonobject, "group", ""); Map map = ShapedRecipes.c(ChatDeserializer.t(jsonobject, "key")); @@ -336,13 +337,10 @@ public class ShapedRecipes implements IRecipe { return new ShapedRecipes(minecraftkey, s, i, j, nonnulllist, itemstack); } - public String a() { - return "crafting_shaped"; - } - + @Override public ShapedRecipes a(MinecraftKey minecraftkey, PacketDataSerializer packetdataserializer) { - int i = packetdataserializer.g(); - int j = packetdataserializer.g(); + int i = packetdataserializer.i(); + int j = packetdataserializer.i(); String s = packetdataserializer.e(32767); NonNullList nonnulllist = NonNullList.a(i * j, RecipeItemStack.a); @@ -350,7 +348,7 @@ public class ShapedRecipes implements IRecipe { nonnulllist.set(k, RecipeItemStack.b(packetdataserializer)); } - ItemStack itemstack = packetdataserializer.k(); + ItemStack itemstack = packetdataserializer.m(); return new ShapedRecipes(minecraftkey, s, i, j, nonnulllist, itemstack); } diff --git a/src/main/java/net/minecraft/server/ShapelessRecipes.java b/src/main/java/net/minecraft/server/ShapelessRecipes.java index ea4083a45..691e697d6 100644 --- a/src/main/java/net/minecraft/server/ShapelessRecipes.java +++ b/src/main/java/net/minecraft/server/ShapelessRecipes.java @@ -11,7 +11,7 @@ import org.bukkit.craftbukkit.inventory.CraftRecipe; import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; // CraftBukkit end -public class ShapelessRecipes implements IRecipe { +public class ShapelessRecipes implements RecipeCrafting { private final MinecraftKey key; private final String group; @@ -39,74 +39,73 @@ public class ShapelessRecipes implements IRecipe { } // CraftBukkit end + @Override public MinecraftKey getKey() { return this.key; } - public RecipeSerializer a() { - return RecipeSerializers.b; + @Override + public RecipeSerializer getRecipeSerializer() { + return RecipeSerializer.b; } - public ItemStack d() { + @Override + public ItemStack c() { return this.result; } - public NonNullList e() { + @Override + public NonNullList a() { return this.ingredients; } - public boolean a(IInventory iinventory, World world) { - if (!(iinventory instanceof InventoryCrafting)) { - return false; - } else { - AutoRecipeStackManager autorecipestackmanager = new AutoRecipeStackManager(); - int i = 0; + public boolean a(InventoryCrafting inventorycrafting, World world) { + AutoRecipeStackManager autorecipestackmanager = new AutoRecipeStackManager(); + int i = 0; - // Paper start - java.util.List providedItems = new java.util.ArrayList<>(); - co.aikar.util.Counter matchedProvided = new co.aikar.util.Counter<>(); - co.aikar.util.Counter matchedIngredients = new co.aikar.util.Counter<>(); - // Paper end - for (int j = 0; j < iinventory.n(); ++j) { - for (int k = 0; k < iinventory.U_(); ++k) { - ItemStack itemstack = iinventory.getItem(k + j * iinventory.U_()); + // Paper start + java.util.List providedItems = new java.util.ArrayList<>(); + co.aikar.util.Counter matchedProvided = new co.aikar.util.Counter<>(); + co.aikar.util.Counter matchedIngredients = new co.aikar.util.Counter<>(); + // Paper end + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack = inventorycrafting.getItem(j); - if (!itemstack.isEmpty()) { - // Paper start - itemstack = itemstack.cloneItemStack(); - providedItems.add(itemstack); - for (RecipeItemStack ingredient : ingredients) { - if (ingredient.test(itemstack)) { - matchedProvided.increment(itemstack); - matchedIngredients.increment(ingredient); - } - } - // Paper end + if (!itemstack.isEmpty()) { + // Paper start + itemstack = itemstack.cloneItemStack(); + providedItems.add(itemstack); + for (RecipeItemStack ingredient : ingredients) { + if (ingredient.test(itemstack)) { + matchedProvided.increment(itemstack); + matchedIngredients.increment(ingredient); } } + // Paper end } - // Paper start - java.util.List ingredients = new java.util.ArrayList<>(this.ingredients); - providedItems.sort(java.util.Comparator.comparingInt((ItemStack c) -> (int) matchedProvided.getCount(c)).reversed()); - ingredients.sort(java.util.Comparator.comparingInt((RecipeItemStack c) -> (int) matchedIngredients.getCount(c))); - - PROVIDED: - for (ItemStack provided : providedItems) { - for (Iterator itIngredient = ingredients.iterator(); itIngredient.hasNext(); ) { - RecipeItemStack ingredient = itIngredient.next(); - if (ingredient.test(provided)) { - itIngredient.remove(); - continue PROVIDED; - } - } - return false; - } - return ingredients.isEmpty(); - // Paper end } + + // Paper start + java.util.List ingredients = new java.util.ArrayList<>(this.ingredients); + providedItems.sort(java.util.Comparator.comparingInt((ItemStack c) -> (int) matchedProvided.getCount(c)).reversed()); + ingredients.sort(java.util.Comparator.comparingInt((RecipeItemStack c) -> (int) matchedIngredients.getCount(c))); + + PROVIDED: + for (ItemStack provided : providedItems) { + for (Iterator itIngredient = ingredients.iterator(); itIngredient.hasNext(); ) { + RecipeItemStack ingredient = itIngredient.next(); + if (ingredient.test(provided)) { + itIngredient.remove(); + continue PROVIDED; + } + } + return false; + } + return ingredients.isEmpty(); + // Paper end } - public ItemStack craftItem(IInventory iinventory) { + public ItemStack a(InventoryCrafting inventorycrafting) { return this.result.cloneItemStack(); } @@ -114,6 +113,7 @@ public class ShapelessRecipes implements IRecipe { public a() {} + @Override public ShapelessRecipes a(MinecraftKey minecraftkey, JsonObject jsonobject) { String s = ChatDeserializer.a(jsonobject, "group", ""); NonNullList nonnulllist = a(ChatDeserializer.u(jsonobject, "ingredients")); @@ -143,20 +143,17 @@ public class ShapelessRecipes implements IRecipe { return nonnulllist; } - public String a() { - return "crafting_shapeless"; - } - + @Override public ShapelessRecipes a(MinecraftKey minecraftkey, PacketDataSerializer packetdataserializer) { String s = packetdataserializer.e(32767); - int i = packetdataserializer.g(); + int i = packetdataserializer.i(); NonNullList nonnulllist = NonNullList.a(i, RecipeItemStack.a); for (int j = 0; j < nonnulllist.size(); ++j) { nonnulllist.set(j, RecipeItemStack.b(packetdataserializer)); } - ItemStack itemstack = packetdataserializer.k(); + ItemStack itemstack = packetdataserializer.m(); return new ShapelessRecipes(minecraftkey, s, itemstack, nonnulllist); } diff --git a/src/main/java/net/minecraft/server/SlotFurnaceResult.java b/src/main/java/net/minecraft/server/SlotFurnaceResult.java index 08837684f..edc4a5c34 100644 --- a/src/main/java/net/minecraft/server/SlotFurnaceResult.java +++ b/src/main/java/net/minecraft/server/SlotFurnaceResult.java @@ -1,15 +1,8 @@ package net.minecraft.server; -import java.util.Iterator; -import java.util.Map.Entry; -// CraftBukkit start -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.FurnaceExtractEvent; -// CraftBukkit end - public class SlotFurnaceResult extends Slot { - private final EntityHuman a;public EntityHuman getPlayer() { return a; } // Paper OBFHELPER + private final EntityHuman a; public final EntityHuman getPlayer() { return this.a; } // Paper OBFHELPER private int b; public SlotFurnaceResult(EntityHuman entityhuman, IInventory iinventory, int i, int j, int k) { @@ -17,10 +10,12 @@ public class SlotFurnaceResult extends Slot { this.a = entityhuman; } + @Override public boolean isAllowed(ItemStack itemstack) { return false; } + @Override public ItemStack a(int i) { if (this.hasItem()) { this.b += Math.min(i, this.getItem().getCount()); @@ -29,67 +24,24 @@ public class SlotFurnaceResult extends Slot { return super.a(i); } + @Override public ItemStack a(EntityHuman entityhuman, ItemStack itemstack) { this.c(itemstack); super.a(entityhuman, itemstack); return itemstack; } + @Override protected void a(ItemStack itemstack, int i) { this.b += i; this.c(itemstack); } + @Override protected void c(ItemStack itemstack) { itemstack.a(this.a.world, this.a, this.b); - if (!this.a.world.isClientSide) { - Iterator iterator = ((TileEntityFurnace) this.inventory).q().entrySet().iterator(); - - while (iterator.hasNext()) { - Entry entry = (Entry) iterator.next(); - FurnaceRecipe furnacerecipe = (FurnaceRecipe) this.a.world.getCraftingManager().a((MinecraftKey) entry.getKey()); - float f; - - if (furnacerecipe != null) { - f = furnacerecipe.g(); - } else { - f = 0.0F; - } - - int i = (Integer) entry.getValue(); - int j; - - if (f == 0.0F) { - i = 0; - } else if (f < 1.0F) { - j = MathHelper.d((float) i * f); - if (j < MathHelper.f((float) i * f) && Math.random() < (double) ((float) i * f - (float) j)) { - ++j; - } - - i = j; - } - - // CraftBukkit start - fire FurnaceExtractEvent - Player player = (Player) a.getBukkitEntity(); - TileEntityFurnace furnace = ((TileEntityFurnace) this.inventory); - org.bukkit.block.Block block = a.world.getWorld().getBlockAt(furnace.position); // Akarin - - if (b != 0) { - FurnaceExtractEvent event = new FurnaceExtractEvent(player, block, org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(itemstack.getItem()), b, i); - a.world.getServer().getPluginManager().callEvent(event); - i = event.getExpToDrop(); - } - // CraftBukkit end - - while (i > 0) { - j = EntityExperienceOrb.getOrbValue(i); - i -= j; - this.a.world.addEntity(new EntityExperienceOrb(this.a.world, this.a.locX, this.a.locY + 0.5D, this.a.locZ + 0.5D, j, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, getPlayer())); // Paper - } - } - - ((RecipeHolder) this.inventory).d(this.a); + if (!this.a.world.isClientSide && this.inventory instanceof TileEntityFurnace) { + ((TileEntityFurnace) this.inventory).d(this.a, itemstack, this.b); // CraftBukkit } this.b = 0; diff --git a/src/main/java/net/minecraft/server/SoundEffectType.java b/src/main/java/net/minecraft/server/SoundEffectType.java new file mode 100644 index 000000000..ccd5b0529 --- /dev/null +++ b/src/main/java/net/minecraft/server/SoundEffectType.java @@ -0,0 +1,67 @@ +package net.minecraft.server; + +public class SoundEffectType { + + public static final SoundEffectType a = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_WOOD_BREAK, SoundEffects.BLOCK_WOOD_STEP, SoundEffects.BLOCK_WOOD_PLACE, SoundEffects.BLOCK_WOOD_HIT, SoundEffects.BLOCK_WOOD_FALL); + public static final SoundEffectType b = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_GRAVEL_BREAK, SoundEffects.BLOCK_GRAVEL_STEP, SoundEffects.BLOCK_GRAVEL_PLACE, SoundEffects.BLOCK_GRAVEL_HIT, SoundEffects.BLOCK_GRAVEL_FALL); + public static final SoundEffectType c = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_GRASS_BREAK, SoundEffects.BLOCK_GRASS_STEP, SoundEffects.BLOCK_GRASS_PLACE, SoundEffects.BLOCK_GRASS_HIT, SoundEffects.BLOCK_GRASS_FALL); + public static final SoundEffectType d = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_STONE_BREAK, SoundEffects.BLOCK_STONE_STEP, SoundEffects.BLOCK_STONE_PLACE, SoundEffects.BLOCK_STONE_HIT, SoundEffects.BLOCK_STONE_FALL); + public static final SoundEffectType e = new SoundEffectType(1.0F, 1.5F, SoundEffects.BLOCK_METAL_BREAK, SoundEffects.BLOCK_METAL_STEP, SoundEffects.BLOCK_METAL_PLACE, SoundEffects.BLOCK_METAL_HIT, SoundEffects.BLOCK_METAL_FALL); + public static final SoundEffectType f = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_GLASS_BREAK, SoundEffects.BLOCK_GLASS_STEP, SoundEffects.BLOCK_GLASS_PLACE, SoundEffects.BLOCK_GLASS_HIT, SoundEffects.BLOCK_GLASS_FALL); + public static final SoundEffectType g = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_WOOL_BREAK, SoundEffects.BLOCK_WOOL_STEP, SoundEffects.BLOCK_WOOL_PLACE, SoundEffects.BLOCK_WOOL_HIT, SoundEffects.BLOCK_WOOL_FALL); + public static final SoundEffectType h = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_SAND_BREAK, SoundEffects.BLOCK_SAND_STEP, SoundEffects.BLOCK_SAND_PLACE, SoundEffects.BLOCK_SAND_HIT, SoundEffects.BLOCK_SAND_FALL); + public static final SoundEffectType i = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_SNOW_BREAK, SoundEffects.BLOCK_SNOW_STEP, SoundEffects.BLOCK_SNOW_PLACE, SoundEffects.BLOCK_SNOW_HIT, SoundEffects.BLOCK_SNOW_FALL); + public static final SoundEffectType j = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_LADDER_BREAK, SoundEffects.BLOCK_LADDER_STEP, SoundEffects.BLOCK_LADDER_PLACE, SoundEffects.BLOCK_LADDER_HIT, SoundEffects.BLOCK_LADDER_FALL); + public static final SoundEffectType k = new SoundEffectType(0.3F, 1.0F, SoundEffects.BLOCK_ANVIL_BREAK, SoundEffects.BLOCK_ANVIL_STEP, SoundEffects.BLOCK_ANVIL_PLACE, SoundEffects.BLOCK_ANVIL_HIT, SoundEffects.BLOCK_ANVIL_FALL); + public static final SoundEffectType l = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_SLIME_BLOCK_BREAK, SoundEffects.BLOCK_SLIME_BLOCK_STEP, SoundEffects.BLOCK_SLIME_BLOCK_PLACE, SoundEffects.BLOCK_SLIME_BLOCK_HIT, SoundEffects.BLOCK_SLIME_BLOCK_FALL); + public static final SoundEffectType m = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_WET_GRASS_BREAK, SoundEffects.BLOCK_WET_GRASS_STEP, SoundEffects.BLOCK_WET_GRASS_PLACE, SoundEffects.BLOCK_WET_GRASS_HIT, SoundEffects.BLOCK_WET_GRASS_FALL); + public static final SoundEffectType n = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_CORAL_BLOCK_BREAK, SoundEffects.BLOCK_CORAL_BLOCK_STEP, SoundEffects.BLOCK_CORAL_BLOCK_PLACE, SoundEffects.BLOCK_CORAL_BLOCK_HIT, SoundEffects.BLOCK_CORAL_BLOCK_FALL); + public static final SoundEffectType o = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_BAMBOO_BREAK, SoundEffects.BLOCK_BAMBOO_STEP, SoundEffects.BLOCK_BAMBOO_PLACE, SoundEffects.BLOCK_BAMBOO_HIT, SoundEffects.BLOCK_BAMBOO_FALL); + public static final SoundEffectType p = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_BAMBOO_SAPLING_BREAK, SoundEffects.BLOCK_BAMBOO_STEP, SoundEffects.BLOCK_BAMBOO_SAPLING_PLACE, SoundEffects.BLOCK_BAMBOO_SAPLING_HIT, SoundEffects.BLOCK_BAMBOO_FALL); + public static final SoundEffectType q = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_SCAFFOLDING_BREAK, SoundEffects.BLOCK_SCAFFOLDING_STEP, SoundEffects.BLOCK_SCAFFOLDING_PLACE, SoundEffects.BLOCK_SCAFFOLDING_HIT, SoundEffects.BLOCK_SCAFFOLDING_FALL); + public static final SoundEffectType r = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_SWEET_BERRY_BUSH_BREAK, SoundEffects.BLOCK_GRASS_STEP, SoundEffects.BLOCK_SWEET_BERRY_BUSH_PLACE, SoundEffects.BLOCK_GRASS_HIT, SoundEffects.BLOCK_GRASS_FALL); + public static final SoundEffectType s = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_CROP_BREAK, SoundEffects.BLOCK_GRASS_STEP, SoundEffects.ITEM_CROP_PLANT, SoundEffects.BLOCK_GRASS_HIT, SoundEffects.BLOCK_GRASS_FALL); + public static final SoundEffectType t = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_WOOD_BREAK, SoundEffects.BLOCK_WOOD_STEP, SoundEffects.ITEM_CROP_PLANT, SoundEffects.BLOCK_WOOD_HIT, SoundEffects.BLOCK_WOOD_FALL); + public static final SoundEffectType u = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_NETHER_WART_BREAK, SoundEffects.BLOCK_STONE_STEP, SoundEffects.ITEM_NETHER_WART_PLANT, SoundEffects.BLOCK_STONE_HIT, SoundEffects.BLOCK_STONE_FALL); + public static final SoundEffectType v = new SoundEffectType(1.0F, 1.0F, SoundEffects.BLOCK_LANTERN_BREAK, SoundEffects.BLOCK_LANTERN_STEP, SoundEffects.BLOCK_LANTERN_PLACE, SoundEffects.BLOCK_LANTERN_HIT, SoundEffects.BLOCK_LANTERN_FALL); + public final float w; + public final float x; + private final SoundEffect y; public final SoundEffect getBreakSound() { return this.y; } // Paper - OBFHELPER + private final SoundEffect z; + private final SoundEffect A; + private final SoundEffect B; public final SoundEffect getHitSound() { return this.B; } // Paper - OBFHELPER + private final SoundEffect C; + + public SoundEffectType(float f, float f1, SoundEffect soundeffect, SoundEffect soundeffect1, SoundEffect soundeffect2, SoundEffect soundeffect3, SoundEffect soundeffect4) { + this.w = f; + this.x = f1; + this.y = soundeffect; + this.z = soundeffect1; + this.A = soundeffect2; + this.B = soundeffect3; + this.C = soundeffect4; + } + + public float a() { + return this.w; + } + + public float b() { + return this.x; + } + + public final SoundEffect getStepSound() { return this.d(); } // Paper - OBFHELPER + public SoundEffect d() { + return this.z; + } + + public final SoundEffect getPlaceSound() { return this.e(); } // Paper - OBFHELPER + public SoundEffect e() { + return this.A; + } + + public final SoundEffect getFallSound() { return this.g(); } // Paper - OBFHELPER + public SoundEffect g() { + return this.C; + } +} diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java index 1eeb8db1b..9d4a96ae4 100644 --- a/src/main/java/net/minecraft/server/SpawnerCreature.java +++ b/src/main/java/net/minecraft/server/SpawnerCreature.java @@ -1,304 +1,208 @@ package net.minecraft.server; -import com.google.common.collect.Sets; - -import io.akarin.server.core.AkarinCreatureSpanwner; -import io.akarin.server.core.AkarinGlobalConfig; - -import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.Random; -import java.util.Set; +import java.util.function.Consumer; // Paper import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; // CraftBukkit start import com.destroystokyo.paper.exception.ServerInternalException; -import org.bukkit.craftbukkit.util.LongHash; -import org.bukkit.craftbukkit.util.LongHashSet; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; // CraftBukkit end public final class SpawnerCreature { - private static final Logger a = LogManager.getLogger(); - private static final int b = (int) Math.pow(17.0D, 2.0D); - private final LongHashSet c = new LongHashSet(); // CraftBukkit + private static final Logger LOGGER = LogManager.getLogger(); - public SpawnerCreature() {} + // Paper start - add maxSpawns parameter and return spawned mobs + public static void a(EnumCreatureType enumcreaturetype, World world, Chunk chunk, BlockPosition blockposition) { + spawnMobs(enumcreaturetype, world, chunk, blockposition, Integer.MAX_VALUE, null); + } + public static int spawnMobs(EnumCreatureType enumcreaturetype, World world, Chunk chunk, BlockPosition blockposition, int maxSpawns, Consumer trackEntity) { + // Paper end + ChunkGenerator chunkgenerator = world.getChunkProvider().getChunkGenerator(); + int i = 0; // Paper - force diff on name change + BlockPosition blockposition1 = getRandomPosition(world, chunk); + int j = blockposition1.getX(); + int k = blockposition1.getY(); + int l = blockposition1.getZ(); - public int a(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) { - // Akarin start - if (AkarinGlobalConfig.improvedMobSpawnMechanics) { - int before = worldserver.entityList.size(); - AkarinCreatureSpanwner.spawnMobs(worldserver, flag, flag1, flag2); - return worldserver.entityList.size() - before; - } - // Akarin end - if (!flag && !flag1) { - return 0; - } else { - this.c.clear(); - int i = 0; - Iterator iterator = worldserver.players.iterator(); + if (k >= 1) { + IBlockData iblockdata = world.getTypeIfLoadedAndInBounds(blockposition1); // Paper - don't load chunks for mob spawn - int j; - int k; + if (iblockdata != null && !iblockdata.isOccluding(chunk, blockposition1)) { // Paper - don't load chunks for mob spawn + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + int i1 = 0; - while (iterator.hasNext()) { - EntityHuman entityhuman = (EntityHuman) iterator.next(); + while (i1 < 3) { + int j1 = j; + int k1 = l; + boolean flag = true; + BiomeBase.BiomeMeta biomebase_biomemeta = null; + GroupDataEntity groupdataentity = null; + int l1 = MathHelper.f(Math.random() * 4.0D); + int i2 = 0; // Paper - force diff on name change + int j2 = 0; - if (!entityhuman.isSpectator() && entityhuman.affectsSpawning) { // Paper - int l = MathHelper.floor(entityhuman.locX / 16.0D); + while (true) { + if (j2 < l1) { + label104: + { + j1 += world.random.nextInt(6) - world.random.nextInt(6); + k1 += world.random.nextInt(6) - world.random.nextInt(6); + blockposition_mutableblockposition.d(j1, k, k1); + float f = (float) j1 + 0.5F; + float f1 = (float) k1 + 0.5F; + EntityHuman entityhuman = world.a((double) f, (double) f1, -1.0D); - j = MathHelper.floor(entityhuman.locZ / 16.0D); - boolean flag3 = true; - // Spigot Start - byte b0 = worldserver.spigotConfig.mobSpawnRange; - b0 = ( b0 > entityhuman.getViewDistance() ) ? (byte) entityhuman.getViewDistance() : b0; // Paper - Use player view distance API - b0 = ( b0 > 8 ) ? 8 : b0; - // Paper start - com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event; - event = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent( - (org.bukkit.entity.Player) entityhuman.getBukkitEntity(), b0); - if (!event.callEvent()) { - continue; - } - b0 = event.getSpawnRadius(); - // Paperr end + if (entityhuman != null) { + double d0 = entityhuman.e((double) f, (double) k, (double) f1); - for (int i1 = -b0; i1 <= b0; ++i1) { - for (k = -b0; k <= b0; ++k) { - boolean flag4 = i1 == -b0 || i1 == b0 || k == -b0 || k == b0; - // Spigot End - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i1 + l, k + j); + if (d0 > 576.0D && !blockposition.a((IPosition) (new Vec3D((double) f, (double) k, (double) f1)), 24.0D) && world.isLoadedAndInBounds(blockposition_mutableblockposition)) { // Paper - don't load chunks for mob spawn + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(blockposition_mutableblockposition); - // CraftBukkit start - use LongHash and LongHashSet - long chunkCoords = LongHash.toLong(chunkcoordintpair.x, chunkcoordintpair.z); - if (!this.c.contains(chunkCoords)) { - ++i; - if (!flag4 && worldserver.getWorldBorder().isInBounds(chunkcoordintpair)) { - PlayerChunk playerchunk = worldserver.getPlayerChunkMap().getChunk(chunkcoordintpair.x, chunkcoordintpair.z); + if (Objects.equals(chunkcoordintpair, chunk.getPos()) || world.getChunkProvider().a(chunkcoordintpair)) { + if (biomebase_biomemeta == null) { + biomebase_biomemeta = a(chunkgenerator, enumcreaturetype, world.random, (BlockPosition) blockposition_mutableblockposition); + if (biomebase_biomemeta == null) { + break label104; + } - if (playerchunk != null && playerchunk.e()) { - this.c.add(chunkCoords); - // CraftBukkit end - } - } - } - } - } - } - } + l1 = biomebase_biomemeta.c + world.random.nextInt(1 + biomebase_biomemeta.d - biomebase_biomemeta.c); + } - int j1 = 0; - BlockPosition blockposition = worldserver.getSpawn(); - EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values(); + if (biomebase_biomemeta.b.e() != EnumCreatureType.MISC && (biomebase_biomemeta.b.d() || d0 <= 16384.0D)) { + EntityTypes entitytypes = biomebase_biomemeta.b; - j = aenumcreaturetype.length; + if (entitytypes.b() && a(chunkgenerator, enumcreaturetype, biomebase_biomemeta, (BlockPosition) blockposition_mutableblockposition)) { + EntityPositionTypes.Surface entitypositiontypes_surface = EntityPositionTypes.a(entitytypes); - for (int k1 = 0; k1 < j; ++k1) { - EnumCreatureType enumcreaturetype = aenumcreaturetype[k1]; + if (a(entitypositiontypes_surface, (IWorldReader) world, (BlockPosition) blockposition_mutableblockposition, entitytypes) && EntityPositionTypes.a(entitytypes, world, EnumMobSpawn.NATURAL, blockposition_mutableblockposition, world.random) && world.c(entitytypes.a((double) f, (double) k, (double) f1))) { + EntityInsentient entityinsentient; - // CraftBukkit start - Use per-world spawn limits - int limit = enumcreaturetype.b(); - switch (enumcreaturetype) { - case MONSTER: - limit = worldserver.getWorld().getMonsterSpawnLimit(); - break; - case CREATURE: - limit = worldserver.getWorld().getAnimalSpawnLimit(); - break; - case WATER_CREATURE: - limit = worldserver.getWorld().getWaterAnimalSpawnLimit(); - break; - case AMBIENT: - limit = worldserver.getWorld().getAmbientSpawnLimit(); - break; - } + // Paper start + com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; + EntityTypes cls = biomebase_biomemeta.b; + org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityTypes.getName(cls).getKey()); + if (type != null) { + event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( + MCUtil.toLocation(world, blockposition_mutableblockposition), + type, SpawnReason.NATURAL + ); + if (!event.callEvent()) { + if (event.shouldAbortSpawn()) { + return i; // Paper + } + ++i2; + continue; + } + } + // Paper end - if (limit == 0) { - continue; - } - // CraftBukkit end + try { + Entity entity = entitytypes.a(world); - if ((!enumcreaturetype.c() || flag1) && (enumcreaturetype.c() || flag) && (!enumcreaturetype.d() || flag2)) { - k = limit * i / SpawnerCreature.b; // CraftBukkit - use per-world limits - int l1 = ((com.destroystokyo.paper.PaperWorldEntityList) worldserver.entityList).getCreatureCount(enumcreaturetype); // Paper - entity count cache - - if (l1 <= k) { - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - Iterator iterator1 = this.c.iterator(); - - label137: - while (iterator1.hasNext()) { - // CraftBukkit start = use LongHash and LongObjectHashMap - long key = ((Long) iterator1.next()).longValue(); - BlockPosition blockposition1 = getRandomPosition(worldserver, LongHash.msw(key), LongHash.lsw(key)); - // CraftBukkit - int i2 = blockposition1.getX(); - int j2 = blockposition1.getY(); - int k2 = blockposition1.getZ(); - IBlockData iblockdata = worldserver.getTypeIfLoadedAndInBounds(blockposition1); // Paper - don't load chunks for mob spawn - - if (iblockdata != null && !iblockdata.isOccluding()) { // Paper - don't load chunks for mob spawn - int l2 = 0; - int i3 = 0; - - while (i3 < 3) { - int j3 = i2; - int k3 = j2; - int l3 = k2; - boolean flag5 = true; - BiomeBase.BiomeMeta biomebase_biomemeta = null; - GroupDataEntity groupdataentity = null; - int i4 = MathHelper.f(Math.random() * 4.0D); - int j4 = 0; - int k4 = 0; - - while (true) { - if (k4 < i4) { - label130: - { - j3 += worldserver.random.nextInt(6) - worldserver.random.nextInt(6); - k3 += worldserver.random.nextInt(1) - worldserver.random.nextInt(1); - l3 += worldserver.random.nextInt(6) - worldserver.random.nextInt(6); - blockposition_mutableblockposition.c(j3, k3, l3); - float f = (float) j3 + 0.5F; - float f1 = (float) l3 + 0.5F; - EntityHuman entityhuman1 = worldserver.a((double) f, (double) f1, -1.0D); - - if (entityhuman1 != null && worldserver.isLoadedAndInBounds(blockposition_mutableblockposition)) { // Paper - don't load chunks for mob spawn - double d0 = entityhuman1.d((double) f, (double) k3, (double) f1); - - if (d0 > 576.0D && blockposition.distanceSquared((double) f, (double) k3, (double) f1) >= 576.0D) { - if (biomebase_biomemeta == null) { - biomebase_biomemeta = worldserver.a(enumcreaturetype, (BlockPosition) blockposition_mutableblockposition); - if (biomebase_biomemeta == null) { - break label130; + if (!(entity instanceof EntityInsentient)) { + throw new IllegalStateException("Trying to spawn a non-mob: " + IRegistry.ENTITY_TYPE.getKey(entitytypes)); } - i4 = biomebase_biomemeta.c + worldserver.random.nextInt(1 + biomebase_biomemeta.d - biomebase_biomemeta.c); + entityinsentient = (EntityInsentient) entity; + } catch (Exception exception) { + SpawnerCreature.LOGGER.warn("Failed to create mob", exception); + ServerInternalException.reportInternalException(exception); // Paper + return i; // Paper } - if (worldserver.a(enumcreaturetype, biomebase_biomemeta, (BlockPosition) blockposition_mutableblockposition)) { - EntityPositionTypes.Surface entitypositiontypes_surface = EntityPositionTypes.a(biomebase_biomemeta.b); - if (entitypositiontypes_surface != null && a(entitypositiontypes_surface, worldserver, blockposition_mutableblockposition, biomebase_biomemeta.b)) { - EntityInsentient entityinsentient; - - // Paper start - com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; - EntityTypes cls = biomebase_biomemeta.b; - org.bukkit.entity.EntityType type = EntityTypes.clsToTypeMap.get(cls); - if (type != null) { - event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( - MCUtil.toLocation(worldserver, blockposition_mutableblockposition), - type, SpawnReason.NATURAL - ); - if (!event.callEvent()) { - if (event.shouldAbortSpawn()) { - continue label137; // right above the iterator for c (Chunk Pos Set) - } - j1 += l2; - ++j4; - continue; + entityinsentient.setPositionRotation((double) f, (double) k, (double) f1, world.random.nextFloat() * 360.0F, 0.0F); + if ((d0 <= 16384.0D || !entityinsentient.isTypeNotPersistent(d0)) && entityinsentient.a((GeneratorAccess) world, EnumMobSpawn.NATURAL) && entityinsentient.a((IWorldReader) world)) { + groupdataentity = entityinsentient.prepare(world, world.getDamageScaler(new BlockPosition(entityinsentient)), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null); + // CraftBukkit start + if (world.addEntity(entityinsentient, SpawnReason.NATURAL)) { + ++i; // Paper - force diff on name change + ++i2; + if (trackEntity != null) { + trackEntity.accept(entityinsentient); // Paper } } - // Paper end + if (i >= maxSpawns) { return i; } // Paper + // CraftBukkit end + if (i >= entityinsentient.dC()) { + return i; // Paper + } - - try { - entityinsentient = (EntityInsentient) biomebase_biomemeta.b.a((World) worldserver); - } catch (Exception exception) { - SpawnerCreature.a.warn("Failed to create mob", exception); - ServerInternalException.reportInternalException(exception); // Paper - return j1; - } - - entityinsentient.setPositionRotation((double) f, (double) k3, (double) f1, worldserver.random.nextFloat() * 360.0F, 0.0F); - if ((d0 <= 16384.0D || !entityinsentient.isTypeNotPersistent()) && entityinsentient.a((GeneratorAccess) worldserver, false) && entityinsentient.a((IWorldReader) worldserver)) { - groupdataentity = entityinsentient.prepare(worldserver.getDamageScaler(new BlockPosition(entityinsentient)), groupdataentity, (NBTTagCompound) null); - if (entityinsentient.a((IWorldReader) worldserver)) { - // CraftBukkit start - if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) { - ++l2; - ++j4; - } - // CraftBukkit end - } else { - entityinsentient.die(); - } - - if (l2 >= entityinsentient.dg()) { - continue label137; - } - - if (entityinsentient.c(j4)) { - break label130; - } - } - - j1 += l2; + if (entityinsentient.c(i2)) { + break label104; } } } } - - ++k4; - continue; } } - - ++i3; - break; } } + + ++j2; + continue; } } + + ++i1; + break; } } + } - - return j1; } + return i; // Paper } - public static BlockPosition getRandomPosition(World world, int i, int j) { // Akarin - public - Chunk chunk = world.getChunkAt(i, j); - int k = i * 16 + world.random.nextInt(16); - int l = j * 16 + world.random.nextInt(16); - int i1 = chunk.a(HeightMap.Type.LIGHT_BLOCKING, k, l) + 1; - int j1 = world.random.nextInt(i1 + 1); + @Nullable + private static BiomeBase.BiomeMeta a(ChunkGenerator chunkgenerator, EnumCreatureType enumcreaturetype, Random random, BlockPosition blockposition) { + List list = chunkgenerator.getMobsFor(enumcreaturetype, blockposition); - return new BlockPosition(k, j1, l); + return list.isEmpty() ? null : (BiomeBase.BiomeMeta) WeightedRandom.a(random, list); } - public static boolean a(IBlockData iblockdata, Fluid fluid) { - return iblockdata.k() ? false : (iblockdata.isPowerSource() ? false : (!fluid.e() ? false : !iblockdata.a(TagsBlock.RAILS))); + private static boolean a(ChunkGenerator chunkgenerator, EnumCreatureType enumcreaturetype, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition blockposition) { + List list = chunkgenerator.getMobsFor(enumcreaturetype, blockposition); + + return list.isEmpty() ? false : list.contains(biomebase_biomemeta); } - public static boolean isValidSpawnSurface(EntityPositionTypes.Surface entitypositiontypes_surface, IWorldReader iworldreader, BlockPosition blockposition, @Nullable EntityTypes entitytypes) { return a(entitypositiontypes_surface, iworldreader, blockposition, entitytypes); } // Akarin - public static boolean a(EntityPositionTypes.Surface entitypositiontypes_surface, IWorldReader iworldreader, BlockPosition blockposition, @Nullable EntityTypes entitytypes) { - if (entitytypes != null && iworldreader.getWorldBorder().a(blockposition)) { + private static BlockPosition getRandomPosition(World world, Chunk chunk) { + ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); + int i = chunkcoordintpair.d() + world.random.nextInt(16); + int j = chunkcoordintpair.e() + world.random.nextInt(16); + int k = chunk.a(HeightMap.Type.WORLD_SURFACE, i, j) + 1; + int l = world.random.nextInt(k + 1); + + return new BlockPosition(i, l, j); + } + + public static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid) { + return iblockdata.o(iblockaccess, blockposition) ? false : (iblockdata.isPowerSource() ? false : (!fluid.isEmpty() ? false : !iblockdata.a(TagsBlock.RAILS))); + } + + public static boolean a(EntityPositionTypes.Surface entitypositiontypes_surface, IWorldReader iworldreader, BlockPosition blockposition, @Nullable EntityTypes entitytypes) { + if (entitypositiontypes_surface == EntityPositionTypes.Surface.NO_RESTRICTIONS) { + return true; + } else if (entitytypes != null && iworldreader.getWorldBorder().a(blockposition)) { IBlockData iblockdata = iworldreader.getType(blockposition); Fluid fluid = iworldreader.getFluid(blockposition); + BlockPosition blockposition1 = blockposition.up(); + BlockPosition blockposition2 = blockposition.down(); switch (entitypositiontypes_surface) { - case IN_WATER: - return fluid.a(TagsFluid.WATER) && iworldreader.getFluid(blockposition.down()).a(TagsFluid.WATER) && !iworldreader.getType(blockposition.up()).isOccluding(); - case ON_GROUND: - default: - IBlockData iblockdata1 = iworldreader.getType(blockposition.down()); + case IN_WATER: + return fluid.a(TagsFluid.WATER) && iworldreader.getFluid(blockposition2).a(TagsFluid.WATER) && !iworldreader.getType(blockposition1).isOccluding(iworldreader, blockposition1); + case ON_GROUND: + default: + IBlockData iblockdata1 = iworldreader.getType(blockposition2); - if (!iblockdata1.q() && (entitytypes == null || !EntityPositionTypes.a(entitytypes, iblockdata1))) { - return false; - } else { - Block block = iblockdata1.getBlock(); - boolean flag = block != Blocks.BEDROCK && block != Blocks.BARRIER; - - return flag && a(iblockdata, fluid) && a(iworldreader.getType(blockposition.up()), iworldreader.getFluid(blockposition.up())); - } + return !iblockdata1.a((IBlockAccess) iworldreader, blockposition2, entitytypes) ? false : a((IBlockAccess) iworldreader, blockposition, iblockdata, fluid) && a((IBlockAccess) iworldreader, blockposition1, iworldreader.getType(blockposition1), iworldreader.getFluid(blockposition1)); } } else { return false; @@ -312,7 +216,7 @@ public final class SpawnerCreature { int k = i << 4; int l = j << 4; - while (random.nextFloat() < biomebase.e()) { + while (random.nextFloat() < biomebase.d()) { BiomeBase.BiomeMeta biomebase_biomemeta = (BiomeBase.BiomeMeta) WeightedRandom.a(random, list); int i1 = biomebase_biomemeta.c + random.nextInt(1 + biomebase_biomemeta.d - biomebase_biomemeta.c); GroupDataEntity groupdataentity = null; @@ -327,25 +231,34 @@ public final class SpawnerCreature { for (int k2 = 0; !flag && k2 < 4; ++k2) { BlockPosition blockposition = a(generatoraccess, biomebase_biomemeta.b, j1, k1); - if (a(EntityPositionTypes.Surface.ON_GROUND, generatoraccess, blockposition, biomebase_biomemeta.b)) { - EntityInsentient entityinsentient; + if (biomebase_biomemeta.b.b() && a(EntityPositionTypes.Surface.ON_GROUND, (IWorldReader) generatoraccess, blockposition, biomebase_biomemeta.b)) { + float f = biomebase_biomemeta.b.i(); + double d0 = MathHelper.a((double) j1, (double) k + (double) f, (double) k + 16.0D - (double) f); + double d1 = MathHelper.a((double) k1, (double) l + (double) f, (double) l + 16.0D - (double) f); + + if (!generatoraccess.c(biomebase_biomemeta.b.a(d0, (double) blockposition.getY(), d1)) || !EntityPositionTypes.a(biomebase_biomemeta.b, generatoraccess, EnumMobSpawn.CHUNK_GENERATION, new BlockPosition(d0, (double) blockposition.getY(), d1), generatoraccess.getRandom())) { + continue; + } + + Entity entity; try { - entityinsentient = (EntityInsentient) biomebase_biomemeta.b.a(generatoraccess.getMinecraftWorld()); + entity = biomebase_biomemeta.b.a(generatoraccess.getMinecraftWorld()); } catch (Exception exception) { - SpawnerCreature.a.warn("Failed to create mob", exception); + SpawnerCreature.LOGGER.warn("Failed to create mob", exception); ServerInternalException.reportInternalException(exception); // Paper continue; } - double d0 = MathHelper.a((double) j1, (double) k + (double) entityinsentient.width, (double) k + 16.0D - (double) entityinsentient.width); - double d1 = MathHelper.a((double) k1, (double) l + (double) entityinsentient.width, (double) l + 16.0D - (double) entityinsentient.width); + entity.setPositionRotation(d0, (double) blockposition.getY(), d1, random.nextFloat() * 360.0F, 0.0F); + if (entity instanceof EntityInsentient) { + EntityInsentient entityinsentient = (EntityInsentient) entity; - entityinsentient.setPositionRotation(d0, (double) blockposition.getY(), d1, random.nextFloat() * 360.0F, 0.0F); - if (entityinsentient.a(generatoraccess, false) && entityinsentient.a((IWorldReader) generatoraccess)) { - groupdataentity = entityinsentient.prepare(generatoraccess.getDamageScaler(new BlockPosition(entityinsentient)), groupdataentity, (NBTTagCompound) null); - generatoraccess.addEntity(entityinsentient, SpawnReason.CHUNK_GEN); // CraftBukkit - flag = true; + if (entityinsentient.a(generatoraccess, EnumMobSpawn.CHUNK_GENERATION) && entityinsentient.a((IWorldReader) generatoraccess)) { + groupdataentity = entityinsentient.prepare(generatoraccess, generatoraccess.getDamageScaler(new BlockPosition(entityinsentient)), EnumMobSpawn.CHUNK_GENERATION, groupdataentity, (NBTTagCompound) null); + generatoraccess.addEntity(entityinsentient, SpawnReason.CHUNK_GEN); // CraftBukkit + flag = true; + } } } @@ -361,10 +274,10 @@ public final class SpawnerCreature { } } - private static BlockPosition a(GeneratorAccess generatoraccess, @Nullable EntityTypes entitytypes, int i, int j) { - BlockPosition blockposition = new BlockPosition(i, generatoraccess.a(EntityPositionTypes.b(entitytypes), i, j), j); + private static BlockPosition a(IWorldReader iworldreader, @Nullable EntityTypes entitytypes, int i, int j) { + BlockPosition blockposition = new BlockPosition(i, iworldreader.a(EntityPositionTypes.b(entitytypes), i, j), j); BlockPosition blockposition1 = blockposition.down(); - return generatoraccess.getType(blockposition1).a((IBlockAccess) generatoraccess, blockposition1, PathMode.LAND) ? blockposition1 : blockposition; + return iworldreader.getType(blockposition1).a((IBlockAccess) iworldreader, blockposition1, PathMode.LAND) ? blockposition1 : blockposition; } } diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java index 2ea5ac316..7b2eace75 100644 --- a/src/main/java/net/minecraft/server/StructureGenerator.java +++ b/src/main/java/net/minecraft/server/StructureGenerator.java @@ -1,54 +1,44 @@ package net.minecraft.server; import com.google.common.collect.Lists; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import com.mojang.datafixers.Dynamic; import it.unimi.dsi.fastutil.longs.LongIterator; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import it.unimi.dsi.fastutil.longs.LongSet; import java.util.Iterator; import java.util.List; import java.util.Random; +import java.util.function.Function; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public abstract class StructureGenerator extends WorldGenerator { - private static final Logger b = LogManager.getLogger(); - public static final StructureStart a = new StructureStart() { - public boolean b() { - return false; - } - }; + private static final Logger LOGGER = LogManager.getLogger(); - public StructureGenerator() {} + public StructureGenerator(Function, ? extends C> function) { + super(function, false); + } - public boolean generate(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, Random random, BlockPosition blockposition, C c0) { - if (!this.a(generatoraccess)) { + @Override + public boolean generate(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, Random random, BlockPosition blockposition, C c0) { + if (!generatoraccess.getWorldData().shouldGenerateMapFeatures()) { return false; } else { - int i = this.b(); - int j = blockposition.getX() >> 4; - int k = blockposition.getZ() >> 4; + int i = blockposition.getX() >> 4; + int j = blockposition.getZ() >> 4; + int k = i << 4; int l = j << 4; - int i1 = k << 4; - long j1 = ChunkCoordIntPair.a(j, k); boolean flag = false; + LongIterator longiterator = generatoraccess.getChunkAt(i, j).b(this.b()).iterator(); - for (int k1 = j - i; k1 <= j + i; ++k1) { - for (int l1 = k - i; l1 <= k + i; ++l1) { - long i2 = ChunkCoordIntPair.a(k1, l1); - StructureStart structurestart = this.a(generatoraccess, chunkgenerator, (SeededRandom) random, i2); + while (longiterator.hasNext()) { + Long olong = (Long) longiterator.next(); + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(olong); + StructureStart structurestart = generatoraccess.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z).a(this.b()); - if (structurestart != StructureGenerator.a && structurestart.c().a(l, i1, l + 15, i1 + 15)) { - ((LongSet) chunkgenerator.getStructureCache(this).computeIfAbsent(j1, (j2) -> { - return new LongOpenHashSet(); - })).add(i2); - generatoraccess.getChunkProvider().a(j, k, true).a(this.a(), i2); - structurestart.a(generatoraccess, random, new StructureBoundingBox(l, i1, l + 15, i1 + 15), new ChunkCoordIntPair(j, k)); - structurestart.b(new ChunkCoordIntPair(j, k)); - flag = true; - } + if (structurestart != null && structurestart != StructureStart.a) { + structurestart.a(generatoraccess, random, new StructureBoundingBox(k, l, k + 15, l + 15), new ChunkCoordIntPair(i, j)); + flag = true; } } @@ -56,52 +46,43 @@ public abstract class StructureGenerator } } - protected StructureStart a(GeneratorAccess generatoraccess, BlockPosition blockposition) { + protected StructureStart a(GeneratorAccess generatoraccess, BlockPosition blockposition, boolean flag) { List list = this.a(generatoraccess, blockposition.getX() >> 4, blockposition.getZ() >> 4); Iterator iterator = list.iterator(); while (iterator.hasNext()) { StructureStart structurestart = (StructureStart) iterator.next(); - if (structurestart.b() && structurestart.c().b((BaseBlockPosition) blockposition)) { + if (structurestart.e() && structurestart.c().b((BaseBlockPosition) blockposition)) { + if (!flag) { + return structurestart; + } + Iterator iterator1 = structurestart.d().iterator(); while (iterator1.hasNext()) { StructurePiece structurepiece = (StructurePiece) iterator1.next(); - if (structurepiece.d().b((BaseBlockPosition) blockposition)) { + if (structurepiece.g().b((BaseBlockPosition) blockposition)) { return structurestart; } } } } - return StructureGenerator.a; + return StructureStart.a; + } + + public boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition) { + return this.a(generatoraccess, blockposition, false).e(); } public boolean b(GeneratorAccess generatoraccess, BlockPosition blockposition) { - List list = this.a(generatoraccess, blockposition.getX() >> 4, blockposition.getZ() >> 4); - Iterator iterator = list.iterator(); - - StructureStart structurestart; - - do { - if (!iterator.hasNext()) { - return false; - } - - structurestart = (StructureStart) iterator.next(); - } while (!structurestart.b() || !structurestart.c().b((BaseBlockPosition) blockposition)); - - return true; - } - - public boolean c(GeneratorAccess generatoraccess, BlockPosition blockposition) { - return this.a(generatoraccess, blockposition).b(); + return this.a(generatoraccess, blockposition, true).e(); } @Nullable - public BlockPosition getNearestGeneratedFeature(World world, ChunkGenerator chunkgenerator, BlockPosition blockposition, int i, boolean flag) { + public BlockPosition getNearestGeneratedFeature(World world, ChunkGenerator chunkgenerator, BlockPosition blockposition, int i, boolean flag) { if (!chunkgenerator.getWorldChunkManager().a(this)) { return null; } else { @@ -123,11 +104,11 @@ public abstract class StructureGenerator if (flag1 || flag2) { ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, seededrandom, j, k, i1, j1); if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper - StructureStart structurestart = this.a(world, chunkgenerator, seededrandom, chunkcoordintpair.a()); + StructureStart structurestart = world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS).a(this.b()); - if (structurestart != StructureGenerator.a) { - if (flag && structurestart.g()) { - structurestart.h(); + if (structurestart != null && structurestart.e()) { + if (flag && structurestart.h()) { + structurestart.i(); return structurestart.a(); } @@ -159,89 +140,36 @@ public abstract class StructureGenerator private List a(GeneratorAccess generatoraccess, int i, int j) { List list = Lists.newArrayList(); - Long2ObjectMap long2objectmap = generatoraccess.getChunkProvider().getChunkGenerator().getStructureStartCache(this); - Long2ObjectMap long2objectmap1 = generatoraccess.getChunkProvider().getChunkGenerator().getStructureCache(this); - long k = ChunkCoordIntPair.a(i, j); - LongSet longset = (LongSet) long2objectmap1.get(k); - - if (longset == null) { - longset = generatoraccess.getChunkProvider().a(i, j, true).b(this.a()); - long2objectmap1.put(k, longset); - } - - LongIterator longiterator = longset.iterator(); + IChunkAccess ichunkaccess = generatoraccess.getChunkAt(i, j, ChunkStatus.STRUCTURE_REFERENCES); + LongIterator longiterator = ichunkaccess.b(this.b()).iterator(); while (longiterator.hasNext()) { - Long olong = (Long) longiterator.next(); - StructureStart structurestart = (StructureStart) long2objectmap.get(olong); + long k = longiterator.nextLong(); + IChunkAccess ichunkaccess1 = generatoraccess.getChunkAt(ChunkCoordIntPair.getX(k), ChunkCoordIntPair.getZ(k), ChunkStatus.STRUCTURE_STARTS, false); // CraftBukkit - don't load chunks + StructureStart structurestart = ichunkaccess1.a(this.b()); if (structurestart != null) { list.add(structurestart); - } else { - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(olong); - IChunkAccess ichunkaccess = generatoraccess.getChunkProvider().a(chunkcoordintpair.x, chunkcoordintpair.z, true); - - structurestart = ichunkaccess.a(this.a()); - if (structurestart != null) { - long2objectmap.put(olong, structurestart); - list.add(structurestart); - } } } return list; } - private StructureStart a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, long i) { - if (!chunkgenerator.getWorldChunkManager().a(this)) { - return StructureGenerator.a; - } else { - Long2ObjectMap long2objectmap = chunkgenerator.getStructureStartCache(this); - StructureStart structurestart = (StructureStart) long2objectmap.get(i); - - if (structurestart != null) { - return structurestart; - } else { - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i); - IChunkAccess ichunkaccess = generatoraccess.getChunkProvider().getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, false, false); // CraftBukkit - don't load chunks - - if (ichunkaccess != null) { - structurestart = ichunkaccess.a(this.a()); - if (structurestart != null) { - long2objectmap.put(i, structurestart); - return structurestart; - } - } - - if (this.a(chunkgenerator, seededrandom, chunkcoordintpair.x, chunkcoordintpair.z)) { - StructureStart structurestart1 = this.a(generatoraccess, chunkgenerator, seededrandom, chunkcoordintpair.x, chunkcoordintpair.z); - - structurestart = structurestart1.b() ? structurestart1 : StructureGenerator.a; - } else { - structurestart = StructureGenerator.a; - } - - if (structurestart.b()) { - generatoraccess.getChunkProvider().a(chunkcoordintpair.x, chunkcoordintpair.z, true).a(this.a(), structurestart); - } - - long2objectmap.put(i, structurestart); - return structurestart; - } - } - } - protected ChunkCoordIntPair a(ChunkGenerator chunkgenerator, Random random, int i, int j, int k, int l) { return new ChunkCoordIntPair(i + k, j + l); } - protected abstract boolean a(ChunkGenerator chunkgenerator, Random random, int i, int j); + public abstract boolean a(ChunkGenerator chunkgenerator, Random random, int i, int j); - protected abstract boolean a(GeneratorAccess generatoraccess); + public abstract StructureGenerator.a a(); - protected abstract StructureStart a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j); + public abstract String b(); - protected abstract String a(); + public abstract int c(); - public abstract int b(); + public interface a { + + StructureStart create(StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l); + } } diff --git a/src/main/java/net/minecraft/server/StructurePiece.java b/src/main/java/net/minecraft/server/StructurePiece.java deleted file mode 100644 index 945a005e9..000000000 --- a/src/main/java/net/minecraft/server/StructurePiece.java +++ /dev/null @@ -1,491 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.ImmutableSet; -import java.util.Iterator; -import java.util.List; -import java.util.Random; -import java.util.Set; -import javax.annotation.Nullable; - -public abstract class StructurePiece { - - protected static final IBlockData m = Blocks.CAVE_AIR.getBlockData(); - protected StructureBoundingBox n; - @Nullable - private EnumDirection a; - private EnumBlockMirror b; - private EnumBlockRotation c; - protected int o; - private static final Set d = ImmutableSet.builder().add(Blocks.NETHER_BRICK_FENCE).add(Blocks.TORCH).add(Blocks.WALL_TORCH).add(Blocks.OAK_FENCE).add(Blocks.SPRUCE_FENCE).add(Blocks.DARK_OAK_FENCE).add(Blocks.ACACIA_FENCE).add(Blocks.BIRCH_FENCE).add(Blocks.JUNGLE_FENCE).add(Blocks.LADDER).add(Blocks.IRON_BARS).build(); // Paper - decompile error - - public StructurePiece() {} - - protected StructurePiece(int i) { - this.o = i; - } - - public final NBTTagCompound c() { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - - nbttagcompound.setString("id", WorldGenFactory.a(this)); - nbttagcompound.set("BB", this.n.g()); - EnumDirection enumdirection = this.f(); - - nbttagcompound.setInt("O", enumdirection == null ? -1 : enumdirection.get2DRotationValue()); - nbttagcompound.setInt("GD", this.o); - this.a(nbttagcompound); - return nbttagcompound; - } - - protected abstract void a(NBTTagCompound nbttagcompound); - - public void a(GeneratorAccess generatoraccess, NBTTagCompound nbttagcompound) { - if (nbttagcompound.hasKey("BB")) { - this.n = new StructureBoundingBox(nbttagcompound.getIntArray("BB")); - } - - int i = nbttagcompound.getInt("O"); - - this.a(i == -1 ? null : EnumDirection.fromType2(i)); - this.o = nbttagcompound.getInt("GD"); - this.a(nbttagcompound, generatoraccess.getDataManager().h()); - } - - protected abstract void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager); - - public void a(StructurePiece structurepiece, List list, Random random) {} - - public abstract boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair); - - public StructureBoundingBox d() { - return this.n; - } - - public int e() { - return this.o; - } - - public static StructurePiece a(List list, StructureBoundingBox structureboundingbox) { - StructurePiece structurepiece; // Paper - synchronized (list) { // Paper - synchronize main structure list - Iterator iterator = list.iterator(); - - //StructurePiece structurepiece; // Paper - move up - - do { - if (!iterator.hasNext()) { - return null; - } - - structurepiece = (StructurePiece) iterator.next(); - } while (structurepiece.d() == null || !structurepiece.d().a(structureboundingbox)); - } // Paper - return structurepiece; - } - - protected boolean a(IBlockAccess iblockaccess, StructureBoundingBox structureboundingbox) { - int i = Math.max(this.n.a - 1, structureboundingbox.a); - int j = Math.max(this.n.b - 1, structureboundingbox.b); - int k = Math.max(this.n.c - 1, structureboundingbox.c); - int l = Math.min(this.n.d + 1, structureboundingbox.d); - int i1 = Math.min(this.n.e + 1, structureboundingbox.e); - int j1 = Math.min(this.n.f + 1, structureboundingbox.f); - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - - int k1; - int l1; - - for (k1 = i; k1 <= l; ++k1) { - for (l1 = k; l1 <= j1; ++l1) { - if (iblockaccess.getType(blockposition_mutableblockposition.c(k1, j, l1)).getMaterial().isLiquid()) { - return true; - } - - if (iblockaccess.getType(blockposition_mutableblockposition.c(k1, i1, l1)).getMaterial().isLiquid()) { - return true; - } - } - } - - for (k1 = i; k1 <= l; ++k1) { - for (l1 = j; l1 <= i1; ++l1) { - if (iblockaccess.getType(blockposition_mutableblockposition.c(k1, l1, k)).getMaterial().isLiquid()) { - return true; - } - - if (iblockaccess.getType(blockposition_mutableblockposition.c(k1, l1, j1)).getMaterial().isLiquid()) { - return true; - } - } - } - - for (k1 = k; k1 <= j1; ++k1) { - for (l1 = j; l1 <= i1; ++l1) { - if (iblockaccess.getType(blockposition_mutableblockposition.c(i, l1, k1)).getMaterial().isLiquid()) { - return true; - } - - if (iblockaccess.getType(blockposition_mutableblockposition.c(l, l1, k1)).getMaterial().isLiquid()) { - return true; - } - } - } - - return false; - } - - protected int a(int i, int j) { - EnumDirection enumdirection = this.f(); - - if (enumdirection == null) { - return i; - } else { - switch (enumdirection) { - case NORTH: - case SOUTH: - return this.n.a + i; - case WEST: - return this.n.d - j; - case EAST: - return this.n.a + j; - default: - return i; - } - } - } - - protected int d(int i) { - return this.f() == null ? i : i + this.n.b; - } - - protected int b(int i, int j) { - EnumDirection enumdirection = this.f(); - - if (enumdirection == null) { - return j; - } else { - switch (enumdirection) { - case NORTH: - return this.n.f - j; - case SOUTH: - return this.n.c + j; - case WEST: - case EAST: - return this.n.c + i; - default: - return j; - } - } - } - - protected void a(GeneratorAccess generatoraccess, IBlockData iblockdata, int i, int j, int k, StructureBoundingBox structureboundingbox) { - BlockPosition blockposition = new BlockPosition(this.a(i, k), this.d(j), this.b(i, k)); - - if (structureboundingbox.b((BaseBlockPosition) blockposition)) { - if (this.b != EnumBlockMirror.NONE) { - iblockdata = iblockdata.a(this.b); - } - - if (this.c != EnumBlockRotation.NONE) { - iblockdata = iblockdata.a(this.c); - } - - generatoraccess.setTypeAndData(blockposition, iblockdata, 2); - Fluid fluid = generatoraccess.getFluid(blockposition); - - if (!fluid.e()) { - generatoraccess.getFluidTickList().a(blockposition, fluid.c(), 0); - } - - if (StructurePiece.d.contains(iblockdata.getBlock())) { - generatoraccess.y(blockposition).e(blockposition); - } - - } - } - - protected IBlockData a(IBlockAccess iblockaccess, int i, int j, int k, StructureBoundingBox structureboundingbox) { - int l = this.a(i, k); - int i1 = this.d(j); - int j1 = this.b(i, k); - BlockPosition blockposition = new BlockPosition(l, i1, j1); - - return !structureboundingbox.b((BaseBlockPosition) blockposition) ? Blocks.AIR.getBlockData() : iblockaccess.getType(blockposition); - } - - protected boolean a(IWorldReader iworldreader, int i, int j, int k, StructureBoundingBox structureboundingbox) { - int l = this.a(i, k); - int i1 = this.d(j + 1); - int j1 = this.b(i, k); - BlockPosition blockposition = new BlockPosition(l, i1, j1); - - return !structureboundingbox.b((BaseBlockPosition) blockposition) ? false : i1 < iworldreader.a(HeightMap.Type.OCEAN_FLOOR_WG, l, j1); - } - - protected void b(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, int i, int j, int k, int l, int i1, int j1) { - for (int k1 = j; k1 <= i1; ++k1) { - for (int l1 = i; l1 <= l; ++l1) { - for (int i2 = k; i2 <= j1; ++i2) { - this.a(generatoraccess, Blocks.AIR.getBlockData(), l1, k1, i2, structureboundingbox); - } - } - } - - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, int i, int j, int k, int l, int i1, int j1, IBlockData iblockdata, IBlockData iblockdata1, boolean flag) { - for (int k1 = j; k1 <= i1; ++k1) { - for (int l1 = i; l1 <= l; ++l1) { - for (int i2 = k; i2 <= j1; ++i2) { - if (!flag || !this.a((IBlockAccess) generatoraccess, l1, k1, i2, structureboundingbox).isAir()) { - if (k1 != j && k1 != i1 && l1 != i && l1 != l && i2 != k && i2 != j1) { - this.a(generatoraccess, iblockdata1, l1, k1, i2, structureboundingbox); - } else { - this.a(generatoraccess, iblockdata, l1, k1, i2, structureboundingbox); - } - } - } - } - } - - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, int i, int j, int k, int l, int i1, int j1, boolean flag, Random random, StructurePiece.StructurePieceBlockSelector structurepiece_structurepieceblockselector) { - for (int k1 = j; k1 <= i1; ++k1) { - for (int l1 = i; l1 <= l; ++l1) { - for (int i2 = k; i2 <= j1; ++i2) { - if (!flag || !this.a((IBlockAccess) generatoraccess, l1, k1, i2, structureboundingbox).isAir()) { - structurepiece_structurepieceblockselector.a(random, l1, k1, i2, k1 == j || k1 == i1 || l1 == i || l1 == l || i2 == k || i2 == j1); - this.a(generatoraccess, structurepiece_structurepieceblockselector.a(), l1, k1, i2, structureboundingbox); - } - } - } - } - - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, Random random, float f, int i, int j, int k, int l, int i1, int j1, IBlockData iblockdata, IBlockData iblockdata1, boolean flag, boolean flag1) { - for (int k1 = j; k1 <= i1; ++k1) { - for (int l1 = i; l1 <= l; ++l1) { - for (int i2 = k; i2 <= j1; ++i2) { - if (random.nextFloat() <= f && (!flag || !this.a((IBlockAccess) generatoraccess, l1, k1, i2, structureboundingbox).isAir()) && (!flag1 || this.a((IWorldReader) generatoraccess, l1, k1, i2, structureboundingbox))) { - if (k1 != j && k1 != i1 && l1 != i && l1 != l && i2 != k && i2 != j1) { - this.a(generatoraccess, iblockdata1, l1, k1, i2, structureboundingbox); - } else { - this.a(generatoraccess, iblockdata, l1, k1, i2, structureboundingbox); - } - } - } - } - } - - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, Random random, float f, int i, int j, int k, IBlockData iblockdata) { - if (random.nextFloat() < f) { - this.a(generatoraccess, iblockdata, i, j, k, structureboundingbox); - } - - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, int i, int j, int k, int l, int i1, int j1, IBlockData iblockdata, boolean flag) { - float f = (float) (l - i + 1); - float f1 = (float) (i1 - j + 1); - float f2 = (float) (j1 - k + 1); - float f3 = (float) i + f / 2.0F; - float f4 = (float) k + f2 / 2.0F; - - for (int k1 = j; k1 <= i1; ++k1) { - float f5 = (float) (k1 - j) / f1; - - for (int l1 = i; l1 <= l; ++l1) { - float f6 = ((float) l1 - f3) / (f * 0.5F); - - for (int i2 = k; i2 <= j1; ++i2) { - float f7 = ((float) i2 - f4) / (f2 * 0.5F); - - if (!flag || !this.a((IBlockAccess) generatoraccess, l1, k1, i2, structureboundingbox).isAir()) { - float f8 = f6 * f6 + f5 * f5 + f7 * f7; - - if (f8 <= 1.05F) { - this.a(generatoraccess, iblockdata, l1, k1, i2, structureboundingbox); - } - } - } - } - } - - } - - protected void a(GeneratorAccess generatoraccess, int i, int j, int k, StructureBoundingBox structureboundingbox) { - BlockPosition blockposition = new BlockPosition(this.a(i, k), this.d(j), this.b(i, k)); - - if (structureboundingbox.b((BaseBlockPosition) blockposition)) { - while (!generatoraccess.isEmpty(blockposition) && blockposition.getY() < 255) { - generatoraccess.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 2); - blockposition = blockposition.up(); - } - - } - } - - protected void b(GeneratorAccess generatoraccess, IBlockData iblockdata, int i, int j, int k, StructureBoundingBox structureboundingbox) { - int l = this.a(i, k); - int i1 = this.d(j); - int j1 = this.b(i, k); - - if (structureboundingbox.b((BaseBlockPosition) (new BlockPosition(l, i1, j1)))) { - while ((generatoraccess.isEmpty(new BlockPosition(l, i1, j1)) || generatoraccess.getType(new BlockPosition(l, i1, j1)).getMaterial().isLiquid()) && i1 > 1) { - generatoraccess.setTypeAndData(new BlockPosition(l, i1, j1), iblockdata, 2); - --i1; - } - - } - } - - protected boolean a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, Random random, int i, int j, int k, MinecraftKey minecraftkey) { - BlockPosition blockposition = new BlockPosition(this.a(i, k), this.d(j), this.b(i, k)); - - return this.a(generatoraccess, structureboundingbox, random, blockposition, minecraftkey, (IBlockData) null); - } - - public static IBlockData a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { - EnumDirection enumdirection = null; - Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); - - while (iterator.hasNext()) { - EnumDirection enumdirection1 = (EnumDirection) iterator.next(); - BlockPosition blockposition1 = blockposition.shift(enumdirection1); - IBlockData iblockdata1 = iblockaccess.getType(blockposition1); - - if (iblockdata1.getBlock() == Blocks.CHEST) { - return iblockdata; - } - - if (iblockdata1.f(iblockaccess, blockposition1)) { - if (enumdirection != null) { - enumdirection = null; - break; - } - - enumdirection = enumdirection1; - } - } - - if (enumdirection != null) { - return (IBlockData) iblockdata.set(BlockFacingHorizontal.FACING, enumdirection.opposite()); - } else { - EnumDirection enumdirection2 = (EnumDirection) iblockdata.get(BlockFacingHorizontal.FACING); - BlockPosition blockposition2 = blockposition.shift(enumdirection2); - - if (iblockaccess.getType(blockposition2).f(iblockaccess, blockposition2)) { - enumdirection2 = enumdirection2.opposite(); - blockposition2 = blockposition.shift(enumdirection2); - } - - if (iblockaccess.getType(blockposition2).f(iblockaccess, blockposition2)) { - enumdirection2 = enumdirection2.e(); - blockposition2 = blockposition.shift(enumdirection2); - } - - if (iblockaccess.getType(blockposition2).f(iblockaccess, blockposition2)) { - enumdirection2 = enumdirection2.opposite(); - blockposition.shift(enumdirection2); - } - - return (IBlockData) iblockdata.set(BlockFacingHorizontal.FACING, enumdirection2); - } - } - - protected boolean a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, Random random, BlockPosition blockposition, MinecraftKey minecraftkey, @Nullable IBlockData iblockdata) { - if (structureboundingbox.b((BaseBlockPosition) blockposition) && generatoraccess.getType(blockposition).getBlock() != Blocks.CHEST) { - if (iblockdata == null) { - iblockdata = a((IBlockAccess) generatoraccess, blockposition, Blocks.CHEST.getBlockData()); - } - - generatoraccess.setTypeAndData(blockposition, iblockdata, 2); - TileEntity tileentity = generatoraccess.getTileEntity(blockposition); - - if (tileentity instanceof TileEntityChest) { - ((TileEntityChest) tileentity).setLootTable(minecraftkey, random.nextLong()); - } - - return true; - } else { - return false; - } - } - - protected boolean a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, Random random, int i, int j, int k, EnumDirection enumdirection, MinecraftKey minecraftkey) { - BlockPosition blockposition = new BlockPosition(this.a(i, k), this.d(j), this.b(i, k)); - - if (structureboundingbox.b((BaseBlockPosition) blockposition) && generatoraccess.getType(blockposition).getBlock() != Blocks.DISPENSER) { - this.a(generatoraccess, (IBlockData) Blocks.DISPENSER.getBlockData().set(BlockDispenser.FACING, enumdirection), i, j, k, structureboundingbox); - TileEntity tileentity = generatoraccess.getTileEntity(blockposition); - - if (tileentity instanceof TileEntityDispenser) { - ((TileEntityDispenser) tileentity).setLootTable(minecraftkey, random.nextLong()); - } - - return true; - } else { - return false; - } - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, Random random, int i, int j, int k, EnumDirection enumdirection, BlockDoor blockdoor) { - this.a(generatoraccess, (IBlockData) blockdoor.getBlockData().set(BlockDoor.FACING, enumdirection), i, j, k, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) blockdoor.getBlockData().set(BlockDoor.FACING, enumdirection)).set(BlockDoor.HALF, BlockPropertyDoubleBlockHalf.UPPER), i, j + 1, k, structureboundingbox); - } - - public void a(int i, int j, int k) { - this.n.a(i, j, k); - } - - @Nullable - public EnumDirection f() { - return this.a; - } - - public void a(@Nullable EnumDirection enumdirection) { - this.a = enumdirection; - if (enumdirection == null) { - this.c = EnumBlockRotation.NONE; - this.b = EnumBlockMirror.NONE; - } else { - switch (enumdirection) { - case SOUTH: - this.b = EnumBlockMirror.LEFT_RIGHT; - this.c = EnumBlockRotation.NONE; - break; - case WEST: - this.b = EnumBlockMirror.LEFT_RIGHT; - this.c = EnumBlockRotation.CLOCKWISE_90; - break; - case EAST: - this.b = EnumBlockMirror.NONE; - this.c = EnumBlockRotation.CLOCKWISE_90; - break; - default: - this.b = EnumBlockMirror.NONE; - this.c = EnumBlockRotation.NONE; - } - } - - } - - public abstract static class StructurePieceBlockSelector { - - protected IBlockData a; - - protected StructurePieceBlockSelector() { - this.a = Blocks.AIR.getBlockData(); - } - - public abstract void a(Random random, int i, int j, int k, boolean flag); - - public IBlockData a() { - return this.a; - } - } -} diff --git a/src/main/java/net/minecraft/server/StructureStart.java b/src/main/java/net/minecraft/server/StructureStart.java deleted file mode 100644 index 8b08efe1f..000000000 --- a/src/main/java/net/minecraft/server/StructureStart.java +++ /dev/null @@ -1,194 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import java.util.Iterator; -import java.util.List; -import java.util.Random; - -public abstract class StructureStart { - - protected final List a = java.util.Collections.synchronizedList(Lists.newArrayList()); // Paper - protected StructureBoundingBox b; - protected int c; - protected int d; - private BiomeBase e; - private int f; - - public StructureStart() {} - - public StructureStart(int i, int j, BiomeBase biomebase, SeededRandom seededrandom, long k) { - this.c = i; - this.d = j; - this.e = biomebase; - seededrandom.c(k, this.c, this.d); - } - - public StructureBoundingBox c() { - return this.b; - } - - public List d() { - return this.a; - } - - public void a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - List list = this.a; - - synchronized (this.a) { - Iterator iterator = this.a.iterator(); - - while (iterator.hasNext()) { - StructurePiece structurepiece = (StructurePiece) iterator.next(); - - if (structurepiece.d().a(structureboundingbox) && !structurepiece.a(generatoraccess, random, structureboundingbox, chunkcoordintpair)) { - iterator.remove(); - } - } - - this.a((IBlockAccess) generatoraccess); - } - } - - protected void a(IBlockAccess iblockaccess) { - this.b = StructureBoundingBox.a(); - synchronized (this.a) { // Paper - synchronize - Iterator iterator = this.a.iterator(); - - while (iterator.hasNext()) { - StructurePiece structurepiece = (StructurePiece) iterator.next(); - - this.b.b(structurepiece.d()); - }} // Paper - - } - - public NBTTagCompound a(int i, int j) { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - - if (this.b()) { - nbttagcompound.setString("id", WorldGenFactory.a(this)); - nbttagcompound.setString("biome", IRegistry.BIOME.getKey(this.e).toString()); - nbttagcompound.setInt("ChunkX", i); - nbttagcompound.setInt("ChunkZ", j); - nbttagcompound.setInt("references", this.f); - nbttagcompound.set("BB", this.b.g()); - NBTTagList nbttaglist = new NBTTagList(); - List list = this.a; - - synchronized (this.a) { - Iterator iterator = this.a.iterator(); - - while (iterator.hasNext()) { - StructurePiece structurepiece = (StructurePiece) iterator.next(); - - nbttaglist.add((NBTBase) structurepiece.c()); - } - } - - nbttagcompound.set("Children", nbttaglist); - this.a(nbttagcompound); - return nbttagcompound; - } else { - nbttagcompound.setString("id", "INVALID"); - return nbttagcompound; - } - } - - public void a(NBTTagCompound nbttagcompound) {} - - public void a(GeneratorAccess generatoraccess, NBTTagCompound nbttagcompound) { - this.c = nbttagcompound.getInt("ChunkX"); - this.d = nbttagcompound.getInt("ChunkZ"); - this.f = nbttagcompound.getInt("references"); - this.e = nbttagcompound.hasKey("biome") ? (BiomeBase) IRegistry.BIOME.get(new MinecraftKey(nbttagcompound.getString("biome"))) : generatoraccess.getChunkProvider().getChunkGenerator().getWorldChunkManager().getBiome(new BlockPosition((this.c << 4) + 9, 0, (this.d << 4) + 9), Biomes.PLAINS); - if (nbttagcompound.hasKey("BB")) { - this.b = new StructureBoundingBox(nbttagcompound.getIntArray("BB")); - } - - NBTTagList nbttaglist = nbttagcompound.getList("Children", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - this.a.add(WorldGenFactory.b(nbttaglist.getCompound(i), generatoraccess)); - } - - this.b(nbttagcompound); - } - - public void b(NBTTagCompound nbttagcompound) {} - - protected void a(IWorldReader iworldreader, Random random, int i) { - int j = iworldreader.getSeaLevel() - i; - int k = this.b.d() + 1; - - if (k < j) { - k += random.nextInt(j - k); - } - - int l = k - this.b.e; - - this.b.a(0, l, 0); - synchronized (this.a) { // Paper - synchronize - Iterator iterator = this.a.iterator(); - - while (iterator.hasNext()) { - StructurePiece structurepiece = (StructurePiece) iterator.next(); - - structurepiece.a(0, l, 0); - }} // Paper - - } - - protected void a(IBlockAccess iblockaccess, Random random, int i, int j) { - int k = j - i + 1 - this.b.d(); - int l; - - if (k > 1) { - l = i + random.nextInt(k); - } else { - l = i; - } - - int i1 = l - this.b.b; - - this.b.a(0, i1, 0); - synchronized (this.a) { - Iterator iterator = this.a.iterator(); - - while (iterator.hasNext()) { - StructurePiece structurepiece = (StructurePiece) iterator.next(); - - structurepiece.a(0, i1, 0); - }} // Paper - - } - - public boolean b() { - return true; - } - - public void b(ChunkCoordIntPair chunkcoordintpair) {} - - public int e() { - return this.c; - } - - public int f() { - return this.d; - } - - public BlockPosition a() { - return new BlockPosition(this.c << 4, 0, this.d << 4); - } - - public boolean g() { - return this.f < this.i(); - } - - public void h() { - ++this.f; - } - - protected int i() { - return 1; - } -} diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java index 5e71d2ac2..35594821c 100644 --- a/src/main/java/net/minecraft/server/SystemUtils.java +++ b/src/main/java/net/minecraft/server/SystemUtils.java @@ -1,23 +1,32 @@ package net.minecraft.server; import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.MoreExecutors; +import com.mojang.datafixers.DataFixUtils; +import com.mojang.datafixers.Dynamic; import it.unimi.dsi.fastutil.Hash.Strategy; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; -import java.nio.file.InvalidPathException; -import java.nio.file.Paths; import java.time.Instant; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; +import java.util.UUID; import java.util.Map.Entry; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.FutureTask; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.LongSupplier; import java.util.function.Supplier; -import java.util.regex.Pattern; import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -27,20 +36,21 @@ import org.apache.logging.log4j.Logger; public class SystemUtils { + private static final AtomicInteger b = new AtomicInteger(1); + private static final ExecutorService c = k(); public static LongSupplier a = System::nanoTime; - private static final Logger b = LogManager.getLogger(); - private static final Pattern c = Pattern.compile(".*\\.|(?:CON|PRN|AUX|NUL|COM1|COM2|COM3|COM4|COM5|COM6|COM7|COM8|COM9|LPT1|LPT2|LPT3|LPT4|LPT5|LPT6|LPT7|LPT8|LPT9)(?:\\..*)?", 2); + private static final Logger LOGGER = LogManager.getLogger(); public static Collector, ?, Map> a() { return Collectors.toMap(Entry::getKey, Entry::getValue); } - public static > String a(IBlockState iblockstate, T object) { + public static > String a(IBlockState iblockstate, T object) { // Paper - decompile fix return iblockstate.a(object); // Paper - decompile fix } public static String a(String s, @Nullable MinecraftKey minecraftkey) { - return minecraftkey == null ? s + ".unregistered_sadface" : s + '.' + minecraftkey.b() + '.' + minecraftkey.getKey().replace('/', '.'); + return minecraftkey == null ? s + ".unregistered_sadface" : s + '.' + minecraftkey.getNamespace() + '.' + minecraftkey.getKey().replace('/', '.'); } public static long getMonotonicMillis() { @@ -55,13 +65,64 @@ public class SystemUtils { return Instant.now().toEpochMilli(); } - public static SystemUtils.OS e() { + private static ExecutorService k() { + int i = Math.min(6, Math.max(Runtime.getRuntime().availableProcessors() - 2, 2)); // Paper - use more reasonable default - 2 is hard minimum to avoid using unlimited threads + Object object; + + if (i <= 0) { + object = MoreExecutors.newDirectExecutorService(); + } else { + object = new ForkJoinPool(i, (forkjoinpool) -> { + ForkJoinWorkerThread forkjoinworkerthread = new ForkJoinWorkerThread(forkjoinpool) { + }; + + forkjoinworkerthread.setName("Server-Worker-" + SystemUtils.b.getAndIncrement()); + return forkjoinworkerthread; + }, (thread, throwable) -> { + if (throwable instanceof CompletionException) { + throwable = throwable.getCause(); + } + + if (throwable instanceof ReportedException) { + DispenserRegistry.a(((ReportedException) throwable).a().e()); + System.exit(-1); + } + + SystemUtils.LOGGER.error(String.format("Caught exception in thread %s", thread), throwable); + }, true); + } + + return (ExecutorService) object; + } + + public static Executor e() { + return SystemUtils.c; + } + + public static void f() { + SystemUtils.c.shutdown(); + + boolean flag; + + try { + flag = SystemUtils.c.awaitTermination(3L, TimeUnit.SECONDS); + } catch (InterruptedException interruptedexception) { + flag = false; + } + + if (!flag) { + SystemUtils.c.shutdownNow(); + } + + } + + public static SystemUtils.OS g() { String s = System.getProperty("os.name").toLowerCase(Locale.ROOT); return s.contains("win") ? SystemUtils.OS.WINDOWS : (s.contains("mac") ? SystemUtils.OS.OSX : (s.contains("solaris") ? SystemUtils.OS.SOLARIS : (s.contains("sunos") ? SystemUtils.OS.SOLARIS : (s.contains("linux") ? SystemUtils.OS.LINUX : (s.contains("unix") ? SystemUtils.OS.LINUX : SystemUtils.OS.UNKNOWN))))); } - public static Stream f() { + public static Stream h() { RuntimeMXBean runtimemxbean = ManagementFactory.getRuntimeMXBean(); return runtimemxbean.getInputArguments().stream().filter((s) -> { @@ -69,53 +130,6 @@ public class SystemUtils { }); } - public static boolean a(java.nio.file.Path java_nio_file_path) { - java.nio.file.Path java_nio_file_path1 = java_nio_file_path.normalize(); - - return java_nio_file_path1.equals(java_nio_file_path); - } - - public static boolean b(java.nio.file.Path java_nio_file_path) { - Iterator iterator = java_nio_file_path.iterator(); - - java.nio.file.Path java_nio_file_path1; - - do { - if (!iterator.hasNext()) { - return true; - } - - java_nio_file_path1 = (java.nio.file.Path) iterator.next(); - } while (!SystemUtils.c.matcher(java_nio_file_path1.toString()).matches()); - - return false; - } - - public static java.nio.file.Path a(java.nio.file.Path java_nio_file_path, String s, String s1) { - String s2 = s + s1; - java.nio.file.Path java_nio_file_path1 = Paths.get(s2); - - if (java_nio_file_path1.endsWith(s1)) { - throw new InvalidPathException(s2, "empty resource name"); - } else { - return java_nio_file_path.resolve(java_nio_file_path1); - } - } - - @Nullable - public static V a(FutureTask futuretask, Logger logger) { - try { - futuretask.run(); - return futuretask.get(); - } catch (ExecutionException executionexception) { - logger.fatal("Error executing task", executionexception.getCause() != null ? executionexception.getCause() : executionexception); // Paper - } catch (InterruptedException interruptedexception) { - logger.fatal("Error executing task", interruptedexception); - } - - return null; - } - public static T a(List list) { return list.get(list.size() - 1); } @@ -169,8 +183,61 @@ public class SystemUtils { return t0; } - public static Strategy g() { - return (Strategy) IdentityHashingStrategy.INSTANCE; // Paper - decompile fix + public static Strategy i() { + return (Strategy) SystemUtils.IdentityHashingStrategy.INSTANCE; // Paper - decompile fix + } + + public static CompletableFuture> b(List> list) { + List list1 = Lists.newArrayListWithCapacity(list.size()); + CompletableFuture[] acompletablefuture = new CompletableFuture[list.size()]; + CompletableFuture completablefuture = new CompletableFuture(); + + list.forEach((completablefuture1) -> { + int i = list1.size(); + + list1.add(null); // Paper - decompile fix + acompletablefuture[i] = completablefuture1.whenComplete((object, throwable) -> { + if (throwable != null) { + completablefuture.completeExceptionally(throwable); + } else { + list1.set(i, object); + } + + }); + }); + return CompletableFuture.allOf(acompletablefuture).applyToEither(completablefuture, (ovoid) -> { + return list1; + }); + } + + public static Stream a(Optional optional) { + return (Stream) DataFixUtils.orElseGet(optional.map(Stream::of), Stream::empty); + } + + public static Optional a(Optional optional, Consumer consumer, Runnable runnable) { + if (optional.isPresent()) { + consumer.accept(optional.get()); + } else { + runnable.run(); + } + + return optional; + } + + public static Runnable a(Runnable runnable, Supplier supplier) { + return runnable; + } + + public static Optional a(String s, Dynamic dynamic) { + return dynamic.get(s + "Most").asNumber().flatMap((number) -> { + return dynamic.get(s + "Least").asNumber().map((number1) -> { + return new UUID(number.longValue(), number1.longValue()); + }); + }); + } + + public static Dynamic a(String s, UUID uuid, Dynamic dynamic) { + return dynamic.set(s + "Most", dynamic.createLong(uuid.getMostSignificantBits())).set(s + "Least", dynamic.createLong(uuid.getLeastSignificantBits())); } static enum IdentityHashingStrategy implements Strategy { diff --git a/src/main/java/net/minecraft/server/TagRegistry.java b/src/main/java/net/minecraft/server/TagRegistry.java index 27d0a2880..36ce76af1 100644 --- a/src/main/java/net/minecraft/server/TagRegistry.java +++ b/src/main/java/net/minecraft/server/TagRegistry.java @@ -1,62 +1,98 @@ package net.minecraft.server; -public class TagRegistry implements IResourcePackListener { +import com.mojang.datafixers.util.Pair; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; - private final TagsServer a; - private final TagsServer b; - private final TagsServer c; +public class TagRegistry implements IReloadListener { + + private final TagsServer blockTags; + private final TagsServer itemTags; + private final TagsServer fluidTags; + private final TagsServer> entityTags; public TagRegistry() { - this.a = new TagsServer<>(IRegistry.BLOCK, "tags/blocks", "block"); - this.b = new TagsServer<>(IRegistry.ITEM, "tags/items", "item"); - this.c = new TagsServer<>(IRegistry.FLUID, "tags/fluids", "fluid"); + this.blockTags = new TagsServer<>(IRegistry.BLOCK, "tags/blocks", "block"); + this.itemTags = new TagsServer<>(IRegistry.ITEM, "tags/items", "item"); + this.fluidTags = new TagsServer<>(IRegistry.FLUID, "tags/fluids", "fluid"); + this.entityTags = new TagsServer<>(IRegistry.ENTITY_TYPE, "tags/entity_types", "entity_type"); } - public TagsServer a() { - return this.a; + public TagsServer getBlockTags() { + return this.blockTags; } - public TagsServer b() { - return this.b; + public TagsServer getItemTags() { + return this.itemTags; } - public TagsServer c() { - return this.c; + public TagsServer getFluidTags() { + return this.fluidTags; } - public void d() { - this.a.b(); - this.b.b(); - this.c.b(); - } - - public void a(IResourceManager iresourcemanager) { - this.d(); - this.a.a(iresourcemanager); - this.b.a(iresourcemanager); - this.c.a(iresourcemanager); - TagsBlock.a((Tags) this.a); - TagsItem.a((Tags) this.b); - TagsFluid.a((Tags) this.c); - // CraftBukkit start - this.a.version++; - this.b.version++; - this.c.version++; - // CraftBukkit end + public TagsServer> getEntityTags() { + return this.entityTags; } public void a(PacketDataSerializer packetdataserializer) { - this.a.a(packetdataserializer); - this.b.a(packetdataserializer); - this.c.a(packetdataserializer); + this.blockTags.a(packetdataserializer); + this.itemTags.a(packetdataserializer); + this.fluidTags.a(packetdataserializer); + this.entityTags.a(packetdataserializer); } public static TagRegistry b(PacketDataSerializer packetdataserializer) { TagRegistry tagregistry = new TagRegistry(); - tagregistry.a().b(packetdataserializer); - tagregistry.b().b(packetdataserializer); - tagregistry.c().b(packetdataserializer); + tagregistry.getBlockTags().b(packetdataserializer); + tagregistry.getItemTags().b(packetdataserializer); + tagregistry.getFluidTags().b(packetdataserializer); + tagregistry.getEntityTags().b(packetdataserializer); return tagregistry; } + + @Override + public CompletableFuture a(IReloadListener.a ireloadlistener_a, IResourceManager iresourcemanager, GameProfilerFiller gameprofilerfiller, GameProfilerFiller gameprofilerfiller1, Executor executor, Executor executor1) { + CompletableFuture>> completablefuture = this.blockTags.a(iresourcemanager, executor); + CompletableFuture>> completablefuture1 = this.itemTags.a(iresourcemanager, executor); + CompletableFuture>> completablefuture2 = this.fluidTags.a(iresourcemanager, executor); + CompletableFuture>>> completablefuture3 = this.entityTags.a(iresourcemanager, executor); + CompletableFuture completablefuture4 = completablefuture.thenCombine(completablefuture1, Pair::of).thenCombine(completablefuture2.thenCombine(completablefuture3, Pair::of), (pair, pair1) -> { // CraftBukkit - decompile error + return new TagRegistry.a((Map) pair.getFirst(), (Map) pair.getSecond(), (Map) pair1.getFirst(), (Map) pair1.getSecond()); + }); + + ireloadlistener_a.getClass(); + return completablefuture4.thenCompose(ireloadlistener_a::a).thenAcceptAsync((tagregistry_a) -> { + this.blockTags.a(tagregistry_a.a); + this.itemTags.a(tagregistry_a.b); + this.fluidTags.a(tagregistry_a.c); + this.entityTags.a(tagregistry_a.d); + TagsBlock.a((Tags) this.blockTags); + TagsItem.a((Tags) this.itemTags); + TagsFluid.a((Tags) this.fluidTags); + TagsEntity.a((Tags) this.entityTags); + // CraftBukkit start + this.blockTags.version++; + this.itemTags.version++; + this.fluidTags.version++; + this.entityTags.version++; + // CraftBukkit end + }, executor1); + } + + public static class a { + + final Map> a; + final Map> b; + final Map> c; + final Map>> d; + + public a(Map> map, Map> map1, Map> map2, Map>> map3) { + this.a = map; + this.b = map1; + this.c = map2; + this.d = map3; + } + } } diff --git a/src/main/java/net/minecraft/server/TagsServer.java b/src/main/java/net/minecraft/server/TagsServer.java index b9c1a3f27..7ed9f2cd5 100644 --- a/src/main/java/net/minecraft/server/TagsServer.java +++ b/src/main/java/net/minecraft/server/TagsServer.java @@ -1,9 +1,8 @@ package net.minecraft.server; -import com.google.common.collect.Lists; -import java.util.Collection; +import com.google.common.collect.Maps; import java.util.Iterator; -import java.util.List; +import java.util.Map; import java.util.Map.Entry; public class TagsServer extends Tags { @@ -12,13 +11,15 @@ public class TagsServer extends Tags { public int version; // CraftBukkit public TagsServer(IRegistry iregistry, String s, String s1) { - super(iregistry::c, iregistry::get, s, false, s1); + super(iregistry::getOptional, s, false, s1); this.a = iregistry; } public void a(PacketDataSerializer packetdataserializer) { - packetdataserializer.d(this.c().size()); - Iterator iterator = this.c().entrySet().iterator(); + Map> map = this.b(); + + packetdataserializer.d(map.size()); + Iterator iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Entry> entry = (Entry) iterator.next(); @@ -37,19 +38,21 @@ public class TagsServer extends Tags { } public void b(PacketDataSerializer packetdataserializer) { - int i = packetdataserializer.g(); + Map> map = Maps.newHashMap(); + int i = packetdataserializer.i(); for (int j = 0; j < i; ++j) { - MinecraftKey minecraftkey = packetdataserializer.l(); - int k = packetdataserializer.g(); - List list = Lists.newArrayList(); + MinecraftKey minecraftkey = packetdataserializer.o(); + int k = packetdataserializer.i(); + Tag.a tag_a = Tag.a.a(); for (int l = 0; l < k; ++l) { - list.add(this.a.fromId(packetdataserializer.g())); + tag_a.a(this.a.fromId(packetdataserializer.i())); } - this.c().put(minecraftkey, (Tag) Tag.a.a().a((Collection) list).b(minecraftkey)); // CraftBukkit - decompile error + map.put(minecraftkey, tag_a.b(minecraftkey)); } + this.b((Map) map); } } diff --git a/src/main/java/net/minecraft/server/TickListServer.java b/src/main/java/net/minecraft/server/TickListServer.java index 9bb826af5..f533860bb 100644 --- a/src/main/java/net/minecraft/server/TickListServer.java +++ b/src/main/java/net/minecraft/server/TickListServer.java @@ -1,44 +1,47 @@ package net.minecraft.server; import com.google.common.collect.Lists; +import com.google.common.collect.Queues; import com.google.common.collect.Sets; -import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Queue; import java.util.Set; import java.util.TreeSet; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; -import org.bukkit.craftbukkit.util.HashTreeSet; // CraftBukkit +import java.util.stream.Stream; +import javax.annotation.Nullable; public class TickListServer implements TickList { protected final Predicate a; - protected final Function b; - protected final Function c; - // protected final Set> nextTickListHash = Sets.newHashSet(); - protected final HashTreeSet nextTickList = new HashTreeSet<>(); // CraftBukkit - HashTreeSet + private final Function b; + private final Function c; + private final Set> nextTickListHash = Sets.newHashSet(); + private final TreeSet> nextTickList = Sets.newTreeSet(NextTickListEntry.a()); private final WorldServer f; - private final List> g = Lists.newArrayList(); - private final Consumer> h; + private final Queue> g = Queues.newArrayDeque(); + private final List> h = Lists.newArrayList(); + private final Consumer> i; public TickListServer(WorldServer worldserver, Predicate predicate, Function function, Function function1, Consumer> consumer, String timingsType) { // Paper this.a = predicate; this.b = function; this.c = function1; this.f = worldserver; - this.h = consumer; - // Paper start - timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(worldserver, timingsType + " - Cleanup"); - timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(worldserver, timingsType + " - Ticking"); + this.i = consumer; + this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(worldserver, timingsType + " - Cleanup"); + this.timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(worldserver, timingsType + " - Ticking"); } private final co.aikar.timings.Timing timingCleanup; // Paper private final co.aikar.timings.Timing timingTicking; // Paper // Paper end - public void a() { + public void b() { int i = this.nextTickList.size(); if (false) { // CraftBukkit @@ -54,35 +57,37 @@ public class TickListServer implements TickList { // CraftBukkit end } - //this.f.methodProfiler.enter("cleaning"); // Akarin - timingCleanup.startTimingUnsafe(); // Paper // Akarin - NextTickListEntry nextticklistentry; // CraftBukkit - decompile error + ChunkProviderServer chunkproviderserver = this.f.getChunkProvider(); + Iterator> iterator = this.nextTickList.iterator(); - for (int j = 0; j < i; ++j) { - nextticklistentry = (NextTickListEntry) this.nextTickList.first(); + this.f.getMethodProfiler().enter("cleaning"); + + this.timingCleanup.startTiming(); // Paper + NextTickListEntry nextticklistentry; + + while (i > 0 && iterator.hasNext()) { + nextticklistentry = (NextTickListEntry) iterator.next(); if (nextticklistentry.b > this.f.getTime()) { break; } - this.nextTickList.remove(nextticklistentry); - // this.nextTickListHash.remove(nextticklistentry); // CraftBukkit - use nextTickList - this.g.add(nextticklistentry); + if (chunkproviderserver.a(nextticklistentry.a)) { + iterator.remove(); + this.nextTickListHash.remove(nextticklistentry); + this.g.add(nextticklistentry); + --i; + } } - timingCleanup.stopTimingUnsafe(); // Paper // Akarin + this.timingCleanup.stopTiming(); // Paper - //this.f.methodProfiler.exit(); // Akarin - //this.f.methodProfiler.enter("ticking"); // Akarin - timingTicking.startTimingUnsafe(); // Paper // Akarin - Iterator iterator = this.g.iterator(); + this.timingTicking.startTiming(); // Paper + this.f.getMethodProfiler().exitEnter("ticking"); - while (iterator.hasNext()) { - nextticklistentry = (NextTickListEntry) iterator.next(); - iterator.remove(); - boolean flag = false; - - if (this.f.areChunksLoadedBetween(nextticklistentry.a.a(0, 0, 0), nextticklistentry.a.a(0, 0, 0))) { + while ((nextticklistentry = (NextTickListEntry) this.g.poll()) != null) { + if (chunkproviderserver.a(nextticklistentry.a)) { try { - this.h.accept(nextticklistentry); + this.h.add(nextticklistentry); + this.i.accept(nextticklistentry); } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Exception while ticking"); CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being ticked"); @@ -91,69 +96,77 @@ public class TickListServer implements TickList { throw new ReportedException(crashreport); } } else { - this.a(nextticklistentry.a, nextticklistentry.a(), 0); + this.a(nextticklistentry.a, (T) nextticklistentry.b(), 0); // CraftBukkit - decompile error } } - //this.f.methodProfiler.exit(); // Akarin + this.f.getMethodProfiler().exit(); + this.timingTicking.stopTiming(); // Paper + this.h.clear(); this.g.clear(); - timingTicking.stopTimingUnsafe(); // Paper // Akarin } } + @Override public boolean b(BlockPosition blockposition, T t0) { return this.g.contains(new NextTickListEntry<>(blockposition, t0)); } - public List> a(Chunk chunk, boolean flag) { - ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); + @Override + public void a(Stream> stream) { + stream.forEach(this::a); + } + + public List> a(ChunkCoordIntPair chunkcoordintpair, boolean flag, boolean flag1) { int i = (chunkcoordintpair.x << 4) - 2; int j = i + 16 + 2; int k = (chunkcoordintpair.z << 4) - 2; int l = k + 16 + 2; - return this.a(new StructureBoundingBox(i, 0, k, j, 256, l), flag); + return this.a(new StructureBoundingBox(i, 0, k, j, 256, l), flag, flag1); } - public List> a(StructureBoundingBox structureboundingbox, boolean flag) { - List> list = null; + public List> a(StructureBoundingBox structureboundingbox, boolean flag, boolean flag1) { + List> list = this.a((List) null, this.nextTickList, structureboundingbox, flag); - for (int i = 0; i < 2; ++i) { - Iterator iterator; + if (flag && list != null) { + this.nextTickListHash.removeAll(list); + } - if (i == 0) { - iterator = this.nextTickList.iterator(); - } else { - iterator = this.g.iterator(); - } + list = this.a(list, this.g, structureboundingbox, flag); + if (!flag1) { + list = this.a(list, this.h, structureboundingbox, flag); + } - while (iterator.hasNext()) { - NextTickListEntry nextticklistentry = (NextTickListEntry) iterator.next(); - BlockPosition blockposition = nextticklistentry.a; + return list == null ? Collections.emptyList() : list; + } - if (blockposition.getX() >= structureboundingbox.a && blockposition.getX() < structureboundingbox.d && blockposition.getZ() >= structureboundingbox.c && blockposition.getZ() < structureboundingbox.f) { - if (flag) { - if (i == 0) { - // this.nextTickListHash.remove(nextticklistentry); // CraftBukkit - removed - } + @Nullable + private List> a(@Nullable List> list, Collection> collection, StructureBoundingBox structureboundingbox, boolean flag) { + Iterator iterator = collection.iterator(); - iterator.remove(); - } + while (iterator.hasNext()) { + NextTickListEntry nextticklistentry = (NextTickListEntry) iterator.next(); + BlockPosition blockposition = nextticklistentry.a; - if (list == null) { - list = Lists.newArrayList(); - } - - list.add(nextticklistentry); + if (blockposition.getX() >= structureboundingbox.a && blockposition.getX() < structureboundingbox.d && blockposition.getZ() >= structureboundingbox.c && blockposition.getZ() < structureboundingbox.f) { + if (flag) { + iterator.remove(); } + + if (list == null) { + list = Lists.newArrayList(); + } + + ((List) list).add(nextticklistentry); } } - return (List) (list == null ? Collections.emptyList() : list); + return (List) list; } public void a(StructureBoundingBox structureboundingbox, BlockPosition blockposition) { - List> list = this.a(structureboundingbox, false); + List> list = this.a(structureboundingbox, false, false); Iterator iterator = list.iterator(); while (iterator.hasNext()) { @@ -161,74 +174,62 @@ public class TickListServer implements TickList { if (structureboundingbox.b((BaseBlockPosition) nextticklistentry.a)) { BlockPosition blockposition1 = nextticklistentry.a.a((BaseBlockPosition) blockposition); + T t0 = nextticklistentry.b(); - this.b(blockposition1, nextticklistentry.a(), (int) (nextticklistentry.b - this.f.getWorldData().getTime()), nextticklistentry.c); + this.a(new NextTickListEntry<>(blockposition1, t0, nextticklistentry.b, nextticklistentry.c)); } } } - public NBTTagList a(Chunk chunk) { - List> list = this.a(chunk, false); - long i = this.f.getTime(); + public NBTTagList a(ChunkCoordIntPair chunkcoordintpair) { + List> list = this.a(chunkcoordintpair, false, true); + + return a(this.b, list, this.f.getTime()); + } + + public static NBTTagList a(Function function, Iterable> iterable, long i) { NBTTagList nbttaglist = new NBTTagList(); - Iterator iterator = list.iterator(); + Iterator iterator = iterable.iterator(); while (iterator.hasNext()) { NextTickListEntry nextticklistentry = (NextTickListEntry) iterator.next(); NBTTagCompound nbttagcompound = new NBTTagCompound(); - nbttagcompound.setString("i", ((MinecraftKey) this.b.apply(nextticklistentry.a())).toString()); + nbttagcompound.setString("i", ((MinecraftKey) function.apply(nextticklistentry.b())).toString()); nbttagcompound.setInt("x", nextticklistentry.a.getX()); nbttagcompound.setInt("y", nextticklistentry.a.getY()); nbttagcompound.setInt("z", nextticklistentry.a.getZ()); nbttagcompound.setInt("t", (int) (nextticklistentry.b - i)); nbttagcompound.setInt("p", nextticklistentry.c.a()); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); } return nbttaglist; } - public void a(NBTTagList nbttaglist) { - for (int i = 0; i < nbttaglist.size(); ++i) { - NBTTagCompound nbttagcompound = nbttaglist.getCompound(i); - T t0 = this.c.apply(new MinecraftKey(nbttagcompound.getString("i"))); - - if (t0 != null) { - this.b(new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")), t0, nbttagcompound.getInt("t"), TickListPriority.a(nbttagcompound.getInt("p"))); - } - } - - } - + @Override public boolean a(BlockPosition blockposition, T t0) { - return this.nextTickList.contains(new NextTickListEntry<>(blockposition, t0)); // CraftBukkit + return this.nextTickListHash.contains(new NextTickListEntry<>(blockposition, t0)); } + @Override public void a(BlockPosition blockposition, T t0, int i, TickListPriority ticklistpriority) { if (!this.a.test(t0)) { - if (this.f.isLoaded(blockposition)) { - this.c(blockposition, t0, i, ticklistpriority); - } - - } - } - - protected void b(BlockPosition blockposition, T t0, int i, TickListPriority ticklistpriority) { - if (!this.a.test(t0)) { - this.c(blockposition, t0, i, ticklistpriority); + this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.f.getTime(), ticklistpriority)); } } - private void c(BlockPosition blockposition, T t0, int i, TickListPriority ticklistpriority) { - NextTickListEntry nextticklistentry = new NextTickListEntry<>(blockposition, t0, (long) i + this.f.getTime(), ticklistpriority); - - // CraftBukkit - use nextTickList - if (!this.nextTickList.contains(nextticklistentry)) { + private void a(NextTickListEntry nextticklistentry) { + if (!this.nextTickListHash.contains(nextticklistentry)) { + this.nextTickListHash.add(nextticklistentry); this.nextTickList.add(nextticklistentry); } } + + public int a() { + return this.nextTickListHash.size(); + } } diff --git a/src/main/java/net/minecraft/server/Ticket.java b/src/main/java/net/minecraft/server/Ticket.java new file mode 100644 index 000000000..badbe6c19 --- /dev/null +++ b/src/main/java/net/minecraft/server/Ticket.java @@ -0,0 +1,65 @@ +package net.minecraft.server; + +import java.util.Objects; + +public final class Ticket implements Comparable> { + + private final TicketType a; + private final int b; + public final T identifier; public final T getObjectReason() { return this.identifier; } // Paper - OBFHELPER + private final long d; public final long getCreationTick() { return this.d; } // Paper - OBFHELPER + + protected Ticket(TicketType tickettype, int i, T t0, long j) { + this.a = tickettype; + this.b = i; + this.identifier = t0; + this.d = j; + } + + public int compareTo(Ticket ticket) { + int i = Integer.compare(this.b, ticket.b); + + if (i != 0) { + return i; + } else { + int j = Integer.compare(System.identityHashCode(this.a), System.identityHashCode(ticket.a)); + + return j != 0 ? j : this.a.a().compare(this.identifier, (T)ticket.identifier); // Paper - decompile fix + } + } + + public boolean equals(Object object) { + if (this == object) { + return true; + } else if (!(object instanceof Ticket)) { + return false; + } else { + Ticket ticket = (Ticket) object; + + return this.b == ticket.b && Objects.equals(this.a, ticket.a) && Objects.equals(this.identifier, ticket.identifier); + } + } + + public int hashCode() { + return Objects.hash(new Object[]{this.a, this.b, this.identifier}); + } + + public String toString() { + return "Ticket[" + this.a + " " + this.b + " (" + this.identifier + ")] at " + this.d; + } + + public TicketType getTicketType() { + return this.a; + } + + public final int getTicketLevel() { return this.b(); } // Paper - OBFHELPER + public int b() { + return this.b; + } + + public boolean a(long i) { + long j = this.a.b(); + + return j != 0L && i - this.d > j; + } +} diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java new file mode 100644 index 000000000..e3150f85a --- /dev/null +++ b/src/main/java/net/minecraft/server/TicketType.java @@ -0,0 +1,52 @@ +package net.minecraft.server; + +import java.util.Comparator; + +public class TicketType { + + private final String i; + private final Comparator j; + public long loadPeriod; + public static final TicketType START = a("start", (unit, unit1) -> { + return 0; + }); + public static final TicketType DRAGON = a("dragon", (unit, unit1) -> { + return 0; + }); + public static final TicketType PLAYER = a("player", Comparator.comparingLong(ChunkCoordIntPair::pair)); + public static final TicketType FORCED = a("forced", Comparator.comparingLong(ChunkCoordIntPair::pair)); + public static final TicketType LIGHT = a("light", Comparator.comparingLong(ChunkCoordIntPair::pair)); + public static final TicketType PORTAL = a("portal", Comparator.comparingLong(BlockPosition2D::b)); + public static final TicketType POST_TELEPORT = a("post_teleport", Integer::compareTo, 5); + public static final TicketType UNKNOWN = a("unknown", Comparator.comparingLong(ChunkCoordIntPair::pair), 1); + public static final TicketType PLUGIN = a("plugin", (a, b) -> 0); // CraftBukkit + public static final TicketType PLUGIN_TICKET = a("plugin_ticket", (plugin1, plugin2) -> plugin1.getClass().getName().compareTo(plugin2.getClass().getName())); // Craftbukkit + public static final TicketType ANTIXRAY = a("antixray", Integer::compareTo); // Paper - Anti-Xray + public static final TicketType ASYNC_LOAD = a("async_load", Long::compareTo); // Paper + + public static TicketType a(String s, Comparator comparator) { + return new TicketType<>(s, comparator, 0L); + } + + public static TicketType a(String s, Comparator comparator, int i) { + return new TicketType<>(s, comparator, (long) i); + } + + protected TicketType(String s, Comparator comparator, long i) { + this.i = s; + this.j = comparator; + this.loadPeriod = i; + } + + public String toString() { + return this.i; + } + + public Comparator a() { + return this.j; + } + + public long b() { + return this.loadPeriod; + } +} diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java index 92ad82b7f..b8ddb99fa 100644 --- a/src/main/java/net/minecraft/server/TileEntity.java +++ b/src/main/java/net/minecraft/server/TileEntity.java @@ -3,26 +3,36 @@ package net.minecraft.server; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; - +import org.apache.logging.log4j.util.Supplier; +// CraftBukkit start +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.inventory.InventoryHolder; +// CraftBukkit end import co.aikar.timings.MinecraftTimings; // Paper import co.aikar.timings.Timing; // Paper -import org.bukkit.inventory.InventoryHolder; // CraftBukkit public abstract class TileEntity implements KeyedObject { // Paper public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper + // CraftBukkit start - data containers + private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); + public CraftPersistentDataContainer persistentDataContainer; + // CraftBukkit end + private static final Logger LOGGER = LogManager.getLogger(); boolean isLoadingStructure = false; // Paper - private static final Logger a = LogManager.getLogger(); - private final TileEntityTypes e; public TileEntityTypes getTileEntityType() { return e; } // Paper - OBFHELPER + private final TileEntityTypes b; public TileEntityTypes getTileEntityType() { return b; } // Paper - OBFHELPER + @Nullable protected World world; protected BlockPosition position; - protected boolean d; + protected boolean f; @Nullable - private IBlockData f; + private IBlockData c; + private boolean g; public TileEntity(TileEntityTypes tileentitytypes) { this.position = BlockPosition.ZERO; - this.e = tileentitytypes; + this.b = tileentitytypes; } // Paper start @@ -70,6 +80,14 @@ public abstract class TileEntity implements KeyedObject { // Paper public void load(NBTTagCompound nbttagcompound) { this.position = new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")); + // CraftBukkit start - read container + this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); + + NBTTagCompound persistentDataTag = nbttagcompound.getCompound("PublicBukkitValues"); + if (persistentDataTag != null) { + this.persistentDataContainer.putAll(persistentDataTag); + } + // CraftBukkit end } public NBTTagCompound save(NBTTagCompound nbttagcompound) { @@ -77,7 +95,7 @@ public abstract class TileEntity implements KeyedObject { // Paper } private NBTTagCompound d(NBTTagCompound nbttagcompound) { - MinecraftKey minecraftkey = TileEntityTypes.a(this.C()); + MinecraftKey minecraftkey = TileEntityTypes.a(this.q()); if (minecraftkey == null) { throw new RuntimeException(this.getClass() + " is missing a mapping! This is a bug!"); @@ -86,50 +104,47 @@ public abstract class TileEntity implements KeyedObject { // Paper nbttagcompound.setInt("x", this.position.getX()); nbttagcompound.setInt("y", this.position.getY()); nbttagcompound.setInt("z", this.position.getZ()); + // CraftBukkit start - store container + if (this.persistentDataContainer != null && !this.persistentDataContainer.isEmpty()) { + nbttagcompound.set("PublicBukkitValues", this.persistentDataContainer.toTagCompound()); + } + // CraftBukkit end return nbttagcompound; } } - // CraftBukkit start @Nullable public static TileEntity create(NBTTagCompound nbttagcompound) { - return create(nbttagcompound, null); - } - - @Nullable - public static TileEntity create(NBTTagCompound nbttagcompound, @Nullable World world) { - // CraftBukkit end - TileEntity tileentity = null; String s = nbttagcompound.getString("id"); - try { - tileentity = TileEntityTypes.a(s); - } catch (Throwable throwable) { - TileEntity.a.error("Failed to create block entity {}", s, throwable); - } - - if (tileentity != null) { + return (TileEntity) IRegistry.BLOCK_ENTITY_TYPE.getOptional(new MinecraftKey(s)).map((tileentitytypes) -> { try { - tileentity.setWorld(world); // CraftBukkit - tileentity.load(nbttagcompound); - } catch (Throwable throwable1) { - TileEntity.a.error("Failed to load data for block entity {}", s, throwable1); - tileentity = null; + return tileentitytypes.a(); + } catch (Throwable throwable) { + TileEntity.LOGGER.error("Failed to create block entity {}", s, throwable); + return null; } - } else { - TileEntity.a.warn("Skipping BlockEntity with id {}", s); - } - - return tileentity; + }).map((tileentity) -> { + try { + tileentity.load(nbttagcompound); + return tileentity; + } catch (Throwable throwable) { + TileEntity.LOGGER.error("Failed to load data for block entity {}", s, throwable); + return null; + } + }).orElseGet(() -> { + TileEntity.LOGGER.warn("Skipping BlockEntity with id {}", s); + return null; + }); } public void update() { if (this.world != null) { if (IGNORE_TILE_UPDATES) return; // Paper - this.f = this.world.getType(this.position); + this.c = this.world.getType(this.position); this.world.b(this.position, this); - if (!this.f.isAir()) { - this.world.updateAdjacentComparators(this.position, this.f.getBlock()); + if (!this.c.isAir()) { + this.world.updateAdjacentComparators(this.position, this.c.getBlock()); } } @@ -140,11 +155,11 @@ public abstract class TileEntity implements KeyedObject { // Paper } public IBlockData getBlock() { - if (this.f == null) { - this.f = this.world.getType(this.position); + if (this.c == null) { + this.c = this.world.getType(this.position); } - return this.f; + return this.c; } @Nullable @@ -152,33 +167,33 @@ public abstract class TileEntity implements KeyedObject { // Paper return null; } - public NBTTagCompound aa_() { + public NBTTagCompound b() { return this.d(new NBTTagCompound()); } - public boolean x() { - return this.d; + public boolean isRemoved() { + return this.f; } - public void y() { - this.d = true; + public void V_() { + this.f = true; } - public void z() { - this.d = false; + public void n() { + this.f = false; } - public boolean c(int i, int j) { + public boolean setProperty(int i, int j) { return false; } public void invalidateBlockCache() { - this.f = null; + this.c = null; } public void a(CrashReportSystemDetails crashreportsystemdetails) { crashreportsystemdetails.a("Name", () -> { - return IRegistry.BLOCK_ENTITY_TYPE.getKey(this.C()) + " // " + this.getClass().getCanonicalName(); + return IRegistry.BLOCK_ENTITY_TYPE.getKey(this.q()) + " // " + this.getClass().getCanonicalName(); }); if (this.world != null) { // Paper start - Prevent TileEntity and Entity crashes @@ -192,7 +207,7 @@ public abstract class TileEntity implements KeyedObject { // Paper } public void setPosition(BlockPosition blockposition) { - this.position = blockposition.h(); + this.position = blockposition.immutableCopy(); } public boolean isFilteredNBT() { @@ -203,8 +218,17 @@ public abstract class TileEntity implements KeyedObject { // Paper public void a(EnumBlockMirror enumblockmirror) {} - public TileEntityTypes C() { - return this.e; + public TileEntityTypes q() { + return this.b; + } + + public void r() { + if (!this.g) { + this.g = true; + TileEntity.LOGGER.warn("Block entity invalid: {} @ {}", new Supplier[]{() -> { + return IRegistry.BLOCK_ENTITY_TYPE.getKey(this.q()); + }, this::getPosition}); + } } // CraftBukkit start - add method @@ -216,7 +240,7 @@ public abstract class TileEntity implements KeyedObject { // Paper // Paper end if (world == null) return null; // Spigot start - org.bukkit.block.Block block = world.getWorld().getBlockAt(position); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()); if (block == null) { org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "No block for owner at %s %d %d %d", new Object[]{world.getWorld(), position.getX(), position.getY(), position.getZ()}); return null; diff --git a/src/main/java/net/minecraft/server/TileEntityBanner.java b/src/main/java/net/minecraft/server/TileEntityBanner.java index dfee7332e..bfc58a775 100644 --- a/src/main/java/net/minecraft/server/TileEntityBanner.java +++ b/src/main/java/net/minecraft/server/TileEntityBanner.java @@ -24,40 +24,22 @@ public class TileEntityBanner extends TileEntity implements INamableTileEntity { this.color = enumcolor; } - public void a(ItemStack itemstack, EnumColor enumcolor) { - this.patterns = null; - NBTTagCompound nbttagcompound = itemstack.b("BlockEntityTag"); - - if (nbttagcompound != null && nbttagcompound.hasKeyOfType("Patterns", 9)) { - this.patterns = nbttagcompound.getList("Patterns", 10).clone(); - // CraftBukkit start - while (this.patterns.size() > 20) { - this.patterns.remove(20); - } - // CraftBukkit end - } - - this.color = enumcolor; - this.h = null; - this.i = null; - this.j = ""; - this.g = true; - this.a = itemstack.hasName() ? itemstack.getName() : null; - } - + @Override public IChatBaseComponent getDisplayName() { return (IChatBaseComponent) (this.a != null ? this.a : new ChatMessage("block.minecraft.banner", new Object[0])); } - public boolean hasCustomName() { - return this.a != null; - } - @Nullable + @Override public IChatBaseComponent getCustomName() { return this.a; } + public void a(IChatBaseComponent ichatbasecomponent) { + this.a = ichatbasecomponent; + } + + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); if (this.patterns != null) { @@ -71,6 +53,7 @@ public class TileEntityBanner extends TileEntity implements INamableTileEntity { return nbttagcompound; } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); if (nbttagcompound.hasKeyOfType("CustomName", 8)) { @@ -78,7 +61,7 @@ public class TileEntityBanner extends TileEntity implements INamableTileEntity { } if (this.hasWorld()) { - this.color = ((BlockBannerAbstract) this.getBlock().getBlock()).b(); + this.color = ((BlockBannerAbstract) this.getBlock().getBlock()).getColor(); } else { this.color = null; } @@ -96,11 +79,13 @@ public class TileEntityBanner extends TileEntity implements INamableTileEntity { } @Nullable + @Override public PacketPlayOutTileEntityData getUpdatePacket() { - return new PacketPlayOutTileEntityData(this.position, 6, this.aa_()); + return new PacketPlayOutTileEntityData(this.position, 6, this.b()); } - public NBTTagCompound aa_() { + @Override + public NBTTagCompound b() { return this.save(new NBTTagCompound()); } @@ -119,32 +104,16 @@ public class TileEntityBanner extends TileEntity implements INamableTileEntity { if (!nbttaglist.isEmpty()) { nbttaglist.remove(nbttaglist.size() - 1); if (nbttaglist.isEmpty()) { - itemstack.c("BlockEntityTag"); + itemstack.removeTag("BlockEntityTag"); } } } } - public ItemStack a(IBlockData iblockdata) { - ItemStack itemstack = new ItemStack(BlockBanner.a(this.a(() -> { - return iblockdata; - }))); - - if (this.patterns != null && !this.patterns.isEmpty()) { - itemstack.a("BlockEntityTag").set("Patterns", this.patterns.clone()); - } - - if (this.a != null) { - itemstack.a(this.a); - } - - return itemstack; - } - public EnumColor a(Supplier supplier) { if (this.color == null) { - this.color = ((BlockBannerAbstract) ((IBlockData) supplier.get()).getBlock()).b(); + this.color = ((BlockBannerAbstract) ((IBlockData) supplier.get()).getBlock()).getColor(); } return this.color; diff --git a/src/main/java/net/minecraft/server/TileEntityBarrel.java b/src/main/java/net/minecraft/server/TileEntityBarrel.java new file mode 100644 index 000000000..5d80ec801 --- /dev/null +++ b/src/main/java/net/minecraft/server/TileEntityBarrel.java @@ -0,0 +1,228 @@ +package net.minecraft.server; + +import java.util.Iterator; + +// CraftBukkit start +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.bukkit.Location; +import org.bukkit.block.Barrel; +import org.bukkit.block.Lectern; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.InventoryHolder; +// CraftBukkit end + +public class TileEntityBarrel extends TileEntityLootable { + + // CraftBukkit start - add fields and methods + public List transaction = new ArrayList<>(); + private int maxStack = MAX_STACK; + + @Override + public List getContents() { + return this.items; + } + + @Override + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + @Override + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + @Override + public List getViewers() { + return transaction; + } + + @Override + public int getMaxStackSize() { + return maxStack; + } + + @Override + public void setMaxStackSize(int i) { + maxStack = i; + } + // CraftBukkit end + private NonNullList items; + private int b; + + private TileEntityBarrel(TileEntityTypes tileentitytypes) { + super(tileentitytypes); + this.items = NonNullList.a(27, ItemStack.a); + } + + public TileEntityBarrel() { + this(TileEntityTypes.BARREL); + } + + @Override + public NBTTagCompound save(NBTTagCompound nbttagcompound) { + super.save(nbttagcompound); + if (!this.e(nbttagcompound)) { + ContainerUtil.a(nbttagcompound, this.items); + } + + return nbttagcompound; + } + + @Override + public void load(NBTTagCompound nbttagcompound) { + super.load(nbttagcompound); + this.items = NonNullList.a(this.getSize(), ItemStack.a); + if (!this.d(nbttagcompound)) { + ContainerUtil.b(nbttagcompound, this.items); + } + + } + + @Override + public int getSize() { + return 27; + } + + @Override + public boolean isNotEmpty() { + Iterator iterator = this.items.iterator(); + + ItemStack itemstack; + + do { + if (!iterator.hasNext()) { + return true; + } + + itemstack = (ItemStack) iterator.next(); + } while (itemstack.isEmpty()); + + return false; + } + + @Override + public ItemStack getItem(int i) { + return (ItemStack) this.items.get(i); + } + + @Override + public ItemStack splitStack(int i, int j) { + return ContainerUtil.a(this.items, i, j); + } + + @Override + public ItemStack splitWithoutUpdate(int i) { + return ContainerUtil.a(this.items, i); + } + + @Override + public void setItem(int i, ItemStack itemstack) { + this.items.set(i, itemstack); + if (itemstack.getCount() > this.getMaxStackSize()) { + itemstack.setCount(this.getMaxStackSize()); + } + + } + + @Override + public void clear() { + this.items.clear(); + } + + @Override + protected NonNullList f() { + return this.items; + } + + @Override + protected void a(NonNullList nonnulllist) { + this.items = nonnulllist; + } + + @Override + protected IChatBaseComponent getContainerName() { + return new ChatMessage("container.barrel", new Object[0]); + } + + @Override + protected Container createContainer(int i, PlayerInventory playerinventory) { + return ContainerChest.a(i, playerinventory, this); + } + + @Override + public void startOpen(EntityHuman entityhuman) { + if (!entityhuman.isSpectator()) { + if (this.b < 0) { + this.b = 0; + } + + ++this.b; + IBlockData iblockdata = this.getBlock(); + boolean flag = (Boolean) iblockdata.get(BlockBarrel.b); + + if (!flag) { + this.a(iblockdata, SoundEffects.BLOCK_BARREL_OPEN); + this.a(iblockdata, true); + } + + this.s(); + } + + } + + private void s() { + this.world.getBlockTickList().a(this.getPosition(), this.getBlock().getBlock(), 5); + } + + public void h() { + int i = this.position.getX(); + int j = this.position.getY(); + int k = this.position.getZ(); + + this.b = TileEntityChest.a(this.world, this, i, j, k); + if (this.b > 0) { + this.s(); + } else { + IBlockData iblockdata = this.getBlock(); + + if (iblockdata.getBlock() != Blocks.BARREL) { + this.V_(); + return; + } + + boolean flag = (Boolean) iblockdata.get(BlockBarrel.b); + + if (flag) { + this.a(iblockdata, SoundEffects.BLOCK_BARREL_CLOSE); + this.a(iblockdata, false); + } + } + + } + + @Override + public void closeContainer(EntityHuman entityhuman) { + if (!entityhuman.isSpectator()) { + --this.b; + } + + } + + private void a(IBlockData iblockdata, boolean flag) { + this.world.setTypeAndData(this.getPosition(), (IBlockData) iblockdata.set(BlockBarrel.b, flag), 3); + } + + private void a(IBlockData iblockdata, SoundEffect soundeffect) { + BaseBlockPosition baseblockposition = ((EnumDirection) iblockdata.get(BlockBarrel.a)).n(); + double d0 = (double) this.position.getX() + 0.5D + (double) baseblockposition.getX() / 2.0D; + double d1 = (double) this.position.getY() + 0.5D + (double) baseblockposition.getY() / 2.0D; + double d2 = (double) this.position.getZ() + 0.5D + (double) baseblockposition.getZ() / 2.0D; + + this.world.playSound((EntityHuman) null, d0, d1, d2, soundeffect, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + } +} diff --git a/src/main/java/net/minecraft/server/TileEntityBeacon.java b/src/main/java/net/minecraft/server/TileEntityBeacon.java index 87d3a1500..e510234db 100644 --- a/src/main/java/net/minecraft/server/TileEntityBeacon.java +++ b/src/main/java/net/minecraft/server/TileEntityBeacon.java @@ -14,51 +14,29 @@ import org.bukkit.craftbukkit.potion.CraftPotionUtil; import org.bukkit.entity.HumanEntity; import org.bukkit.potion.PotionEffect; // CraftBukkit end - // Paper start import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.entity.Player; import com.destroystokyo.paper.event.block.BeaconEffectEvent; // Paper end -public class TileEntityBeacon extends TileEntityContainer implements IWorldInventory, ITickable { +public class TileEntityBeacon extends TileEntity implements ITileInventory, ITickable { - public static final MobEffectList[][] a = new MobEffectList[][] { { MobEffects.FASTER_MOVEMENT, MobEffects.FASTER_DIG}, { MobEffects.RESISTANCE, MobEffects.JUMP}, { MobEffects.INCREASE_DAMAGE}, { MobEffects.REGENERATION}}; - private static final Set e = (Set) Arrays.stream(TileEntityBeacon.a).flatMap(Arrays::stream).collect(Collectors.toSet()); - private final List f = Lists.newArrayList(); - private boolean i; - private boolean j; - public int levels = -1; + public static final MobEffectList[][] a = new MobEffectList[][]{{MobEffects.FASTER_MOVEMENT, MobEffects.FASTER_DIG}, {MobEffects.RESISTANCE, MobEffects.JUMP}, {MobEffects.INCREASE_DAMAGE}, {MobEffects.REGENERATION}}; + private static final Set b = (Set) Arrays.stream(TileEntityBeacon.a).flatMap(Arrays::stream).collect(Collectors.toSet()); + private List c = Lists.newArrayList(); + private List g = Lists.newArrayList(); + public int levels = 0; + private int i = -1; @Nullable public MobEffectList primaryEffect; @Nullable public MobEffectList secondaryEffect; - private ItemStack inventorySlot; - private IChatBaseComponent o; + @Nullable + public IChatBaseComponent customName; + public ChestLock chestLock; + private final IContainerProperties containerProperties; // CraftBukkit start - add fields and methods - public List transaction = new java.util.ArrayList(); - private int maxStack = MAX_STACK; - - public List getContents() { - return Arrays.asList(this.inventorySlot); - } - - public void onOpen(CraftHumanEntity who) { - transaction.add(who); - } - - public void onClose(CraftHumanEntity who) { - transaction.remove(who); - } - - public List getViewers() { - return transaction; - } - - public void setMaxStackSize(int size) { - maxStack = size; - } - public PotionEffect getPrimaryEffect() { return (this.primaryEffect != null) ? CraftPotionUtil.toBukkit(new MobEffect(this.primaryEffect, getLevel(), getAmplification(), true, true)) : null; } @@ -70,34 +48,171 @@ public class TileEntityBeacon extends TileEntityContainer implements IWorldInven public TileEntityBeacon() { super(TileEntityTypes.BEACON); - this.inventorySlot = ItemStack.a; + this.chestLock = ChestLock.a; + this.containerProperties = new IContainerProperties() { + @Override + public int getProperty(int i) { + switch (i) { + case 0: + return TileEntityBeacon.this.levels; + case 1: + return MobEffectList.getId(TileEntityBeacon.this.primaryEffect); + case 2: + return MobEffectList.getId(TileEntityBeacon.this.secondaryEffect); + default: + return 0; + } + } + + @Override + public void setProperty(int i, int j) { + switch (i) { + case 0: + TileEntityBeacon.this.levels = j; + break; + case 1: + if (!TileEntityBeacon.this.world.isClientSide && !TileEntityBeacon.this.c.isEmpty()) { + TileEntityBeacon.this.a(SoundEffects.BLOCK_BEACON_POWER_SELECT); + } + + TileEntityBeacon.this.primaryEffect = TileEntityBeacon.b(j); + break; + case 2: + TileEntityBeacon.this.secondaryEffect = TileEntityBeacon.b(j); + } + + } + + @Override + public int a() { + return 3; + } + }; } + @Override public void tick() { + int i = this.position.getX(); + int j = this.position.getY(); + int k = this.position.getZ(); + BlockPosition blockposition; + + if (this.i < j) { + blockposition = this.position; + this.g = Lists.newArrayList(); + this.i = blockposition.getY() - 1; + } else { + blockposition = new BlockPosition(i, this.i + 1, k); + } + + TileEntityBeacon.BeaconColorTracker tileentitybeacon_beaconcolortracker = this.g.isEmpty() ? null : (TileEntityBeacon.BeaconColorTracker) this.g.get(this.g.size() - 1); + int l = this.world.a(HeightMap.Type.WORLD_SURFACE, i, k); + + int i1; + + for (i1 = 0; i1 < 10 && blockposition.getY() <= l; ++i1) { + IBlockData iblockdata = this.world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (block instanceof IBeaconBeam) { + float[] afloat = ((IBeaconBeam) block).a().d(); + + if (this.g.size() <= 1) { + tileentitybeacon_beaconcolortracker = new TileEntityBeacon.BeaconColorTracker(afloat); + this.g.add(tileentitybeacon_beaconcolortracker); + } else if (tileentitybeacon_beaconcolortracker != null) { + if (Arrays.equals(afloat, tileentitybeacon_beaconcolortracker.a)) { + tileentitybeacon_beaconcolortracker.a(); + } else { + tileentitybeacon_beaconcolortracker = new TileEntityBeacon.BeaconColorTracker(new float[]{(tileentitybeacon_beaconcolortracker.a[0] + afloat[0]) / 2.0F, (tileentitybeacon_beaconcolortracker.a[1] + afloat[1]) / 2.0F, (tileentitybeacon_beaconcolortracker.a[2] + afloat[2]) / 2.0F}); + this.g.add(tileentitybeacon_beaconcolortracker); + } + } + } else { + if (tileentitybeacon_beaconcolortracker == null || iblockdata.b((IBlockAccess) this.world, blockposition) >= 15 && block != Blocks.BEDROCK) { + this.g.clear(); + this.i = l; + break; + } + + tileentitybeacon_beaconcolortracker.a(); + } + + blockposition = blockposition.up(); + ++this.i; + } + + i1 = this.levels; if (this.world.getTime() % 80L == 0L) { - this.p(); - if (this.i) { + if (!this.c.isEmpty()) { + this.a(i, j, k); + } + + if (this.levels > 0 && !this.c.isEmpty()) { + this.applyEffects(); this.a(SoundEffects.BLOCK_BEACON_AMBIENT); } } - if (!this.world.isClientSide && this.i != this.j) { - this.j = this.i; - this.a(this.i ? SoundEffects.BLOCK_BEACON_ACTIVATE : SoundEffects.BLOCK_BEACON_DEACTIVATE); + if (this.i >= l) { + this.i = -1; + boolean flag = i1 > 0; + + this.c = this.g; + if (!this.world.isClientSide) { + boolean flag1 = this.levels > 0; + + if (!flag && flag1) { + this.a(SoundEffects.BLOCK_BEACON_ACTIVATE); + Iterator iterator = this.world.a(EntityPlayer.class, (new AxisAlignedBB((double) i, (double) j, (double) k, (double) i, (double) (j - 4), (double) k)).grow(10.0D, 5.0D, 10.0D)).iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + CriterionTriggers.l.a(entityplayer, this); + } + } else if (flag && !flag1) { + this.a(SoundEffects.BLOCK_BEACON_DEACTIVATE); + } + } } } - public void p() { - if (this.world != null) { - this.E(); - this.applyEffects(); + private void a(int i, int j, int k) { + this.levels = 0; + + for (int l = 1; l <= 4; this.levels = l++) { + int i1 = j - l; + + if (i1 < 0) { + break; + } + + boolean flag = true; + + for (int j1 = i - l; j1 <= i + l && flag; ++j1) { + for (int k1 = k - l; k1 <= k + l; ++k1) { + Block block = this.world.getType(new BlockPosition(j1, i1, k1)).getBlock(); + + if (block != Blocks.EMERALD_BLOCK && block != Blocks.GOLD_BLOCK && block != Blocks.DIAMOND_BLOCK && block != Blocks.IRON_BLOCK) { + flag = false; + break; + } + } + } + + if (!flag) { + break; + } } } - public void a(SoundEffect soundeffect) { - this.world.a((EntityHuman) null, this.position, soundeffect, SoundCategory.BLOCKS, 1.0F, 1.0F); + @Override + public void V_() { + this.a(SoundEffects.BLOCK_BEACON_DEACTIVATE); + super.V_(); } // CraftBukkit start - split into components @@ -124,10 +239,7 @@ public class TileEntityBeacon extends TileEntityContainer implements IWorldInven { double d0 = (double) (this.levels * 10 + 10); - int j = this.position.getX(); - int k = this.position.getY(); - int l = this.position.getZ(); - AxisAlignedBB axisalignedbb = (new AxisAlignedBB((double) j, (double) k, (double) l, (double) (j + 1), (double) (k + 1), (double) (l + 1))).g(d0).b(0.0D, (double) this.world.getHeight(), 0.0D); + AxisAlignedBB axisalignedbb = (new AxisAlignedBB(this.position)).g(d0).b(0.0D, (double) this.world.getBuildHeight(), 0.0D); List list = this.world.a(EntityHuman.class, axisalignedbb); return list; @@ -147,7 +259,7 @@ public class TileEntityBeacon extends TileEntityContainer implements IWorldInven EntityHuman entityhuman; // Paper start - BeaconEffectEvent - org.bukkit.block.Block block = world.getWorld().getBlockAt(position); // Akarin + org.bukkit.block.Block block = world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()); PotionEffect effect = CraftPotionUtil.toBukkit(new MobEffect(effects, i, b0, true, true)); // Paper end @@ -175,7 +287,8 @@ public class TileEntityBeacon extends TileEntityContainer implements IWorldInven } private void applyEffects() { - if (this.i && this.levels > 0 && !this.world.isClientSide && this.primaryEffect != null) { + if (!this.world.isClientSide && this.primaryEffect != null) { + double d0 = (double) (this.levels * 10 + 10); byte b0 = getAmplification(); int i = getLevel(); @@ -191,283 +304,74 @@ public class TileEntityBeacon extends TileEntityContainer implements IWorldInven } // CraftBukkit end - private void E() { - int i = this.position.getX(); - int j = this.position.getY(); - int k = this.position.getZ(); - int l = this.levels; - - this.levels = 0; - this.f.clear(); - this.i = true; - TileEntityBeacon.BeaconColorTracker tileentitybeacon_beaconcolortracker = new TileEntityBeacon.BeaconColorTracker(EnumColor.WHITE.d()); - - this.f.add(tileentitybeacon_beaconcolortracker); - boolean flag = true; - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - - int i1; - - for (i1 = j + 1; i1 < 256; ++i1) { - IBlockData iblockdata = this.world.getType(blockposition_mutableblockposition.c(i, i1, k)); - Block block = iblockdata.getBlock(); - float[] afloat; - - if (block instanceof BlockStainedGlass) { - afloat = ((BlockStainedGlass) block).d().d(); - } else { - if (!(block instanceof BlockStainedGlassPane)) { - if (iblockdata.b(this.world, blockposition_mutableblockposition) >= 15 && block != Blocks.BEDROCK) { - this.i = false; - this.f.clear(); - break; - } - - tileentitybeacon_beaconcolortracker.a(); - continue; - } - - afloat = ((BlockStainedGlassPane) block).d().d(); - } - - if (!flag) { - afloat = new float[] { (tileentitybeacon_beaconcolortracker.b()[0] + afloat[0]) / 2.0F, (tileentitybeacon_beaconcolortracker.b()[1] + afloat[1]) / 2.0F, (tileentitybeacon_beaconcolortracker.b()[2] + afloat[2]) / 2.0F}; - } - - if (Arrays.equals(afloat, tileentitybeacon_beaconcolortracker.b())) { - tileentitybeacon_beaconcolortracker.a(); - } else { - tileentitybeacon_beaconcolortracker = new TileEntityBeacon.BeaconColorTracker(afloat); - this.f.add(tileentitybeacon_beaconcolortracker); - } - - flag = false; - } - - if (this.i) { - for (i1 = 1; i1 <= 4; this.levels = i1++) { - int j1 = j - i1; - - if (j1 < 0) { - break; - } - - boolean flag1 = true; - - for (int k1 = i - i1; k1 <= i + i1 && flag1; ++k1) { - for (int l1 = k - i1; l1 <= k + i1; ++l1) { - Block block1 = this.world.getType(new BlockPosition(k1, j1, l1)).getBlock(); - - if (block1 != Blocks.EMERALD_BLOCK && block1 != Blocks.GOLD_BLOCK && block1 != Blocks.DIAMOND_BLOCK && block1 != Blocks.IRON_BLOCK) { - flag1 = false; - break; - } - } - } - - if (!flag1) { - break; - } - } - - if (this.levels == 0) { - this.i = false; - } - } - - if (!this.world.isClientSide && l < this.levels) { - Iterator iterator = this.world.a(EntityPlayer.class, (new AxisAlignedBB((double) i, (double) j, (double) k, (double) i, (double) (j - 4), (double) k)).grow(10.0D, 5.0D, 10.0D)).iterator(); - - while (iterator.hasNext()) { - EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - - CriterionTriggers.l.a(entityplayer, this); - } - } - + public void a(SoundEffect soundeffect) { + this.world.playSound((EntityHuman) null, this.position, soundeffect, SoundCategory.BLOCKS, 1.0F, 1.0F); } - public int s() { + public int h() { return this.levels; } @Nullable + @Override public PacketPlayOutTileEntityData getUpdatePacket() { - return new PacketPlayOutTileEntityData(this.position, 3, this.aa_()); + return new PacketPlayOutTileEntityData(this.position, 3, this.b()); } - public NBTTagCompound aa_() { + @Override + public NBTTagCompound b() { return this.save(new NBTTagCompound()); } @Nullable - private static MobEffectList e(int i) { + private static MobEffectList b(int i) { MobEffectList mobeffectlist = MobEffectList.fromId(i); - return TileEntityBeacon.e.contains(mobeffectlist) ? mobeffectlist : null; + return TileEntityBeacon.b.contains(mobeffectlist) ? mobeffectlist : null; } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); // Craftbukkit start - persist manually set non-default beacon effects (SPIGOT-3598) this.primaryEffect = MobEffectList.fromId(nbttagcompound.getInt("Primary")); this.secondaryEffect = MobEffectList.fromId(nbttagcompound.getInt("Secondary")); + this.levels = nbttagcompound.getInt("Levels"); // SPIGOT-5053, use where available // Craftbukkit end - this.levels = nbttagcompound.getInt("Levels"); + if (nbttagcompound.hasKeyOfType("CustomName", 8)) { + this.customName = IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("CustomName")); + } + + this.chestLock = ChestLock.b(nbttagcompound); } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); nbttagcompound.setInt("Primary", MobEffectList.getId(this.primaryEffect)); nbttagcompound.setInt("Secondary", MobEffectList.getId(this.secondaryEffect)); nbttagcompound.setInt("Levels", this.levels); + if (this.customName != null) { + nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(this.customName)); + } + + this.chestLock.a(nbttagcompound); return nbttagcompound; } - public int getSize() { - return 1; - } - - public boolean P_() { - return this.inventorySlot.isEmpty(); - } - - public ItemStack getItem(int i) { - return i == 0 ? this.inventorySlot : ItemStack.a; - } - - public ItemStack splitStack(int i, int j) { - if (i == 0 && !this.inventorySlot.isEmpty()) { - if (j >= this.inventorySlot.getCount()) { - ItemStack itemstack = this.inventorySlot; - - this.inventorySlot = ItemStack.a; - return itemstack; - } else { - return this.inventorySlot.cloneAndSubtract(j); - } - } else { - return ItemStack.a; - } - } - - public ItemStack splitWithoutUpdate(int i) { - if (i == 0) { - ItemStack itemstack = this.inventorySlot; - - this.inventorySlot = ItemStack.a; - return itemstack; - } else { - return ItemStack.a; - } - } - - public void setItem(int i, ItemStack itemstack) { - if (i == 0) { - this.inventorySlot = itemstack; - } - - } - - public IChatBaseComponent getDisplayName() { - return (IChatBaseComponent) (this.o != null ? this.o : new ChatMessage("container.beacon", new Object[0])); - } - - public boolean hasCustomName() { - return this.o != null; + public void setCustomName(@Nullable IChatBaseComponent ichatbasecomponent) { + this.customName = ichatbasecomponent; } @Nullable - public IChatBaseComponent getCustomName() { - return this.o; + @Override + public Container createMenu(int i, PlayerInventory playerinventory, EntityHuman entityhuman) { + return TileEntityContainer.a(entityhuman, this.chestLock, this.getScoreboardDisplayName()) ? new ContainerBeacon(i, playerinventory, this.containerProperties, ContainerAccess.at(this.world, this.getPosition())) : null; } - public void setCustomName(@Nullable IChatBaseComponent ichatbasecomponent) { - this.o = ichatbasecomponent; - } - - public int getMaxStackSize() { - return 1; - } - - public boolean a(EntityHuman entityhuman) { - return this.world.getTileEntity(this.position) != this ? false : entityhuman.d((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; - } - - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - - public boolean b(int i, ItemStack itemstack) { - return itemstack.getItem() == Items.EMERALD || itemstack.getItem() == Items.DIAMOND || itemstack.getItem() == Items.GOLD_INGOT || itemstack.getItem() == Items.IRON_INGOT; - } - - public String getContainerName() { - return "minecraft:beacon"; - } - - public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { - return new ContainerBeacon(playerinventory, this); - } - - public int getProperty(int i) { - switch (i) { - case 0: - return this.levels; - case 1: - return MobEffectList.getId(this.primaryEffect); - case 2: - return MobEffectList.getId(this.secondaryEffect); - default: - return 0; - } - } - - public void setProperty(int i, int j) { - switch (i) { - case 0: - this.levels = j; - break; - case 1: - this.primaryEffect = e(j); - break; - case 2: - this.secondaryEffect = e(j); - } - - if (!this.world.isClientSide && i == 1 && this.i) { - this.a(SoundEffects.BLOCK_BEACON_POWER_SELECT); - } - - } - - public int h() { - return 3; - } - - public void clear() { - this.inventorySlot = ItemStack.a; - } - - public boolean c(int i, int j) { - if (i == 1) { - this.p(); - return true; - } else { - return super.c(i, j); - } - } - - public int[] getSlotsForFace(EnumDirection enumdirection) { - return new int[0]; - } - - public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, @Nullable EnumDirection enumdirection) { - return false; - } - - public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { - return false; + @Override + public IChatBaseComponent getScoreboardDisplayName() { + return (IChatBaseComponent) (this.customName != null ? this.customName : new ChatMessage("container.beacon", new Object[0])); } public static class BeaconColorTracker { @@ -483,9 +387,5 @@ public class TileEntityBeacon extends TileEntityContainer implements IWorldInven protected void a() { ++this.b; } - - public float[] b() { - return this.a; - } } } diff --git a/src/main/java/net/minecraft/server/TileEntityBrewingStand.java b/src/main/java/net/minecraft/server/TileEntityBrewingStand.java index 3dc9ff0cf..f96da4ee4 100644 --- a/src/main/java/net/minecraft/server/TileEntityBrewingStand.java +++ b/src/main/java/net/minecraft/server/TileEntityBrewingStand.java @@ -16,15 +16,15 @@ import org.bukkit.inventory.InventoryHolder; public class TileEntityBrewingStand extends TileEntityContainer implements IWorldInventory, ITickable { - private static final int[] a = new int[] { 3}; - private static final int[] e = new int[] { 0, 1, 2, 3}; - private static final int[] f = new int[] { 0, 1, 2, 4}; + private static final int[] b = new int[]{3}; + private static final int[] c = new int[]{0, 1, 2, 3}; + private static final int[] g = new int[]{0, 1, 2, 4}; private NonNullList items; - private int brewTime; - private boolean[] i; - private Item j; - private IChatBaseComponent k; - private int fuelLevel; + public int brewTime; + private boolean[] j; + private Item k; + public int fuelLevel; + protected final IContainerProperties a; // CraftBukkit start - add fields and methods private int lastTick = MinecraftServer.currentTick; public List transaction = new java.util.ArrayList(); @@ -46,6 +46,11 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl return this.items; } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; } @@ -54,30 +59,50 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl public TileEntityBrewingStand() { super(TileEntityTypes.BREWING_STAND); this.items = NonNullList.a(5, ItemStack.a); + this.a = new IContainerProperties() { + @Override + public int getProperty(int i) { + switch (i) { + case 0: + return TileEntityBrewingStand.this.brewTime; + case 1: + return TileEntityBrewingStand.this.fuelLevel; + default: + return 0; + } + } + + @Override + public void setProperty(int i, int j) { + switch (i) { + case 0: + TileEntityBrewingStand.this.brewTime = j; + break; + case 1: + TileEntityBrewingStand.this.fuelLevel = j; + } + + } + + @Override + public int a() { + return 2; + } + }; } - public IChatBaseComponent getDisplayName() { - return (IChatBaseComponent) (this.k != null ? this.k : new ChatMessage("container.brewing", new Object[0])); - } - - public boolean hasCustomName() { - return this.k != null; - } - - @Nullable - public IChatBaseComponent getCustomName() { - return this.k; - } - - public void setCustomName(@Nullable IChatBaseComponent ichatbasecomponent) { - this.k = ichatbasecomponent; + @Override + protected IChatBaseComponent getContainerName() { + return new ChatMessage("container.brewing", new Object[0]); } + @Override public int getSize() { return this.items.size(); } - public boolean P_() { + @Override + public boolean isNotEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -93,12 +118,13 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl return false; } + @Override public void tick() { ItemStack itemstack = (ItemStack) this.items.get(4); if (this.fuelLevel <= 0 && itemstack.getItem() == Items.BLAZE_POWDER) { // CraftBukkit start - BrewingStandFuelEvent event = new BrewingStandFuelEvent(world.getWorld().getBlockAt(position), CraftItemStack.asCraftMirror(itemstack), 20); // Akarin + BrewingStandFuelEvent event = new BrewingStandFuelEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), CraftItemStack.asCraftMirror(itemstack), 20); this.world.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -113,7 +139,7 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl this.update(); } - boolean flag = this.q(); + boolean flag = this.h(); boolean flag1 = this.brewTime > 0; ItemStack itemstack1 = (ItemStack) this.items.get(3); @@ -127,27 +153,27 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl // CraftBukkit end if (flag2 && flag) { - this.r(); + this.s(); this.update(); } else if (!flag) { this.brewTime = 0; this.update(); - } else if (this.j != itemstack1.getItem()) { + } else if (this.k != itemstack1.getItem()) { this.brewTime = 0; this.update(); } } else if (flag && this.fuelLevel > 0) { --this.fuelLevel; this.brewTime = 400; - this.j = itemstack1.getItem(); + this.k = itemstack1.getItem(); this.update(); } if (!this.world.isClientSide) { - boolean[] aboolean = this.p(); + boolean[] aboolean = this.f(); - if (!Arrays.equals(aboolean, this.i)) { - this.i = aboolean; + if (!Arrays.equals(aboolean, this.j)) { + this.j = aboolean; IBlockData iblockdata = this.world.getType(this.getPosition()); if (!(iblockdata.getBlock() instanceof BlockBrewingStand)) { @@ -164,7 +190,7 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl } - public boolean[] p() { + public boolean[] f() { boolean[] aboolean = new boolean[3]; for (int i = 0; i < 3; ++i) { @@ -176,7 +202,7 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl return aboolean; } - private boolean q() { + private boolean h() { ItemStack itemstack = (ItemStack) this.items.get(3); if (itemstack.isEmpty()) { @@ -196,12 +222,12 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl } } - private void r() { + private void s() { ItemStack itemstack = (ItemStack) this.items.get(3); // CraftBukkit start InventoryHolder owner = this.getOwner(); if (owner != null) { - BrewEvent event = new BrewEvent(world.getWorld().getBlockAt(position), (org.bukkit.inventory.BrewerInventory) owner.getInventory(), this.fuelLevel); // Akarin + BrewEvent event = new BrewEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), (org.bukkit.inventory.BrewerInventory) owner.getInventory(), this.fuelLevel); org.bukkit.Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { return; @@ -216,12 +242,12 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl itemstack.subtract(1); BlockPosition blockposition = this.getPosition(); - if (itemstack.getItem().p()) { - ItemStack itemstack1 = new ItemStack(itemstack.getItem().o()); + if (itemstack.getItem().o()) { + ItemStack itemstack1 = new ItemStack(itemstack.getItem().n()); if (itemstack.isEmpty()) { itemstack = itemstack1; - } else { + } else if (!this.world.isClientSide) { InventoryUtils.dropItem(this.world, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), itemstack1); } } @@ -230,42 +256,40 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl this.world.triggerEffect(1035, blockposition, 0); } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); this.items = NonNullList.a(this.getSize(), ItemStack.a); ContainerUtil.b(nbttagcompound, this.items); this.brewTime = nbttagcompound.getShort("BrewTime"); - if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.k = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException - } - this.fuelLevel = nbttagcompound.getByte("Fuel"); } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); nbttagcompound.setShort("BrewTime", (short) this.brewTime); ContainerUtil.a(nbttagcompound, this.items); - if (this.k != null) { - nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(this.k)); - } - nbttagcompound.setByte("Fuel", (byte) this.fuelLevel); return nbttagcompound; } + @Override public ItemStack getItem(int i) { return i >= 0 && i < this.items.size() ? (ItemStack) this.items.get(i) : ItemStack.a; } + @Override public ItemStack splitStack(int i, int j) { return ContainerUtil.a(this.items, i, j); } + @Override public ItemStack splitWithoutUpdate(int i) { return ContainerUtil.a(this.items, i); } + @Override public void setItem(int i, ItemStack itemstack) { if (i >= 0 && i < this.items.size()) { this.items.set(i, itemstack); @@ -273,18 +297,12 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl } - public int getMaxStackSize() { - return this.maxStack; // CraftBukkit - } - + @Override public boolean a(EntityHuman entityhuman) { - return this.world.getTileEntity(this.position) != this ? false : entityhuman.d((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; } - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - + @Override public boolean b(int i, ItemStack itemstack) { if (i == 3) { return PotionBrewer.a(itemstack); @@ -295,53 +313,28 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl } } + @Override public int[] getSlotsForFace(EnumDirection enumdirection) { - return enumdirection == EnumDirection.UP ? TileEntityBrewingStand.a : (enumdirection == EnumDirection.DOWN ? TileEntityBrewingStand.e : TileEntityBrewingStand.f); + return enumdirection == EnumDirection.UP ? TileEntityBrewingStand.b : (enumdirection == EnumDirection.DOWN ? TileEntityBrewingStand.c : TileEntityBrewingStand.g); } + @Override public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, @Nullable EnumDirection enumdirection) { return this.b(i, itemstack); } + @Override public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { return i == 3 ? itemstack.getItem() == Items.GLASS_BOTTLE : true; } - public String getContainerName() { - return "minecraft:brewing_stand"; - } - - public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { - return new ContainerBrewingStand(playerinventory, this); - } - - public int getProperty(int i) { - switch (i) { - case 0: - return this.brewTime; - case 1: - return this.fuelLevel; - default: - return 0; - } - } - - public void setProperty(int i, int j) { - switch (i) { - case 0: - this.brewTime = j; - break; - case 1: - this.fuelLevel = j; - } - - } - - public int h() { - return 2; - } - + @Override public void clear() { this.items.clear(); } + + @Override + protected Container createContainer(int i, PlayerInventory playerinventory) { + return new ContainerBrewingStand(i, playerinventory, this, this.a); + } } diff --git a/src/main/java/net/minecraft/server/TileEntityCampfire.java b/src/main/java/net/minecraft/server/TileEntityCampfire.java new file mode 100644 index 000000000..2317adde4 --- /dev/null +++ b/src/main/java/net/minecraft/server/TileEntityCampfire.java @@ -0,0 +1,204 @@ +package net.minecraft.server; + +import java.util.Optional; +import java.util.Random; +import javax.annotation.Nullable; +// CraftBukkit start +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockCookEvent; +// CraftBukkit end + +public class TileEntityCampfire extends TileEntity implements Clearable, ITickable { + + private final NonNullList items; + public final int[] cookingTimes; + public final int[] cookingTotalTimes; + + public TileEntityCampfire() { + super(TileEntityTypes.CAMPFIRE); + this.items = NonNullList.a(4, ItemStack.a); + this.cookingTimes = new int[4]; + this.cookingTotalTimes = new int[4]; + } + + @Override + public void tick() { + boolean flag = (Boolean) this.getBlock().get(BlockCampfire.b); + boolean flag1 = this.world.isClientSide; + + if (flag1) { + if (flag) { + this.s(); + } + + } else { + if (flag) { + this.h(); + } else { + for (int i = 0; i < this.items.size(); ++i) { + if (this.cookingTimes[i] > 0) { + this.cookingTimes[i] = MathHelper.clamp(this.cookingTimes[i] - 2, 0, this.cookingTotalTimes[i]); + } + } + } + + } + } + + private void h() { + for (int i = 0; i < this.items.size(); ++i) { + ItemStack itemstack = (ItemStack) this.items.get(i); + + if (!itemstack.isEmpty()) { + int j = this.cookingTimes[i]++; + + if (this.cookingTimes[i] >= this.cookingTotalTimes[i]) { + InventorySubcontainer inventorysubcontainer = new InventorySubcontainer(new ItemStack[]{itemstack}); + ItemStack itemstack1 = (ItemStack) this.world.getCraftingManager().craft(Recipes.CAMPFIRE_COOKING, inventorysubcontainer, this.world).map((recipecampfire) -> { + return recipecampfire.a(inventorysubcontainer); + }).orElse(itemstack); + BlockPosition blockposition = this.getPosition(); + + // CraftBukkit start - fire BlockCookEvent + CraftItemStack source = CraftItemStack.asCraftMirror(itemstack); + org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack1); + + BlockCookEvent blockCookEvent = new BlockCookEvent(CraftBlock.at(this.world, this.position), source, result); + this.world.getServer().getPluginManager().callEvent(blockCookEvent); + + if (blockCookEvent.isCancelled()) { + return; + } + + result = blockCookEvent.getResult(); + itemstack1 = CraftItemStack.asNMSCopy(result); + // CraftBukkit end + InventoryUtils.dropItem(this.world, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), itemstack1); + this.items.set(i, ItemStack.a); + this.t(); + } + } + } + + } + + private void s() { + World world = this.getWorld(); + + if (world != null) { + BlockPosition blockposition = this.getPosition(); + Random random = world.random; + int i; + + if (random.nextFloat() < 0.11F) { + for (i = 0; i < random.nextInt(2) + 2; ++i) { + BlockCampfire.a(world, blockposition, (Boolean) this.getBlock().get(BlockCampfire.c), false); + } + } + + i = ((EnumDirection) this.getBlock().get(BlockCampfire.e)).get2DRotationValue(); + + for (int j = 0; j < this.items.size(); ++j) { + if (!((ItemStack) this.items.get(j)).isEmpty() && random.nextFloat() < 0.2F) { + EnumDirection enumdirection = EnumDirection.fromType2(Math.floorMod(j + i, 4)); + float f = 0.3125F; + double d0 = (double) blockposition.getX() + 0.5D - (double) ((float) enumdirection.getAdjacentX() * 0.3125F) + (double) ((float) enumdirection.e().getAdjacentX() * 0.3125F); + double d1 = (double) blockposition.getY() + 0.5D; + double d2 = (double) blockposition.getZ() + 0.5D - (double) ((float) enumdirection.getAdjacentZ() * 0.3125F) + (double) ((float) enumdirection.e().getAdjacentZ() * 0.3125F); + + for (int k = 0; k < 4; ++k) { + world.addParticle(Particles.SMOKE, d0, d1, d2, 0.0D, 5.0E-4D, 0.0D); + } + } + } + + } + } + + public NonNullList getItems() { + return this.items; + } + + @Override + public void load(NBTTagCompound nbttagcompound) { + super.load(nbttagcompound); + this.items.clear(); + ContainerUtil.b(nbttagcompound, this.items); + int[] aint; + + if (nbttagcompound.hasKeyOfType("CookingTimes", 11)) { + aint = nbttagcompound.getIntArray("CookingTimes"); + System.arraycopy(aint, 0, this.cookingTimes, 0, Math.min(this.cookingTotalTimes.length, aint.length)); + } + + if (nbttagcompound.hasKeyOfType("CookingTotalTimes", 11)) { + aint = nbttagcompound.getIntArray("CookingTotalTimes"); + System.arraycopy(aint, 0, this.cookingTotalTimes, 0, Math.min(this.cookingTotalTimes.length, aint.length)); + } + + } + + @Override + public NBTTagCompound save(NBTTagCompound nbttagcompound) { + this.d(nbttagcompound); + nbttagcompound.setIntArray("CookingTimes", this.cookingTimes); + nbttagcompound.setIntArray("CookingTotalTimes", this.cookingTotalTimes); + return nbttagcompound; + } + + private NBTTagCompound d(NBTTagCompound nbttagcompound) { + super.save(nbttagcompound); + ContainerUtil.a(nbttagcompound, this.items, true); + return nbttagcompound; + } + + @Nullable + @Override + public PacketPlayOutTileEntityData getUpdatePacket() { + return new PacketPlayOutTileEntityData(this.position, 13, this.b()); + } + + @Override + public NBTTagCompound b() { + return this.d(new NBTTagCompound()); + } + + public Optional a(ItemStack itemstack) { + return this.items.stream().noneMatch(ItemStack::isEmpty) ? Optional.empty() : this.world.getCraftingManager().craft(Recipes.CAMPFIRE_COOKING, new InventorySubcontainer(new ItemStack[]{itemstack}), this.world); + } + + public boolean a(ItemStack itemstack, int i) { + for (int j = 0; j < this.items.size(); ++j) { + ItemStack itemstack1 = (ItemStack) this.items.get(j); + + if (itemstack1.isEmpty()) { + this.cookingTotalTimes[j] = i; + this.cookingTimes[j] = 0; + this.items.set(j, itemstack.cloneAndSubtract(1)); + this.t(); + return true; + } + } + + return false; + } + + private void t() { + this.update(); + this.getWorld().notify(this.getPosition(), this.getBlock(), this.getBlock(), 3); + } + + @Override + public void clear() { + this.items.clear(); + } + + public void f() { + if (!this.getWorld().isClientSide) { + InventoryUtils.a(this.getWorld(), this.getPosition(), this.getItems()); + } + + this.t(); + } +} diff --git a/src/main/java/net/minecraft/server/TileEntityChest.java b/src/main/java/net/minecraft/server/TileEntityChest.java index 77c012946..4aa56e50e 100644 --- a/src/main/java/net/minecraft/server/TileEntityChest.java +++ b/src/main/java/net/minecraft/server/TileEntityChest.java @@ -11,9 +11,9 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic private NonNullList items; protected float a; - protected float e; - protected int f; - private int k; + protected float b; + protected int viewingCount; + private int j; // CraftBukkit start - add fields and methods public List transaction = new java.util.ArrayList(); @@ -35,6 +35,11 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic return transaction; } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; } @@ -49,11 +54,13 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic this(TileEntityTypes.CHEST); } + @Override public int getSize() { return 27; } - public boolean P_() { + @Override + public boolean isNotEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -69,12 +76,12 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic return false; } - public IChatBaseComponent getDisplayName() { - IChatBaseComponent ichatbasecomponent = this.getCustomName(); - - return (IChatBaseComponent) (ichatbasecomponent != null ? ichatbasecomponent : new ChatMessage("container.chest", new Object[0])); + @Override + protected IChatBaseComponent getContainerName() { + return new ChatMessage("container.chest", new Object[0]); } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); this.items = NonNullList.a(this.getSize(), ItemStack.a); @@ -82,78 +89,46 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic ContainerUtil.b(nbttagcompound, this.items); } - if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.i = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException - } - } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); if (!this.e(nbttagcompound)) { ContainerUtil.a(nbttagcompound, this.items); } - IChatBaseComponent ichatbasecomponent = this.getCustomName(); - - if (ichatbasecomponent != null) { - nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(ichatbasecomponent)); - } - return nbttagcompound; } - public int getMaxStackSize() { - return maxStack; // CraftBukkit - } - public void tick() { int i = this.position.getX(); int j = this.position.getY(); int k = this.position.getZ(); - ++this.k; - // Paper start + ++this.j; } - private void doOpenLogic() { - float f; + + public void doOpenLogic() { int i = this.position.getX(); int j = this.position.getY(); int k = this.position.getZ(); - if (false && !this.world.isClientSide && this.f != 0 && (this.k + i + j + k) % 200 == 0) { // Paper - disable block - // Paper end - this.f = 0; - f = 5.0F; - List list = this.world.a(EntityHuman.class, new AxisAlignedBB((double) ((float) i - 5.0F), (double) ((float) j - 5.0F), (double) ((float) k - 5.0F), (double) ((float) (i + 1) + 5.0F), (double) ((float) (j + 1) + 5.0F), (double) ((float) (k + 1) + 5.0F))); - Iterator iterator = list.iterator(); - while (iterator.hasNext()) { - EntityHuman entityhuman = (EntityHuman) iterator.next(); + //this.viewingCount = a(this.world, this, this.j, i, j, k, this.viewingCount); // Paper - check is faulty given our logic is called before active container set + this.b = this.a; + float f = 0.1F; - if (entityhuman.activeContainer instanceof ContainerChest) { - IInventory iinventory = ((ContainerChest) entityhuman.activeContainer).d(); - - if (iinventory == this || iinventory instanceof InventoryLargeChest && ((InventoryLargeChest) iinventory).a((IInventory) this)) { - ++this.f; - } - } - } - } - - if (this.f == 1 && this.a == 0.0F) { // check == 1 instead of > 0, first open + if (this.viewingCount > 0 && this.a == 0.0F) { this.a(SoundEffects.BLOCK_CHEST_OPEN); } - // Paper start } - private void doCloseLogic() { - this.e = this.a; - // Paper end - if (this.f == 0/* && this.a > 0.0F || this.f > 0 && this.a < 1.0F*/) { // Paper disable all but player count check - /* // Paper disable animation stuff + public void doCloseLogic() { + if (this.viewingCount == 0 /* && this.a > 0.0F || this.viewingCount > 0 && this.a < 1.0F */) { // Paper - disable all but player count check + /* // Paper - disable animation stuff float f1 = this.a; - if (this.f > 0) { + if (this.viewingCount > 0) { this.a += 0.1F; } else { this.a -= 0.1F; @@ -165,14 +140,12 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic float f2 = 0.5F; - if (this.a < 0.5F && f1 >= 0.5F) { - */ - // add some delay - MCUtil.scheduleTask(10, () -> { - if (this.f == 0) this.a(SoundEffects.BLOCK_CHEST_CLOSE); + */ + MCUtil.scheduleTask(10, () -> { + this.a(SoundEffects.BLOCK_CHEST_CLOSE); }); - // } // Paper end + //} // Paper end if (this.a < 0.0F) { this.a = 0.0F; @@ -181,7 +154,37 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic } + public static int a(World world, TileEntityContainer tileentitycontainer, int i, int j, int k, int l, int i1) { + if (!world.isClientSide && i1 != 0 && (i + j + k + l) % 200 == 0) { + i1 = a(world, tileentitycontainer, j, k, l); + } + + return i1; + } + + public static int a(World world, TileEntityContainer tileentitycontainer, int i, int j, int k) { + int l = 0; + float f = 5.0F; + List list = world.a(EntityHuman.class, new AxisAlignedBB((double) ((float) i - 5.0F), (double) ((float) j - 5.0F), (double) ((float) k - 5.0F), (double) ((float) (i + 1) + 5.0F), (double) ((float) (j + 1) + 5.0F), (double) ((float) (k + 1) + 5.0F))); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + if (entityhuman.activeContainer instanceof ContainerChest) { + IInventory iinventory = ((ContainerChest) entityhuman.activeContainer).e(); + + if (iinventory == tileentitycontainer || iinventory instanceof InventoryLargeChest && ((InventoryLargeChest) iinventory).a((IInventory) tileentitycontainer)) { + ++l; + } + } + } + + return l; + } + private void a(SoundEffect soundeffect) { + if (!this.getBlock().hasProperty(BlockChest.b)) { return; } // Paper - this can be delayed, double check exists - Fixes GH-2074 BlockPropertyChestType blockpropertychesttype = (BlockPropertyChestType) this.getBlock().get(BlockChest.b); if (blockpropertychesttype != BlockPropertyChestType.LEFT) { @@ -190,93 +193,89 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic double d2 = (double) this.position.getZ() + 0.5D; if (blockpropertychesttype == BlockPropertyChestType.RIGHT) { - EnumDirection enumdirection = BlockChest.k(this.getBlock()); + EnumDirection enumdirection = BlockChest.j(this.getBlock()); d0 += (double) enumdirection.getAdjacentX() * 0.5D; d2 += (double) enumdirection.getAdjacentZ() * 0.5D; } - this.world.a((EntityHuman) null, d0, d1, d2, soundeffect, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + this.world.playSound((EntityHuman) null, d0, d1, d2, soundeffect, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); } } - public boolean c(int i, int j) { + @Override + public boolean setProperty(int i, int j) { if (i == 1) { - this.f = j; + this.viewingCount = j; return true; } else { - return super.c(i, j); + return super.setProperty(i, j); } } + @Override public void startOpen(EntityHuman entityhuman) { if (!entityhuman.isSpectator()) { - if (this.f < 0) { - this.f = 0; + if (this.viewingCount < 0) { + this.viewingCount = 0; } - int oldPower = Math.max(0, Math.min(15, this.f)); // CraftBukkit - Get power before new viewer is added + int oldPower = Math.max(0, Math.min(15, this.viewingCount)); // CraftBukkit - Get power before new viewer is added - ++this.f; + ++this.viewingCount; if (this.world == null) return; // CraftBukkit doOpenLogic(); // Paper // CraftBukkit start - Call redstone event - if (this.getBlock() == Blocks.TRAPPED_CHEST) { - int newPower = Math.max(0, Math.min(15, this.f)); + if (this.getBlock().getBlock() == Blocks.TRAPPED_CHEST) { + int newPower = Math.max(0, Math.min(15, this.viewingCount)); if (oldPower != newPower) { org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, position, oldPower, newPower); } } // CraftBukkit end - this.p(); + this.onOpen(); } } + @Override public void closeContainer(EntityHuman entityhuman) { if (!entityhuman.isSpectator()) { - int oldPower = Math.max(0, Math.min(15, this.f)); // CraftBukkit - Get power before new viewer is added - --this.f; + int oldPower = Math.max(0, Math.min(15, this.viewingCount)); // CraftBukkit - Get power before new viewer is added + --this.viewingCount; // CraftBukkit start - Call redstone event doCloseLogic(); // Paper - if (this.getBlock() == Blocks.TRAPPED_CHEST) { - int newPower = Math.max(0, Math.min(15, this.f)); + if (this.getBlock().getBlock() == Blocks.TRAPPED_CHEST) { + int newPower = Math.max(0, Math.min(15, this.viewingCount)); if (oldPower != newPower) { org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, position, oldPower, newPower); } } // CraftBukkit end - this.p(); + this.onOpen(); } } - protected void p() { + protected void onOpen() { Block block = this.getBlock().getBlock(); if (block instanceof BlockChest) { - this.world.playBlockAction(this.position, block, 1, this.f); + this.world.playBlockAction(this.position, block, 1, this.viewingCount); this.world.applyPhysics(this.position, block); } } - public String getContainerName() { - return "minecraft:chest"; - } - - public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { - this.d(entityhuman); - return new ContainerChest(playerinventory, this, entityhuman); - } - - protected NonNullList q() { + @Override + protected NonNullList f() { return this.items; } + @Override protected void a(NonNullList nonnulllist) { this.items = nonnulllist; } @@ -288,7 +287,7 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic TileEntity tileentity = iblockaccess.getTileEntity(blockposition); if (tileentity instanceof TileEntityChest) { - return ((TileEntityChest) tileentity).f; + return ((TileEntityChest) tileentity).viewingCount; } } @@ -296,12 +295,17 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic } public static void a(TileEntityChest tileentitychest, TileEntityChest tileentitychest1) { - NonNullList nonnulllist = tileentitychest.q(); + NonNullList nonnulllist = tileentitychest.f(); - tileentitychest.a(tileentitychest1.q()); + tileentitychest.a(tileentitychest1.f()); tileentitychest1.a(nonnulllist); } + @Override + protected Container createContainer(int i, PlayerInventory playerinventory) { + return ContainerChest.a(i, playerinventory, this); + } + // CraftBukkit start @Override public boolean isFilteredNBT() { diff --git a/src/main/java/net/minecraft/server/TileEntityCommand.java b/src/main/java/net/minecraft/server/TileEntityCommand.java index f94978117..22e5828d5 100644 --- a/src/main/java/net/minecraft/server/TileEntityCommand.java +++ b/src/main/java/net/minecraft/server/TileEntityCommand.java @@ -5,8 +5,8 @@ import javax.annotation.Nullable; public class TileEntityCommand extends TileEntity { private boolean a; - private boolean e; - private boolean f; + private boolean b; + private boolean c; private boolean g; private final CommandBlockListenerAbstract h = new CommandBlockListenerAbstract() { // CraftBukkit start @@ -16,21 +16,25 @@ public class TileEntityCommand extends TileEntity { } // CraftBukkit end + @Override public void setCommand(String s) { super.setCommand(s); TileEntityCommand.this.update(); } + @Override public WorldServer d() { return (WorldServer) TileEntityCommand.this.world; } + @Override public void e() { IBlockData iblockdata = TileEntityCommand.this.world.getType(TileEntityCommand.this.position); this.d().notify(TileEntityCommand.this.position, iblockdata, iblockdata, 3); } + @Override public CommandListenerWrapper getWrapper() { return new CommandListenerWrapper(this, new Vec3D((double) TileEntityCommand.this.position.getX() + 0.5D, (double) TileEntityCommand.this.position.getY() + 0.5D, (double) TileEntityCommand.this.position.getZ() + 0.5D), Vec2F.a, this.d(), 2, this.getName().getString(), this.getName(), this.d().getMinecraftServer(), (Entity) null); } @@ -40,26 +44,29 @@ public class TileEntityCommand extends TileEntity { super(TileEntityTypes.COMMAND_BLOCK); } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); this.h.a(nbttagcompound); - nbttagcompound.setBoolean("powered", this.d()); - nbttagcompound.setBoolean("conditionMet", this.f()); - nbttagcompound.setBoolean("auto", this.e()); + nbttagcompound.setBoolean("powered", this.f()); + nbttagcompound.setBoolean("conditionMet", this.h()); + nbttagcompound.setBoolean("auto", this.g()); return nbttagcompound; } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); this.h.b(nbttagcompound); this.a = nbttagcompound.getBoolean("powered"); - this.f = nbttagcompound.getBoolean("conditionMet"); + this.c = nbttagcompound.getBoolean("conditionMet"); this.b(nbttagcompound.getBoolean("auto")); } @Nullable + @Override public PacketPlayOutTileEntityData getUpdatePacket() { - if (this.i()) { + if (this.t()) { this.c(false); NBTTagCompound nbttagcompound = this.save(new NBTTagCompound()); @@ -69,6 +76,7 @@ public class TileEntityCommand extends TileEntity { } } + @Override public boolean isFilteredNBT() { return true; } @@ -81,51 +89,51 @@ public class TileEntityCommand extends TileEntity { this.a = flag; } - public boolean d() { + public boolean f() { return this.a; } - public boolean e() { - return this.e; + public boolean g() { + return this.b; } public void b(boolean flag) { - boolean flag1 = this.e; + boolean flag1 = this.b; - this.e = flag; - if (!flag1 && flag && !this.a && this.world != null && this.j() != TileEntityCommand.Type.SEQUENCE) { + this.b = flag; + if (!flag1 && flag && !this.a && this.world != null && this.u() != TileEntityCommand.Type.SEQUENCE) { Block block = this.getBlock().getBlock(); if (block instanceof BlockCommand) { - this.h(); + this.s(); this.world.getBlockTickList().a(this.position, block, block.a((IWorldReader) this.world)); } } } - public boolean f() { - return this.f; + public boolean h() { + return this.c; } - public boolean h() { - this.f = true; - if (this.k()) { + public boolean s() { + this.c = true; + if (this.v()) { BlockPosition blockposition = this.position.shift(((EnumDirection) this.world.getType(this.position).get(BlockCommand.a)).opposite()); if (this.world.getType(blockposition).getBlock() instanceof BlockCommand) { TileEntity tileentity = this.world.getTileEntity(blockposition); - this.f = tileentity instanceof TileEntityCommand && ((TileEntityCommand) tileentity).getCommandBlock().i() > 0; + this.c = tileentity instanceof TileEntityCommand && ((TileEntityCommand) tileentity).getCommandBlock().i() > 0; } else { - this.f = false; + this.c = false; } } - return this.f; + return this.c; } - public boolean i() { + public boolean t() { return this.g; } @@ -133,21 +141,22 @@ public class TileEntityCommand extends TileEntity { this.g = flag; } - public TileEntityCommand.Type j() { + public TileEntityCommand.Type u() { Block block = this.getBlock().getBlock(); return block == Blocks.COMMAND_BLOCK ? TileEntityCommand.Type.REDSTONE : (block == Blocks.REPEATING_COMMAND_BLOCK ? TileEntityCommand.Type.AUTO : (block == Blocks.CHAIN_COMMAND_BLOCK ? TileEntityCommand.Type.SEQUENCE : TileEntityCommand.Type.REDSTONE)); } - public boolean k() { + public boolean v() { IBlockData iblockdata = this.world.getType(this.getPosition()); return iblockdata.getBlock() instanceof BlockCommand ? (Boolean) iblockdata.get(BlockCommand.b) : false; } - public void z() { + @Override + public void n() { this.invalidateBlockCache(); - super.z(); + super.n(); } public static enum Type { diff --git a/src/main/java/net/minecraft/server/TileEntityConduit.java b/src/main/java/net/minecraft/server/TileEntityConduit.java index 1f9ee125c..d5011ec9b 100644 --- a/src/main/java/net/minecraft/server/TileEntityConduit.java +++ b/src/main/java/net/minecraft/server/TileEntityConduit.java @@ -13,13 +13,15 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; public class TileEntityConduit extends TileEntity implements ITickable { - private static final Block[] e = new Block[] { Blocks.PRISMARINE, Blocks.PRISMARINE_BRICKS, Blocks.SEA_LANTERN, Blocks.DARK_PRISMARINE}; + private static final Block[] b = new Block[]{Blocks.PRISMARINE, Blocks.PRISMARINE_BRICKS, Blocks.SEA_LANTERN, Blocks.DARK_PRISMARINE}; public int a; - private float f; + private float c; private boolean g; private boolean h; private final List i; + @Nullable private EntityLiving target; + @Nullable private UUID k; private long l; @@ -32,6 +34,7 @@ public class TileEntityConduit extends TileEntity implements ITickable { this.i = Lists.newArrayList(); } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); if (nbttagcompound.hasKey("target_uuid")) { @@ -42,6 +45,7 @@ public class TileEntityConduit extends TileEntity implements ITickable { } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); if (this.target != null) { @@ -52,46 +56,49 @@ public class TileEntityConduit extends TileEntity implements ITickable { } @Nullable + @Override public PacketPlayOutTileEntityData getUpdatePacket() { - return new PacketPlayOutTileEntityData(this.position, 5, this.aa_()); + return new PacketPlayOutTileEntityData(this.position, 5, this.b()); } - public NBTTagCompound aa_() { + @Override + public NBTTagCompound b() { return this.save(new NBTTagCompound()); } + @Override public void tick() { ++this.a; long i = this.world.getTime(); if (i % 40L == 0L) { - this.a(this.f()); - if (!this.world.isClientSide && this.c()) { - this.h(); - this.i(); + this.a(this.h()); + if (!this.world.isClientSide && this.d()) { + this.s(); + this.t(); } } - if (i % 80L == 0L && this.c()) { + if (i % 80L == 0L && this.d()) { this.a(SoundEffects.BLOCK_CONDUIT_AMBIENT); } - if (i > this.l && this.c()) { - this.l = i + 60L + (long) this.world.m().nextInt(40); + if (i > this.l && this.d()) { + this.l = i + 60L + (long) this.world.getRandom().nextInt(40); this.a(SoundEffects.BLOCK_CONDUIT_AMBIENT_SHORT); } if (this.world.isClientSide) { - this.j(); - this.m(); - if (this.c()) { - ++this.f; + this.u(); + this.y(); + if (this.d()) { + ++this.c; } } } - private boolean f() { + private boolean h() { this.i.clear(); int i; @@ -101,9 +108,9 @@ public class TileEntityConduit extends TileEntity implements ITickable { for (i = -1; i <= 1; ++i) { for (j = -1; j <= 1; ++j) { for (k = -1; k <= 1; ++k) { - BlockPosition blockposition = this.position.a(i, j, k); + BlockPosition blockposition = this.position.b(i, j, k); - if (!this.world.B(blockposition)) { + if (!this.world.x(blockposition)) { return false; } } @@ -118,9 +125,9 @@ public class TileEntityConduit extends TileEntity implements ITickable { int j1 = Math.abs(k); if ((l > 1 || i1 > 1 || j1 > 1) && (i == 0 && (i1 == 2 || j1 == 2) || j == 0 && (l == 2 || j1 == 2) || k == 0 && (l == 2 || i1 == 2))) { - BlockPosition blockposition1 = this.position.a(i, j, k); + BlockPosition blockposition1 = this.position.b(i, j, k); IBlockData iblockdata = this.world.getType(blockposition1); - Block[] ablock = TileEntityConduit.e; + Block[] ablock = TileEntityConduit.b; int k1 = ablock.length; for (int l1 = 0; l1 < k1; ++l1) { @@ -139,13 +146,13 @@ public class TileEntityConduit extends TileEntity implements ITickable { return this.i.size() >= 16; } - private void h() { + private void s() { int i = this.i.size(); int j = i / 7 * 16; int k = this.position.getX(); int l = this.position.getY(); int i1 = this.position.getZ(); - AxisAlignedBB axisalignedbb = (new AxisAlignedBB((double) k, (double) l, (double) i1, (double) (k + 1), (double) (l + 1), (double) (i1 + 1))).g((double) j).b(0.0D, (double) this.world.getHeight(), 0.0D); + AxisAlignedBB axisalignedbb = (new AxisAlignedBB((double) k, (double) l, (double) i1, (double) (k + 1), (double) (l + 1), (double) (i1 + 1))).g((double) j).b(0.0D, (double) this.world.getBuildHeight(), 0.0D); List list = this.world.a(EntityHuman.class, axisalignedbb); if (!list.isEmpty()) { @@ -154,7 +161,7 @@ public class TileEntityConduit extends TileEntity implements ITickable { while (iterator.hasNext()) { EntityHuman entityhuman = (EntityHuman) iterator.next(); - if (this.position.m(new BlockPosition(entityhuman)) <= (double) j && entityhuman.ao()) { + if (this.position.a((BaseBlockPosition) (new BlockPosition(entityhuman)), (double) j) && entityhuman.isInWaterOrRain()) { entityhuman.addEffect(new MobEffect(MobEffects.CONDUIT_POWER, 260, 0, true, true), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONDUIT); // CraftBukkit } } @@ -162,24 +169,24 @@ public class TileEntityConduit extends TileEntity implements ITickable { } } - private void i() { + private void t() { EntityLiving entityliving = this.target; int i = this.i.size(); if (i < 42) { this.target = null; } else if (this.target == null && this.k != null) { - this.target = this.l(); + this.target = this.x(); this.k = null; } else if (this.target == null) { - List list = this.world.a(EntityLiving.class, this.k(), (java.util.function.Predicate) (entityliving1) -> { // CraftBukkit - decompile error - return entityliving1 instanceof IMonster && entityliving1.ao(); + List list = this.world.a(EntityLiving.class, this.v(), (java.util.function.Predicate) (entityliving1) -> { // CraftBukkit - decompile error + return entityliving1 instanceof IMonster && entityliving1.isInWaterOrRain(); }); if (!list.isEmpty()) { this.target = (EntityLiving) list.get(this.world.random.nextInt(list.size())); } - } else if (!this.target.isAlive() || this.position.m(new BlockPosition(this.target)) > 8.0D) { + } else if (!this.target.isAlive() || !this.position.a((BaseBlockPosition) (new BlockPosition(this.target)), 8.0D)) { this.target = null; } @@ -187,7 +194,7 @@ public class TileEntityConduit extends TileEntity implements ITickable { // CraftBukkit start CraftEventFactory.blockDamage = CraftBlock.at(this.world, this.position); if (this.target.damageEntity(DamageSource.MAGIC, 4.0F)) { - this.world.a((EntityHuman) null, this.target.locX, this.target.locY, this.target.locZ, SoundEffects.BLOCK_CONDUIT_ATTACK_TARGET, SoundCategory.BLOCKS, 1.0F, 1.0F); + this.world.playSound((EntityHuman) null, this.target.locX, this.target.locY, this.target.locZ, SoundEffects.BLOCK_CONDUIT_ATTACK_TARGET, SoundCategory.BLOCKS, 1.0F, 1.0F); } CraftEventFactory.blockDamage = null; // CraftBukkit end @@ -201,11 +208,11 @@ public class TileEntityConduit extends TileEntity implements ITickable { } - private void j() { + private void u() { if (this.k == null) { this.target = null; } else if (this.target == null || !this.target.getUniqueID().equals(this.k)) { - this.target = this.l(); + this.target = this.x(); if (this.target == null) { this.k = null; } @@ -213,7 +220,7 @@ public class TileEntityConduit extends TileEntity implements ITickable { } - private AxisAlignedBB k() { + private AxisAlignedBB v() { int i = this.position.getX(); int j = this.position.getY(); int k = this.position.getZ(); @@ -222,15 +229,15 @@ public class TileEntityConduit extends TileEntity implements ITickable { } @Nullable - private EntityLiving l() { - List list = this.world.a(EntityLiving.class, this.k(), (java.util.function.Predicate) (entityliving) -> { // CraftBukkit - decompile error + private EntityLiving x() { + List list = this.world.a(EntityLiving.class, this.v(), (java.util.function.Predicate) (entityliving) -> { // CraftBukkit - decompile error return entityliving.getUniqueID().equals(this.k); }); return list.size() == 1 ? (EntityLiving) list.get(0) : null; } - private void m() { + private void y() { Random random = this.world.random; float f = MathHelper.sin((float) (this.a + 35) * 0.1F) / 2.0F + 0.5F; @@ -251,24 +258,24 @@ public class TileEntityConduit extends TileEntity implements ITickable { BlockPosition blockposition1 = blockposition.b(this.position); Vec3D vec3d1 = (new Vec3D((double) f1, (double) f2, (double) f3)).add((double) blockposition1.getX(), (double) blockposition1.getY(), (double) blockposition1.getZ()); - this.world.addParticle(Particles.W, vec3d.x, vec3d.y, vec3d.z, vec3d1.x, vec3d1.y, vec3d1.z); + this.world.addParticle(Particles.NAUTILUS, vec3d.x, vec3d.y, vec3d.z, vec3d1.x, vec3d1.y, vec3d1.z); } } if (this.target != null) { Vec3D vec3d2 = new Vec3D(this.target.locX, this.target.locY + (double) this.target.getHeadHeight(), this.target.locZ); - float f4 = (-0.5F + random.nextFloat()) * (3.0F + this.target.width); + float f4 = (-0.5F + random.nextFloat()) * (3.0F + this.target.getWidth()); - f1 = -1.0F + random.nextFloat() * this.target.length; - f2 = (-0.5F + random.nextFloat()) * (3.0F + this.target.width); + f1 = -1.0F + random.nextFloat() * this.target.getHeight(); + f2 = (-0.5F + random.nextFloat()) * (3.0F + this.target.getWidth()); Vec3D vec3d3 = new Vec3D((double) f4, (double) f1, (double) f2); - this.world.addParticle(Particles.W, vec3d2.x, vec3d2.y, vec3d2.z, vec3d3.x, vec3d3.y, vec3d3.z); + this.world.addParticle(Particles.NAUTILUS, vec3d2.x, vec3d2.y, vec3d2.z, vec3d3.x, vec3d3.y, vec3d3.z); } } - public boolean c() { + public boolean d() { return this.g; } @@ -285,6 +292,6 @@ public class TileEntityConduit extends TileEntity implements ITickable { } public void a(SoundEffect soundeffect) { - this.world.a((EntityHuman) null, this.position, soundeffect, SoundCategory.BLOCKS, 1.0F, 1.0F); + this.world.playSound((EntityHuman) null, this.position, soundeffect, SoundCategory.BLOCKS, 1.0F, 1.0F); } } diff --git a/src/main/java/net/minecraft/server/TileEntityContainer.java b/src/main/java/net/minecraft/server/TileEntityContainer.java index cff9f1a24..ab6b86e4e 100644 --- a/src/main/java/net/minecraft/server/TileEntityContainer.java +++ b/src/main/java/net/minecraft/server/TileEntityContainer.java @@ -1,40 +1,82 @@ package net.minecraft.server; -public abstract class TileEntityContainer extends TileEntity implements ITileInventory { +import javax.annotation.Nullable; - private ChestLock a; +public abstract class TileEntityContainer extends TileEntity implements IInventory, ITileInventory, INamableTileEntity { + + public ChestLock chestLock; + public IChatBaseComponent customName; protected TileEntityContainer(TileEntityTypes tileentitytypes) { super(tileentitytypes); - this.a = ChestLock.a; + this.chestLock = ChestLock.a; } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); - this.a = ChestLock.b(nbttagcompound); + this.chestLock = ChestLock.b(nbttagcompound); + if (nbttagcompound.hasKeyOfType("CustomName", 8)) { + this.customName = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException + } + } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); - if (this.a != null) { - this.a.a(nbttagcompound); + this.chestLock.a(nbttagcompound); + if (this.customName != null) { + nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(this.customName)); } return nbttagcompound; } - public boolean isLocked() { - return this.a != null && !this.a.a(); + public void setCustomName(IChatBaseComponent ichatbasecomponent) { + this.customName = ichatbasecomponent; } - public ChestLock getLock() { - return this.a; + @Override + public IChatBaseComponent getDisplayName() { + return this.customName != null ? this.customName : this.getContainerName(); } - public void setLock(ChestLock chestlock) { - this.a = chestlock; + @Override + public IChatBaseComponent getScoreboardDisplayName() { + return this.getDisplayName(); } + @Nullable + @Override + public IChatBaseComponent getCustomName() { + return this.customName; + } + + protected abstract IChatBaseComponent getContainerName(); + + public boolean e(EntityHuman entityhuman) { + return a(entityhuman, this.chestLock, this.getScoreboardDisplayName()); + } + + public static boolean a(EntityHuman entityhuman, ChestLock chestlock, IChatBaseComponent ichatbasecomponent) { + if (!entityhuman.isSpectator() && !chestlock.a(entityhuman.getItemInMainHand())) { + entityhuman.a((IChatBaseComponent) (new ChatMessage("container.isLocked", new Object[]{ichatbasecomponent})), true); + entityhuman.a(SoundEffects.BLOCK_CHEST_LOCKED, SoundCategory.BLOCKS, 1.0F, 1.0F); + return false; + } else { + return true; + } + } + + @Nullable + @Override + public Container createMenu(int i, PlayerInventory playerinventory, EntityHuman entityhuman) { + return this.e(entityhuman) ? this.createContainer(i, playerinventory) : null; + } + + protected abstract Container createContainer(int i, PlayerInventory playerinventory); + // CraftBukkit start @Override public org.bukkit.Location getLocation() { diff --git a/src/main/java/net/minecraft/server/TileEntityDispenser.java b/src/main/java/net/minecraft/server/TileEntityDispenser.java index 21bd156e9..37a5bde68 100644 --- a/src/main/java/net/minecraft/server/TileEntityDispenser.java +++ b/src/main/java/net/minecraft/server/TileEntityDispenser.java @@ -34,6 +34,11 @@ public class TileEntityDispenser extends TileEntityLootable { return transaction; } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; } @@ -48,11 +53,13 @@ public class TileEntityDispenser extends TileEntityLootable { this(TileEntityTypes.DISPENSER); } + @Override public int getSize() { return 9; } - public boolean P_() { + @Override + public boolean isNotEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -68,7 +75,7 @@ public class TileEntityDispenser extends TileEntityLootable { return false; } - public int p() { + public int h() { this.d((EntityHuman) null); int i = -1; int j = 1; @@ -93,12 +100,12 @@ public class TileEntityDispenser extends TileEntityLootable { return -1; } - public IChatBaseComponent getDisplayName() { - IChatBaseComponent ichatbasecomponent = this.getCustomName(); - - return (IChatBaseComponent) (ichatbasecomponent != null ? ichatbasecomponent : new ChatMessage("container.dispenser", new Object[0])); + @Override + protected IChatBaseComponent getContainerName() { + return new ChatMessage("container.dispenser", new Object[0]); } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); this.items = NonNullList.a(this.getSize(), ItemStack.a); @@ -106,45 +113,30 @@ public class TileEntityDispenser extends TileEntityLootable { ContainerUtil.b(nbttagcompound, this.items); } - if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.i = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException - } - } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); if (!this.e(nbttagcompound)) { ContainerUtil.a(nbttagcompound, this.items); } - IChatBaseComponent ichatbasecomponent = this.getCustomName(); - - if (ichatbasecomponent != null) { - nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(ichatbasecomponent)); - } - return nbttagcompound; } - public int getMaxStackSize() { - return maxStack; // CraftBukkit - } - - public String getContainerName() { - return "minecraft:dispenser"; - } - - public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { - this.d(entityhuman); - return new ContainerDispenser(playerinventory, this); - } - - protected NonNullList q() { + @Override + protected NonNullList f() { return this.items; } + @Override protected void a(NonNullList nonnulllist) { this.items = nonnulllist; } + + @Override + protected Container createContainer(int i, PlayerInventory playerinventory) { + return new ContainerDispenser(i, playerinventory, this); + } } diff --git a/src/main/java/net/minecraft/server/TileEntityEndGateway.java b/src/main/java/net/minecraft/server/TileEntityEndGateway.java index 2af225021..15dccc905 100644 --- a/src/main/java/net/minecraft/server/TileEntityEndGateway.java +++ b/src/main/java/net/minecraft/server/TileEntityEndGateway.java @@ -15,9 +15,9 @@ import org.bukkit.event.player.PlayerTeleportEvent; public class TileEntityEndGateway extends TileEntityEnderPortal implements ITickable { - private static final Logger a = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); public long age; - private int f; + private int c; public BlockPosition exitPortal; public boolean exactTeleport; @@ -25,6 +25,7 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick super(TileEntityTypes.END_GATEWAY); } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); nbttagcompound.setLong("Age", this.age); @@ -39,6 +40,7 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick return nbttagcompound; } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); this.age = nbttagcompound.getLong("Age"); @@ -49,13 +51,14 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick this.exactTeleport = nbttagcompound.getBoolean("ExactTeleport"); } + @Override public void tick() { - boolean flag = this.c(); - boolean flag1 = this.d(); + boolean flag = this.d(); + boolean flag1 = this.f(); ++this.age; if (flag1) { - --this.f; + --this.c; } else if (!this.world.isClientSide) { List list = this.world.a(Entity.class, new AxisAlignedBB(this.getPosition())); @@ -64,60 +67,63 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick } if (this.age % 2400L == 0L) { - this.f(); + this.h(); } } - if (flag != this.c() || flag1 != this.d()) { + if (flag != this.d() || flag1 != this.f()) { this.update(); } } - public boolean c() { + public boolean d() { return this.age < 200L; } - public boolean d() { - return this.f > 0; + public boolean f() { + return this.c > 0; } @Nullable + @Override public PacketPlayOutTileEntityData getUpdatePacket() { - return new PacketPlayOutTileEntityData(this.position, 8, this.aa_()); + return new PacketPlayOutTileEntityData(this.position, 8, this.b()); } - public NBTTagCompound aa_() { + @Override + public NBTTagCompound b() { return this.save(new NBTTagCompound()); } - public void f() { + public void h() { if (!this.world.isClientSide) { - this.f = 40; + this.c = 40; this.world.playBlockAction(this.getPosition(), this.getBlock().getBlock(), 1, 0); this.update(); } } - public boolean c(int i, int j) { + @Override + public boolean setProperty(int i, int j) { if (i == 1) { - this.f = 40; + this.c = 40; return true; } else { - return super.c(i, j); + return super.setProperty(i, j); } } public void a(Entity entity) { - if (!this.world.isClientSide && !this.d()) { - this.f = 100; + if (!this.world.isClientSide && !this.f()) { + this.c = 100; if (this.exitPortal == null && this.world.worldProvider instanceof WorldProviderTheEnd) { - this.j(); + this.u(); } if (this.exitPortal != null) { - BlockPosition blockposition = this.exactTeleport ? this.exitPortal : this.i(); + BlockPosition blockposition = this.exactTeleport ? this.exitPortal : this.t(); // CraftBukkit start - Fire PlayerTeleportEvent if (entity instanceof EntityPlayer) { @@ -149,51 +155,51 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick return; } - entity.enderTeleportTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); + entity.enderTeleportAndLoad(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); // Paper end - EntityTeleportEndGatewayEvent } - this.f(); + this.h(); } } - private BlockPosition i() { + private BlockPosition t() { BlockPosition blockposition = a(this.world, this.exitPortal, 5, false); - TileEntityEndGateway.a.debug("Best exit position for portal at {} is {}", this.exitPortal, blockposition); + TileEntityEndGateway.LOGGER.debug("Best exit position for portal at {} is {}", this.exitPortal, blockposition); return blockposition.up(); } - private void j() { - Vec3D vec3d = (new Vec3D((double) this.getPosition().getX(), 0.0D, (double) this.getPosition().getZ())).a(); + private void u() { + Vec3D vec3d = (new Vec3D((double) this.getPosition().getX(), 0.0D, (double) this.getPosition().getZ())).d(); Vec3D vec3d1 = vec3d.a(1024.0D); int i; for (i = 16; a(this.world, vec3d1).b() > 0 && i-- > 0; vec3d1 = vec3d1.e(vec3d.a(-16.0D))) { - TileEntityEndGateway.a.debug("Skipping backwards past nonempty chunk at {}", vec3d1); + TileEntityEndGateway.LOGGER.debug("Skipping backwards past nonempty chunk at {}", vec3d1); } for (i = 16; a(this.world, vec3d1).b() == 0 && i-- > 0; vec3d1 = vec3d1.e(vec3d.a(16.0D))) { - TileEntityEndGateway.a.debug("Skipping forward past empty chunk at {}", vec3d1); + TileEntityEndGateway.LOGGER.debug("Skipping forward past empty chunk at {}", vec3d1); } - TileEntityEndGateway.a.debug("Found chunk at {}", vec3d1); + TileEntityEndGateway.LOGGER.debug("Found chunk at {}", vec3d1); Chunk chunk = a(this.world, vec3d1); this.exitPortal = a(chunk); if (this.exitPortal == null) { this.exitPortal = new BlockPosition(vec3d1.x + 0.5D, 75.0D, vec3d1.z + 0.5D); - TileEntityEndGateway.a.debug("Failed to find suitable block, settling on {}", this.exitPortal); - (new WorldGenEndIsland()).a(this.world, this.world.getChunkProvider().getChunkGenerator(), new Random(this.exitPortal.asLong()), this.exitPortal, WorldGenFeatureConfiguration.e); + TileEntityEndGateway.LOGGER.debug("Failed to find suitable block, settling on {}", this.exitPortal); + WorldGenerator.END_ISLAND.generate(this.world, this.world.getChunkProvider().getChunkGenerator(), new Random(this.exitPortal.asLong()), this.exitPortal, WorldGenFeatureConfiguration.e); } else { - TileEntityEndGateway.a.debug("Found block at {}", this.exitPortal); + TileEntityEndGateway.LOGGER.debug("Found block at {}", this.exitPortal); } this.exitPortal = a(this.world, this.exitPortal, 16, true); - TileEntityEndGateway.a.debug("Creating portal at {}", this.exitPortal); + TileEntityEndGateway.LOGGER.debug("Creating portal at {}", this.exitPortal); this.exitPortal = this.exitPortal.up(10); - this.c(this.exitPortal); + this.b(this.exitPortal); this.update(); } @@ -207,7 +213,7 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick BlockPosition blockposition2 = new BlockPosition(blockposition.getX() + j, l, blockposition.getZ() + k); IBlockData iblockdata = iblockaccess.getType(blockposition2); - if (iblockdata.k() && (flag || iblockdata.getBlock() != Blocks.BEDROCK)) { + if (iblockdata.o(iblockaccess, blockposition2) && (flag || iblockdata.getBlock() != Blocks.BEDROCK)) { blockposition1 = blockposition2; break; } @@ -225,9 +231,10 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick @Nullable private static BlockPosition a(Chunk chunk) { - BlockPosition blockposition = new BlockPosition(chunk.locX * 16, 30, chunk.locZ * 16); + ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); + BlockPosition blockposition = new BlockPosition(chunkcoordintpair.d(), 30, chunkcoordintpair.e()); int i = chunk.b() + 16 - 1; - BlockPosition blockposition1 = new BlockPosition(chunk.locX * 16 + 16 - 1, i, chunk.locZ * 16 + 16 - 1); + BlockPosition blockposition1 = new BlockPosition(chunkcoordintpair.f(), i, chunkcoordintpair.g()); BlockPosition blockposition2 = null; double d0 = 0.0D; Iterator iterator = BlockPosition.a(blockposition, blockposition1).iterator(); @@ -235,9 +242,11 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick while (iterator.hasNext()) { BlockPosition blockposition3 = (BlockPosition) iterator.next(); IBlockData iblockdata = chunk.getType(blockposition3); + BlockPosition blockposition4 = blockposition3.up(); + BlockPosition blockposition5 = blockposition3.up(2); - if (iblockdata.getBlock() == Blocks.END_STONE && !chunk.getType(blockposition3.up(1)).k() && !chunk.getType(blockposition3.up(2)).k()) { - double d1 = blockposition3.g(0.0D, 0.0D, 0.0D); + if (iblockdata.getBlock() == Blocks.END_STONE && !chunk.getType(blockposition4).o(chunk, blockposition4) && !chunk.getType(blockposition5).o(chunk, blockposition5)) { + double d1 = blockposition3.distanceSquared(0.0D, 0.0D, 0.0D, true); if (blockposition2 == null || d1 < d0) { blockposition2 = blockposition3; @@ -249,23 +258,12 @@ public class TileEntityEndGateway extends TileEntityEnderPortal implements ITick return blockposition2; } - private void c(BlockPosition blockposition) { - WorldGenerator.ax.generate(this.world, this.world.getChunkProvider().getChunkGenerator(), new Random(), blockposition, new WorldGenEndGatewayConfiguration(false)); - TileEntity tileentity = this.world.getTileEntity(blockposition); - - if (tileentity instanceof TileEntityEndGateway) { - TileEntityEndGateway tileentityendgateway = (TileEntityEndGateway) tileentity; - - tileentityendgateway.exitPortal = new BlockPosition(this.getPosition()); - tileentityendgateway.update(); - } else { - TileEntityEndGateway.a.warn("Couldn't save exit portal at {}", blockposition); - } - + private void b(BlockPosition blockposition) { + WorldGenerator.END_GATEWAY.generate(this.world, this.world.getChunkProvider().getChunkGenerator(), new Random(), blockposition, WorldGenEndGatewayConfiguration.a(this.getPosition(), false)); } - public void b(BlockPosition blockposition) { - this.exactTeleport = true; + public void a(BlockPosition blockposition, boolean flag) { + this.exactTeleport = flag; this.exitPortal = blockposition; } } diff --git a/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/src/main/java/net/minecraft/server/TileEntityEnderChest.java index f2df6f395..ae6784b6a 100644 --- a/src/main/java/net/minecraft/server/TileEntityEnderChest.java +++ b/src/main/java/net/minecraft/server/TileEntityEnderChest.java @@ -3,8 +3,8 @@ package net.minecraft.server; public class TileEntityEnderChest extends TileEntity { // Paper - Remove ITickable public float a; - public float e; - public int f; + public float b; + public int c; private int g; public TileEntityEnderChest() { @@ -13,45 +13,47 @@ public class TileEntityEnderChest extends TileEntity { // Paper - Remove ITickab public void tick() { if (++this.g % 20 * 4 == 0) { - this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.f); + this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.c); } - this.e = this.a; - // Paper start - /* + this.b = this.a; + /* // Paper int i = this.position.getX(); int j = this.position.getY(); int k = this.position.getZ(); float f = 0.1F; double d0; - - */ // Paper start + */ } + private void doOpenLogic() { int i = this.position.getX(); int j = this.position.getY(); int k = this.position.getZ(); + double d0; // Paper end - if (this.f > 0 && this.a == 0.0F) { + + if (this.c > 0 && this.a == 0.0F) { double d1 = (double) i + 0.5D; - double d0 = (double) k + 0.5D; // Paper - this.world.a((EntityHuman) null, d1, (double) j + 0.5D, d0, SoundEffects.BLOCK_ENDER_CHEST_OPEN, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + d0 = (double) k + 0.5D; + this.world.playSound((EntityHuman) null, d1, (double) j + 0.5D, d0, SoundEffects.BLOCK_ENDER_CHEST_OPEN, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); } // Paper start } + private void doCloseLogic() { int i = this.position.getX(); int j = this.position.getY(); int k = this.position.getZ(); - this.e = this.a; double d0; + + if (this.c == 0) { /* && this.a > 0.0F || this.c > 0 && this.a < 1.0F) { // Paper end - if (this.f == 0 && this.a > 0.0F || this.f > 0 && this.a < 1.0F) { float f1 = this.a; - if (this.f > 0) { + if (this.c > 0) { this.a += 0.1F; } else { this.a -= 0.1F; @@ -64,11 +66,14 @@ public class TileEntityEnderChest extends TileEntity { // Paper - Remove ITickab float f2 = 0.5F; if (this.a < 0.5F && f1 >= 0.5F) { + // Paper start + */ d0 = (double) i + 0.5D; double d2 = (double) k + 0.5D; - this.world.a((EntityHuman) null, d0, (double) j + 0.5D, d2, SoundEffects.BLOCK_ENDER_CHEST_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); - } + MCUtil.scheduleTask(10, () -> { + this.world.playSound((EntityHuman) null, d0, (double) j + 0.5D, d2, SoundEffects.BLOCK_ENDER_CHEST_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + }); if (this.a < 0.0F) { this.a = 0.0F; @@ -77,33 +82,35 @@ public class TileEntityEnderChest extends TileEntity { // Paper - Remove ITickab } - public boolean c(int i, int j) { + @Override + public boolean setProperty(int i, int j) { if (i == 1) { - this.f = j; + this.c = j; return true; } else { - return super.c(i, j); + return super.setProperty(i, j); } } - public void y() { + @Override + public void V_() { this.invalidateBlockCache(); - super.y(); - } - - public void c() { - ++this.f; - this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.f); - doOpenLogic(); // Paper + super.V_(); } public void d() { - --this.f; - this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.f); + ++this.c; + this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.c); + doOpenLogic(); // Paper + } + + public void f() { + --this.c; + this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.c); doCloseLogic(); // Paper } public boolean a(EntityHuman entityhuman) { - return this.world.getTileEntity(this.position) != this ? false : entityhuman.d((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; } } diff --git a/src/main/java/net/minecraft/server/TileEntityFurnace.java b/src/main/java/net/minecraft/server/TileEntityFurnace.java index d307467fb..55b564610 100644 --- a/src/main/java/net/minecraft/server/TileEntityFurnace.java +++ b/src/main/java/net/minecraft/server/TileEntityFurnace.java @@ -9,45 +9,79 @@ import java.util.Map.Entry; import javax.annotation.Nullable; // CraftBukkit start import java.util.List; - import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.entity.CraftHumanEntity; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; import org.bukkit.event.inventory.FurnaceBurnEvent; +import org.bukkit.event.inventory.FurnaceExtractEvent; import org.bukkit.event.inventory.FurnaceSmeltEvent; // CraftBukkit end -public class TileEntityFurnace extends TileEntityContainer implements IWorldInventory, RecipeHolder, AutoRecipeOutput, ITickable { +public abstract class TileEntityFurnace extends TileEntityContainer implements IWorldInventory, RecipeHolder, AutoRecipeOutput, ITickable { - private static final int[] a = new int[] { 0}; - private static final int[] e = new int[] { 2, 1}; - private static final int[] f = new int[] { 1}; - private NonNullList items; - private int burnTime; + private static final int[] g = new int[]{0}; + private static final int[] h = new int[]{2, 1}; + private static final int[] i = new int[]{1}; + protected NonNullList items; + public int burnTime; private int ticksForCurrentFuel; public double cookSpeedMultiplier = 1.0; // Paper - cook speed multiplier API - private int cookTime; - private int cookTimeTotal; - private IChatBaseComponent l; - private final Map m; + public int cookTime; + public int cookTimeTotal; + protected final IContainerProperties b; + private final Map n; + protected final Recipes c; - private static void a(Map map, Tag tag, int i) { - Iterator iterator = tag.a().iterator(); + protected TileEntityFurnace(TileEntityTypes tileentitytypes, Recipes recipes) { + super(tileentitytypes); + this.items = NonNullList.a(3, ItemStack.a); + this.b = new IContainerProperties() { + @Override + public int getProperty(int i) { + switch (i) { + case 0: + return TileEntityFurnace.this.burnTime; + case 1: + return TileEntityFurnace.this.ticksForCurrentFuel; + case 2: + return TileEntityFurnace.this.cookTime; + case 3: + return TileEntityFurnace.this.cookTimeTotal; + default: + return 0; + } + } - while (iterator.hasNext()) { - Item item = (Item) iterator.next(); + @Override + public void setProperty(int i, int j) { + switch (i) { + case 0: + TileEntityFurnace.this.burnTime = j; + break; + case 1: + TileEntityFurnace.this.ticksForCurrentFuel = j; + break; + case 2: + TileEntityFurnace.this.cookTime = j; + break; + case 3: + TileEntityFurnace.this.cookTimeTotal = j; + } - map.put(item, i); - } + } + @Override + public int a() { + return 4; + } + }; + this.n = Maps.newHashMap(); + this.c = recipes; } - private static void a(Map map, IMaterial imaterial, int i) { - map.put(imaterial.getItem(), i); - } - - public static Map p() { + public static Map f() { Map map = Maps.newLinkedHashMap(); a(map, (IMaterial) Items.LAVA_BUCKET, 20000); @@ -75,6 +109,7 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve a(map, (IMaterial) Blocks.ACACIA_FENCE_GATE, 300); a(map, (IMaterial) Blocks.NOTE_BLOCK, 300); a(map, (IMaterial) Blocks.BOOKSHELF, 300); + a(map, (IMaterial) Blocks.LECTERN, 300); a(map, (IMaterial) Blocks.JUKEBOX, 300); a(map, (IMaterial) Blocks.CHEST, 300); a(map, (IMaterial) Blocks.TRAPPED_CHEST, 300); @@ -84,7 +119,7 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve a(map, (IMaterial) Items.BOW, 300); a(map, (IMaterial) Items.FISHING_ROD, 300); a(map, (IMaterial) Blocks.LADDER, 300); - a(map, (IMaterial) Items.SIGN, 200); + a(map, TagsItem.SIGNS, 200); a(map, (IMaterial) Items.WOODEN_SHOVEL, 200); a(map, (IMaterial) Items.WOODEN_SWORD, 200); a(map, (IMaterial) Items.WOODEN_HOE, 200); @@ -99,6 +134,16 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve a(map, (IMaterial) Items.BOWL, 100); a(map, TagsItem.CARPETS, 67); a(map, (IMaterial) Blocks.DRIED_KELP_BLOCK, 4001); + a(map, (IMaterial) Items.CROSSBOW, 300); + a(map, (IMaterial) Blocks.BAMBOO, 50); + a(map, (IMaterial) Blocks.DEAD_BUSH, 100); + a(map, (IMaterial) Blocks.SCAFFOLDING, 50); + a(map, (IMaterial) Blocks.LOOM, 300); + a(map, (IMaterial) Blocks.BARREL, 300); + a(map, (IMaterial) Blocks.CARTOGRAPHY_TABLE, 300); + a(map, (IMaterial) Blocks.FLETCHING_TABLE, 300); + a(map, (IMaterial) Blocks.SMITHING_TABLE, 300); + a(map, (IMaterial) Blocks.COMPOSTER, 300); return map; } @@ -122,83 +167,36 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve return transaction; } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; } // CraftBukkit end - public TileEntityFurnace() { - super(TileEntityTypes.FURNACE); - this.items = NonNullList.a(3, ItemStack.a); - this.m = Maps.newHashMap(); - } + private static void a(Map map, Tag tag, int i) { + Iterator iterator = tag.a().iterator(); - public int getSize() { - return this.items.size(); - } + while (iterator.hasNext()) { + Item item = (Item) iterator.next(); - public boolean P_() { - Iterator iterator = this.items.iterator(); - - ItemStack itemstack; - - do { - if (!iterator.hasNext()) { - return true; - } - - itemstack = (ItemStack) iterator.next(); - } while (itemstack.isEmpty()); - - return false; - } - - public ItemStack getItem(int i) { - return (ItemStack) this.items.get(i); - } - - public ItemStack splitStack(int i, int j) { - return ContainerUtil.a(this.items, i, j); - } - - public ItemStack splitWithoutUpdate(int i) { - return ContainerUtil.a(this.items, i); - } - - public void setItem(int i, ItemStack itemstack) { - ItemStack itemstack1 = (ItemStack) this.items.get(i); - boolean flag = !itemstack.isEmpty() && itemstack.doMaterialsMatch(itemstack1) && ItemStack.equals(itemstack, itemstack1); - - this.items.set(i, itemstack); - if (itemstack.getCount() > this.getMaxStackSize()) { - itemstack.setCount(this.getMaxStackSize()); - } - - if (i == 0 && !flag) { - this.cookTimeTotal = this.s(); - this.cookTime = 0; - this.update(); + map.put(item, i); } } - public IChatBaseComponent getDisplayName() { - return (IChatBaseComponent) (this.l != null ? this.l : new ChatMessage("container.furnace", new Object[0])); + private static void a(Map map, IMaterial imaterial, int i) { + map.put(imaterial.getItem(), i); } - public boolean hasCustomName() { - return this.l != null; - } - - @Nullable - public IChatBaseComponent getCustomName() { - return this.l; - } - - public void setCustomName(@Nullable IChatBaseComponent ichatbasecomponent) { - this.l = ichatbasecomponent; + private boolean isBurning() { + return this.burnTime > 0; } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); this.items = NonNullList.a(this.getSize(), ItemStack.a); @@ -206,18 +204,14 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve this.burnTime = nbttagcompound.getShort("BurnTime"); this.cookTime = nbttagcompound.getShort("CookTime"); this.cookTimeTotal = nbttagcompound.getShort("CookTimeTotal"); - this.ticksForCurrentFuel = fuelTime((ItemStack) this.items.get(1)); + this.ticksForCurrentFuel = this.fuelTime((ItemStack) this.items.get(1)); short short0 = nbttagcompound.getShort("RecipesUsedSize"); for (int i = 0; i < short0; ++i) { MinecraftKey minecraftkey = new MinecraftKey(nbttagcompound.getString("RecipeLocation" + i)); int j = nbttagcompound.getInt("RecipeAmount" + i); - this.m.put(minecraftkey, j); - } - - if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.l = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException + this.n.put(minecraftkey, j); } // Paper start - cook speed API @@ -227,6 +221,7 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve // Paper end } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); nbttagcompound.setShort("BurnTime", (short) this.burnTime); @@ -234,31 +229,20 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve nbttagcompound.setShort("CookTimeTotal", (short) this.cookTimeTotal); nbttagcompound.setDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API ContainerUtil.a(nbttagcompound, this.items); - nbttagcompound.setShort("RecipesUsedSize", (short) this.m.size()); + nbttagcompound.setShort("RecipesUsedSize", (short) this.n.size()); int i = 0; - for (Iterator iterator = this.m.entrySet().iterator(); iterator.hasNext(); ++i) { + for (Iterator iterator = this.n.entrySet().iterator(); iterator.hasNext(); ++i) { Entry entry = (Entry) iterator.next(); nbttagcompound.setString("RecipeLocation" + i, ((MinecraftKey) entry.getKey()).toString()); nbttagcompound.setInt("RecipeAmount" + i, (Integer) entry.getValue()); } - if (this.l != null) { - nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(this.l)); - } - return nbttagcompound; } - public int getMaxStackSize() { - return 64; - } - - private boolean isBurning() { - return this.burnTime > 0; - } - + @Override public void tick() { boolean flag = this.isBurning(); boolean flag1 = false; @@ -275,7 +259,7 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve this.cookTime = MathHelper.clamp(this.cookTime - 2, 0, this.cookTimeTotal); } } else { - IRecipe irecipe = this.world.getCraftingManager().b(this, this.world); + IRecipe irecipe = this.world.getCraftingManager().craft((Recipes) this.c, this, this.world).orElse(null); // Eclipse fail if (!this.isBurning() && this.canBurn(irecipe)) { // CraftBukkit start @@ -298,7 +282,7 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve itemstack.subtract(1); if (itemstack.isEmpty()) { - Item item1 = item.o(); + Item item1 = item.n(); this.items.set(1, item1 == null ? ItemStack.a : new ItemStack(item1)); } @@ -310,7 +294,7 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve this.cookTime += cookSpeedMultiplier; // Paper - cook speed multiplier API if (this.cookTime >= this.cookTimeTotal) { // Paper - cook speed multiplier API this.cookTime = 0; - this.cookTimeTotal = this.s(); + this.cookTimeTotal = this.getRecipeCookingTime(); this.burn(irecipe); flag1 = true; } @@ -331,15 +315,9 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve } - private int s() { - FurnaceRecipe furnacerecipe = (this.hasWorld()) ? (FurnaceRecipe) this.world.getCraftingManager().b(this, this.world) : null; // CraftBukkit - SPIGOT-4302 - - return furnacerecipe != null ? furnacerecipe.h() : 200; - } - - private boolean canBurn(@Nullable IRecipe irecipe) { + protected boolean canBurn(@Nullable IRecipe irecipe) { if (!((ItemStack) this.items.get(0)).isEmpty() && irecipe != null) { - ItemStack itemstack = irecipe.d(); + ItemStack itemstack = irecipe.c(); if (itemstack.isEmpty()) { return false; @@ -353,17 +331,17 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve } } - private void burn(@Nullable IRecipe irecipe) { + private void burn(@Nullable IRecipe irecipe) { if (irecipe != null && this.canBurn(irecipe)) { ItemStack itemstack = (ItemStack) this.items.get(0); - ItemStack itemstack1 = irecipe.d(); + ItemStack itemstack1 = irecipe.c(); ItemStack itemstack2 = (ItemStack) this.items.get(2); // CraftBukkit start - fire FurnaceSmeltEvent CraftItemStack source = CraftItemStack.asCraftMirror(itemstack); org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack1); - FurnaceSmeltEvent furnaceSmeltEvent = new FurnaceSmeltEvent(this.world.getWorld().getBlockAt(position), source, result); // Akarin + FurnaceSmeltEvent furnaceSmeltEvent = new FurnaceSmeltEvent(this.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), source, result); this.world.getServer().getPluginManager().callEvent(furnaceSmeltEvent); if (furnaceSmeltEvent.isCancelled()) { @@ -393,7 +371,7 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve // CraftBukkit end if (!this.world.isClientSide) { - this.a(this.world, (EntityPlayer) null, irecipe); + this.a(irecipe); } if (itemstack.getItem() == Blocks.WET_SPONGE.getItem() && !((ItemStack) this.items.get(1)).isEmpty() && ((ItemStack) this.items.get(1)).getItem() == Items.BUCKET) { @@ -404,48 +382,35 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve } } - private static int fuelTime(ItemStack itemstack) { + protected int fuelTime(ItemStack itemstack) { if (itemstack.isEmpty()) { return 0; } else { Item item = itemstack.getItem(); - return (Integer) p().getOrDefault(item, 0); + return (Integer) f().getOrDefault(item, 0); } } + protected int getRecipeCookingTime() { + return (this.hasWorld()) ? (Integer) this.world.getCraftingManager().craft((Recipes) this.c, this, this.world).map(RecipeCooking::e).orElse(200) : 200; // CraftBukkit - SPIGOT-4302 // Eclipse fail + } + public static boolean isFuel(ItemStack itemstack) { - return p().containsKey(itemstack.getItem()); - } - - public boolean a(EntityHuman entityhuman) { - return this.world.getTileEntity(this.position) != this ? false : entityhuman.d((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; - } - - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - - public boolean b(int i, ItemStack itemstack) { - if (i == 2) { - return false; - } else if (i != 1) { - return true; - } else { - ItemStack itemstack1 = (ItemStack) this.items.get(1); - - return isFuel(itemstack) || SlotFurnaceFuel.d_(itemstack) && itemstack1.getItem() != Items.BUCKET; - } + return f().containsKey(itemstack.getItem()); } + @Override public int[] getSlotsForFace(EnumDirection enumdirection) { - return enumdirection == EnumDirection.DOWN ? TileEntityFurnace.e : (enumdirection == EnumDirection.UP ? TileEntityFurnace.a : TileEntityFurnace.f); + return enumdirection == EnumDirection.DOWN ? TileEntityFurnace.h : (enumdirection == EnumDirection.UP ? TileEntityFurnace.g : TileEntityFurnace.i); } + @Override public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, @Nullable EnumDirection enumdirection) { return this.b(i, itemstack); } + @Override public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { if (enumdirection == EnumDirection.DOWN && i == 1) { Item item = itemstack.getItem(); @@ -458,54 +423,151 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve return true; } - public String getContainerName() { - return "minecraft:furnace"; + @Override + public int getSize() { + return this.items.size(); } - public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { - return new ContainerFurnace(playerinventory, this); + @Override + public boolean isNotEmpty() { + Iterator iterator = this.items.iterator(); + + ItemStack itemstack; + + do { + if (!iterator.hasNext()) { + return true; + } + + itemstack = (ItemStack) iterator.next(); + } while (itemstack.isEmpty()); + + return false; } - public int getProperty(int i) { - switch (i) { - case 0: - return this.burnTime; - case 1: - return this.ticksForCurrentFuel; - case 2: - return this.cookTime; - case 3: - return this.cookTimeTotal; - default: - return 0; + @Override + public ItemStack getItem(int i) { + return (ItemStack) this.items.get(i); + } + + @Override + public ItemStack splitStack(int i, int j) { + return ContainerUtil.a(this.items, i, j); + } + + @Override + public ItemStack splitWithoutUpdate(int i) { + return ContainerUtil.a(this.items, i); + } + + @Override + public void setItem(int i, ItemStack itemstack) { + ItemStack itemstack1 = (ItemStack) this.items.get(i); + boolean flag = !itemstack.isEmpty() && itemstack.doMaterialsMatch(itemstack1) && ItemStack.equals(itemstack, itemstack1); + + this.items.set(i, itemstack); + if (itemstack.getCount() > this.getMaxStackSize()) { + itemstack.setCount(this.getMaxStackSize()); } - } - public void setProperty(int i, int j) { - switch (i) { - case 0: - this.burnTime = j; - break; - case 1: - this.ticksForCurrentFuel = j; - break; - case 2: - this.cookTime = j; - break; - case 3: - this.cookTimeTotal = j; + if (i == 0 && !flag) { + this.cookTimeTotal = this.getRecipeCookingTime(); + this.cookTime = 0; + this.update(); } } - public int h() { - return 4; + @Override + public boolean a(EntityHuman entityhuman) { + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; } + @Override + public boolean b(int i, ItemStack itemstack) { + if (i == 2) { + return false; + } else if (i != 1) { + return true; + } else { + ItemStack itemstack1 = (ItemStack) this.items.get(1); + + return isFuel(itemstack) || itemstack.getItem() == Items.BUCKET && itemstack1.getItem() != Items.BUCKET; + } + } + + @Override public void clear() { this.items.clear(); } + @Override + public void a(@Nullable IRecipe irecipe) { + if (irecipe != null) { + this.n.compute(irecipe.getKey(), (minecraftkey, integer) -> { + return 1 + (integer == null ? 0 : integer); + }); + } + + } + + @Nullable + @Override + public IRecipe U_() { + return null; + } + + @Override + public void b(EntityHuman entityhuman) {} + + public void d(EntityHuman entityhuman, ItemStack itemstack, int amount) { // CraftBukkit + List> list = Lists.newArrayList(); + Iterator iterator = this.n.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + + entityhuman.world.getCraftingManager().a((MinecraftKey) entry.getKey()).ifPresent((irecipe) -> { + list.add(irecipe); + a(entityhuman, (Integer) entry.getValue(), ((RecipeCooking) irecipe).b(), itemstack, amount); // CraftBukkit + }); + } + + entityhuman.discoverRecipes(list); + this.n.clear(); + } + + private void a(EntityHuman entityhuman, int i, float f, ItemStack itemstack, int amount) { // CraftBukkit + int j; + + if (f == 0.0F) { + i = 0; + } else if (f < 1.0F) { + j = MathHelper.d((float) i * f); + if (j < MathHelper.f((float) i * f) && Math.random() < (double) ((float) i * f - (float) j)) { + ++j; + } + + i = j; + } + + // CraftBukkit start - fire FurnaceExtractEvent + if (amount != 0) { + FurnaceExtractEvent event = new FurnaceExtractEvent((Player) entityhuman.getBukkitEntity(), CraftBlock.at(world, position), org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(itemstack.getItem()), amount, i); + world.getServer().getPluginManager().callEvent(event); + i = event.getExpToDrop(); + } + // CraftBukkit end + + while (i > 0) { + j = EntityExperienceOrb.getOrbValue(i); + i -= j; + entityhuman.world.addEntity(new EntityExperienceOrb(entityhuman.world, entityhuman.locX, entityhuman.locY + 0.5D, entityhuman.locZ + 0.5D, j, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, entityhuman)); // Paper + } + + } + + @Override public void a(AutoRecipeStackManager autorecipestackmanager) { Iterator iterator = this.items.iterator(); @@ -516,51 +578,4 @@ public class TileEntityFurnace extends TileEntityContainer implements IWorldInve } } - - public void a(IRecipe irecipe) { - if (this.m.containsKey(irecipe.getKey())) { - this.m.put(irecipe.getKey(), (Integer) this.m.get(irecipe.getKey()) + 1); - } else { - this.m.put(irecipe.getKey(), 1); - } - - } - - @Nullable - public IRecipe i() { - return null; - } - - public Map q() { - return this.m; - } - - public boolean a(World world, EntityPlayer entityplayer, @Nullable IRecipe irecipe) { - if (irecipe != null) { - this.a(irecipe); - return true; - } else { - return false; - } - } - - public void d(EntityHuman entityhuman) { - if (!this.world.getGameRules().getBoolean("doLimitedCrafting")) { - List list = Lists.newArrayList(); - Iterator iterator = this.m.keySet().iterator(); - - while (iterator.hasNext()) { - MinecraftKey minecraftkey = (MinecraftKey) iterator.next(); - IRecipe irecipe = entityhuman.world.getCraftingManager().a(minecraftkey); - - if (irecipe != null) { - list.add(irecipe); - } - } - - entityhuman.discoverRecipes(list); - } - - this.m.clear(); - } } diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java index 544dde428..6f6519f6c 100644 --- a/src/main/java/net/minecraft/server/TileEntityHopper.java +++ b/src/main/java/net/minecraft/server/TileEntityHopper.java @@ -4,6 +4,7 @@ import java.util.Iterator; import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; +import java.util.stream.IntStream; import javax.annotation.Nullable; // CraftBukkit start @@ -18,8 +19,8 @@ import org.bukkit.inventory.Inventory; public class TileEntityHopper extends TileEntityLootable implements IHopper, ITickable { private NonNullList items; - private int f; - private long j; + private int j; + private long k; // CraftBukkit start - add fields and methods public List transaction = new java.util.ArrayList(); @@ -41,6 +42,11 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi return transaction; } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; } @@ -49,9 +55,10 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi public TileEntityHopper() { super(TileEntityTypes.HOPPER); this.items = NonNullList.a(5, ItemStack.a); - this.f = -1; + this.j = -1; } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); this.items = NonNullList.a(this.getSize(), ItemStack.a); @@ -59,60 +66,52 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi ContainerUtil.b(nbttagcompound, this.items); } - if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.setCustomName(MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound)); // Paper - Catch ParseException - } - - this.f = nbttagcompound.getInt("TransferCooldown"); + this.j = nbttagcompound.getInt("TransferCooldown"); } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); if (!this.e(nbttagcompound)) { ContainerUtil.a(nbttagcompound, this.items); } - nbttagcompound.setInt("TransferCooldown", this.f); - IChatBaseComponent ichatbasecomponent = this.getCustomName(); - - if (ichatbasecomponent != null) { - nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(ichatbasecomponent)); - } - + nbttagcompound.setInt("TransferCooldown", this.j); return nbttagcompound; } + @Override public int getSize() { return this.items.size(); } + @Override public ItemStack splitStack(int i, int j) { this.d((EntityHuman) null); - return ContainerUtil.a(this.q(), i, j); + return ContainerUtil.a(this.f(), i, j); } + @Override public void setItem(int i, ItemStack itemstack) { this.d((EntityHuman) null); - this.q().set(i, itemstack); + this.f().set(i, itemstack); if (itemstack.getCount() > this.getMaxStackSize()) { itemstack.setCount(this.getMaxStackSize()); } } - public IChatBaseComponent getDisplayName() { - return (IChatBaseComponent) (this.i != null ? this.i : new ChatMessage("container.hopper", new Object[0])); - } - - public int getMaxStackSize() { - return maxStack; // CraftBukkit + @Override + protected IChatBaseComponent getContainerName() { + return new ChatMessage("container.hopper", new Object[0]); } + @Override public void tick() { if (this.world != null && !this.world.isClientSide) { - --this.f; - this.j = this.world.getTime(); - if (!this.E()) { + --this.j; + this.k = this.world.getTime(); + if (!this.v()) { this.setCooldown(0); // Spigot start boolean result = this.a(() -> { @@ -129,14 +128,14 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi private boolean a(Supplier supplier) { if (this.world != null && !this.world.isClientSide) { - if (!this.E() && (Boolean) this.getBlock().get(BlockHopper.ENABLED)) { + if (!this.v() && (Boolean) this.getBlock().get(BlockHopper.ENABLED)) { boolean flag = false; - if (!this.p()) { - flag = this.s(); + if (!this.h()) { + flag = this.t(); } - if (!this.r()) { + if (!this.s()) { flag |= (Boolean) supplier.get(); } @@ -153,7 +152,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi } } - private boolean p() { + private boolean h() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -169,11 +168,12 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi return false; } - public boolean P_() { - return this.p(); + @Override + public boolean isNotEmpty() { + return this.h(); } - private boolean r() { + private boolean s() { Iterator iterator = this.items.iterator(); ItemStack itemstack; @@ -276,7 +276,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi private ItemStack callPushMoveEvent(IInventory iinventory, ItemStack itemstack) { Inventory destinationInventory = getInventory(iinventory); InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner(false).getInventory(), - CraftItemStack.asCraftMirror(itemstack), destinationInventory, true); + CraftItemStack.asCraftMirror(itemstack), destinationInventory, true); boolean result = event.callEvent(); if (!event.calledGetItem && !event.calledSetItem) { skipPushModeEventFire = true; @@ -298,8 +298,8 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi Inventory destination = getInventory(hopper); InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, - // Mirror is safe as we no plugins ever use this item - CraftItemStack.asCraftMirror(itemstack), destination, false); + // Mirror is safe as we no plugins ever use this item + CraftItemStack.asCraftMirror(itemstack), destination, false); boolean result = event.callEvent(); if (!event.calledGetItem && !event.calledSetItem) { skipPullModeEventFire = true; @@ -335,17 +335,17 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi ((EntityMinecartHopper) hopper).setCooldown(hopper.getWorld().spigotConfig.hopperTransfer / 2); } } - // Paper end - private boolean s() { - IInventory iinventory = this.D(); + + private boolean t() { + IInventory iinventory = this.u(); if (iinventory == null) { return false; } else { EnumDirection enumdirection = ((EnumDirection) this.getBlock().get(BlockHopper.FACING)).opposite(); - if (this.a(iinventory, enumdirection)) { + if (this.b(iinventory, enumdirection)) { return false; } else { return hopperPush(iinventory, enumdirection); /* // Paper - disable rest @@ -391,61 +391,22 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi } } - private boolean a(IInventory iinventory, EnumDirection enumdirection) { - if (iinventory instanceof IWorldInventory) { - IWorldInventory iworldinventory = (IWorldInventory) iinventory; - int[] aint = iworldinventory.getSlotsForFace(enumdirection); - int[] aint1 = aint; - int i = aint.length; - - for (int j = 0; j < i; ++j) { - int k = aint1[j]; - ItemStack itemstack = iworldinventory.getItem(k); - - if (itemstack.isEmpty() || itemstack.getCount() != itemstack.getMaxStackSize()) { - return false; - } - } - } else { - int l = iinventory.getSize(); - - for (int i1 = 0; i1 < l; ++i1) { - ItemStack itemstack1 = iinventory.getItem(i1); - - if (itemstack1.isEmpty() || itemstack1.getCount() != itemstack1.getMaxStackSize()) { - return false; - } - } - } - - return true; + private static IntStream a(IInventory iinventory, EnumDirection enumdirection) { + return iinventory instanceof IWorldInventory ? IntStream.of(((IWorldInventory) iinventory).getSlotsForFace(enumdirection)) : IntStream.range(0, iinventory.getSize()); } - private static boolean b(IInventory iinventory, EnumDirection enumdirection) { - if (iinventory instanceof IWorldInventory) { - IWorldInventory iworldinventory = (IWorldInventory) iinventory; - int[] aint = iworldinventory.getSlotsForFace(enumdirection); - int[] aint1 = aint; - int i = aint.length; + private boolean b(IInventory iinventory, EnumDirection enumdirection) { + return a(iinventory, enumdirection).allMatch((i) -> { + ItemStack itemstack = iinventory.getItem(i); - for (int j = 0; j < i; ++j) { - int k = aint1[j]; + return itemstack.getCount() >= itemstack.getMaxStackSize(); + }); + } - if (!iworldinventory.getItem(k).isEmpty()) { - return false; - } - } - } else { - int l = iinventory.getSize(); - - for (int i1 = 0; i1 < l; ++i1) { - if (!iinventory.getItem(i1).isEmpty()) { - return false; - } - } - } - - return true; + private static boolean c(IInventory iinventory, EnumDirection enumdirection) { + return a(iinventory, enumdirection).allMatch((i) -> { + return iinventory.getItem(i).isEmpty(); + }); } public static boolean a(IHopper ihopper) { @@ -454,46 +415,25 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi if (iinventory != null) { EnumDirection enumdirection = EnumDirection.DOWN; - if (b(iinventory, enumdirection)) { - return false; - } - skipPullModeEventFire = skipHopperEvents; // Paper - - if (iinventory instanceof IWorldInventory) { - IWorldInventory iworldinventory = (IWorldInventory) iinventory; - int[] aint = iworldinventory.getSlotsForFace(enumdirection); - int[] aint1 = aint; - int i = aint.length; - - for (int j = 0; j < i; ++j) { - int k = aint1[j]; - - if (a(ihopper, iinventory, k, enumdirection)) { - return true; - } - } - } else { - int l = iinventory.getSize(); - - for (int i1 = 0; i1 < l; ++i1) { - if (a(ihopper, iinventory, i1, enumdirection)) { - return true; - } - } - } + return c(iinventory, enumdirection) ? false : a(iinventory, enumdirection).anyMatch((i) -> { + skipPullModeEventFire = skipHopperEvents; // Paper + return a(ihopper, iinventory, i, enumdirection); + }); } else { Iterator iterator = c(ihopper).iterator(); - while (iterator.hasNext()) { - EntityItem entityitem = (EntityItem) iterator.next(); + EntityItem entityitem; - if (a((IInventory) ihopper, entityitem)) { - return true; + do { + if (!iterator.hasNext()) { + return false; } - } - } - return false; + entityitem = (EntityItem) iterator.next(); + } while (!a((IInventory) ihopper, entityitem)); + + return true; + } } private static boolean a(IHopper ihopper, IInventory iinventory, int i, EnumDirection enumdirection) { @@ -597,7 +537,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi if (a(iinventory1, itemstack, i, enumdirection)) { boolean flag = false; - boolean flag1 = iinventory1.P_(); + boolean flag1 = iinventory1.isNotEmpty(); if (itemstack1.isEmpty()) { IGNORE_TILE_UPDATES = true; // Paper @@ -618,13 +558,13 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi if (flag1 && iinventory1 instanceof TileEntityHopper) { TileEntityHopper tileentityhopper = (TileEntityHopper) iinventory1; - if (!tileentityhopper.J()) { + if (!tileentityhopper.x()) { byte b0 = 0; if (iinventory instanceof TileEntityHopper) { TileEntityHopper tileentityhopper1 = (TileEntityHopper) iinventory; - if (tileentityhopper.j >= tileentityhopper1.j) { + if (tileentityhopper.k >= tileentityhopper1.k) { b0 = 1; } } @@ -641,7 +581,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi } @Nullable - private IInventory D() { + private IInventory u() { EnumDirection enumdirection = (EnumDirection) this.getBlock().get(BlockHopper.FACING); return a(this.getWorld(), this.position.shift(enumdirection)); @@ -649,12 +589,12 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi @Nullable public static IInventory b(IHopper ihopper) { - return a(ihopper.getWorld(), ihopper.G(), ihopper.H() + 1.0D, ihopper.I()); + return a(ihopper.getWorld(), ihopper.z(), ihopper.A() + 1.0D, ihopper.B()); } public static List c(IHopper ihopper) { - return (List) ihopper.i().d().stream().flatMap((axisalignedbb) -> { - return ihopper.getWorld().a(EntityItem.class, axisalignedbb.d(ihopper.G() - 0.5D, ihopper.H() - 0.5D, ihopper.I() - 0.5D), IEntitySelector.a).stream(); + return (List) ihopper.N_().d().stream().flatMap((axisalignedbb) -> { + return ihopper.getWorld().a(EntityItem.class, axisalignedbb.d(ihopper.z() - 0.5D, ihopper.A() - 0.5D, ihopper.B() - 0.5D), IEntitySelector.a).stream(); }).collect(Collectors.toList()); } @@ -671,13 +611,15 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi IBlockData iblockdata = world.getType(blockposition); Block block = iblockdata.getBlock(); - if (block.isTileEntity()) { + if (block instanceof IInventoryHolder) { + object = ((IInventoryHolder) block).a(iblockdata, world, blockposition); + } else if (block.isTileEntity()) { TileEntity tileentity = world.getTileEntity(blockposition); if (tileentity instanceof IInventory) { object = (IInventory) tileentity; if (object instanceof TileEntityChest && block instanceof BlockChest) { - object = ((BlockChest) block).getInventory(iblockdata, world, blockposition, true); + object = BlockChest.getInventory(iblockdata, world, blockposition, true); } } } @@ -697,43 +639,39 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi return itemstack.getItem() != itemstack1.getItem() ? false : (itemstack.getDamage() != itemstack1.getDamage() ? false : (itemstack.getCount() > itemstack.getMaxStackSize() ? false : ItemStack.equals(itemstack, itemstack1))); } - public double G() { + @Override + public double z() { return (double) this.position.getX() + 0.5D; } - public double H() { + @Override + public double A() { return (double) this.position.getY() + 0.5D; } - public double I() { + @Override + public double B() { return (double) this.position.getZ() + 0.5D; } private void setCooldown(int i) { - this.f = i; + this.j = i; } - private boolean E() { - return this.f > 0; + private boolean v() { + return this.j > 0; } - private boolean J() { - return this.f > 8; + private boolean x() { + return this.j > 8; } - public String getContainerName() { - return "minecraft:hopper"; - } - - public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { - this.d(entityhuman); - return new ContainerHopper(playerinventory, this, entityhuman); - } - - protected NonNullList q() { + @Override + protected NonNullList f() { return this.items; } + @Override protected void a(NonNullList nonnulllist) { this.items = nonnulllist; } @@ -742,7 +680,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi if (entity instanceof EntityItem) { BlockPosition blockposition = this.getPosition(); - if (VoxelShapes.c(VoxelShapes.a(entity.getBoundingBox().d((double) (-blockposition.getX()), (double) (-blockposition.getY()), (double) (-blockposition.getZ()))), this.i(), OperatorBoolean.AND)) { + if (VoxelShapes.c(VoxelShapes.a(entity.getBoundingBox().d((double) (-blockposition.getX()), (double) (-blockposition.getY()), (double) (-blockposition.getZ()))), this.N_(), OperatorBoolean.AND)) { this.a(() -> { return a((IInventory) this, (EntityItem) entity); }); @@ -750,4 +688,9 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi } } + + @Override + protected Container createContainer(int i, PlayerInventory playerinventory) { + return new ContainerHopper(i, playerinventory, this); + } } diff --git a/src/main/java/net/minecraft/server/TileEntityLectern.java b/src/main/java/net/minecraft/server/TileEntityLectern.java new file mode 100644 index 000000000..221de42e5 --- /dev/null +++ b/src/main/java/net/minecraft/server/TileEntityLectern.java @@ -0,0 +1,310 @@ +package net.minecraft.server; + +import javax.annotation.Nullable; +// CraftBukkit start +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.bukkit.Location; +import org.bukkit.block.Lectern; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.InventoryHolder; +// CraftBukkit end + +public class TileEntityLectern extends TileEntity implements Clearable, ITileInventory, ICommandListener { // CraftBukkit - ICommandListener + + // CraftBukkit start - add fields and methods + public final IInventory inventory = new LecternInventory(); + public class LecternInventory implements IInventory { + + public List transaction = new ArrayList<>(); + private int maxStack = 1; + + @Override + public List getContents() { + return Arrays.asList(book); + } + + @Override + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + @Override + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + @Override + public List getViewers() { + return transaction; + } + + @Override + public void setMaxStackSize(int i) { + maxStack = i; + } + + @Override + public Location getLocation() { + return new Location(world.getWorld(), position.getX(), position.getY(), position.getZ()); + } + + @Override + public InventoryHolder getOwner() { + return (Lectern) TileEntityLectern.this.getOwner(); + } + // CraftBukkit end + + @Override + public int getSize() { + return 1; + } + + @Override + public boolean isNotEmpty() { + return TileEntityLectern.this.book.isEmpty(); + } + + @Override + public ItemStack getItem(int i) { + return i == 0 ? TileEntityLectern.this.book : ItemStack.a; + } + + @Override + public ItemStack splitStack(int i, int j) { + if (i == 0) { + ItemStack itemstack = TileEntityLectern.this.book.cloneAndSubtract(j); + + if (TileEntityLectern.this.book.isEmpty()) { + TileEntityLectern.this.t(); + } + + return itemstack; + } else { + return ItemStack.a; + } + } + + @Override + public ItemStack splitWithoutUpdate(int i) { + if (i == 0) { + ItemStack itemstack = TileEntityLectern.this.book; + + TileEntityLectern.this.book = ItemStack.a; + TileEntityLectern.this.t(); + return itemstack; + } else { + return ItemStack.a; + } + } + + @Override + // CraftBukkit start + public void setItem(int i, ItemStack itemstack) { + if (i == 0) { + TileEntityLectern.this.setBook(itemstack); + if (TileEntityLectern.this.getWorld() != null) { + BlockLectern.setHasBook(TileEntityLectern.this.getWorld(), TileEntityLectern.this.getPosition(), TileEntityLectern.this.getBlock(), TileEntityLectern.this.hasBook()); + } + } + } + // CraftBukkit end + + @Override + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + @Override + public void update() { + TileEntityLectern.this.update(); + } + + @Override + public boolean a(EntityHuman entityhuman) { + return TileEntityLectern.this.world.getTileEntity(TileEntityLectern.this.position) != TileEntityLectern.this ? false : (entityhuman.e((double) TileEntityLectern.this.position.getX() + 0.5D, (double) TileEntityLectern.this.position.getY() + 0.5D, (double) TileEntityLectern.this.position.getZ() + 0.5D) > 64.0D ? false : TileEntityLectern.this.hasBook()); + } + + @Override + public boolean b(int i, ItemStack itemstack) { + return false; + } + + @Override + public void clear() {} + }; + private final IContainerProperties containerProperties = new IContainerProperties() { + @Override + public int getProperty(int i) { + return i == 0 ? TileEntityLectern.this.page : 0; + } + + @Override + public void setProperty(int i, int j) { + if (i == 0) { + TileEntityLectern.this.setPage(j); + } + + } + + @Override + public int a() { + return 1; + } + }; + private ItemStack book; + private int page; + private int maxPage; + + public TileEntityLectern() { + super(TileEntityTypes.LECTERN); + this.book = ItemStack.a; + } + + public ItemStack getBook() { + return this.book; + } + + public boolean hasBook() { + Item item = this.book.getItem(); + + return item == Items.WRITABLE_BOOK || item == Items.WRITTEN_BOOK; + } + + public void setBook(ItemStack itemstack) { + this.a(itemstack, (EntityHuman) null); + } + + private void t() { + this.page = 0; + this.maxPage = 0; + BlockLectern.setHasBook(this.getWorld(), this.getPosition(), this.getBlock(), false); + } + + public void a(ItemStack itemstack, @Nullable EntityHuman entityhuman) { + this.book = this.b(itemstack, entityhuman); + this.page = 0; + this.maxPage = ItemWrittenBook.j(this.book); + this.update(); + } + + public void setPage(int i) { + int j = MathHelper.clamp(i, 0, this.maxPage - 1); + + if (j != this.page) { + this.page = j; + this.update(); + BlockLectern.a(this.getWorld(), this.getPosition(), this.getBlock()); + } + + } + + public int getPage() { + return this.page; + } + + public int s() { + float f = this.maxPage > 1 ? (float) this.getPage() / ((float) this.maxPage - 1.0F) : 1.0F; + + return MathHelper.d(f * 14.0F) + (this.hasBook() ? 1 : 0); + } + + private ItemStack b(ItemStack itemstack, @Nullable EntityHuman entityhuman) { + if (this.world instanceof WorldServer && itemstack.getItem() == Items.WRITTEN_BOOK) { + ItemWrittenBook.a(itemstack, this.a(entityhuman), entityhuman); + } + + return itemstack; + } + + // CraftBukkit start + @Override + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + } + + @Override + public org.bukkit.command.CommandSender getBukkitSender(CommandListenerWrapper wrapper) { + return wrapper.getEntity() != null ? wrapper.getEntity().getBukkitSender(wrapper) : new org.bukkit.craftbukkit.command.CraftBlockCommandSender(wrapper, this); + } + + @Override + public boolean shouldSendSuccess() { + return false; + } + + @Override + public boolean shouldSendFailure() { + return false; + } + + @Override + public boolean shouldBroadcastCommands() { + return false; + } + + // CraftBukkit end + private CommandListenerWrapper a(@Nullable EntityHuman entityhuman) { + String s; + Object object; + + if (entityhuman == null) { + s = "Lectern"; + object = new ChatComponentText("Lectern"); + } else { + s = entityhuman.getDisplayName().getString(); + object = entityhuman.getScoreboardDisplayName(); + } + + Vec3D vec3d = new Vec3D((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D); + + // CraftBukkit - this + return new CommandListenerWrapper(this, vec3d, Vec2F.a, (WorldServer) this.world, 2, s, (IChatBaseComponent) object, this.world.getMinecraftServer(), entityhuman); + } + + @Override + public boolean isFilteredNBT() { + return true; + } + + @Override + public void load(NBTTagCompound nbttagcompound) { + super.load(nbttagcompound); + if (nbttagcompound.hasKeyOfType("Book", 10)) { + this.book = this.b(ItemStack.a(nbttagcompound.getCompound("Book")), (EntityHuman) null); + } else { + this.book = ItemStack.a; + } + + this.maxPage = ItemWrittenBook.j(this.book); + this.page = MathHelper.clamp(nbttagcompound.getInt("Page"), 0, this.maxPage - 1); + } + + @Override + public NBTTagCompound save(NBTTagCompound nbttagcompound) { + super.save(nbttagcompound); + if (!this.getBook().isEmpty()) { + nbttagcompound.set("Book", this.getBook().save(new NBTTagCompound())); + nbttagcompound.setInt("Page", this.page); + } + + return nbttagcompound; + } + + @Override + public void clear() { + this.setBook(ItemStack.a); + } + + @Override + public Container createMenu(int i, PlayerInventory playerinventory, EntityHuman entityhuman) { + return new ContainerLectern(i, this.inventory, this.containerProperties, playerinventory); // CraftBukkit + } + + @Override + public IChatBaseComponent getScoreboardDisplayName() { + return new ChatMessage("container.lectern", new Object[0]); + } +} diff --git a/src/main/java/net/minecraft/server/TileEntityLootable.java b/src/main/java/net/minecraft/server/TileEntityLootable.java index 60f0b5046..a12d49fc4 100644 --- a/src/main/java/net/minecraft/server/TileEntityLootable.java +++ b/src/main/java/net/minecraft/server/TileEntityLootable.java @@ -3,11 +3,11 @@ package net.minecraft.server; import java.util.Random; import javax.annotation.Nullable; -public abstract class TileEntityLootable extends TileEntityContainer implements ILootable { +public abstract class TileEntityLootable extends TileEntityContainer { - protected MinecraftKey g; public MinecraftKey getLootTableKey() { return g; } public void setLootTable(MinecraftKey key) { g = key; } // Paper - OBFHELPER - protected long h; public long getSeed() { return h; } public void setSeed(long seed) { h = seed; } // Paper - OBFHELPER - protected IChatBaseComponent i; + @Nullable + public MinecraftKey lootTable; public MinecraftKey getLootTableKey() { return this.lootTable; } public void setLootTable(final MinecraftKey key) { this.lootTable = key; } // Paper - OBFHELPER + public long lootTableSeed; public long getSeed() { return this.lootTableSeed; } public void setSeed(final long seed) { this.lootTableSeed = seed; } // Paper - OBFHELPER public final com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(new com.destroystokyo.paper.loottable.PaperTileEntityLootableInventory(this)); // Paper protected TileEntityLootable(TileEntityTypes tileentitytypes) { @@ -24,10 +24,10 @@ public abstract class TileEntityLootable extends TileEntityContainer implements } protected boolean d(NBTTagCompound nbttagcompound) { - lootableData.loadNbt(nbttagcompound); // Paper + this.lootableData.loadNbt(nbttagcompound); // Paper if (nbttagcompound.hasKeyOfType("LootTable", 8)) { - this.g = new MinecraftKey(nbttagcompound.getString("LootTable")); - this.h = nbttagcompound.getLong("LootTableSeed"); + this.lootTable = new MinecraftKey(nbttagcompound.getString("LootTable")); + this.lootTableSeed = nbttagcompound.getLong("LootTableSeed"); return false; // Paper - always load the items, table may still remain } else { return false; @@ -35,13 +35,13 @@ public abstract class TileEntityLootable extends TileEntityContainer implements } protected boolean e(NBTTagCompound nbttagcompound) { - lootableData.saveNbt(nbttagcompound); // Paper - if (this.g == null) { + this.lootableData.saveNbt(nbttagcompound); // Paper + if (this.lootTable == null) { return false; } else { - nbttagcompound.setString("LootTable", this.g.toString()); - if (this.h != 0L) { - nbttagcompound.setLong("LootTableSeed", this.h); + nbttagcompound.setString("LootTable", this.lootTable.toString()); + if (this.lootTableSeed != 0L) { + nbttagcompound.setLong("LootTableSeed", this.lootTableSeed); } return false; // Paper - always save the items, table may still remain @@ -49,60 +49,36 @@ public abstract class TileEntityLootable extends TileEntityContainer implements } public void d(@Nullable EntityHuman entityhuman) { - if (lootableData.shouldReplenish(entityhuman) && this.world.getMinecraftServer() != null) { // Paper - LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(this.g); + if (this.lootableData.shouldReplenish(entityhuman) && this.world.getMinecraftServer() != null) { // Paper + LootTable loottable = this.world.getMinecraftServer().getLootTableRegistry().getLootTable(this.lootTable); - lootableData.processRefill(entityhuman); // Paper - Random random; + this.lootableData.processRefill(entityhuman); // Paper + LootTableInfo.Builder loottableinfo_builder = (new LootTableInfo.Builder((WorldServer) this.world)).set(LootContextParameters.POSITION, new BlockPosition(this.position)).a(this.lootTableSeed); - if (this.h == 0L) { - random = new Random(); - } else { - random = new Random(this.h); - } - - LootTableInfo.Builder loottableinfo_builder = new LootTableInfo.Builder((WorldServer) this.world); - - loottableinfo_builder.position(this.position); if (entityhuman != null) { - loottableinfo_builder.luck(entityhuman.dJ()); + loottableinfo_builder.a(entityhuman.eb()).set(LootContextParameters.THIS_ENTITY, entityhuman); } - loottable.fillInventory(this, random, loottableinfo_builder.build()); + loottable.fillInventory(this, loottableinfo_builder.build(LootContextParameterSets.CHEST)); } } - public MinecraftKey getLootTable() { - return this.g; - } - public void setLootTable(MinecraftKey minecraftkey, long i) { - this.g = minecraftkey; - this.h = i; - } - - public boolean hasCustomName() { - return this.i != null; - } - - public void setCustomName(@Nullable IChatBaseComponent ichatbasecomponent) { - this.i = ichatbasecomponent; - } - - @Nullable - public IChatBaseComponent getCustomName() { - return this.i; + this.lootTable = minecraftkey; + this.lootTableSeed = i; } + @Override public ItemStack getItem(int i) { this.d((EntityHuman) null); - return (ItemStack) this.q().get(i); + return (ItemStack) this.f().get(i); } + @Override public ItemStack splitStack(int i, int j) { this.d((EntityHuman) null); - ItemStack itemstack = ContainerUtil.a(this.q(), i, j); + ItemStack itemstack = ContainerUtil.a(this.f(), i, j); if (!itemstack.isEmpty()) { this.update(); @@ -111,14 +87,16 @@ public abstract class TileEntityLootable extends TileEntityContainer implements return itemstack; } + @Override public ItemStack splitWithoutUpdate(int i) { this.d((EntityHuman) null); - return ContainerUtil.a(this.q(), i); + return ContainerUtil.a(this.f(), i); } - public void setItem(int i, @Nullable ItemStack itemstack) { + @Override + public void setItem(int i, ItemStack itemstack) { this.d((EntityHuman) null); - this.q().set(i, itemstack); + this.f().set(i, itemstack); if (itemstack.getCount() > this.getMaxStackSize()) { itemstack.setCount(this.getMaxStackSize()); } @@ -126,33 +104,33 @@ public abstract class TileEntityLootable extends TileEntityContainer implements this.update(); } + @Override public boolean a(EntityHuman entityhuman) { - return this.world.getTileEntity(this.position) != this ? false : entityhuman.d((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; - } - - public void startOpen(EntityHuman entityhuman) {} - - public void closeContainer(EntityHuman entityhuman) {} - - public boolean b(int i, ItemStack itemstack) { - return true; - } - - public int getProperty(int i) { - return 0; - } - - public void setProperty(int i, int j) {} - - public int h() { - return 0; + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; } + @Override public void clear() { - this.q().clear(); + this.f().clear(); } - protected abstract NonNullList q(); + protected abstract NonNullList f(); protected abstract void a(NonNullList nonnulllist); + + @Override + public boolean e(EntityHuman entityhuman) { + return super.e(entityhuman) && (this.lootTable == null || !entityhuman.isSpectator()); + } + + @Nullable + @Override + public Container createMenu(int i, PlayerInventory playerinventory, EntityHuman entityhuman) { + if (this.e(entityhuman)) { + this.d(playerinventory.player); + return this.createContainer(i, playerinventory); + } else { + return null; + } + } } diff --git a/src/main/java/net/minecraft/server/TileEntityShulkerBox.java b/src/main/java/net/minecraft/server/TileEntityShulkerBox.java index 296b8dd56..fe64a99bd 100644 --- a/src/main/java/net/minecraft/server/TileEntityShulkerBox.java +++ b/src/main/java/net/minecraft/server/TileEntityShulkerBox.java @@ -12,22 +12,20 @@ import org.bukkit.entity.HumanEntity; public class TileEntityShulkerBox extends TileEntityLootable implements IWorldInventory, ITickable { private static final int[] a = IntStream.range(0, 27).toArray(); - private NonNullList e; - private boolean f; - private int j; - private TileEntityShulkerBox.AnimationPhase k; - private float l; - private float m; - private EnumColor n; - private boolean o; - private boolean p; + private NonNullList contents; + private int c; + private TileEntityShulkerBox.AnimationPhase i; + private float j; + private float k; + private EnumColor l; + private boolean m; // CraftBukkit start - add fields and methods public List transaction = new java.util.ArrayList(); private int maxStack = MAX_STACK; public List getContents() { - return this.e; + return this.contents; } public void onOpen(CraftHumanEntity who) { @@ -42,6 +40,11 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn return transaction; } + @Override + public int getMaxStackSize() { + return maxStack; + } + public void setMaxStackSize(int size) { maxStack = size; } @@ -49,53 +52,56 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn public TileEntityShulkerBox(@Nullable EnumColor enumcolor) { super(TileEntityTypes.SHULKER_BOX); - this.e = NonNullList.a(27, ItemStack.a); - this.k = TileEntityShulkerBox.AnimationPhase.CLOSED; - this.n = enumcolor; + this.contents = NonNullList.a(27, ItemStack.a); + this.i = TileEntityShulkerBox.AnimationPhase.CLOSED; + this.l = enumcolor; } public TileEntityShulkerBox() { this((EnumColor) null); - this.o = true; + this.m = true; } + @Override public void tick() { - this.p(); - if (this.k == TileEntityShulkerBox.AnimationPhase.OPENING || this.k == TileEntityShulkerBox.AnimationPhase.CLOSING) { - this.H(); + this.h(); + if (this.i == TileEntityShulkerBox.AnimationPhase.OPENING || this.i == TileEntityShulkerBox.AnimationPhase.CLOSING) { + this.u(); } } - protected void p() { - this.m = this.l; - switch (this.k) { - case CLOSED: - this.l = 0.0F; - break; - case OPENING: - this.l += 0.1F; - if (this.l >= 1.0F) { - this.H(); - this.k = TileEntityShulkerBox.AnimationPhase.OPENED; - this.l = 1.0F; - } - break; - case CLOSING: - this.l -= 0.1F; - if (this.l <= 0.0F) { - this.k = TileEntityShulkerBox.AnimationPhase.CLOSED; - this.l = 0.0F; - } - break; - case OPENED: - this.l = 1.0F; + protected void h() { + this.k = this.j; + switch (this.i) { + case CLOSED: + this.j = 0.0F; + break; + case OPENING: + this.j += 0.1F; + if (this.j >= 1.0F) { + this.u(); + this.i = TileEntityShulkerBox.AnimationPhase.OPENED; + this.j = 1.0F; + this.v(); + } + break; + case CLOSING: + this.j -= 0.1F; + if (this.j <= 0.0F) { + this.i = TileEntityShulkerBox.AnimationPhase.CLOSED; + this.j = 0.0F; + this.v(); + } + break; + case OPENED: + this.j = 1.0F; } } - public TileEntityShulkerBox.AnimationPhase r() { - return this.k; + public TileEntityShulkerBox.AnimationPhase s() { + return this.i; } public AxisAlignedBB a(IBlockData iblockdata) { @@ -103,7 +109,9 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn } public AxisAlignedBB b(EnumDirection enumdirection) { - return VoxelShapes.b().getBoundingBox().b((double) (0.5F * this.a(1.0F) * (float) enumdirection.getAdjacentX()), (double) (0.5F * this.a(1.0F) * (float) enumdirection.getAdjacentY()), (double) (0.5F * this.a(1.0F) * (float) enumdirection.getAdjacentZ())); + float f = this.a(1.0F); + + return VoxelShapes.b().getBoundingBox().b((double) (0.5F * f * (float) enumdirection.getAdjacentX()), (double) (0.5F * f * (float) enumdirection.getAdjacentY()), (double) (0.5F * f * (float) enumdirection.getAdjacentZ())); } private AxisAlignedBB c(EnumDirection enumdirection) { @@ -112,7 +120,7 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn return this.b(enumdirection).a((double) enumdirection1.getAdjacentX(), (double) enumdirection1.getAdjacentY(), (double) enumdirection1.getAdjacentZ()); } - private void H() { + private void u() { IBlockData iblockdata = this.world.getType(this.getPosition()); if (iblockdata.getBlock() instanceof BlockShulkerBox) { @@ -131,35 +139,35 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn AxisAlignedBB axisalignedbb1 = entity.getBoundingBox(); switch (enumdirection.k()) { - case X: - if (enumdirection.c() == EnumDirection.EnumAxisDirection.POSITIVE) { - d0 = axisalignedbb.maxX - axisalignedbb1.minX; - } else { - d0 = axisalignedbb1.maxX - axisalignedbb.minX; - } + case X: + if (enumdirection.c() == EnumDirection.EnumAxisDirection.POSITIVE) { + d0 = axisalignedbb.maxX - axisalignedbb1.minX; + } else { + d0 = axisalignedbb1.maxX - axisalignedbb.minX; + } - d0 += 0.01D; - break; - case Y: - if (enumdirection.c() == EnumDirection.EnumAxisDirection.POSITIVE) { - d1 = axisalignedbb.maxY - axisalignedbb1.minY; - } else { - d1 = axisalignedbb1.maxY - axisalignedbb.minY; - } + d0 += 0.01D; + break; + case Y: + if (enumdirection.c() == EnumDirection.EnumAxisDirection.POSITIVE) { + d1 = axisalignedbb.maxY - axisalignedbb1.minY; + } else { + d1 = axisalignedbb1.maxY - axisalignedbb.minY; + } - d1 += 0.01D; - break; - case Z: - if (enumdirection.c() == EnumDirection.EnumAxisDirection.POSITIVE) { - d2 = axisalignedbb.maxZ - axisalignedbb1.minZ; - } else { - d2 = axisalignedbb1.maxZ - axisalignedbb.minZ; - } + d1 += 0.01D; + break; + case Z: + if (enumdirection.c() == EnumDirection.EnumAxisDirection.POSITIVE) { + d2 = axisalignedbb.maxZ - axisalignedbb1.minZ; + } else { + d2 = axisalignedbb1.maxZ - axisalignedbb.minZ; + } - d2 += 0.01D; + d2 += 0.01D; } - entity.move(EnumMoveType.SHULKER_BOX, d0 * (double) enumdirection.getAdjacentX(), d1 * (double) enumdirection.getAdjacentY(), d2 * (double) enumdirection.getAdjacentZ()); + entity.move(EnumMoveType.SHULKER_BOX, new Vec3D(d0 * (double) enumdirection.getAdjacentX(), d1 * (double) enumdirection.getAdjacentY(), d2 * (double) enumdirection.getAdjacentZ())); } } @@ -167,121 +175,109 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn } } + @Override public int getSize() { - return this.e.size(); + return this.contents.size(); } - public int getMaxStackSize() { - return maxStack; // CraftBukkit - } - - public boolean c(int i, int j) { + @Override + public boolean setProperty(int i, int j) { if (i == 1) { - this.j = j; + this.c = j; if (j == 0) { - this.k = TileEntityShulkerBox.AnimationPhase.CLOSING; + this.i = TileEntityShulkerBox.AnimationPhase.CLOSING; + this.v(); } if (j == 1) { - this.k = TileEntityShulkerBox.AnimationPhase.OPENING; + this.i = TileEntityShulkerBox.AnimationPhase.OPENING; + this.v(); } return true; } else { - return super.c(i, j); + return super.setProperty(i, j); } } + private void v() { + this.getBlock().a(this.getWorld(), this.getPosition(), 3); + } + + @Override public void startOpen(EntityHuman entityhuman) { if (!entityhuman.isSpectator()) { - if (this.j < 0) { - this.j = 0; + if (this.c < 0) { + this.c = 0; } - ++this.j; - this.world.playBlockAction(this.position, this.getBlock().getBlock(), 1, this.j); - if (this.j == 1) { - this.world.a((EntityHuman) null, this.position, SoundEffects.BLOCK_SHULKER_BOX_OPEN, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + ++this.c; + this.world.playBlockAction(this.position, this.getBlock().getBlock(), 1, this.c); + if (this.c == 1) { + this.world.playSound((EntityHuman) null, this.position, SoundEffects.BLOCK_SHULKER_BOX_OPEN, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); } } } + @Override public void closeContainer(EntityHuman entityhuman) { if (!entityhuman.isSpectator()) { - --this.j; - this.world.playBlockAction(this.position, this.getBlock().getBlock(), 1, this.j); - if (this.j <= 0) { - this.world.a((EntityHuman) null, this.position, SoundEffects.BLOCK_SHULKER_BOX_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + --this.c; + this.world.playBlockAction(this.position, this.getBlock().getBlock(), 1, this.c); + if (this.c <= 0) { + this.world.playSound((EntityHuman) null, this.position, SoundEffects.BLOCK_SHULKER_BOX_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); } } } - public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { - return new ContainerShulkerBox(playerinventory, this, entityhuman); - } - - public String getContainerName() { - return "minecraft:shulker_box"; - } - - public IChatBaseComponent getDisplayName() { - IChatBaseComponent ichatbasecomponent = this.getCustomName(); - - return (IChatBaseComponent) (ichatbasecomponent != null ? ichatbasecomponent : new ChatMessage("container.shulkerBox", new Object[0])); + @Override + protected IChatBaseComponent getContainerName() { + return new ChatMessage("container.shulkerBox", new Object[0]); } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); this.f(nbttagcompound); } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); return this.g(nbttagcompound); } public void f(NBTTagCompound nbttagcompound) { - this.e = NonNullList.a(this.getSize(), ItemStack.a); + this.contents = NonNullList.a(this.getSize(), ItemStack.a); if (!this.d(nbttagcompound) && nbttagcompound.hasKeyOfType("Items", 9)) { - ContainerUtil.b(nbttagcompound, this.e); - } - - if (nbttagcompound.hasKeyOfType("CustomName", 8)) { - this.i = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException + ContainerUtil.b(nbttagcompound, this.contents); } } public NBTTagCompound g(NBTTagCompound nbttagcompound) { if (!this.e(nbttagcompound)) { - ContainerUtil.a(nbttagcompound, this.e, false); - } - - IChatBaseComponent ichatbasecomponent = this.getCustomName(); - - if (ichatbasecomponent != null) { - nbttagcompound.setString("CustomName", IChatBaseComponent.ChatSerializer.a(ichatbasecomponent)); - } - - if (!nbttagcompound.hasKey("Lock") && this.isLocked()) { - this.getLock().a(nbttagcompound); + ContainerUtil.a(nbttagcompound, this.contents, false); } return nbttagcompound; } - protected NonNullList q() { - return this.e; + @Override + protected NonNullList f() { + return this.contents; } + @Override protected void a(NonNullList nonnulllist) { - this.e = nonnulllist; + this.contents = nonnulllist; } - public boolean P_() { - Iterator iterator = this.e.iterator(); + @Override + public boolean isNotEmpty() { + Iterator iterator = this.contents.iterator(); ItemStack itemstack; @@ -296,46 +292,28 @@ public class TileEntityShulkerBox extends TileEntityLootable implements IWorldIn return false; } + @Override public int[] getSlotsForFace(EnumDirection enumdirection) { return TileEntityShulkerBox.a; } + @Override public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, @Nullable EnumDirection enumdirection) { return !(Block.asBlock(itemstack.getItem()) instanceof BlockShulkerBox); } + @Override public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { return true; } - public void clear() { - this.f = true; - super.clear(); - } - - public boolean s() { - return this.f; - } - public float a(float f) { - return this.m + (this.l - this.m) * f; + return MathHelper.g(f, this.k, this.j); } - @Nullable - public PacketPlayOutTileEntityData getUpdatePacket() { - return new PacketPlayOutTileEntityData(this.position, 10, this.aa_()); - } - - public boolean E() { - return this.p; - } - - public void a(boolean flag) { - this.p = flag; - } - - public boolean G() { - return !this.E() || !this.P_() || this.hasCustomName() || this.g != null; + @Override + protected Container createContainer(int i, PlayerInventory playerinventory) { + return new ContainerShulkerBox(i, playerinventory, this); } public static enum AnimationPhase { diff --git a/src/main/java/net/minecraft/server/TileEntitySign.java b/src/main/java/net/minecraft/server/TileEntitySign.java index d0a91f675..0a8d9b52d 100644 --- a/src/main/java/net/minecraft/server/TileEntitySign.java +++ b/src/main/java/net/minecraft/server/TileEntitySign.java @@ -3,13 +3,16 @@ package net.minecraft.server; import com.mojang.brigadier.exceptions.CommandSyntaxException; import javax.annotation.Nullable; -public class TileEntitySign extends TileEntity implements ICommandListener { +public class TileEntitySign extends TileEntity implements ICommandListener { // CraftBukkit - implements - public final IChatBaseComponent[] lines = new IChatBaseComponent[] { new ChatComponentText(""), new ChatComponentText(""), new ChatComponentText(""), new ChatComponentText("")}; - public int e = -1; + public final IChatBaseComponent[] lines = new IChatBaseComponent[]{new ChatComponentText(""), new ChatComponentText(""), new ChatComponentText(""), new ChatComponentText("")}; + private int c = -1; + private int g = -1; + private int h = -1; public boolean isEditable = true; - private EntityHuman g; - private final String[] h = new String[4]; + private EntityHuman j; + private final String[] k = new String[4]; + private EnumColor color; // Paper start - Strip invalid unicode from signs on load private static final boolean keepInvalidUnicode = Boolean.getBoolean("Paper.keepInvalidUnicode"); // Allow people to keep their bad unicode if they really want it @@ -20,8 +23,10 @@ public class TileEntitySign extends TileEntity implements ICommandListener { public TileEntitySign() { super(TileEntityTypes.SIGN); + this.color = EnumColor.BLACK; } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); @@ -37,7 +42,8 @@ public class TileEntitySign extends TileEntity implements ICommandListener { } // CraftBukkit end - // Paper start - Only remove private area unicode once + nbttagcompound.setString("Color", this.color.b()); + // Paper start - Only remove private area unicode once // TODO - this doesn't need to run for every sign, check data ver if (this.privateUnicodeRemoved) { nbttagcompound.setBoolean("Paper.RemovedPrivateUnicode", true); } @@ -46,9 +52,11 @@ public class TileEntitySign extends TileEntity implements ICommandListener { return nbttagcompound; } + @Override public void load(NBTTagCompound nbttagcompound) { this.isEditable = false; super.load(nbttagcompound); + this.color = EnumColor.a(nbttagcompound.getString("Color"), EnumColor.BLACK); // Paper start - Keep track, only do it once per sign this.privateUnicodeRemoved = nbttagcompound.getBoolean("Paper.RemovedPrivateUnicode"); @@ -81,18 +89,18 @@ public class TileEntitySign extends TileEntity implements ICommandListener { // Paper end try { - //IChatBaseComponent ichatbasecomponent = IChatBaseComponent.ChatSerializer.a(s); // Paper - move down - the old format might throw a json error + //IChatBaseComponent ichatbasecomponent = IChatBaseComponent.ChatSerializer.a(s.isEmpty() ? "\"\"" : s); // Paper - move down - the old format might throw a json error if (oldSign && !isLoadingStructure) { // Paper - saved structures will be in the new format, but will not have isConverted lines[i] = org.bukkit.craftbukkit.util.CraftChatMessage.fromString(s)[0]; continue; } // CraftBukkit end - IChatBaseComponent ichatbasecomponent = IChatBaseComponent.ChatSerializer.a(s); // Paper - after old sign + IChatBaseComponent ichatbasecomponent = IChatBaseComponent.ChatSerializer.a(s.isEmpty() ? "\"\"" : s); // Paper - after old sign if (this.world instanceof WorldServer) { try { - this.lines[i] = ChatComponentUtils.filterForDisplay(this.a((EntityPlayer) null), ichatbasecomponent, (Entity) null); + this.lines[i] = ChatComponentUtils.filterForDisplay(this.a((EntityPlayer) null), ichatbasecomponent, (Entity) null, 0); } catch (CommandSyntaxException commandsyntaxexception) { this.lines[i] = ichatbasecomponent; } @@ -103,7 +111,7 @@ public class TileEntitySign extends TileEntity implements ICommandListener { this.lines[i] = new ChatComponentText(s); } - this.h[i] = null; + this.k[i] = null; } if (ranUnicodeRemoval) this.privateUnicodeRemoved = true; // Paper - Flag to write NBT @@ -111,18 +119,21 @@ public class TileEntitySign extends TileEntity implements ICommandListener { public void a(int i, IChatBaseComponent ichatbasecomponent) { this.lines[i] = ichatbasecomponent; - this.h[i] = null; + this.k[i] = null; } @Nullable + @Override public PacketPlayOutTileEntityData getUpdatePacket() { - return new PacketPlayOutTileEntityData(this.position, 9, this.aa_()); + return new PacketPlayOutTileEntityData(this.position, 9, this.b()); } - public NBTTagCompound aa_() { + @Override + public NBTTagCompound b() { return this.save(new NBTTagCompound()); } + @Override public boolean isFilteredNBT() { return true; } @@ -138,8 +149,8 @@ public class TileEntitySign extends TileEntity implements ICommandListener { // Paper end } - public EntityHuman e() { - return this.g; + public EntityHuman f() { + return this.j; } public boolean b(EntityHuman entityhuman) { @@ -150,11 +161,11 @@ public class TileEntitySign extends TileEntity implements ICommandListener { IChatBaseComponent ichatbasecomponent = aichatbasecomponent[j]; ChatModifier chatmodifier = ichatbasecomponent == null ? null : ichatbasecomponent.getChatModifier(); - if (chatmodifier != null && chatmodifier.h() != null) { - ChatClickable chatclickable = chatmodifier.h(); + if (chatmodifier != null && chatmodifier.getClickEvent() != null) { + ChatClickable chatclickable = chatmodifier.getClickEvent(); if (chatclickable.a() == ChatClickable.EnumClickAction.RUN_COMMAND) { - entityhuman.bK().getCommandDispatcher().a(this.a((EntityPlayer) entityhuman), chatclickable.b()); + entityhuman.getMinecraftServer().getCommandDispatcher().a(this.a((EntityPlayer) entityhuman), chatclickable.b()); } } } @@ -162,31 +173,51 @@ public class TileEntitySign extends TileEntity implements ICommandListener { return true; } + // CraftBukkit start + @Override public void sendMessage(IChatBaseComponent ichatbasecomponent) {} - // CraftBukkit start @Override public org.bukkit.command.CommandSender getBukkitSender(CommandListenerWrapper wrapper) { return wrapper.getEntity() != null ? wrapper.getEntity().getBukkitSender(wrapper) : new org.bukkit.craftbukkit.command.CraftBlockCommandSender(wrapper, this); } + + @Override + public boolean shouldSendSuccess() { + return false; + } + + @Override + public boolean shouldSendFailure() { + return false; + } + + @Override + public boolean shouldBroadcastCommands() { + return false; + } // CraftBukkit end public CommandListenerWrapper a(@Nullable EntityPlayer entityplayer) { String s = entityplayer == null ? "Sign" : entityplayer.getDisplayName().getString(); Object object = entityplayer == null ? new ChatComponentText("Sign") : entityplayer.getScoreboardDisplayName(); + // CraftBukkit - this return new CommandListenerWrapper(this, new Vec3D((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D), Vec2F.a, (WorldServer) this.world, 2, s, (IChatBaseComponent) object, this.world.getMinecraftServer(), entityplayer); } - public boolean a() { - return false; + public EnumColor getColor() { + return this.color; } - public boolean b() { - return false; - } - - public boolean B_() { - return false; + public boolean setColor(EnumColor enumcolor) { + if (enumcolor != this.getColor()) { + this.color = enumcolor; + this.update(); + if (this.world != null) this.world.notify(this.getPosition(), this.getBlock(), this.getBlock(), 3); // CraftBukkit - skip notify if world is null (SPIGOT-5122) + return true; + } else { + return false; + } } } diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java index 45c90c254..0882d82ce 100644 --- a/src/main/java/net/minecraft/server/TileEntitySkull.java +++ b/src/main/java/net/minecraft/server/TileEntitySkull.java @@ -26,10 +26,9 @@ import java.util.concurrent.Callable; public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Paper - remove tickable - private GameProfile a; - private int e; - private boolean f; - public boolean drop = true; + public GameProfile gameProfile; + private int b; + private boolean c; private static UserCache userCache; private static MinecraftSessionService sessionService; // Spigot start @@ -38,10 +37,10 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa .setNameFormat("Head Conversion Thread - %1$d") .build() ); - public static final com.github.benmanes.caffeine.cache.LoadingCache skinCache = com.github.benmanes.caffeine.cache.Caffeine.newBuilder() // Akarin - caffeine + public static final LoadingCache skinCache = CacheBuilder.newBuilder() .maximumSize( 5000 ) .expireAfterAccess( 60, TimeUnit.MINUTES ) - .build( new com.github.benmanes.caffeine.cache.CacheLoader() + .build( new CacheLoader() { @Override public GameProfile load(String key) throws Exception @@ -97,18 +96,20 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa TileEntitySkull.sessionService = minecraftsessionservice; } + @Override public NBTTagCompound save(NBTTagCompound nbttagcompound) { super.save(nbttagcompound); - if (this.a != null) { + if (this.gameProfile != null) { NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - GameProfileSerializer.serialize(nbttagcompound1, this.a); + GameProfileSerializer.serialize(nbttagcompound1, this.gameProfile); nbttagcompound.set("Owner", nbttagcompound1); } return nbttagcompound; } + @Override public void load(NBTTagCompound nbttagcompound) { super.load(nbttagcompound); if (nbttagcompound.hasKeyOfType("Owner", 10)) { @@ -123,23 +124,25 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa } + // Paper - remove override public void tick() { Block block = this.getBlock().getBlock(); if (block == Blocks.DRAGON_HEAD || block == Blocks.DRAGON_WALL_HEAD) { if (this.world.isBlockIndirectlyPowered(this.position)) { - this.f = true; - ++this.e; + this.c = true; + ++this.b; } else { - this.f = false; + this.c = false; } } } @Nullable - public GameProfile getGameProfile() { - return this.a; + @Override + public PacketPlayOutTileEntityData getUpdatePacket() { + return new PacketPlayOutTileEntityData(this.position, 4, sanitizeTileEntityUUID(this.b())); // Paper } // Paper start @@ -170,28 +173,24 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa } // Paper end - @Nullable - public PacketPlayOutTileEntityData getUpdatePacket() { - return new PacketPlayOutTileEntityData(this.position, 4, sanitizeTileEntityUUID(this.aa_())); // Paper - } - - public NBTTagCompound aa_() { + @Override + public NBTTagCompound b() { return this.save(new NBTTagCompound()); } public void setGameProfile(@Nullable GameProfile gameprofile) { - this.a = gameprofile; + this.gameProfile = gameprofile; this.f(); } private void f() { // Spigot start - GameProfile profile = this.getGameProfile(); + GameProfile profile = this.gameProfile; b(profile, new Predicate() { @Override public boolean apply(GameProfile input) { - a = input; + gameProfile = input; update(); return false; } @@ -216,7 +215,7 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa Callable callable = new Callable() { @Override public GameProfile call() { - final GameProfile profile = skinCache.get(gameprofile.getName().toLowerCase(java.util.Locale.ROOT)); // Akarin - caffeine + final GameProfile profile = skinCache.getUnchecked(gameprofile.getName().toLowerCase(java.util.Locale.ROOT)); MinecraftServer.getServer().processQueue.add(new Runnable() { @Override public void run() { @@ -249,25 +248,4 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa return Futures.immediateFuture(gameprofile); } // Spigot end - - // CraftBukkit start - public static void a(IBlockAccess iblockaccess, BlockPosition blockposition) { - setShouldDrop(iblockaccess, blockposition, false); - } - - public static void setShouldDrop(IBlockAccess iblockaccess, BlockPosition blockposition, boolean flag) { - // CraftBukkit end - TileEntity tileentity = iblockaccess.getTileEntity(blockposition); - - if (tileentity instanceof TileEntitySkull) { - TileEntitySkull tileentityskull = (TileEntitySkull) tileentity; - - tileentityskull.drop = flag; // CraftBukkit - } - - } - - public boolean shouldDrop() { - return this.drop; - } } diff --git a/src/main/java/net/minecraft/server/UserCache.java b/src/main/java/net/minecraft/server/UserCache.java index 02de6eb1c..1d4bf64b1 100644 --- a/src/main/java/net/minecraft/server/UserCache.java +++ b/src/main/java/net/minecraft/server/UserCache.java @@ -43,15 +43,15 @@ public class UserCache { public static final SimpleDateFormat a = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); private static boolean c; - private final Map d = Maps.newHashMap();private final Map nameCache = d; // Paper - OBFHELPER - private final Map e = Maps.newHashMap(); + private final Map d = new java.util.concurrent.ConcurrentHashMap<>();private final Map nameCache = d; // Paper - OBFHELPER // Paper + private final Map e = new java.util.concurrent.ConcurrentHashMap<>(); // Paper private final Deque f = new java.util.concurrent.LinkedBlockingDeque(); // CraftBukkit - private GameProfileRepository g; public GameProfileRepository gameProfileRepository() { return this.g; } // Akarin - removed final - protected final Gson b; protected Gson gson() { return this.b; } // Akarin - OBFHELPER - private final File h; File file() { return this.h; } // Akarin - OBFHELPER + private final GameProfileRepository g; + protected final Gson b; + private final File h; private static final ParameterizedType i = new ParameterizedType() { public Type[] getActualTypeArguments() { - return new Type[] { UserCache.UserCacheEntry.class}; + return new Type[]{UserCache.UserCacheEntry.class}; } public Type getRawType() { @@ -62,16 +62,15 @@ public class UserCache { return null; } }; - static final ParameterizedType PARAMETERIZED_TYPE = i; // Akarin - OBFHELPER public UserCache(GameProfileRepository gameprofilerepository, File file) { - //this.g = gameprofilerepository; // Akarin + this.g = gameprofilerepository; this.h = file; GsonBuilder gsonbuilder = new GsonBuilder(); gsonbuilder.registerTypeHierarchyAdapter(UserCache.UserCacheEntry.class, new UserCache.BanEntrySerializer()); this.b = gsonbuilder.create(); - //this.b(); // Akarin + this.b(); } private static GameProfile a(GameProfileRepository gameprofilerepository, String s) { @@ -86,7 +85,7 @@ public class UserCache { } }; - gameprofilerepository.findProfilesByNames(new String[] { s}, Agent.MINECRAFT, profilelookupcallback); + gameprofilerepository.findProfilesByNames(new String[]{s}, Agent.MINECRAFT, profilelookupcallback); if (!d() && agameprofile[0] == null && !org.apache.commons.lang3.StringUtils.isBlank(s)) { // Paper - Don't lookup a profile with a blank name UUID uuid = EntityHuman.a(new GameProfile((UUID) null, s)); GameProfile gameprofile = new GameProfile(uuid, s); @@ -101,7 +100,6 @@ public class UserCache { UserCache.c = flag; } - static boolean isOnlineMode() { return d(); } // Akarin - OBFHELPER private static boolean d() { return UserCache.c; } @@ -176,7 +174,7 @@ public class UserCache { @Nullable public GameProfile getProfile(UUID uuid) { return a(uuid); } // Paper - OBFHELPER @Nullable - public synchronized GameProfile a(UUID uuid) { // Paper - synchronize + public GameProfile a(UUID uuid) { UserCache.UserCacheEntry usercache_usercacheentry = (UserCache.UserCacheEntry) this.e.get(uuid); return usercache_usercacheentry == null ? null : usercache_usercacheentry.a(); @@ -220,7 +218,7 @@ public class UserCache { ; // Spigot Start } catch (com.google.gson.JsonSyntaxException ex) { - JsonList.a.warn( "Usercache.json is corrupted or has bad formatting. Deleting it to prevent further issues." ); + JsonList.LOGGER.warn( "Usercache.json is corrupted or has bad formatting. Deleting it to prevent further issues." ); this.h.delete(); // Spigot End } catch (JsonParseException jsonparseexception) { @@ -281,12 +279,12 @@ public class UserCache { return list; } - static class UserCacheEntry { // Akarin - static + class UserCacheEntry { private final GameProfile b;public GameProfile getProfile() { return b; } // Paper - OBFHELPER - private final Date c; public Date getExpireDate() { return c; } // Akarin - OBFHELPER + private final Date c; - UserCacheEntry(GameProfile gameprofile, Date date) { // Akarin - package + private UserCacheEntry(GameProfile gameprofile, Date date) { this.b = gameprofile; this.c = date; } @@ -300,7 +298,7 @@ public class UserCache { } } - static class BanEntrySerializer implements JsonDeserializer, JsonSerializer { // Akarin - static + class BanEntrySerializer implements JsonDeserializer, JsonSerializer { private BanEntrySerializer() {} @@ -344,7 +342,7 @@ public class UserCache { return null; } - return new UserCacheEntry(new GameProfile(uuid, s1), date); // Akarin - static + return UserCache.this.new UserCacheEntry(new GameProfile(uuid, s1), date); } else { return null; } diff --git a/src/main/java/net/minecraft/server/Village.java b/src/main/java/net/minecraft/server/Village.java deleted file mode 100644 index 02b1229ff..000000000 --- a/src/main/java/net/minecraft/server/Village.java +++ /dev/null @@ -1,499 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.ProfileLookupCallback; - -import io.akarin.server.api.structure.CraftVillage; -import net.minecraft.server.UserCache.UserCacheEntry; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import javax.annotation.Nullable; - -public class Village { - - private World a; private World getWorld() { return a; } // Paper - OBFHELPER - private final List b = Lists.newArrayList(); - private BlockPosition c; - private BlockPosition d;public BlockPosition getCenter() { return d; } // Paper - OBFHELPER // Akarin - public - private int e; - private int f; - private int g; - private int h; - private int i; - private final Map j; - private final List k; - private int l; - public CraftVillage village = new CraftVillage(this); // Akarin - - private Village() { // Paper - Nothing should call this - world needs to be set. - this.c = BlockPosition.ZERO; - this.d = BlockPosition.ZERO; - this.j = Maps.newHashMap(); - this.k = Lists.newArrayList(); - } - - public Village(World world) { - this.c = BlockPosition.ZERO; - this.d = BlockPosition.ZERO; - this.j = Maps.newHashMap(); - this.k = Lists.newArrayList(); - this.a = world; - } - - public void a(World world) { - this.a = world; - } - - public void a(int i) { - // Paper - don't tick village if chunk isn't loaded - Chunk chunk = getWorld().getChunkIfLoaded(getCenter()); - if (chunk == null || !chunk.areNeighborsLoaded(1)) { - return; - } - // Paper end - this.g = i; - this.m(); - this.l(); - if (i % 20 == 0) { - this.k(); - } - - if (i % 30 == 0) { - this.j(); - } - - int j = this.h / 10; - - if (this.l < j && this.b.size() > 20 && this.a.random.nextInt(7000) == 0) { - Entity entity = this.f(this.d); - - if (entity != null) { - ++this.l; - } - } - - } - - @Nullable - private Entity f(BlockPosition blockposition) { - for (int i = 0; i < 10; ++i) { - BlockPosition blockposition1 = blockposition.a(this.a.random.nextInt(16) - 8, this.a.random.nextInt(6) - 3, this.a.random.nextInt(16) - 8); - - if (this.a(blockposition1)) { - EntityIronGolem entityirongolem = (EntityIronGolem) EntityTypes.IRON_GOLEM.b(this.a, (NBTTagCompound) null, (IChatBaseComponent) null, (EntityHuman) null, blockposition1, false, false); - - if (entityirongolem != null) { - if (entityirongolem.a((GeneratorAccess) this.a, false) && entityirongolem.a((IWorldReader) this.a)) { - this.a.addEntity(entityirongolem, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE); // CraftBukkit - return entityirongolem; - } - - entityirongolem.die(); - } - } - } - - return null; - } - - private void j() { - List list = this.a.a(EntityIronGolem.class, new AxisAlignedBB((double) (this.d.getX() - this.e), (double) (this.d.getY() - 4), (double) (this.d.getZ() - this.e), (double) (this.d.getX() + this.e), (double) (this.d.getY() + 4), (double) (this.d.getZ() + this.e))); - - this.l = list.size(); - } - - private void k() { - List list = this.a.a(EntityVillager.class, new AxisAlignedBB((double) (this.d.getX() - this.e), (double) (this.d.getY() - 4), (double) (this.d.getZ() - this.e), (double) (this.d.getX() + this.e), (double) (this.d.getY() + 4), (double) (this.d.getZ() + this.e))); - - this.h = list.size(); - if (this.h == 0) { - this.j.clear(); - } - - } - - public BlockPosition a() { - return this.d; - } - - public int b() { - return this.e; - } - - public int c() { - return this.b.size(); - } - - public int d() { - return this.g - this.f; - } - - public int e() { - return this.h; - } - - public boolean a(BlockPosition blockposition) { - return this.d.n(blockposition) < (double) (this.e * this.e); - } - - public List f() { - return this.b; - } - - public VillageDoor b(BlockPosition blockposition) { - VillageDoor villagedoor = null; - int i = Integer.MAX_VALUE; - Iterator iterator = this.b.iterator(); - - while (iterator.hasNext()) { - VillageDoor villagedoor1 = (VillageDoor) iterator.next(); - int j = villagedoor1.a(blockposition); - - if (j < i) { - villagedoor = villagedoor1; - i = j; - } - } - - return villagedoor; - } - - public VillageDoor c(BlockPosition blockposition) { - VillageDoor villagedoor = null; - int i = Integer.MAX_VALUE; - Iterator iterator = this.b.iterator(); - - while (iterator.hasNext()) { - VillageDoor villagedoor1 = (VillageDoor) iterator.next(); - int j = villagedoor1.a(blockposition); - - if (j > 256) { - j *= 1000; - } else { - j = villagedoor1.c(); - } - - if (j < i) { - BlockPosition blockposition1 = villagedoor1.d(); - EnumDirection enumdirection = villagedoor1.j(); - - if (this.a.getType(blockposition1.shift(enumdirection, 1)).a((IBlockAccess) this.a, blockposition1.shift(enumdirection, 1), PathMode.LAND) && this.a.getType(blockposition1.shift(enumdirection, -1)).a((IBlockAccess) this.a, blockposition1.shift(enumdirection, -1), PathMode.LAND) && this.a.getType(blockposition1.up().shift(enumdirection, 1)).a((IBlockAccess) this.a, blockposition1.up().shift(enumdirection, 1), PathMode.LAND) && this.a.getType(blockposition1.up().shift(enumdirection, -1)).a((IBlockAccess) this.a, blockposition1.up().shift(enumdirection, -1), PathMode.LAND)) { - villagedoor = villagedoor1; - i = j; - } - } - } - - return villagedoor; - } - - @Nullable - public VillageDoor e(BlockPosition blockposition) { - if (this.d.n(blockposition) > (double) (this.e * this.e)) { - return null; - } else { - Iterator iterator = this.b.iterator(); - - VillageDoor villagedoor; - - do { - if (!iterator.hasNext()) { - return null; - } - - villagedoor = (VillageDoor) iterator.next(); - } while (villagedoor.d().getX() != blockposition.getX() || villagedoor.d().getZ() != blockposition.getZ() || Math.abs(villagedoor.d().getY() - blockposition.getY()) > 1); - - return villagedoor; - } - } - - public void a(VillageDoor villagedoor) { - this.b.add(villagedoor); - this.c = this.c.a((BaseBlockPosition) villagedoor.d()); - this.n(); - this.f = villagedoor.h(); - } - - public boolean g() { - return this.b.isEmpty(); - } - - public void a(EntityLiving entityliving) { - Iterator iterator = this.k.iterator(); - - Village.Aggressor village_aggressor; - - do { - if (!iterator.hasNext()) { - this.k.add(new Village.Aggressor(entityliving, this.g)); - return; - } - - village_aggressor = (Village.Aggressor) iterator.next(); - } while (village_aggressor.a != entityliving); - - village_aggressor.b = this.g; - } - - @Nullable - public EntityLiving b(EntityLiving entityliving) { - double d0 = Double.MAX_VALUE; - Village.Aggressor village_aggressor = null; - - for (int i = 0; i < this.k.size(); ++i) { - Village.Aggressor village_aggressor1 = (Village.Aggressor) this.k.get(i); - double d1 = village_aggressor1.a.h(entityliving); - - if (d1 <= d0) { - village_aggressor = village_aggressor1; - d0 = d1; - } - } - - return village_aggressor == null ? null : village_aggressor.a; - } - - public EntityHuman c(EntityLiving entityliving) { - double d0 = Double.MAX_VALUE; - EntityHuman entityhuman = null; - Iterator iterator = this.j.keySet().iterator(); - - while (iterator.hasNext()) { - String s = (String) iterator.next(); - - if (this.d(s)) { - EntityHuman entityhuman1 = this.a.a(s); - - if (entityhuman1 != null) { - double d1 = entityhuman1.h(entityliving); - - if (d1 <= d0) { - entityhuman = entityhuman1; - d0 = d1; - } - } - } - } - - return entityhuman; - } - - private void l() { - Iterator iterator = this.k.iterator(); - - while (iterator.hasNext()) { - Village.Aggressor village_aggressor = (Village.Aggressor) iterator.next(); - - if (!village_aggressor.a.isAlive() || Math.abs(this.g - village_aggressor.b) > 300) { - iterator.remove(); - } - } - - } - - private void m() { - boolean flag = false; - boolean flag1 = this.a.random.nextInt(50) == 0; - Iterator iterator = this.b.iterator(); - - while (iterator.hasNext()) { - VillageDoor villagedoor = (VillageDoor) iterator.next(); - // Paper start - don't remove doors from unloaded chunks - if (!getWorld().isLoaded(villagedoor.getPosition())) { - villagedoor.setLastSeen(villagedoor.getLastSeen() + 1); - continue; - } - // Paper end - - if (flag1) { - villagedoor.a(); - } - - if (!this.g(villagedoor.d()) || Math.abs(this.g - villagedoor.h()) > 1200) { - this.c = this.c.b(villagedoor.d()); - flag = true; - villagedoor.a(true); - iterator.remove(); - } - } - - if (flag) { - this.n(); - } - - } - - private boolean g(BlockPosition blockposition) { - IBlockData iblockdata = this.a.paperConfig.villagesLoadChunks ? this.a.getType(blockposition) : this.a.getTypeIfLoaded(blockposition); // Paper - if (iblockdata == null) return false; // Paper - - Block block = iblockdata.getBlock(); - - return block instanceof BlockDoor ? iblockdata.getMaterial() == Material.WOOD : false; - } - - private void n() { - int i = this.b.size(); - - if (i == 0) { - this.d = BlockPosition.ZERO; - this.e = 0; - } else { - this.d = new BlockPosition(this.c.getX() / i, this.c.getY() / i, this.c.getZ() / i); - int j = 0; - - VillageDoor villagedoor; - - for (Iterator iterator = this.b.iterator(); iterator.hasNext(); j = Math.max(villagedoor.a(this.d), j)) { - villagedoor = (VillageDoor) iterator.next(); - } - - this.e = Math.max(32, (int) Math.sqrt((double) j) + 1); - } - } - - public int a(String s) { - Integer integer = (Integer) this.j.get(s); - - return integer == null ? 0 : integer; - } - - public int a(String s, int i) { - int j = this.a(s); - int k = MathHelper.clamp(j + i, -30, 10); - - this.j.put(s, k); - return k; - } - - public boolean d(String s) { - return this.a(s) <= -15; - } - - public void a(NBTTagCompound nbttagcompound) { - this.h = nbttagcompound.getInt("PopSize"); - this.e = nbttagcompound.getInt("Radius"); - this.l = nbttagcompound.getInt("Golems"); - this.f = nbttagcompound.getInt("Stable"); - this.g = nbttagcompound.getInt("Tick"); - this.i = nbttagcompound.getInt("MTick"); - this.d = new BlockPosition(nbttagcompound.getInt("CX"), nbttagcompound.getInt("CY"), nbttagcompound.getInt("CZ")); - this.c = new BlockPosition(nbttagcompound.getInt("ACX"), nbttagcompound.getInt("ACY"), nbttagcompound.getInt("ACZ")); - NBTTagList nbttaglist = nbttagcompound.getList("Doors", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); - VillageDoor villagedoor = new VillageDoor(new BlockPosition(nbttagcompound1.getInt("X"), nbttagcompound1.getInt("Y"), nbttagcompound1.getInt("Z")), nbttagcompound1.getInt("IDX"), nbttagcompound1.getInt("IDZ"), nbttagcompound1.getInt("TS")); - - this.b.add(villagedoor); - } - - NBTTagList nbttaglist1 = nbttagcompound.getList("Players", 10); - - for (int j = 0; j < nbttaglist1.size(); ++j) { - NBTTagCompound nbttagcompound2 = nbttaglist1.getCompound(j); - - if (nbttagcompound2.hasKey("UUID") && this.a != null && this.a.getMinecraftServer() != null) { - AkarinUserCache usercache = this.a.getMinecraftServer().getModernUserCache(); // Akarin - GameProfile gameprofile = usercache.peek(nbttagcompound2.getString("Name")); // Akarin - - if (gameprofile != null) { - this.j.put(gameprofile.getName(), nbttagcompound2.getInt("S")); - } - } else { - this.j.put(nbttagcompound2.getString("Name"), nbttagcompound2.getInt("S")); - } - } - - } - - public void b(NBTTagCompound nbttagcompound) { - nbttagcompound.setInt("PopSize", this.h); - nbttagcompound.setInt("Radius", this.e); - nbttagcompound.setInt("Golems", this.l); - nbttagcompound.setInt("Stable", this.f); - nbttagcompound.setInt("Tick", this.g); - nbttagcompound.setInt("MTick", this.i); - nbttagcompound.setInt("CX", this.d.getX()); - nbttagcompound.setInt("CY", this.d.getY()); - nbttagcompound.setInt("CZ", this.d.getZ()); - nbttagcompound.setInt("ACX", this.c.getX()); - nbttagcompound.setInt("ACY", this.c.getY()); - nbttagcompound.setInt("ACZ", this.c.getZ()); - NBTTagList nbttaglist = new NBTTagList(); - Iterator iterator = this.b.iterator(); - - while (iterator.hasNext()) { - VillageDoor villagedoor = (VillageDoor) iterator.next(); - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - - nbttagcompound1.setInt("X", villagedoor.d().getX()); - nbttagcompound1.setInt("Y", villagedoor.d().getY()); - nbttagcompound1.setInt("Z", villagedoor.d().getZ()); - nbttagcompound1.setInt("IDX", villagedoor.f()); - nbttagcompound1.setInt("IDZ", villagedoor.g()); - nbttagcompound1.setInt("TS", villagedoor.h()); - nbttaglist.add((NBTBase) nbttagcompound1); - } - - nbttagcompound.set("Doors", nbttaglist); - NBTTagList nbttaglist1 = new NBTTagList(); - Iterator iterator1 = this.j.keySet().iterator(); - - while (iterator1.hasNext()) { - String s = (String) iterator1.next(); - NBTTagCompound nbttagcompound2 = new NBTTagCompound(); - AkarinUserCache usercache = this.a.getMinecraftServer().getModernUserCache(); // Akarin - - try { - GameProfile gameprofile = usercache.peek(s); - - if (gameprofile != null) { - nbttagcompound2.setString("UUID", gameprofile.getId().toString()); - nbttagcompound2.setInt("S", (Integer) this.j.get(s)); - nbttaglist1.add((NBTBase) nbttagcompound2); - } - } catch (RuntimeException runtimeexception) { - ; - } - } - - nbttagcompound.set("Players", nbttaglist1); - } - - public void h() { - this.i = this.g; - } - - public boolean i() { - return this.i == 0 || this.g - this.i >= 3600; - } - - public void b(int i) { - Iterator iterator = this.j.keySet().iterator(); - - while (iterator.hasNext()) { - String s = (String) iterator.next(); - - this.a(s, i); - } - - } - - class Aggressor { - - public EntityLiving a; - public int b; - - Aggressor(EntityLiving entityliving, int i) { - this.a = entityliving; - this.b = i; - } - } -} diff --git a/src/main/java/net/minecraft/server/VillageDoor.java b/src/main/java/net/minecraft/server/VillageDoor.java deleted file mode 100644 index 1edffc462..000000000 --- a/src/main/java/net/minecraft/server/VillageDoor.java +++ /dev/null @@ -1,96 +0,0 @@ -package net.minecraft.server; - -public class VillageDoor { - - private final BlockPosition a; - private final BlockPosition b; - private final EnumDirection c; - private int d; - private boolean e; - private int f; - - public VillageDoor(BlockPosition blockposition, int i, int j, int k) { - this(blockposition, a(i, j), k); - } - - private static EnumDirection a(int i, int j) { - return i < 0 ? EnumDirection.WEST : (i > 0 ? EnumDirection.EAST : (j < 0 ? EnumDirection.NORTH : EnumDirection.SOUTH)); - } - - public VillageDoor(BlockPosition blockposition, EnumDirection enumdirection, int i) { - this.a = blockposition.h(); - this.c = enumdirection; - this.b = blockposition.shift(enumdirection, 2); - this.d = i; - } - - public int b(int i, int j, int k) { - return (int) this.a.distanceSquared((double) i, (double) j, (double) k); - } - - public int a(BlockPosition blockposition) { - return (int) blockposition.n(this.d()); - } - - public int b(BlockPosition blockposition) { - return (int) this.b.n(blockposition); - } - - public boolean c(BlockPosition blockposition) { - int i = blockposition.getX() - this.a.getX(); - int j = blockposition.getZ() - this.a.getY(); - - return i * this.c.getAdjacentX() + j * this.c.getAdjacentZ() >= 0; - } - - public void a() { - this.f = 0; - } - - public void b() { - ++this.f; - } - - public int c() { - return this.f; - } - - public BlockPosition getPosition() { return d(); } // Paper - OBFHELPER - public BlockPosition d() { - return this.a; - } - - public BlockPosition e() { - return this.b; - } - - public int f() { - return this.c.getAdjacentX() * 2; - } - - public int g() { - return this.c.getAdjacentZ() * 2; - } - - public int getLastSeen() { return h(); } // Paper - OBFHELPER - public int h() { - return this.d; - } - - public void setLastSeen(int i) { a(i); } // Paper - OBFHELPER - public void a(int i) { - this.d = i; - } - - public boolean i() { - return this.e; - } - - public void a(boolean flag) { - this.e = flag; - } - - public EnumDirection j() { - return this.c; - } -} diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java new file mode 100644 index 000000000..fb99b4306 --- /dev/null +++ b/src/main/java/net/minecraft/server/VillagePlace.java @@ -0,0 +1,289 @@ +package net.minecraft.server; + +import com.mojang.datafixers.DataFixer; +import it.unimi.dsi.fastutil.longs.Long2ByteMap; +import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap; +import java.io.File; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.function.BiConsumer; +import java.util.function.BooleanSupplier; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class VillagePlace extends RegionFileSection { + + private final VillagePlace.a a = new VillagePlace.a(); + + private final WorldServer world; // Paper + + public VillagePlace(File file, DataFixer datafixer) { + // Paper start + this(file, datafixer, null); + } + public VillagePlace(File file, DataFixer datafixer, WorldServer world) { + // Paper end + super(file, VillagePlaceSection::new, VillagePlaceSection::new, datafixer, DataFixTypes.POI_CHUNK); + this.world = world; // Paper + } + + public void a(BlockPosition blockposition, VillagePlaceType villageplacetype) { + ((VillagePlaceSection) this.e(SectionPosition.a(blockposition).v())).a(blockposition, villageplacetype); + } + + public void a(BlockPosition blockposition) { + ((VillagePlaceSection) this.e(SectionPosition.a(blockposition).v())).a(blockposition); + } + + public long a(Predicate predicate, BlockPosition blockposition, int i, VillagePlace.Occupancy villageplace_occupancy) { + return this.b(predicate, blockposition, i, villageplace_occupancy).count(); + } + + public Stream b(Predicate predicate, BlockPosition blockposition, int i, VillagePlace.Occupancy villageplace_occupancy) { + int j = i * i; + + return ChunkCoordIntPair.a(new ChunkCoordIntPair(blockposition), Math.floorDiv(i, 16)).flatMap((chunkcoordintpair) -> { + return this.a(predicate, chunkcoordintpair, villageplace_occupancy).filter((villageplacerecord) -> { + return villageplacerecord.f().m(blockposition) <= (double) j; + }); + }); + } + + public Stream a(Predicate predicate, ChunkCoordIntPair chunkcoordintpair, VillagePlace.Occupancy villageplace_occupancy) { + return IntStream.range(0, 16).boxed().flatMap((integer) -> { + return this.a(predicate, SectionPosition.a(chunkcoordintpair, integer).v(), villageplace_occupancy); + }); + } + + private Stream a(Predicate predicate, long i, VillagePlace.Occupancy villageplace_occupancy) { + return (Stream) this.d(i).map((villageplacesection) -> { + return villageplacesection.a(predicate, villageplace_occupancy); + }).orElseGet(Stream::empty); + } + + public Stream a(Predicate predicate, Predicate predicate1, BlockPosition blockposition, int i, VillagePlace.Occupancy villageplace_occupancy) { + return this.b(predicate, blockposition, i, villageplace_occupancy).map(VillagePlaceRecord::f).filter(predicate1); + } + + public Optional b(Predicate predicate, Predicate predicate1, BlockPosition blockposition, int i, VillagePlace.Occupancy villageplace_occupancy) { + return this.a(predicate, predicate1, blockposition, i, villageplace_occupancy).findFirst(); + } + + public Optional c(Predicate predicate, Predicate predicate1, BlockPosition blockposition, int i, VillagePlace.Occupancy villageplace_occupancy) { + return this.b(predicate, blockposition, i, villageplace_occupancy).map(VillagePlaceRecord::f).sorted(Comparator.comparingDouble((blockposition1) -> { + return blockposition1.m(blockposition); + })).filter(predicate1).findFirst(); + } + + public Optional a(Predicate predicate, Predicate predicate1, BlockPosition blockposition, int i) { + return this.b(predicate, blockposition, i, VillagePlace.Occupancy.HAS_SPACE).filter((villageplacerecord) -> { + return predicate1.test(villageplacerecord.f()); + }).findFirst().map((villageplacerecord) -> { + villageplacerecord.b(); + return villageplacerecord.f(); + }); + } + + public Optional a(Predicate predicate, Predicate predicate1, VillagePlace.Occupancy villageplace_occupancy, BlockPosition blockposition, int i, Random random) { + List list = (List) this.b(predicate, blockposition, i, villageplace_occupancy).collect(Collectors.toList()); + + Collections.shuffle(list, random); + return list.stream().filter((villageplacerecord) -> { + return predicate1.test(villageplacerecord.f()); + }).findFirst().map(VillagePlaceRecord::f); + } + + public boolean b(BlockPosition blockposition) { + return ((VillagePlaceSection) this.e(SectionPosition.a(blockposition).v())).c(blockposition); + } + + public boolean a(BlockPosition blockposition, Predicate predicate) { + return (Boolean) this.d(SectionPosition.a(blockposition).v()).map((villageplacesection) -> { + return villageplacesection.a(blockposition, predicate); + }).orElse(false); + } + + public Optional c(BlockPosition blockposition) { + VillagePlaceSection villageplacesection = (VillagePlaceSection) this.e(SectionPosition.a(blockposition).v()); + + return villageplacesection.d(blockposition); + } + + public int a(SectionPosition sectionposition) { + this.a.a(); + return this.a.c(sectionposition.v()); + } + + private boolean f(long i) { + Optional optional = this.c(i); + + return optional == null ? false : (Boolean) optional.map((villageplacesection) -> { + return villageplacesection.a(VillagePlaceType.a, VillagePlace.Occupancy.IS_OCCUPIED).count() > 0L; + }).orElse(false); + } + + @Override + public void a(BooleanSupplier booleansupplier) { + // Paper start - async chunk io + if (this.world == null) { + super.a(booleansupplier); + } else if (!this.world.isSavingDisabled()) { // Paper - only save if saving is enabled + //super.a(booleansupplier); // re-implement below + // Paper start - target unloading aggressively + int queueTarget = Math.min(this.d.size() - 100, (int)(this.d.size() * 0.96)); + while (!((RegionFileSection)this).d.isEmpty() && (this.d.size() > queueTarget || booleansupplier.getAsBoolean())) { + // Paper end + ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(((RegionFileSection)this).d.firstLong()).u(); + + NBTTagCompound data; + try (co.aikar.timings.Timing ignored1 = this.world.timings.poiSaveDataSerialization.startTiming()) { + data = this.getData(chunkcoordintpair); + } + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, + chunkcoordintpair.x, chunkcoordintpair.z, data, null, com.destroystokyo.paper.io.PrioritizedTaskQueue.LOW_PRIORITY); + } + } + // Paper end + this.a.a(); + } + + @Override + protected void a(long i) { + super.a(i); + this.a.b(i, this.a.b(i), false); + } + + @Override + protected void b(long i) { + this.a.b(i, this.a.b(i), false); + } + + public void a(ChunkCoordIntPair chunkcoordintpair, ChunkSection chunksection) { + SectionPosition sectionposition = SectionPosition.a(chunkcoordintpair, chunksection.getYPosition() >> 4); + + SystemUtils.a(this.d(sectionposition.v()), (villageplacesection) -> { + villageplacesection.a((biconsumer) -> { + if (a(chunksection)) { + this.a(chunksection, sectionposition, biconsumer); + } + + }); + }, () -> { + if (a(chunksection)) { + VillagePlaceSection villageplacesection = (VillagePlaceSection) this.e(sectionposition.v()); + + this.a(chunksection, sectionposition, villageplacesection::a); + } + + }); + } + + private static boolean a(ChunkSection chunksection) { + Stream stream = VillagePlaceType.f(); // Paper - decompile fix + + chunksection.getClass(); + return stream.anyMatch(chunksection::a); + } + + private void a(ChunkSection chunksection, SectionPosition sectionposition, BiConsumer biconsumer) { + sectionposition.w().forEach((blockposition) -> { + IBlockData iblockdata = chunksection.getType(SectionPosition.b(blockposition.getX()), SectionPosition.b(blockposition.getY()), SectionPosition.b(blockposition.getZ())); + + VillagePlaceType.b(iblockdata).ifPresent((villageplacetype) -> { + biconsumer.accept(blockposition, villageplacetype); + }); + }); + } + + final class a extends LightEngineGraphSection { + + private final Long2ByteMap b = new Long2ByteOpenHashMap(); + + protected a() { + super(7, 16, 256); + this.b.defaultReturnValue((byte) 7); + } + + @Override + protected int b(long i) { + return VillagePlace.this.f(i) ? 0 : 7; + } + + @Override + protected int c(long i) { + return this.b.get(i); + } + + @Override + protected void a(long i, int j) { + if (j > 6) { + this.b.remove(i); + } else { + this.b.put(i, (byte) j); + } + + } + + public void a() { + super.b(Integer.MAX_VALUE); + } + } + + // Paper start - Asynchronous chunk io + @javax.annotation.Nullable + @Override + public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws java.io.IOException { + if (this.world != null && Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) { + NBTTagCompound ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE + .loadChunkDataAsyncFuture(this.world, chunkcoordintpair.x, chunkcoordintpair.z, com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread(), + true, false, true).join().poiData; + + if (ret == com.destroystokyo.paper.io.PaperFileIOThread.FAILURE_VALUE) { + throw new java.io.IOException("See logs for further detail"); + } + return ret; + } + return super.read(chunkcoordintpair); + } + + @Override + public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws java.io.IOException { + if (this.world != null && Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) { + com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave( + this.world, chunkcoordintpair.x, chunkcoordintpair.z, nbttagcompound, null, + com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread()); + + Boolean ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.waitForIOToComplete(this.world, + chunkcoordintpair.x, chunkcoordintpair.z, true, true); + + if (ret == Boolean.FALSE) { + throw new java.io.IOException("See logs for further detail"); + } + return; + } + super.write(chunkcoordintpair, nbttagcompound); + } + // Paper end + + public static enum Occupancy { + + HAS_SPACE(VillagePlaceRecord::d), IS_OCCUPIED(VillagePlaceRecord::e), ANY((villageplacerecord) -> { + return true; + }); + + private final Predicate d; + + private Occupancy(Predicate predicate) { // Paper - decompile fix + this.d = predicate; + } + + public Predicate a() { + return this.d; + } + } +} diff --git a/src/main/java/net/minecraft/server/VillageSiege.java b/src/main/java/net/minecraft/server/VillageSiege.java index 509d62f6b..6e4c5d4d8 100644 --- a/src/main/java/net/minecraft/server/VillageSiege.java +++ b/src/main/java/net/minecraft/server/VillageSiege.java @@ -3,121 +3,87 @@ package net.minecraft.server; import com.destroystokyo.paper.exception.ServerInternalException; import java.util.Iterator; -import java.util.List; import javax.annotation.Nullable; public class VillageSiege { - private final World a; - private boolean b; - private int c = -1; + private boolean a; + private VillageSiege.State b; + private int c; private int d; private int e; - private Village f; + private int f; private int g; - private int h; - private int i; - public VillageSiege(World world) { - this.a = world; + public VillageSiege() { + this.b = VillageSiege.State.SIEGE_DONE; } - public void a() { - if (this.a.L()) { - this.c = 0; - } else if (this.c != 2) { - if (this.c == 0) { - float f = this.a.k(0.0F); + public int a(WorldServer worldserver, boolean flag, boolean flag1) { + if (!worldserver.J() && flag) { + float f = worldserver.j(0.0F); - if ((double) f < 0.5D || (double) f > 0.501D) { - return; - } - - this.c = this.a.random.nextInt(10) == 0 ? 1 : 2; - this.b = false; - if (this.c == 2) { - return; - } + if ((double) f == 0.5D) { + this.b = worldserver.random.nextInt(10) == 0 ? VillageSiege.State.SIEGE_TONIGHT : VillageSiege.State.SIEGE_DONE; } - if (this.c != -1) { - if (!this.b) { - if (!this.b()) { - return; + if (this.b == VillageSiege.State.SIEGE_DONE) { + return 0; + } else { + if (!this.a) { + if (!this.a(worldserver)) { + return 0; } - this.b = true; + this.a = true; } - if (this.e > 0) { - --this.e; + if (this.d > 0) { + --this.d; + return 0; } else { - this.e = 2; - if (this.d > 0) { - this.c(); - --this.d; + this.d = 2; + if (this.c > 0) { + this.b(worldserver); + --this.c; } else { - this.c = 2; + this.b = VillageSiege.State.SIEGE_DONE; } + return 1; } } + } else { + this.b = VillageSiege.State.SIEGE_DONE; + this.a = false; + return 0; } } - private boolean b() { - List list = this.a.players; - Iterator iterator = list.iterator(); + private boolean a(WorldServer worldserver) { + Iterator iterator = worldserver.getPlayers().iterator(); while (iterator.hasNext()) { EntityHuman entityhuman = (EntityHuman) iterator.next(); if (!entityhuman.isSpectator()) { - this.f = this.a.af().getClosestVillage(new BlockPosition(entityhuman), 1); - if (this.f != null && this.f.c() >= 10 && this.f.d() >= 20 && this.f.e() >= 20) { - BlockPosition blockposition = this.f.a(); - float f = (float) this.f.b(); - boolean flag = false; - int i = 0; + BlockPosition blockposition = entityhuman.getChunkCoordinates(); - while (true) { - if (i < 10) { - float f1 = this.a.random.nextFloat() * 6.2831855F; + if (worldserver.b_(blockposition) && worldserver.getBiome(blockposition).o() != BiomeBase.Geography.MUSHROOM) { + for (int i = 0; i < 10; ++i) { + float f = worldserver.random.nextFloat() * 6.2831855F; - this.g = blockposition.getX() + (int) ((double) (MathHelper.cos(f1) * f) * 0.9D); - this.h = blockposition.getY(); - this.i = blockposition.getZ() + (int) ((double) (MathHelper.sin(f1) * f) * 0.9D); - flag = false; - Iterator iterator1 = this.a.af().getVillages().iterator(); - - while (iterator1.hasNext()) { - Village village = (Village) iterator1.next(); - - if (village != this.f && village.a(new BlockPosition(this.g, this.h, this.i))) { - flag = true; - break; - } - } - - if (flag) { - ++i; - continue; - } + this.e = blockposition.getX() + MathHelper.d(MathHelper.cos(f) * 32.0F); + this.f = blockposition.getY(); + this.g = blockposition.getZ() + MathHelper.d(MathHelper.sin(f) * 32.0F); + if (this.a(worldserver, new BlockPosition(this.e, this.f, this.g)) != null) { + this.d = 0; + this.c = 20; + break; } - - if (flag) { - return false; - } - - Vec3D vec3d = this.a(new BlockPosition(this.g, this.h, this.i)); - - if (vec3d != null) { - this.e = 0; - this.d = 20; - return true; - } - break; } + + return true; } } } @@ -125,42 +91,46 @@ public class VillageSiege { return false; } - private boolean c() { - Vec3D vec3d = this.a(new BlockPosition(this.g, this.h, this.i)); + private void b(WorldServer worldserver) { + Vec3D vec3d = this.a(worldserver, new BlockPosition(this.e, this.f, this.g)); - if (vec3d == null) { - return false; - } else { + if (vec3d != null) { EntityZombie entityzombie; try { - entityzombie = EntityTypes.ZOMBIE.create(this.a); // Paper - entityzombie.prepare(this.a.getDamageScaler(new BlockPosition(entityzombie)), (GroupDataEntity) null, (NBTTagCompound) null); + entityzombie = new EntityZombie(worldserver); + entityzombie.prepare(worldserver, worldserver.getDamageScaler(new BlockPosition(entityzombie)), EnumMobSpawn.EVENT, (GroupDataEntity) null, (NBTTagCompound) null); } catch (Exception exception) { exception.printStackTrace(); ServerInternalException.reportInternalException(exception); // Paper - return false; + return; } - entityzombie.setPositionRotation(vec3d.x, vec3d.y, vec3d.z, this.a.random.nextFloat() * 360.0F, 0.0F); - this.a.addEntity(entityzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_INVASION); // CraftBukkit - BlockPosition blockposition = this.f.a(); - - entityzombie.a(blockposition, this.f.b()); - return true; + entityzombie.setPositionRotation(vec3d.x, vec3d.y, vec3d.z, worldserver.random.nextFloat() * 360.0F, 0.0F); + worldserver.addEntity(entityzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_INVASION); // CraftBukkit } } @Nullable - private Vec3D a(BlockPosition blockposition) { + private Vec3D a(WorldServer worldserver, BlockPosition blockposition) { for (int i = 0; i < 10; ++i) { - BlockPosition blockposition1 = blockposition.a(this.a.random.nextInt(16) - 8, this.a.random.nextInt(6) - 3, this.a.random.nextInt(16) - 8); + int j = blockposition.getX() + worldserver.random.nextInt(16) - 8; + int k = blockposition.getZ() + worldserver.random.nextInt(16) - 8; + int l = worldserver.a(HeightMap.Type.WORLD_SURFACE, j, k); + BlockPosition blockposition1 = new BlockPosition(j, l, k); - if (this.f.a(blockposition1) && SpawnerCreature.a(EntityPositionTypes.Surface.ON_GROUND, this.a, blockposition1, (EntityTypes) null)) { - return new Vec3D((double) blockposition1.getX(), (double) blockposition1.getY(), (double) blockposition1.getZ()); + if (worldserver.b_(blockposition1) && EntityMonster.c(EntityTypes.ZOMBIE, worldserver, EnumMobSpawn.EVENT, blockposition1, worldserver.random)) { + return new Vec3D((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D); } } return null; } + + static enum State { + + SIEGE_CAN_ACTIVATE, SIEGE_TONIGHT, SIEGE_DONE; + + private State() {} + } } diff --git a/src/main/java/net/minecraft/server/VillagerTrades.java b/src/main/java/net/minecraft/server/VillagerTrades.java new file mode 100644 index 000000000..99374fe2a --- /dev/null +++ b/src/main/java/net/minecraft/server/VillagerTrades.java @@ -0,0 +1,372 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Random; +import java.util.stream.Collectors; +import javax.annotation.Nullable; + +public class VillagerTrades { + + public static final Map> a = SystemUtils.a(Maps.newHashMap(), (hashmap) -> { // Paper - decompile fix + hashmap.put(VillagerProfession.FARMER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.WHEAT, 20, 16, 2), new VillagerTrades.b(Items.POTATO, 26, 16, 2), new VillagerTrades.b(Items.CARROT, 22, 16, 2), new VillagerTrades.b(Items.BEETROOT, 15, 16, 2), new VillagerTrades.h(Items.BREAD, 1, 6, 16, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Blocks.PUMPKIN, 6, 12, 10), new VillagerTrades.h(Items.PUMPKIN_PIE, 1, 4, 5), new VillagerTrades.h(Items.APPLE, 1, 4, 16, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.COOKIE, 3, 18, 10), new VillagerTrades.b(Blocks.MELON, 4, 12, 20)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Blocks.CAKE, 1, 1, 12, 15), new VillagerTrades.i(MobEffects.NIGHT_VISION, 100, 15), new VillagerTrades.i(MobEffects.JUMP, 160, 15), new VillagerTrades.i(MobEffects.WEAKNESS, 140, 15), new VillagerTrades.i(MobEffects.BLINDNESS, 120, 15), new VillagerTrades.i(MobEffects.POISON, 280, 15), new VillagerTrades.i(MobEffects.SATURATION, 7, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.GOLDEN_CARROT, 3, 3, 30), new VillagerTrades.h(Items.GLISTERING_MELON_SLICE, 4, 3, 30)}))); + hashmap.put(VillagerProfession.FISHERMAN, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STRING, 20, 16, 2), new VillagerTrades.b(Items.COAL, 10, 16, 2), new VillagerTrades.g(Items.COD, 6, Items.COOKED_COD, 6, 16, 1), new VillagerTrades.h(Items.COD_BUCKET, 3, 1, 16, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COD, 15, 16, 10), new VillagerTrades.g(Items.SALMON, 6, Items.COOKED_SALMON, 6, 16, 5), new VillagerTrades.h(Items.pS, 2, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.SALMON, 13, 16, 20), new VillagerTrades.e(Items.FISHING_ROD, 3, 3, 10, 0.2F)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.TROPICAL_FISH, 6, 12, 30)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PUFFERFISH, 4, 12, 30), new VillagerTrades.c(1, 12, 30, ImmutableMap.builder().put(VillagerType.PLAINS, Items.OAK_BOAT).put(VillagerType.TAIGA, Items.SPRUCE_BOAT).put(VillagerType.SNOW, Items.SPRUCE_BOAT).put(VillagerType.DESERT, Items.JUNGLE_BOAT).put(VillagerType.JUNGLE, Items.JUNGLE_BOAT).put(VillagerType.SAVANNA, Items.ACACIA_BOAT).put(VillagerType.SWAMP, Items.DARK_OAK_BOAT).build())}))); // Paper - decompile fix + hashmap.put(VillagerProfession.SHEPHERD, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Blocks.WHITE_WOOL, 18, 16, 2), new VillagerTrades.b(Blocks.BROWN_WOOL, 18, 16, 2), new VillagerTrades.b(Blocks.BLACK_WOOL, 18, 16, 2), new VillagerTrades.b(Blocks.GRAY_WOOL, 18, 16, 2), new VillagerTrades.h(Items.SHEARS, 2, 1, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.WHITE_DYE, 12, 16, 10), new VillagerTrades.b(Items.GRAY_DYE, 12, 16, 10), new VillagerTrades.b(Items.BLACK_DYE, 12, 16, 10), new VillagerTrades.b(Items.LIGHT_BLUE_DYE, 12, 16, 10), new VillagerTrades.b(Items.LIME_DYE, 12, 16, 10), new VillagerTrades.h(Blocks.WHITE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.ORANGE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.MAGENTA_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.LIGHT_BLUE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.YELLOW_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.LIME_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.PINK_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.GRAY_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.LIGHT_GRAY_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.CYAN_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.PURPLE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.BLUE_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.BROWN_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.GREEN_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.RED_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.BLACK_WOOL, 1, 1, 16, 5), new VillagerTrades.h(Blocks.WHITE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.ORANGE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.MAGENTA_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.LIGHT_BLUE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.YELLOW_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.LIME_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.PINK_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.GRAY_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.LIGHT_GRAY_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.CYAN_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.PURPLE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.BLUE_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.BROWN_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.GREEN_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.RED_CARPET, 1, 4, 16, 5), new VillagerTrades.h(Blocks.BLACK_CARPET, 1, 4, 16, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.YELLOW_DYE, 12, 16, 20), new VillagerTrades.b(Items.LIGHT_GRAY_DYE, 12, 16, 20), new VillagerTrades.b(Items.ORANGE_DYE, 12, 16, 20), new VillagerTrades.b(Items.RED_DYE, 12, 16, 20), new VillagerTrades.b(Items.PINK_DYE, 12, 16, 20), new VillagerTrades.h(Blocks.WHITE_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.YELLOW_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.RED_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.BLACK_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.BLUE_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.BROWN_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.CYAN_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.GRAY_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.GREEN_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.LIGHT_BLUE_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.LIGHT_GRAY_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.LIME_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.MAGENTA_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.ORANGE_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.PINK_BED, 3, 1, 12, 10), new VillagerTrades.h(Blocks.PURPLE_BED, 3, 1, 12, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.BROWN_DYE, 12, 16, 30), new VillagerTrades.b(Items.PURPLE_DYE, 12, 16, 30), new VillagerTrades.b(Items.BLUE_DYE, 12, 16, 30), new VillagerTrades.b(Items.GREEN_DYE, 12, 16, 30), new VillagerTrades.b(Items.MAGENTA_DYE, 12, 16, 30), new VillagerTrades.b(Items.CYAN_DYE, 12, 16, 30), new VillagerTrades.h(Items.WHITE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.BLUE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.LIGHT_BLUE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.RED_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.PINK_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.GREEN_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.LIME_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.GRAY_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.BLACK_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.PURPLE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.MAGENTA_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.CYAN_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.BROWN_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.YELLOW_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.ORANGE_BANNER, 3, 1, 12, 15), new VillagerTrades.h(Items.LIGHT_GRAY_BANNER, 3, 1, 12, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.PAINTING, 2, 3, 30)}))); + hashmap.put(VillagerProfession.FLETCHER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STICK, 32, 16, 2), new VillagerTrades.h(Items.ARROW, 1, 16, 1), new VillagerTrades.g(Blocks.GRAVEL, 10, Items.FLINT, 10, 12, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.FLINT, 26, 12, 10), new VillagerTrades.h(Items.BOW, 2, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.STRING, 14, 16, 20), new VillagerTrades.h(Items.CROSSBOW, 3, 1, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.FEATHER, 24, 16, 30), new VillagerTrades.e(Items.BOW, 2, 3, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.dE, 8, 12, 30), new VillagerTrades.e(Items.CROSSBOW, 3, 3, 15), new VillagerTrades.j(Items.ARROW, 5, Items.TIPPED_ARROW, 5, 2, 12, 30)}))); + hashmap.put(VillagerProfession.LIBRARIAN, a(ImmutableMap.builder().put(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PAPER, 24, 16, 2), new VillagerTrades.d(1), new VillagerTrades.h(Blocks.BOOKSHELF, 6, 3, 12, 1)}).put(2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.BOOK, 4, 12, 10), new VillagerTrades.d(5), new VillagerTrades.h(Items.pQ, 1, 1, 5)}).put(3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.INK_SAC, 5, 12, 20), new VillagerTrades.d(10), new VillagerTrades.h(Items.am, 1, 4, 10)}).put(4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.WRITABLE_BOOK, 2, 12, 30), new VillagerTrades.d(15), new VillagerTrades.h(Items.CLOCK, 5, 1, 15), new VillagerTrades.h(Items.COMPASS, 4, 1, 15)}).put(5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.NAME_TAG, 20, 1, 30)}).build())); // Paper - decompile fix + hashmap.put(VillagerProfession.CARTOGRAPHER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.PAPER, 24, 16, 2), new VillagerTrades.h(Items.MAP, 7, 1, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.df, 11, 16, 10), new VillagerTrades.k(13, "Monument", MapIcon.Type.MONUMENT, 12, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COMPASS, 1, 12, 20), new VillagerTrades.k(14, "Mansion", MapIcon.Type.MANSION, 12, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.ITEM_FRAME, 7, 1, 15), new VillagerTrades.h(Items.WHITE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.BLUE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.LIGHT_BLUE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.RED_BANNER, 3, 1, 15), new VillagerTrades.h(Items.PINK_BANNER, 3, 1, 15), new VillagerTrades.h(Items.GREEN_BANNER, 3, 1, 15), new VillagerTrades.h(Items.LIME_BANNER, 3, 1, 15), new VillagerTrades.h(Items.GRAY_BANNER, 3, 1, 15), new VillagerTrades.h(Items.BLACK_BANNER, 3, 1, 15), new VillagerTrades.h(Items.PURPLE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.MAGENTA_BANNER, 3, 1, 15), new VillagerTrades.h(Items.CYAN_BANNER, 3, 1, 15), new VillagerTrades.h(Items.BROWN_BANNER, 3, 1, 15), new VillagerTrades.h(Items.YELLOW_BANNER, 3, 1, 15), new VillagerTrades.h(Items.ORANGE_BANNER, 3, 1, 15), new VillagerTrades.h(Items.LIGHT_GRAY_BANNER, 3, 1, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.GLOBE_BANNER_PATTERN, 8, 1, 30)}))); + hashmap.put(VillagerProfession.CLERIC, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.ROTTEN_FLESH, 32, 16, 2), new VillagerTrades.h(Items.REDSTONE, 1, 2, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.GOLD_INGOT, 3, 12, 10), new VillagerTrades.h(Items.LAPIS_LAZULI, 1, 1, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.RABBIT_FOOT, 2, 12, 20), new VillagerTrades.h(Blocks.GLOWSTONE, 4, 1, 12, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.SCUTE, 4, 12, 30), new VillagerTrades.b(Items.GLASS_BOTTLE, 9, 12, 30), new VillagerTrades.h(Items.ENDER_PEARL, 5, 1, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.NETHER_WART, 22, 12, 30), new VillagerTrades.h(Items.EXPERIENCE_BOTTLE, 3, 1, 30)}))); + hashmap.put(VillagerProfession.ARMORER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COAL, 15, 16, 2), new VillagerTrades.h(new ItemStack(Items.IRON_LEGGINGS), 7, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.IRON_BOOTS), 4, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.IRON_HELMET), 5, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.IRON_CHESTPLATE), 9, 1, 12, 1, 0.2F)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.IRON_INGOT, 4, 12, 10), new VillagerTrades.h(new ItemStack(Items.pP), 36, 1, 12, 5, 0.2F), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_BOOTS), 1, 1, 12, 5, 0.2F), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_LEGGINGS), 3, 1, 12, 5, 0.2F)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.LAVA_BUCKET, 1, 12, 20), new VillagerTrades.b(Items.DIAMOND, 1, 12, 20), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_HELMET), 1, 1, 12, 10, 0.2F), new VillagerTrades.h(new ItemStack(Items.CHAINMAIL_CHESTPLATE), 4, 1, 12, 10, 0.2F), new VillagerTrades.h(new ItemStack(Items.SHIELD), 5, 1, 12, 10, 0.2F)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.e(Items.DIAMOND_LEGGINGS, 14, 3, 15, 0.2F), new VillagerTrades.e(Items.DIAMOND_BOOTS, 8, 3, 15, 0.2F)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.e(Items.DIAMOND_HELMET, 8, 3, 30, 0.2F), new VillagerTrades.e(Items.DIAMOND_CHESTPLATE, 16, 3, 30, 0.2F)}))); + hashmap.put(VillagerProfession.WEAPONSMITH, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COAL, 15, 16, 2), new VillagerTrades.h(new ItemStack(Items.IRON_AXE), 3, 1, 12, 1, 0.2F), new VillagerTrades.e(Items.IRON_SWORD, 2, 3, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.IRON_INGOT, 4, 12, 10), new VillagerTrades.h(new ItemStack(Items.pP), 36, 1, 12, 5, 0.2F)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.FLINT, 24, 12, 20)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.DIAMOND, 1, 12, 30), new VillagerTrades.e(Items.DIAMOND_AXE, 12, 3, 15, 0.2F)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.e(Items.DIAMOND_SWORD, 8, 3, 30, 0.2F)}))); + hashmap.put(VillagerProfession.TOOLSMITH, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COAL, 15, 16, 2), new VillagerTrades.h(new ItemStack(Items.STONE_AXE), 1, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.STONE_SHOVEL), 1, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.STONE_PICKAXE), 1, 1, 12, 1, 0.2F), new VillagerTrades.h(new ItemStack(Items.STONE_HOE), 1, 1, 12, 1, 0.2F)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.IRON_INGOT, 4, 12, 10), new VillagerTrades.h(new ItemStack(Items.pP), 36, 1, 12, 5, 0.2F)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.FLINT, 30, 12, 20), new VillagerTrades.e(Items.IRON_AXE, 1, 3, 10, 0.2F), new VillagerTrades.e(Items.IRON_SHOVEL, 2, 3, 10, 0.2F), new VillagerTrades.e(Items.IRON_PICKAXE, 3, 3, 10, 0.2F), new VillagerTrades.h(new ItemStack(Items.DIAMOND_HOE), 4, 1, 3, 10, 0.2F)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.DIAMOND, 1, 12, 30), new VillagerTrades.e(Items.DIAMOND_AXE, 12, 3, 15, 0.2F), new VillagerTrades.e(Items.DIAMOND_SHOVEL, 5, 3, 15, 0.2F)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.e(Items.DIAMOND_PICKAXE, 13, 3, 30, 0.2F)}))); + hashmap.put(VillagerProfession.BUTCHER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.CHICKEN, 14, 16, 2), new VillagerTrades.b(Items.PORKCHOP, 7, 16, 2), new VillagerTrades.b(Items.RABBIT, 4, 16, 2), new VillagerTrades.h(Items.RABBIT_STEW, 1, 1, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.COAL, 15, 16, 2), new VillagerTrades.h(Items.COOKED_PORKCHOP, 1, 5, 16, 5), new VillagerTrades.h(Items.COOKED_CHICKEN, 1, 8, 16, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.MUTTON, 7, 16, 20), new VillagerTrades.b(Items.BEEF, 10, 16, 20)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.kP, 10, 12, 30)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.SWEET_BERRIES, 10, 12, 30)}))); + hashmap.put(VillagerProfession.LEATHERWORKER, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.LEATHER, 6, 16, 2), new VillagerTrades.a(Items.LEATHER_LEGGINGS, 3), new VillagerTrades.a(Items.LEATHER_CHESTPLATE, 7)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.FLINT, 26, 12, 10), new VillagerTrades.a(Items.LEATHER_HELMET, 5, 12, 5), new VillagerTrades.a(Items.LEATHER_BOOTS, 4, 12, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.RABBIT_HIDE, 9, 12, 20), new VillagerTrades.a(Items.LEATHER_CHESTPLATE, 7)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.SCUTE, 4, 12, 30), new VillagerTrades.a(Items.LEATHER_HORSE_ARMOR, 6, 12, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(new ItemStack(Items.SADDLE), 6, 1, 12, 30, 0.2F), new VillagerTrades.a(Items.LEATHER_HELMET, 5, 12, 30)}))); + hashmap.put(VillagerProfession.MASON, a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.CLAY_BALL, 10, 16, 2), new VillagerTrades.h(Items.BRICK, 1, 10, 16, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Blocks.STONE, 20, 16, 10), new VillagerTrades.h(Blocks.CHISELED_STONE_BRICKS, 1, 4, 16, 5)}, 3, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Blocks.GRANITE, 16, 16, 20), new VillagerTrades.b(Blocks.ANDESITE, 16, 16, 20), new VillagerTrades.b(Blocks.DIORITE, 16, 16, 20), new VillagerTrades.h(Blocks.POLISHED_ANDESITE, 1, 4, 16, 10), new VillagerTrades.h(Blocks.POLISHED_DIORITE, 1, 4, 16, 10), new VillagerTrades.h(Blocks.POLISHED_GRANITE, 1, 4, 16, 10)}, 4, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.b(Items.QUARTZ, 12, 12, 30), new VillagerTrades.h(Blocks.ORANGE_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.WHITE_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.BLUE_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.LIGHT_BLUE_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.GRAY_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.LIGHT_GRAY_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.BLACK_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.RED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.PINK_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.MAGENTA_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.LIME_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.GREEN_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.CYAN_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.PURPLE_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.YELLOW_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.BROWN_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.ORANGE_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.WHITE_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.BLUE_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.LIGHT_BLUE_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.GRAY_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.LIGHT_GRAY_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.BLACK_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.RED_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.PINK_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.MAGENTA_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.LIME_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.GREEN_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.CYAN_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.PURPLE_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.YELLOW_GLAZED_TERRACOTTA, 1, 1, 12, 15), new VillagerTrades.h(Blocks.BROWN_GLAZED_TERRACOTTA, 1, 1, 12, 15)}, 5, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Blocks.QUARTZ_PILLAR, 1, 1, 12, 30), new VillagerTrades.h(Blocks.QUARTZ_BLOCK, 1, 1, 12, 30)}))); + }); + public static final Int2ObjectMap b = a(ImmutableMap.of(1, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.aC, 2, 1, 5, 1), new VillagerTrades.h(Items.SLIME_BALL, 4, 1, 5, 1), new VillagerTrades.h(Items.cJ, 2, 1, 5, 1), new VillagerTrades.h(Items.NAUTILUS_SHELL, 5, 1, 5, 1), new VillagerTrades.h(Items.az, 1, 1, 12, 1), new VillagerTrades.h(Items.kN, 1, 1, 8, 1), new VillagerTrades.h(Items.cF, 1, 1, 4, 1), new VillagerTrades.h(Items.kO, 3, 1, 12, 1), new VillagerTrades.h(Items.cw, 3, 1, 8, 1), new VillagerTrades.h(Items.aU, 1, 1, 12, 1), new VillagerTrades.h(Items.aV, 1, 1, 12, 1), new VillagerTrades.h(Items.aW, 1, 1, 8, 1), new VillagerTrades.h(Items.aX, 1, 1, 12, 1), new VillagerTrades.h(Items.aY, 1, 1, 12, 1), new VillagerTrades.h(Items.aZ, 1, 1, 12, 1), new VillagerTrades.h(Items.ba, 1, 1, 12, 1), new VillagerTrades.h(Items.bb, 1, 1, 12, 1), new VillagerTrades.h(Items.bc, 1, 1, 12, 1), new VillagerTrades.h(Items.bd, 1, 1, 12, 1), new VillagerTrades.h(Items.be, 1, 1, 12, 1), new VillagerTrades.h(Items.bf, 1, 1, 7, 1), new VillagerTrades.h(Items.WHEAT_SEEDS, 1, 1, 12, 1), new VillagerTrades.h(Items.BEETROOT_SEEDS, 1, 1, 12, 1), new VillagerTrades.h(Items.PUMPKIN_SEEDS, 1, 1, 12, 1), new VillagerTrades.h(Items.MELON_SEEDS, 1, 1, 12, 1), new VillagerTrades.h(Items.x, 5, 1, 8, 1), new VillagerTrades.h(Items.v, 5, 1, 8, 1), new VillagerTrades.h(Items.y, 5, 1, 8, 1), new VillagerTrades.h(Items.w, 5, 1, 8, 1), new VillagerTrades.h(Items.t, 5, 1, 8, 1), new VillagerTrades.h(Items.u, 5, 1, 8, 1), new VillagerTrades.h(Items.RED_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.WHITE_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.BLUE_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.PINK_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.BLACK_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.GREEN_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.LIGHT_GRAY_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.MAGENTA_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.YELLOW_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.GRAY_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.PURPLE_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.LIGHT_BLUE_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.LIME_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.ORANGE_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.BROWN_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.CYAN_DYE, 1, 3, 12, 1), new VillagerTrades.h(Items.hK, 3, 1, 8, 1), new VillagerTrades.h(Items.hL, 3, 1, 8, 1), new VillagerTrades.h(Items.hM, 3, 1, 8, 1), new VillagerTrades.h(Items.hN, 3, 1, 8, 1), new VillagerTrades.h(Items.hJ, 3, 1, 8, 1), new VillagerTrades.h(Items.dh, 1, 1, 12, 1), new VillagerTrades.h(Items.bh, 1, 1, 12, 1), new VillagerTrades.h(Items.bi, 1, 1, 12, 1), new VillagerTrades.h(Items.dr, 1, 2, 5, 1), new VillagerTrades.h(Items.A, 1, 8, 8, 1), new VillagerTrades.h(Items.B, 1, 4, 6, 1)}, 2, new VillagerTrades.IMerchantRecipeOption[]{new VillagerTrades.h(Items.TROPICAL_FISH_BUCKET, 5, 1, 4, 1), new VillagerTrades.h(Items.PUFFERFISH_BUCKET, 5, 1, 4, 1), new VillagerTrades.h(Items.fg, 3, 1, 6, 1), new VillagerTrades.h(Items.ii, 6, 1, 6, 1), new VillagerTrades.h(Items.GUNPOWDER, 1, 1, 8, 1), new VillagerTrades.h(Items.l, 3, 3, 6, 1)})); + + private static Int2ObjectMap a(ImmutableMap immutablemap) { + return new Int2ObjectOpenHashMap(immutablemap); + } + + static class g implements VillagerTrades.IMerchantRecipeOption { + + private final ItemStack a; + private final int b; + private final int c; + private final ItemStack d; + private final int e; + private final int f; + private final int g; + private final float h; + + public g(IMaterial imaterial, int i, Item item, int j, int k, int l) { + this(imaterial, i, 1, item, j, k, l); + } + + public g(IMaterial imaterial, int i, int j, Item item, int k, int l, int i1) { + this.a = new ItemStack(imaterial); + this.b = i; + this.c = j; + this.d = new ItemStack(item); + this.e = k; + this.f = l; + this.g = i1; + this.h = 0.05F; + } + + @Nullable + @Override + public MerchantRecipe a(Entity entity, Random random) { + return new MerchantRecipe(new ItemStack(Items.EMERALD, this.c), new ItemStack(this.a.getItem(), this.b), new ItemStack(this.d.getItem(), this.e), this.f, this.g, this.h); + } + } + + static class k implements VillagerTrades.IMerchantRecipeOption { + + private final int a; + private final String b; + private final MapIcon.Type c; + private final int d; + private final int e; + + public k(int i, String s, MapIcon.Type mapicon_type, int j, int k) { + this.a = i; + this.b = s; + this.c = mapicon_type; + this.d = j; + this.e = k; + } + + @Nullable + @Override + public MerchantRecipe a(Entity entity, Random random) { + World world = entity.world; + if (!world.paperConfig.enableTreasureMaps) return null; //Paper + BlockPosition blockposition = world.a(this.b, new BlockPosition(entity), 100, !world.paperConfig.treasureMapsAlreadyDiscovered); //Paper + + if (blockposition != null) { + ItemStack itemstack = ItemWorldMap.createFilledMapView(world, blockposition.getX(), blockposition.getZ(), (byte) 2, true, true); + + ItemWorldMap.applySepiaFilter(world, itemstack); + WorldMap.decorateMap(itemstack, blockposition, "+", this.c); + itemstack.a((IChatBaseComponent) (new ChatMessage("filled_map." + this.b.toLowerCase(Locale.ROOT), new Object[0]))); + return new MerchantRecipe(new ItemStack(Items.EMERALD, this.a), new ItemStack(Items.COMPASS), itemstack, this.d, this.e, 0.2F); + } else { + return null; + } + } + } + + static class d implements VillagerTrades.IMerchantRecipeOption { + + private final int a; + + public d(int i) { + this.a = i; + } + + @Override + public MerchantRecipe a(Entity entity, Random random) { + Enchantment enchantment = (Enchantment) IRegistry.ENCHANTMENT.a(random); + int i = MathHelper.nextInt(random, enchantment.getStartLevel(), enchantment.getMaxLevel()); + ItemStack itemstack = ItemEnchantedBook.a(new WeightedRandomEnchant(enchantment, i)); + int j = 2 + random.nextInt(5 + i * 10) + 3 * i; + + if (enchantment.isTreasure()) { + j *= 2; + } + + if (j > 64) { + j = 64; + } + + return new MerchantRecipe(new ItemStack(Items.EMERALD, j), new ItemStack(Items.BOOK), itemstack, 12, this.a, 0.2F); + } + } + + static class a implements VillagerTrades.IMerchantRecipeOption { + + private final Item a; + private final int b; + private final int c; + private final int d; + + public a(Item item, int i) { + this(item, i, 12, 1); + } + + public a(Item item, int i, int j, int k) { + this.a = item; + this.b = i; + this.c = j; + this.d = k; + } + + @Override + public MerchantRecipe a(Entity entity, Random random) { + ItemStack itemstack = new ItemStack(Items.EMERALD, this.b); + ItemStack itemstack1 = new ItemStack(this.a); + + if (this.a instanceof ItemArmorColorable) { + List list = Lists.newArrayList(); + + list.add(a(random)); + if (random.nextFloat() > 0.7F) { + list.add(a(random)); + } + + if (random.nextFloat() > 0.8F) { + list.add(a(random)); + } + + itemstack1 = IDyeable.a(itemstack1, list); + } + + return new MerchantRecipe(itemstack, itemstack1, this.c, this.d, 0.2F); + } + + private static ItemDye a(Random random) { + return ItemDye.a(EnumColor.fromColorIndex(random.nextInt(16))); + } + } + + static class j implements VillagerTrades.IMerchantRecipeOption { + + private final ItemStack a; + private final int b; + private final int c; + private final int d; + private final int e; + private final Item f; + private final int g; + private final float h; + + public j(Item item, int i, Item item1, int j, int k, int l, int i1) { + this.a = new ItemStack(item1); + this.c = k; + this.d = l; + this.e = i1; + this.f = item; + this.g = i; + this.b = j; + this.h = 0.05F; + } + + @Override + public MerchantRecipe a(Entity entity, Random random) { + ItemStack itemstack = new ItemStack(Items.EMERALD, this.c); + List list = (List) IRegistry.POTION.d().filter((potionregistry) -> { + return !potionregistry.a().isEmpty() && PotionBrewer.a(potionregistry); + }).collect(Collectors.toList()); + PotionRegistry potionregistry = (PotionRegistry) list.get(random.nextInt(list.size())); + ItemStack itemstack1 = PotionUtil.a(new ItemStack(this.a.getItem(), this.b), potionregistry); + + return new MerchantRecipe(itemstack, new ItemStack(this.f, this.g), itemstack1, this.d, this.e, this.h); + } + } + + static class e implements VillagerTrades.IMerchantRecipeOption { + + private final ItemStack a; + private final int b; + private final int c; + private final int d; + private final float e; + + public e(Item item, int i, int j, int k) { + this(item, i, j, k, 0.05F); + } + + public e(Item item, int i, int j, int k, float f) { + this.a = new ItemStack(item); + this.b = i; + this.c = j; + this.d = k; + this.e = f; + } + + @Override + public MerchantRecipe a(Entity entity, Random random) { + int i = 5 + random.nextInt(15); + ItemStack itemstack = EnchantmentManager.a(random, new ItemStack(this.a.getItem()), i, false); + int j = Math.min(this.b + i, 64); + ItemStack itemstack1 = new ItemStack(Items.EMERALD, j); + + return new MerchantRecipe(itemstack1, itemstack, this.c, this.d, this.e); + } + } + + static class i implements VillagerTrades.IMerchantRecipeOption { + + final MobEffectList a; + final int b; + final int c; + private final float d; + + public i(MobEffectList mobeffectlist, int i, int j) { + this.a = mobeffectlist; + this.b = i; + this.c = j; + this.d = 0.05F; + } + + @Nullable + @Override + public MerchantRecipe a(Entity entity, Random random) { + ItemStack itemstack = new ItemStack(Items.SUSPICIOUS_STEW, 1); + + ItemSuspiciousStew.a(itemstack, this.a, this.b); + return new MerchantRecipe(new ItemStack(Items.EMERALD, 1), itemstack, 12, this.c, this.d); + } + } + + static class h implements VillagerTrades.IMerchantRecipeOption { + + private final ItemStack a; + private final int b; + private final int c; + private final int d; + private final int e; + private final float f; + + public h(Block block, int i, int j, int k, int l) { + this(new ItemStack(block), i, j, k, l); + } + + public h(Item item, int i, int j, int k) { + this(new ItemStack(item), i, j, 12, k); + } + + public h(Item item, int i, int j, int k, int l) { + this(new ItemStack(item), i, j, k, l); + } + + public h(ItemStack itemstack, int i, int j, int k, int l) { + this(itemstack, i, j, k, l, 0.05F); + } + + public h(ItemStack itemstack, int i, int j, int k, int l, float f) { + this.a = itemstack; + this.b = i; + this.c = j; + this.d = k; + this.e = l; + this.f = f; + } + + @Override + public MerchantRecipe a(Entity entity, Random random) { + return new MerchantRecipe(new ItemStack(Items.EMERALD, this.b), new ItemStack(this.a.getItem(), this.c), this.d, this.e, this.f); + } + } + + static class c implements VillagerTrades.IMerchantRecipeOption { + + private final Map a; + private final int b; + private final int c; + private final int d; + + public c(int i, int j, int k, Map map) { + IRegistry.VILLAGER_TYPE.d().filter((villagertype) -> { + return !map.containsKey(villagertype); + }).findAny().ifPresent((villagertype) -> { + throw new IllegalStateException("Missing trade for villager type: " + IRegistry.VILLAGER_TYPE.getKey(villagertype)); + }); + this.a = map; + this.b = i; + this.c = j; + this.d = k; + } + + @Nullable + @Override + public MerchantRecipe a(Entity entity, Random random) { + if (entity instanceof VillagerDataHolder) { + ItemStack itemstack = new ItemStack((IMaterial) this.a.get(((VillagerDataHolder) entity).getVillagerData().getType()), this.b); + + return new MerchantRecipe(itemstack, new ItemStack(Items.EMERALD), this.c, this.d, 0.05F); + } else { + return null; + } + } + } + + static class b implements VillagerTrades.IMerchantRecipeOption { + + private final Item a; + private final int b; + private final int c; + private final int d; + private final float e; + + public b(IMaterial imaterial, int i, int j, int k) { + this.a = imaterial.getItem(); + this.b = i; + this.c = j; + this.d = k; + this.e = 0.05F; + } + + @Override + public MerchantRecipe a(Entity entity, Random random) { + ItemStack itemstack = new ItemStack(this.a, this.b); + + return new MerchantRecipe(itemstack, new ItemStack(Items.EMERALD), this.c, this.d, this.e); + } + } + + public interface IMerchantRecipeOption { + + @Nullable + MerchantRecipe a(Entity entity, Random random); + } +} diff --git a/src/main/java/net/minecraft/server/VoxelShape.java b/src/main/java/net/minecraft/server/VoxelShape.java new file mode 100644 index 000000000..092f02cc2 --- /dev/null +++ b/src/main/java/net/minecraft/server/VoxelShape.java @@ -0,0 +1,211 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.math.DoubleMath; +import it.unimi.dsi.fastutil.doubles.DoubleList; +import java.util.List; +import javax.annotation.Nullable; + +public abstract class VoxelShape { + + protected final VoxelShapeDiscrete a; + @Nullable + private VoxelShape[] b; + + VoxelShape(VoxelShapeDiscrete voxelshapediscrete) { + this.a = voxelshapediscrete; + } + + public double b(EnumDirection.EnumAxis enumdirection_enumaxis) { + int i = this.a.a(enumdirection_enumaxis); + + return i >= this.a.c(enumdirection_enumaxis) ? Double.POSITIVE_INFINITY : this.a(enumdirection_enumaxis, i); + } + + public double c(EnumDirection.EnumAxis enumdirection_enumaxis) { + int i = this.a.b(enumdirection_enumaxis); + + return i <= 0 ? Double.NEGATIVE_INFINITY : this.a(enumdirection_enumaxis, i); + } + + public AxisAlignedBB getBoundingBox() { + if (this.isEmpty()) { + throw new UnsupportedOperationException("No bounds for empty shape."); + } else { + return new AxisAlignedBB(this.b(EnumDirection.EnumAxis.X), this.b(EnumDirection.EnumAxis.Y), this.b(EnumDirection.EnumAxis.Z), this.c(EnumDirection.EnumAxis.X), this.c(EnumDirection.EnumAxis.Y), this.c(EnumDirection.EnumAxis.Z)); + } + } + + protected double a(EnumDirection.EnumAxis enumdirection_enumaxis, int i) { + return this.a(enumdirection_enumaxis).getDouble(i); + } + + protected abstract DoubleList a(EnumDirection.EnumAxis enumdirection_enumaxis); + + public boolean isEmpty() { + return this.a.a(); + } + + public final VoxelShape offset(double x, double y, double z) { return this.a(x, y, z); } // Paper - OBFHELPER + public VoxelShape a(double d0, double d1, double d2) { + return (VoxelShape) (this.isEmpty() ? VoxelShapes.a() : new VoxelShapeArray(this.a, new DoubleListOffset(this.a(EnumDirection.EnumAxis.X), d0), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Y), d1), new DoubleListOffset(this.a(EnumDirection.EnumAxis.Z), d2))); + } + + public VoxelShape c() { + VoxelShape[] avoxelshape = new VoxelShape[]{VoxelShapes.a()}; + + this.b((d0, d1, d2, d3, d4, d5) -> { + avoxelshape[0] = VoxelShapes.b(avoxelshape[0], VoxelShapes.create(d0, d1, d2, d3, d4, d5), OperatorBoolean.OR); + }); + return avoxelshape[0]; + } + + public void b(VoxelShapes.a voxelshapes_a) { + DoubleList doublelist = this.a(EnumDirection.EnumAxis.X); + DoubleList doublelist1 = this.a(EnumDirection.EnumAxis.Y); + DoubleList doublelist2 = this.a(EnumDirection.EnumAxis.Z); + + this.a.b((i, j, k, l, i1, j1) -> { + voxelshapes_a.consume(doublelist.getDouble(i), doublelist1.getDouble(j), doublelist2.getDouble(k), doublelist.getDouble(l), doublelist1.getDouble(i1), doublelist2.getDouble(j1)); + }, true); + } + + public List d() { + List list = Lists.newArrayList(); + + this.b((d0, d1, d2, d3, d4, d5) -> { + list.add(new AxisAlignedBB(d0, d1, d2, d3, d4, d5)); + }); + return list; + } + + protected int a(EnumDirection.EnumAxis enumdirection_enumaxis, double d0) { + return MathHelper.a(0, this.a.c(enumdirection_enumaxis) + 1, (i) -> { + return i < 0 ? false : (i > this.a.c(enumdirection_enumaxis) ? true : d0 < this.a(enumdirection_enumaxis, i)); + }) - 1; + } + + protected boolean b(double d0, double d1, double d2) { + return this.a.c(this.a(EnumDirection.EnumAxis.X, d0), this.a(EnumDirection.EnumAxis.Y, d1), this.a(EnumDirection.EnumAxis.Z, d2)); + } + + @Nullable + public MovingObjectPositionBlock rayTrace(Vec3D vec3d, Vec3D vec3d1, BlockPosition blockposition) { + if (this.isEmpty()) { + return null; + } else { + Vec3D vec3d2 = vec3d1.d(vec3d); + + if (vec3d2.g() < 1.0E-7D) { + return null; + } else { + Vec3D vec3d3 = vec3d.e(vec3d2.a(0.001D)); + + return this.b(vec3d3.x - (double) blockposition.getX(), vec3d3.y - (double) blockposition.getY(), vec3d3.z - (double) blockposition.getZ()) ? new MovingObjectPositionBlock(vec3d3, EnumDirection.a(vec3d2.x, vec3d2.y, vec3d2.z).opposite(), blockposition, true) : AxisAlignedBB.a(this.d(), vec3d, vec3d1, blockposition); + } + } + } + + public VoxelShape a(EnumDirection enumdirection) { + if (!this.isEmpty() && this != VoxelShapes.b()) { + VoxelShape voxelshape; + + if (this.b != null) { + voxelshape = this.b[enumdirection.ordinal()]; + if (voxelshape != null) { + return voxelshape; + } + } else { + this.b = new VoxelShape[6]; + } + + voxelshape = this.b(enumdirection); + this.b[enumdirection.ordinal()] = voxelshape; + return voxelshape; + } else { + return this; + } + } + + private VoxelShape b(EnumDirection enumdirection) { + EnumDirection.EnumAxis enumdirection_enumaxis = enumdirection.k(); + EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection = enumdirection.c(); + DoubleList doublelist = this.a(enumdirection_enumaxis); + + if (doublelist.size() == 2 && DoubleMath.fuzzyEquals(doublelist.getDouble(0), 0.0D, 1.0E-7D) && DoubleMath.fuzzyEquals(doublelist.getDouble(1), 1.0D, 1.0E-7D)) { + return this; + } else { + int i = this.a(enumdirection_enumaxis, enumdirection_enumaxisdirection == EnumDirection.EnumAxisDirection.POSITIVE ? 0.9999999D : 1.0E-7D); + + return new VoxelShapeSlice(this, enumdirection_enumaxis, i); + } + } + + public double a(EnumDirection.EnumAxis enumdirection_enumaxis, AxisAlignedBB axisalignedbb, double d0) { + return this.a(EnumAxisCycle.a(enumdirection_enumaxis, EnumDirection.EnumAxis.X), axisalignedbb, d0); + } + + protected double a(EnumAxisCycle enumaxiscycle, AxisAlignedBB axisalignedbb, double d0) { + if (this.isEmpty()) { + return d0; + } else if (Math.abs(d0) < 1.0E-7D) { + return 0.0D; + } else { + EnumAxisCycle enumaxiscycle1 = enumaxiscycle.a(); + EnumDirection.EnumAxis enumdirection_enumaxis = enumaxiscycle1.a(EnumDirection.EnumAxis.X); + EnumDirection.EnumAxis enumdirection_enumaxis1 = enumaxiscycle1.a(EnumDirection.EnumAxis.Y); + EnumDirection.EnumAxis enumdirection_enumaxis2 = enumaxiscycle1.a(EnumDirection.EnumAxis.Z); + double d1 = axisalignedbb.b(enumdirection_enumaxis); + double d2 = axisalignedbb.a(enumdirection_enumaxis); + int i = this.a(enumdirection_enumaxis, d2 + 1.0E-7D); + int j = this.a(enumdirection_enumaxis, d1 - 1.0E-7D); + int k = Math.max(0, this.a(enumdirection_enumaxis1, axisalignedbb.a(enumdirection_enumaxis1) + 1.0E-7D)); + int l = Math.min(this.a.c(enumdirection_enumaxis1), this.a(enumdirection_enumaxis1, axisalignedbb.b(enumdirection_enumaxis1) - 1.0E-7D) + 1); + int i1 = Math.max(0, this.a(enumdirection_enumaxis2, axisalignedbb.a(enumdirection_enumaxis2) + 1.0E-7D)); + int j1 = Math.min(this.a.c(enumdirection_enumaxis2), this.a(enumdirection_enumaxis2, axisalignedbb.b(enumdirection_enumaxis2) - 1.0E-7D) + 1); + int k1 = this.a.c(enumdirection_enumaxis); + double d3; + int l1; + int i2; + int j2; + + if (d0 > 0.0D) { + for (l1 = j + 1; l1 < k1; ++l1) { + for (i2 = k; i2 < l; ++i2) { + for (j2 = i1; j2 < j1; ++j2) { + if (this.a.a(enumaxiscycle1, l1, i2, j2)) { + d3 = this.a(enumdirection_enumaxis, l1) - d1; + if (d3 >= -1.0E-7D) { + d0 = Math.min(d0, d3); + } + + return d0; + } + } + } + } + } else if (d0 < 0.0D) { + for (l1 = i - 1; l1 >= 0; --l1) { + for (i2 = k; i2 < l; ++i2) { + for (j2 = i1; j2 < j1; ++j2) { + if (this.a.a(enumaxiscycle1, l1, i2, j2)) { + d3 = this.a(enumdirection_enumaxis, l1 + 1) - d2; + if (d3 <= 1.0E-7D) { + d0 = Math.max(d0, d3); + } + + return d0; + } + } + } + } + } + + return d0; + } + } + + public String toString() { + return this.isEmpty() ? "EMPTY" : "VoxelShape[" + this.getBoundingBox() + "]"; + } +} diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java new file mode 100644 index 000000000..c8bd4b703 --- /dev/null +++ b/src/main/java/net/minecraft/server/VoxelShapes.java @@ -0,0 +1,338 @@ +package net.minecraft.server; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.math.DoubleMath; +import com.google.common.math.IntMath; +import it.unimi.dsi.fastutil.doubles.DoubleArrayList; +import it.unimi.dsi.fastutil.doubles.DoubleList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Objects; +import java.util.stream.Stream; + +public final class VoxelShapes { + + private static final VoxelShape b = (VoxelShape) SystemUtils.a(() -> { + VoxelShapeBitSet voxelshapebitset = new VoxelShapeBitSet(1, 1, 1); + + voxelshapebitset.a(0, 0, 0, true, true); + return new VoxelShapeCube(voxelshapebitset); + }); + public static final VoxelShape a = create(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); + private static final VoxelShape c = new VoxelShapeArray(new VoxelShapeBitSet(0, 0, 0), new DoubleArrayList(new double[]{0.0D}), new DoubleArrayList(new double[]{0.0D}), new DoubleArrayList(new double[]{0.0D})); + + public static VoxelShape a() { + return VoxelShapes.c; + } + + public static VoxelShape b() { + return VoxelShapes.b; + } + + public static VoxelShape create(double d0, double d1, double d2, double d3, double d4, double d5) { + return a(new AxisAlignedBB(d0, d1, d2, d3, d4, d5)); + } + + public static final VoxelShape of(AxisAlignedBB axisAlignedbb) { return VoxelShapes.a(axisAlignedbb); } // Paper - OBFHELPER + public static VoxelShape a(AxisAlignedBB axisalignedbb) { + int i = a(axisalignedbb.minX, axisalignedbb.maxX); + int j = a(axisalignedbb.minY, axisalignedbb.maxY); + int k = a(axisalignedbb.minZ, axisalignedbb.maxZ); + + if (i >= 0 && j >= 0 && k >= 0) { + if (i == 0 && j == 0 && k == 0) { + return axisalignedbb.e(0.5D, 0.5D, 0.5D) ? b() : a(); + } else { + int l = 1 << i; + int i1 = 1 << j; + int j1 = 1 << k; + int k1 = (int) Math.round(axisalignedbb.minX * (double) l); + int l1 = (int) Math.round(axisalignedbb.maxX * (double) l); + int i2 = (int) Math.round(axisalignedbb.minY * (double) i1); + int j2 = (int) Math.round(axisalignedbb.maxY * (double) i1); + int k2 = (int) Math.round(axisalignedbb.minZ * (double) j1); + int l2 = (int) Math.round(axisalignedbb.maxZ * (double) j1); + VoxelShapeBitSet voxelshapebitset = new VoxelShapeBitSet(l, i1, j1, k1, i2, k2, l1, j2, l2); + + for (long i3 = (long) k1; i3 < (long) l1; ++i3) { + for (long j3 = (long) i2; j3 < (long) j2; ++j3) { + for (long k3 = (long) k2; k3 < (long) l2; ++k3) { + voxelshapebitset.a((int) i3, (int) j3, (int) k3, false, true); + } + } + } + + return new VoxelShapeCube(voxelshapebitset); + } + } else { + return new VoxelShapeArray(VoxelShapes.b.a, new double[]{axisalignedbb.minX, axisalignedbb.maxX}, new double[]{axisalignedbb.minY, axisalignedbb.maxY}, new double[]{axisalignedbb.minZ, axisalignedbb.maxZ}); + } + } + + private static int a(double d0, double d1) { + if (d0 >= -1.0E-7D && d1 <= 1.0000001D) { + for (int i = 0; i <= 3; ++i) { + double d2 = d0 * (double) (1 << i); + double d3 = d1 * (double) (1 << i); + boolean flag = Math.abs(d2 - Math.floor(d2)) < 1.0E-7D; + boolean flag1 = Math.abs(d3 - Math.floor(d3)) < 1.0E-7D; + + if (flag && flag1) { + return i; + } + } + + return -1; + } else { + return -1; + } + } + + protected static long a(int i, int j) { + return (long) i * (long) (j / IntMath.gcd(i, j)); + } + + public static VoxelShape a(VoxelShape voxelshape, VoxelShape voxelshape1) { + return a(voxelshape, voxelshape1, OperatorBoolean.OR); + } + + public static VoxelShape a(VoxelShape voxelshape, VoxelShape... avoxelshape) { + return (VoxelShape) Arrays.stream(avoxelshape).reduce(voxelshape, VoxelShapes::a); + } + + public static VoxelShape a(VoxelShape voxelshape, VoxelShape voxelshape1, OperatorBoolean operatorboolean) { + return b(voxelshape, voxelshape1, operatorboolean).c(); + } + + public static VoxelShape b(VoxelShape voxelshape, VoxelShape voxelshape1, OperatorBoolean operatorboolean) { + if (operatorboolean.apply(false, false)) { + throw new IllegalArgumentException(); + } else if (voxelshape == voxelshape1) { + return operatorboolean.apply(true, true) ? voxelshape : a(); + } else { + boolean flag = operatorboolean.apply(true, false); + boolean flag1 = operatorboolean.apply(false, true); + + if (voxelshape.isEmpty()) { + return flag1 ? voxelshape1 : a(); + } else if (voxelshape1.isEmpty()) { + return flag ? voxelshape : a(); + } else { + VoxelShapeMerger voxelshapemerger = a(1, voxelshape.a(EnumDirection.EnumAxis.X), voxelshape1.a(EnumDirection.EnumAxis.X), flag, flag1); + VoxelShapeMerger voxelshapemerger1 = a(voxelshapemerger.a().size() - 1, voxelshape.a(EnumDirection.EnumAxis.Y), voxelshape1.a(EnumDirection.EnumAxis.Y), flag, flag1); + VoxelShapeMerger voxelshapemerger2 = a((voxelshapemerger.a().size() - 1) * (voxelshapemerger1.a().size() - 1), voxelshape.a(EnumDirection.EnumAxis.Z), voxelshape1.a(EnumDirection.EnumAxis.Z), flag, flag1); + VoxelShapeBitSet voxelshapebitset = VoxelShapeBitSet.a(voxelshape.a, voxelshape1.a, voxelshapemerger, voxelshapemerger1, voxelshapemerger2, operatorboolean); + + return (VoxelShape) (voxelshapemerger instanceof VoxelShapeCubeMerger && voxelshapemerger1 instanceof VoxelShapeCubeMerger && voxelshapemerger2 instanceof VoxelShapeCubeMerger ? new VoxelShapeCube(voxelshapebitset) : new VoxelShapeArray(voxelshapebitset, voxelshapemerger.a(), voxelshapemerger1.a(), voxelshapemerger2.a())); + } + } + } + + public static final boolean applyOperation(VoxelShape voxelshape, VoxelShape voxelshape1, OperatorBoolean operatorboolean) { return VoxelShapes.c(voxelshape, voxelshape1, operatorboolean); } // Paper - OBFHELPER + public static boolean c(VoxelShape voxelshape, VoxelShape voxelshape1, OperatorBoolean operatorboolean) { + if (operatorboolean.apply(false, false)) { + throw new IllegalArgumentException(); + } else if (voxelshape == voxelshape1) { + return operatorboolean.apply(true, true); + } else if (voxelshape.isEmpty()) { + return operatorboolean.apply(false, !voxelshape1.isEmpty()); + } else if (voxelshape1.isEmpty()) { + return operatorboolean.apply(!voxelshape.isEmpty(), false); + } else { + boolean flag = operatorboolean.apply(true, false); + boolean flag1 = operatorboolean.apply(false, true); + EnumDirection.EnumAxis[] aenumdirection_enumaxis = EnumAxisCycle.d; + int i = aenumdirection_enumaxis.length; + + for (int j = 0; j < i; ++j) { + EnumDirection.EnumAxis enumdirection_enumaxis = aenumdirection_enumaxis[j]; + + if (voxelshape.c(enumdirection_enumaxis) < voxelshape1.b(enumdirection_enumaxis) - 1.0E-7D) { + return flag || flag1; + } + + if (voxelshape1.c(enumdirection_enumaxis) < voxelshape.b(enumdirection_enumaxis) - 1.0E-7D) { + return flag || flag1; + } + } + + VoxelShapeMerger voxelshapemerger = a(1, voxelshape.a(EnumDirection.EnumAxis.X), voxelshape1.a(EnumDirection.EnumAxis.X), flag, flag1); + VoxelShapeMerger voxelshapemerger1 = a(voxelshapemerger.a().size() - 1, voxelshape.a(EnumDirection.EnumAxis.Y), voxelshape1.a(EnumDirection.EnumAxis.Y), flag, flag1); + VoxelShapeMerger voxelshapemerger2 = a((voxelshapemerger.a().size() - 1) * (voxelshapemerger1.a().size() - 1), voxelshape.a(EnumDirection.EnumAxis.Z), voxelshape1.a(EnumDirection.EnumAxis.Z), flag, flag1); + + return a(voxelshapemerger, voxelshapemerger1, voxelshapemerger2, voxelshape.a, voxelshape1.a, operatorboolean); + } + } + + private static boolean a(VoxelShapeMerger voxelshapemerger, VoxelShapeMerger voxelshapemerger1, VoxelShapeMerger voxelshapemerger2, VoxelShapeDiscrete voxelshapediscrete, VoxelShapeDiscrete voxelshapediscrete1, OperatorBoolean operatorboolean) { + return !voxelshapemerger.a((i, j, k) -> { + return voxelshapemerger1.a((l, i1, j1) -> { + return voxelshapemerger2.a((k1, l1, i2) -> { + return !operatorboolean.apply(voxelshapediscrete.c(i, l, k1), voxelshapediscrete1.c(j, i1, l1)); + }); + }); + }); + } + + public static double a(EnumDirection.EnumAxis enumdirection_enumaxis, AxisAlignedBB axisalignedbb, Stream stream, double d0) { + for (Iterator iterator = stream.iterator(); iterator.hasNext(); d0 = ((VoxelShape) iterator.next()).a(enumdirection_enumaxis, axisalignedbb, d0)) { + if (Math.abs(d0) < 1.0E-7D) { + return 0.0D; + } + } + + return d0; + } + + public static double a(EnumDirection.EnumAxis enumdirection_enumaxis, AxisAlignedBB axisalignedbb, IWorldReader iworldreader, double d0, VoxelShapeCollision voxelshapecollision, Stream stream) { + return a(axisalignedbb, iworldreader, d0, voxelshapecollision, EnumAxisCycle.a(enumdirection_enumaxis, EnumDirection.EnumAxis.Z), stream); + } + + private static double a(AxisAlignedBB axisalignedbb, IWorldReader iworldreader, double d0, VoxelShapeCollision voxelshapecollision, EnumAxisCycle enumaxiscycle, Stream stream) { + if (axisalignedbb.b() >= 1.0E-6D && axisalignedbb.c() >= 1.0E-6D && axisalignedbb.d() >= 1.0E-6D) { + if (Math.abs(d0) < 1.0E-7D) { + return 0.0D; + } else { + EnumAxisCycle enumaxiscycle1 = enumaxiscycle.a(); + EnumDirection.EnumAxis enumdirection_enumaxis = enumaxiscycle1.a(EnumDirection.EnumAxis.X); + EnumDirection.EnumAxis enumdirection_enumaxis1 = enumaxiscycle1.a(EnumDirection.EnumAxis.Y); + EnumDirection.EnumAxis enumdirection_enumaxis2 = enumaxiscycle1.a(EnumDirection.EnumAxis.Z); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + int i = MathHelper.floor(axisalignedbb.a(enumdirection_enumaxis) - 1.0E-7D) - 1; + int j = MathHelper.floor(axisalignedbb.b(enumdirection_enumaxis) + 1.0E-7D) + 1; + int k = MathHelper.floor(axisalignedbb.a(enumdirection_enumaxis1) - 1.0E-7D) - 1; + int l = MathHelper.floor(axisalignedbb.b(enumdirection_enumaxis1) + 1.0E-7D) + 1; + double d1 = axisalignedbb.a(enumdirection_enumaxis2) - 1.0E-7D; + double d2 = axisalignedbb.b(enumdirection_enumaxis2) + 1.0E-7D; + boolean flag = d0 > 0.0D; + int i1 = flag ? MathHelper.floor(axisalignedbb.b(enumdirection_enumaxis2) - 1.0E-7D) - 1 : MathHelper.floor(axisalignedbb.a(enumdirection_enumaxis2) + 1.0E-7D) + 1; + int j1 = a(d0, d1, d2); + int k1 = flag ? 1 : -1; + int l1 = i1; + + while (true) { + if (flag) { + if (l1 > j1) { + break; + } + } else if (l1 < j1) { + break; + } + + for (int i2 = i; i2 <= j; ++i2) { + for (int j2 = k; j2 <= l; ++j2) { + int k2 = 0; + + if (i2 == i || i2 == j) { + ++k2; + } + + if (j2 == k || j2 == l) { + ++k2; + } + + if (l1 == i1 || l1 == j1) { + ++k2; + } + + if (k2 < 3) { + blockposition_mutableblockposition.a(enumaxiscycle1, i2, j2, l1); + IBlockData iblockdata = iworldreader.getType(blockposition_mutableblockposition); + + if ((k2 != 1 || iblockdata.f()) && (k2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { + d0 = iblockdata.b((IBlockAccess) iworldreader, blockposition_mutableblockposition, voxelshapecollision).a(enumdirection_enumaxis2, axisalignedbb.d((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), d0); + if (Math.abs(d0) < 1.0E-7D) { + return 0.0D; + } + + j1 = a(d0, d1, d2); + } + } + } + } + + l1 += k1; + } + + double[] adouble = new double[]{d0}; + + stream.forEach((voxelshape) -> { + adouble[0] = voxelshape.a(enumdirection_enumaxis2, axisalignedbb, adouble[0]); + }); + return adouble[0]; + } + } else { + return d0; + } + } + + private static int a(double d0, double d1, double d2) { + return d0 > 0.0D ? MathHelper.floor(d2 + d0) + 1 : MathHelper.floor(d1 + d0) - 1; + } + + public static VoxelShape a(VoxelShape voxelshape, EnumDirection enumdirection) { + if (voxelshape == b()) { + return b(); + } else { + EnumDirection.EnumAxis enumdirection_enumaxis = enumdirection.k(); + boolean flag; + int i; + + if (enumdirection.c() == EnumDirection.EnumAxisDirection.POSITIVE) { + flag = DoubleMath.fuzzyEquals(voxelshape.c(enumdirection_enumaxis), 1.0D, 1.0E-7D); + i = voxelshape.a.c(enumdirection_enumaxis) - 1; + } else { + flag = DoubleMath.fuzzyEquals(voxelshape.b(enumdirection_enumaxis), 0.0D, 1.0E-7D); + i = 0; + } + + return (VoxelShape) (!flag ? a() : new VoxelShapeSlice(voxelshape, enumdirection_enumaxis, i)); + } + } + + public static boolean b(VoxelShape voxelshape, VoxelShape voxelshape1, EnumDirection enumdirection) { + if (voxelshape != b() && voxelshape1 != b()) { + EnumDirection.EnumAxis enumdirection_enumaxis = enumdirection.k(); + EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection = enumdirection.c(); + VoxelShape voxelshape2 = enumdirection_enumaxisdirection == EnumDirection.EnumAxisDirection.POSITIVE ? voxelshape : voxelshape1; + VoxelShape voxelshape3 = enumdirection_enumaxisdirection == EnumDirection.EnumAxisDirection.POSITIVE ? voxelshape1 : voxelshape; + + if (!DoubleMath.fuzzyEquals(voxelshape2.c(enumdirection_enumaxis), 1.0D, 1.0E-7D)) { + voxelshape2 = a(); + } + + if (!DoubleMath.fuzzyEquals(voxelshape3.b(enumdirection_enumaxis), 0.0D, 1.0E-7D)) { + voxelshape3 = a(); + } + + return !c(b(), b(new VoxelShapeSlice(voxelshape2, enumdirection_enumaxis, voxelshape2.a.c(enumdirection_enumaxis) - 1), new VoxelShapeSlice(voxelshape3, enumdirection_enumaxis, 0), OperatorBoolean.OR), OperatorBoolean.ONLY_FIRST); + } else { + return true; + } + } + + public static boolean b(VoxelShape voxelshape, VoxelShape voxelshape1) { + return voxelshape != b() && voxelshape1 != b() ? (voxelshape.isEmpty() && voxelshape1.isEmpty() ? false : !c(b(), b(voxelshape, voxelshape1, OperatorBoolean.OR), OperatorBoolean.ONLY_FIRST)) : true; + } + + @VisibleForTesting + protected static VoxelShapeMerger a(int i, DoubleList doublelist, DoubleList doublelist1, boolean flag, boolean flag1) { + int j = doublelist.size() - 1; + int k = doublelist1.size() - 1; + + if (doublelist instanceof VoxelShapeCubePoint && doublelist1 instanceof VoxelShapeCubePoint) { + long l = a(j, k); + + if ((long) i * l <= 256L) { + return new VoxelShapeCubeMerger(j, k); + } + } + + return (VoxelShapeMerger) (doublelist.getDouble(j) < doublelist1.getDouble(0) - 1.0E-7D ? new VoxelShapeMergerDisjoint(doublelist, doublelist1, false) : (doublelist1.getDouble(k) < doublelist.getDouble(0) - 1.0E-7D ? new VoxelShapeMergerDisjoint(doublelist1, doublelist, true) : (j == k && Objects.equals(doublelist, doublelist1) ? (doublelist instanceof VoxelShapeMergerIdentical ? (VoxelShapeMerger) doublelist : (doublelist1 instanceof VoxelShapeMergerIdentical ? (VoxelShapeMerger) doublelist1 : new VoxelShapeMergerIdentical(doublelist))) : new VoxelShapeMergerList(doublelist, doublelist1, flag, flag1)))); + } + + public interface a { + + void consume(double d0, double d1, double d2, double d3, double d4, double d5); + } +} diff --git a/src/main/java/net/minecraft/server/WhiteList.java b/src/main/java/net/minecraft/server/WhiteList.java deleted file mode 100644 index b46458bd8..000000000 --- a/src/main/java/net/minecraft/server/WhiteList.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.minecraft.server; - -import com.google.gson.JsonObject; -import com.mojang.authlib.GameProfile; -import java.io.File; -import java.util.Iterator; -import java.util.Locale; - -import org.apache.commons.lang3.builder.ToStringBuilder; - -public class WhiteList extends JsonList { - - public WhiteList(File file) { - super(file); - } - - protected JsonListEntry a(JsonObject jsonobject) { - return new WhiteListEntry(jsonobject); - } - - public boolean isWhitelisted(GameProfile gameprofile) { - return this.d(gameprofile); - } - - public String[] getEntries() { - String[] astring = new String[this.e().size()]; - int i = 0; - - JsonListEntry jsonlistentry; - - for (Iterator iterator = this.e().iterator(); iterator.hasNext(); astring[i++] = ((GameProfile) jsonlistentry.getKey()).getName()) { - jsonlistentry = (JsonListEntry) iterator.next(); - } - - return astring; - } - - protected String a(GameProfile gameprofile) { - return AkarinUserCache.isOnlineMode() ? gameprofile.getId().toString() : gameprofile.getName(); // Akarin - } -} diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java index 297106747..1bea6dffe 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -1,38 +1,28 @@ - package net.minecraft.server; +package net.minecraft.server; +import co.aikar.timings.Timing; import co.aikar.timings.Timings; -import io.akarin.server.core.AkarinWorldAccessor; - import com.destroystokyo.paper.antixray.ChunkPacketBlockController; // Paper - Anti-Xray import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray; // Paper - Anti-Xray import com.destroystokyo.paper.event.server.ServerExceptionEvent; import com.destroystokyo.paper.exception.ServerInternalException; import com.google.common.base.MoreObjects; import com.google.common.collect.Lists; -import it.unimi.dsi.fastutil.longs.LongSet; -import it.unimi.dsi.fastutil.longs.LongSets; +import java.io.IOException; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Random; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.function.BooleanSupplier; -import java.util.function.Function; +import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Predicate; -import java.util.stream.Stream; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.util.Supplier; // CraftBukkit start import com.google.common.collect.Maps; -import com.koloboke.collect.map.hash.HashObjFloatMap; -import com.koloboke.collect.map.hash.HashObjFloatMaps; -import com.koloboke.collect.map.hash.HashObjObjMaps; -import com.koloboke.collect.set.hash.HashObjSets; - import java.util.ArrayList; import java.util.HashMap; // Paper import java.util.Map; @@ -43,105 +33,43 @@ import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.event.CraftEventFactory; -import org.bukkit.craftbukkit.util.LongHashSet; // Paper import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -import org.bukkit.generator.ChunkGenerator; +import org.bukkit.event.weather.LightningStrikeEvent; // CraftBukkit end -public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAccess, AutoCloseable, Cloneable { // Paper +public abstract class World implements IIBlockAccess, GeneratorAccess, AutoCloseable { - protected static final Logger e = LogManager.getLogger(); + protected static final Logger LOGGER = LogManager.getLogger(); private static final EnumDirection[] a = EnumDirection.values(); - private int b = 63; - // Spigot start - guard entity list from removals - public final List entityList = new com.destroystokyo.paper.PaperWorldEntityList(this); - /* // Paper start - { - @Override - public Entity remove(int index) - { - guard(); - return super.remove( index ); - } - - @Override - public boolean remove(Object o) - { - guard(); - return super.remove( o ); - } - - private void guard() - { - if ( guardEntityList ) - { - throw new java.util.ConcurrentModificationException(); - } - } - }; - */ // Paper end - // Spigot end - protected final Set g = HashObjSets.newMutableSet(); public Set getEntityUnloadQueue() { return g; };// Paper - OBFHELPER // Akarin //public final List tileEntityList = Lists.newArrayList(); // Paper - remove unused list public final List tileEntityListTick = Lists.newArrayList(); - private final List c = Lists.newArrayList(); - private final Set tileEntityListUnload = HashObjSets.newMutableSet(); // Paper // Akarin - public final List players = Lists.newCopyOnWriteArrayList(); // Akarin - iterate safety - public final Map playersByName = HashObjObjMaps.newMutableMap(); // Paper - World EntityHuman Lookup Optimizations // Akarin - public final List k = Lists.newArrayList(); - protected final IntHashMap entitiesById = new IntHashMap<>(); - private final long F = 16777215L; - private int G; public int getSkylightSubtracted() { return this.G; } public void setSkylightSubtracted(int value) { this.G = value;} // Paper - OBFHELPER - protected int m = (new Random()).nextInt(); - protected final int n = 1013904223; - protected float o; - protected float p; - protected float q; - protected float r; - private int H; + protected final List tileEntityListPending = Lists.newArrayList(); + protected final java.util.Set tileEntityListUnload = com.google.common.collect.Sets.newHashSet(); // Paper + private final long b = 16777215L; + final Thread serverThread; // CraftBukkit - package private + private int u; public int getSkylightSubtracted() { return this.u; } public void setSkylightSubtracted(int value) { this.u = value;} // Paper - OBFHELPER + protected int i = (new Random()).nextInt(); + protected final int j = 1013904223; + protected float lastRainLevel; + protected float rainLevel; + protected float lastThunderLevel; + protected float thunderLevel; + private int v; public final Random random = new Random(); public WorldProvider worldProvider; - protected NavigationListener u = new NavigationListener(); - protected List v; - private AkarinWorldAccessor worldAccessor; // Akarin - protected IChunkProvider chunkProvider; - protected final IDataManager dataManager; - public WorldData worldData; - @Nullable - public final PersistentCollection worldMaps; - protected PersistentVillage villages; - public final MethodProfiler methodProfiler; + protected final IChunkProvider chunkProvider; + public final WorldData worldData; + private final GameProfilerFiller methodProfiler; public final boolean isClientSide; - // Paper start - yes this is hacky as shit - RegionLimitedWorldAccess regionLimited; - World originalWorld; - public World regionLimited(RegionLimitedWorldAccess limitedWorldAccess) { - try { - World clone = (World) super.clone(); - clone.regionLimited = limitedWorldAccess; - clone.originalWorld = this; - return clone; - } catch (CloneNotSupportedException e1) { - } - return null; - } - ChunkCoordIntPair[] strongholdCoords; - final java.util.concurrent.atomic.AtomicBoolean - strongholdInit = new java.util.concurrent.atomic.AtomicBoolean - (false); - // Paper end - public boolean allowMonsters; - public boolean allowAnimals; - private boolean J; - private final WorldBorder K; - int[] E; + protected boolean tickingTileEntities; + private final WorldBorder worldBorder; // CraftBukkit start Added the following private final CraftWorld world; public boolean pvpMode; public boolean keepSpawnInMemory = true; - public ChunkGenerator generator; + public org.bukkit.generator.ChunkGenerator generator; public static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // Paper public boolean captureBlockStates = false; @@ -164,21 +92,35 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc public long ticksPerAnimalSpawns; public long ticksPerMonsterSpawns; public boolean populating; - private int tickPosition; public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot public final com.destroystokyo.paper.PaperWorldConfig paperConfig; // Paper public final ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray public final co.aikar.timings.WorldTimingsHandler timings; // Paper - public boolean guardEntityList; // Spigot // Paper - public public static BlockPosition lastPhysicsProblem; // Spigot - public static boolean haveWeSilencedAPhysicsCrash; - public static String blockLocation; private org.spigotmc.TickLimiter entityLimiter; private org.spigotmc.TickLimiter tileLimiter; private int tileTickPosition; - public final HashObjFloatMap explosionDensityCache = HashObjFloatMaps.newMutableMap(); + public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions + public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here + // Paper start - yes this is hacky as shit + RegionLimitedWorldAccess regionLimited; + World originalWorld; + public World regionLimited(RegionLimitedWorldAccess limitedWorldAccess) { + try { + World clone = (World) super.clone(); + clone.regionLimited = limitedWorldAccess; + clone.originalWorld = this; + return clone; + } catch (CloneNotSupportedException e1) { + } + return null; + } + ChunkCoordIntPair[] strongholdCoords; + List strongholdStuctures = Lists.newArrayList(); + final java.lang.Object stuctureLock = new Object(); + // Paper end public CraftWorld getWorld() { return this.world; @@ -189,10 +131,10 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } public Chunk getChunkIfLoaded(int x, int z) { - return ((ChunkProviderServer) this.chunkProvider).chunks.get(ChunkCoordIntPair.a(x, z)); // Paper - optimize getChunkIfLoaded + return ((ChunkProviderServer) this.chunkProvider).getChunkAtIfLoadedImmediately(x, z); // Paper } - protected World(IDataManager idatamanager, @Nullable PersistentCollection persistentcollection, WorldData worlddata, WorldProvider worldprovider, MethodProfiler methodprofiler, boolean flag, ChunkGenerator gen, org.bukkit.World.Environment env) { + protected World(WorldData worlddata, DimensionManager dimensionmanager, BiFunction bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(worlddata.getName(), this.spigotConfig); // Paper this.chunkPacketBlockController = this.paperConfig.antiXray ? new ChunkPacketBlockControllerAntiXray(this.paperConfig) : ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray @@ -201,17 +143,13 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit // CraftBukkit end - this.v = Lists.newArrayList(); // Akarin - this.allowMonsters = true; - this.allowAnimals = true; - this.E = new int['\u8000']; - this.dataManager = idatamanager; - this.worldMaps = persistentcollection; - this.methodProfiler = methodprofiler; + this.methodProfiler = gameprofilerfiller; this.worldData = worlddata; - this.worldProvider = worldprovider; + this.worldProvider = dimensionmanager.getWorldProvider(this); + this.chunkProvider = (IChunkProvider) bifunction.apply(this, this.worldProvider); this.isClientSide = flag; - this.K = worldprovider.getWorldBorder(); + this.worldBorder = this.worldProvider.getWorldBorder(); + this.serverThread = Thread.currentThread(); // CraftBukkit start getWorldBorder().world = (WorldServer) this; // From PlayerList.setPlayerFileData @@ -240,40 +178,70 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc public void c(WorldBorder worldborder, double d0) {} }); - this.getServer().addWorld(this.world); // CraftBukkit end timings = new co.aikar.timings.WorldTimingsHandler(this); // Paper - code below can generate new world and access timings this.keepSpawnInMemory = this.paperConfig.keepSpawnInMemory; // Paper - this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime); + this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime); this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime); } - public BiomeBase getBiome(BlockPosition blockposition) { - if (this.isLoaded(blockposition)) { - Chunk chunk = this.getChunkAtWorldCoords(blockposition); + // Paper start + // ret true if no collision + public final boolean checkEntityCollision(IBlockData data, Entity source, VoxelShapeCollision voxelshapedcollision, + BlockPosition position, boolean checkCanSee) { + // Copied from IWorldReader#a(IBlockData, BlockPosition, VoxelShapeCollision) & EntityAccess#a(Entity, VoxelShape) + VoxelShape voxelshape = data.getCollisionShape(this, position, voxelshapedcollision); + if (voxelshape.isEmpty()) { + return true; + } - try { - return chunk.getBiome(blockposition); - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Getting biome"); - CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Coordinates of biome request"); + voxelshape = voxelshape.offset((double) position.getX(), (double) position.getY(), (double) position.getZ()); - crashreportsystemdetails.a("Location", () -> { - return CrashReportSystemDetails.a(blockposition); - }); - throw new ReportedException(crashreport); + if (voxelshape.isEmpty()) { + return true; + } + + List entities = this.getEntities(null, voxelshape.getBoundingBox()); + + for (int i = 0, len = entities.size(); i < len; ++i) { + Entity entity = entities.get(i); + + if (checkCanSee && source instanceof EntityPlayer && entity instanceof EntityPlayer + && !((EntityPlayer)source).getBukkitEntity().canSee(((EntityPlayer)entity).getBukkitEntity())) { + continue; } + + // !entity1.dead && entity1.i && (entity == null || !entity1.x(entity)); + // elide the last check since vanilla calls with entity = null + // only we care about the source for the canSee check + if (entity.dead || !entity.blocksEntitySpawning()) { + continue; + } + + if (VoxelShapes.applyOperation(voxelshape, VoxelShapes.of(entity.getBoundingBox()), OperatorBoolean.AND)) { + return false; + } + } + + return true; + } + // Paper end + + @Override + public BiomeBase getBiome(BlockPosition blockposition) { + IChunkProvider ichunkprovider = this.getChunkProvider(); + Chunk chunk = ichunkprovider.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4, false); + + if (chunk != null) { + return chunk.getBiome(blockposition); } else { - return this.chunkProvider.getChunkGenerator().getWorldChunkManager().getBiome(blockposition, Biomes.PLAINS); + ChunkGenerator chunkgenerator = this.getChunkProvider().getChunkGenerator(); + + return chunkgenerator == null ? Biomes.PLAINS : chunkgenerator.getWorldChunkManager().getBiome(blockposition); } } - protected abstract IChunkProvider r(); - - public void a(WorldSettings worldsettings) { - this.worldData.d(true); - } - + @Override public boolean e() { return this.isClientSide; } @@ -297,21 +265,21 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return blockposition.isValidLocation(); // Paper } - public static boolean k(BlockPosition blockposition) { + public static boolean isOutsideWorld(BlockPosition blockposition) { return blockposition.isInvalidYLocation(); // Paper } - public boolean isEmpty(BlockPosition blockposition) { - return this.getType(blockposition).isAir(); + public static boolean b(int i) { + return i < 0 || i >= 256; } public boolean isLoaded(BlockPosition blockposition) { - return getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null; // Paper + return getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null; // Paper } // Paper start public boolean isLoadedAndInBounds(BlockPosition blockposition) { - return getWorldBorder().isInBounds(blockposition) && getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null; + return getWorldBorder().isInBounds(blockposition) && getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null; } public Chunk getChunkIfLoaded(BlockPosition blockposition) { return getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); @@ -319,41 +287,61 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc // test if meets light level, return faster // logic copied from below public boolean isLightLevel(BlockPosition blockposition, int level) { - if (blockposition.isValidLocation()) { - if (this.getType(blockposition).c(this, blockposition)) { - int sky = getSkylightSubtracted(); - if (this.getLightLevel(blockposition.up(), sky) >= level) { - return true; - } - if (this.getLightLevel(blockposition.east(), sky) >= level) { - return true; - } - if (this.getLightLevel(blockposition.west(), sky) >= level) { - return true; - } - if (this.getLightLevel(blockposition.south(), sky) >= level) { - return true; - } - if (this.getLightLevel(blockposition.north(), sky) >= level) { - return true; - } - return false; - } else { - if (blockposition.getY() >= 256) { - blockposition = new BlockPosition(blockposition.getX(), 255, blockposition.getZ()); - } - - Chunk chunk = this.getChunkAtWorldCoords(blockposition); - return chunk.getLightSubtracted(blockposition, this.getSkylightSubtracted()) >= level; - } - } else { - return true; - } + return this.getLightLevel(blockposition) >= level; // TODO +// if (isValidLocation(blockposition)) { +// if (this.getType(blockposition).c(this, blockposition)) { // use neighbour brightness (where did this go) +// int sky = getSkylightSubtracted(); +// if (this.getLightLevel(blockposition.up(), sky) >= level) { +// return true; +// } +// if (this.getLightLevel(blockposition.east(), sky) >= level) { +// return true; +// } +// if (this.getLightLevel(blockposition.west(), sky) >= level) { +// return true; +// } +// if (this.getLightLevel(blockposition.south(), sky) >= level) { +// return true; +// } +// if (this.getLightLevel(blockposition.north(), sky) >= level) { +// return true; +// } +// return false; +// } else { +// if (blockposition.getY() >= 256) { +// blockposition = new BlockPosition(blockposition.getX(), 255, blockposition.getZ()); +// } +// +// Chunk chunk = this.getChunkAtWorldCoords(blockposition); +// return chunk.getLightSubtracted(blockposition, this.getSkylightSubtracted()) >= level; +// } +// } else { +// return true; +// } } // reduces need to do isLoaded before getType public IBlockData getTypeIfLoadedAndInBounds(BlockPosition blockposition) { return getWorldBorder().isInBounds(blockposition) ? getTypeIfLoaded(blockposition) : null; } + // Paper end + + public Chunk getChunkAtWorldCoords(BlockPosition blockposition) { + return this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); + } + + @Override + public Chunk getChunkAt(int i, int j) { + return (Chunk) this.getChunkAt(i, j, ChunkStatus.FULL); + } + + // Paper start - if loaded + @Nullable + @Override + public IChunkAccess getChunkIfLoadedImmediately(int x, int z) { + return ((ChunkProviderServer)this.chunkProvider).getChunkAtIfLoadedImmediately(x, z); + } + + @Override public IBlockData getTypeIfLoaded(BlockPosition blockposition) { // CraftBukkit start - tree generation if (captureTreeGeneration) { @@ -364,42 +352,34 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } } // CraftBukkit end - Chunk chunk = this.getChunkIfLoaded(blockposition); - if (chunk != null) { - return blockposition.isValidLocation() ? chunk.getBlockData(blockposition) : Blocks.AIR.getBlockData(); // Paper + if (!isValidLocation(blockposition)) { + return Blocks.AIR.getBlockData(); } - return null; + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + + return chunk == null ? null : chunk.getType(blockposition); } - public Block getBlockIfLoaded(BlockPosition blockposition) { - IBlockData type = getTypeIfLoaded(blockposition); - if (type == null) { - return null; - } - return type.getBlock(); - } - public Material getMaterialIfLoaded(BlockPosition blockposition) { - IBlockData type = getTypeIfLoaded(blockposition); - if (type == null) { - return null; - } - return type.getBlock().material; + + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + + return chunk == null ? null : chunk.getFluid(blockposition); } // Paper end - public Chunk getChunkAtWorldCoords(BlockPosition blockposition) { - return this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); - } + @Override + public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { + IChunkAccess ichunkaccess = this.chunkProvider.getChunkAt(i, j, chunkstatus, flag); - public Chunk getChunkAt(int i, int j) { - Chunk chunk = this.chunkProvider.getChunkAt(i, j, true, true); - - if (chunk == null) { + if (ichunkaccess == null && flag) { throw new IllegalStateException("Should always be able to create a chunk!"); } else { - return chunk; + return ichunkaccess; } } + @Override public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { // CraftBukkit start - tree generation if (this.captureTreeGeneration) { @@ -421,7 +401,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return true; } // CraftBukkit end - if (blockposition.isInvalidYLocation()) { // Paper + if (isOutsideWorld(blockposition)) { return false; } else if (!this.isClientSide && this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { return false; @@ -432,7 +412,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc // CraftBukkit start - capture blockstates CraftBlockState blockstate = null; if (this.captureBlockStates) { - blockstate = (CraftBlockState) world.getBlockAt(blockposition).getState(); // Paper - use CB getState to get a suitable snapshot // Akarin + blockstate = (CraftBlockState) world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()).getState(); // Paper - use CB getState to get a suitable snapshot this.capturedBlockStates.add(blockstate); } // CraftBukkit end @@ -450,19 +430,19 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } else { IBlockData iblockdata2 = this.getType(blockposition); - if (iblockdata2.b(this, blockposition) != iblockdata1.b(this, blockposition) || iblockdata2.e() != iblockdata1.e()) { - //this.methodProfiler.enter(* // Akarin - remove caller - chunk.runOrQueueLightUpdate(() -> this.r(blockposition)); // Paper - Queue light update - //this.methodProfiler.exit(); // Akarin - remove caller + if (iblockdata2 != iblockdata1 && (iblockdata2.b((IBlockAccess) this, blockposition) != iblockdata1.b((IBlockAccess) this, blockposition) || iblockdata2.h() != iblockdata1.h() || iblockdata2.g() || iblockdata1.g())) { + this.methodProfiler.enter("queueCheckLight"); + this.getChunkProvider().getLightEngine().a(blockposition); + this.methodProfiler.exit(); } /* if (iblockdata2 == iblockdata) { if (iblockdata1 != iblockdata2) { - this.a(blockposition, blockposition); + this.b(blockposition, iblockdata1, iblockdata2); } - if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && chunk.isReady()) { + if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && (this.isClientSide || chunk.getState() != null && chunk.getState().isAtLeast(PlayerChunk.State.TICKING))) { this.notify(blockposition, iblockdata1, iblockdata, i); } @@ -477,9 +457,11 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc int j = i & -2; iblockdata1.b(this, blockposition, j); - iblockdata.a((GeneratorAccess) this, blockposition, j); + iblockdata.a(this, blockposition, j); iblockdata.b(this, blockposition, j); } + + this.a(blockposition, iblockdata1, iblockdata2); } */ @@ -507,15 +489,11 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc IBlockData iblockdata1 = oldBlock; IBlockData iblockdata2 = actualBlock; if (iblockdata2 == iblockdata) { - // Akarin start - /* if (iblockdata1 != iblockdata2) { - this.a(blockposition, blockposition); + this.b(blockposition, iblockdata1, iblockdata2); } - */ - // Akarin end - if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && (chunk == null || chunk.isReady())) { // allow chunk to be null here as chunk.isReady() is false when we send our notification during block placement + if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && (this.isClientSide || chunk == null || (chunk.getState() != null && chunk.getState().isAtLeast(PlayerChunk.State.TICKING)))) { // allow chunk to be null here as chunk.isReady() is false when we send our notification during block placement this.notify(blockposition, iblockdata1, iblockdata, i); } @@ -532,8 +510,8 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc // CraftBukkit start iblockdata1.b(this, blockposition, j); // Don't call an event for the old block to limit event spam CraftWorld world = ((WorldServer) this).getWorld(); - if (world != null && ((WorldServer)this).hasPhysicsEvent && !io.akarin.server.core.AkarinGlobalConfig.fixPhysicsEventBehaviour) { // Paper // Akarin - fixes physics event - BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition), CraftBlockData.fromData(iblockdata)); // Akarin + if (world != null && ((WorldServer)this).hasPhysicsEvent) { // Paper + BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata)); this.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -541,20 +519,27 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } } // CraftBukkit end - iblockdata.a((GeneratorAccess) this, blockposition, j); + iblockdata.a(this, blockposition, j); iblockdata.b(this, blockposition, j); } + + this.a(blockposition, iblockdata1, iblockdata2); } } // CraftBukkit end - public boolean setAir(BlockPosition blockposition) { + public void a(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) {} + + public boolean setAir(BlockPosition blockposition) { return this.a(blockposition, false); } // Paper - OBFHELPER + public boolean setAir(BlockPosition blockposition, boolean moved) { return this.a(blockposition, moved); } // Paper - OBFHELPER + @Override public boolean a(BlockPosition blockposition, boolean flag) { // Paper - OBFHELPER Fluid fluid = this.getFluid(blockposition); - return this.setTypeAndData(blockposition, fluid.i(), 3); + return this.setTypeAndData(blockposition, fluid.getBlockData(), 3 | (flag ? 64 : 0)); } - public boolean setAir(BlockPosition blockposition, boolean flag) { + @Override + public boolean b(BlockPosition blockposition, boolean flag) { IBlockData iblockdata = this.getType(blockposition); if (iblockdata.isAir()) { @@ -566,7 +551,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc // it doesn't imply destruction of a block that plays a sound effect / drops an item. boolean playEffect = true; if (com.destroystokyo.paper.event.block.BlockDestroyEvent.getHandlerList().getRegisteredListeners().length > 0) { - com.destroystokyo.paper.event.block.BlockDestroyEvent event = new com.destroystokyo.paper.event.block.BlockDestroyEvent(MCUtil.toBukkitBlock(this, blockposition), fluid.i().createCraftBlockData(), flag); + com.destroystokyo.paper.event.block.BlockDestroyEvent event = new com.destroystokyo.paper.event.block.BlockDestroyEvent(MCUtil.toBukkitBlock(this, blockposition), fluid.getBlockData().createCraftBlockData(), flag); if (!event.callEvent()) { return false; } @@ -576,10 +561,12 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc if (playEffect) this.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); // Paper if (flag) { - iblockdata.a(this, blockposition, 0); + TileEntity tileentity = iblockdata.getBlock().isTileEntity() ? this.getTileEntity(blockposition) : null; + + Block.a(iblockdata, this, blockposition, tileentity); } - return this.setTypeAndData(blockposition, fluid.i(), 3); + return this.setTypeAndData(blockposition, fluid.getBlockData(), 3); } } @@ -587,18 +574,9 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return this.setTypeAndData(blockposition, iblockdata, 3); } - public void notify(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, int i) { - // Akarin start - /* - for (int j = 0; j < this.v.size(); ++j) { - ((IWorldAccess) this.v.get(j)).a(this, blockposition, iblockdata, iblockdata1, i); - } - */ - worldAccessor.a(this, blockposition, iblockdata, iblockdata1, i); - // Akarin end - - } + public abstract void notify(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, int i); + @Override public void update(BlockPosition blockposition, Block block) { if (this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) { // CraftBukkit start @@ -611,35 +589,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } - public void a(int i, int j, int k, int l) { - int i1; - - if (k > l) { - i1 = l; - l = k; - k = i1; - } - - if (this.worldProvider.g()) { - Chunk chunk = getChunkIfLoaded(i >> 4, j >> 4); // Paper - for (i1 = k; chunk != null && i1 <= l; ++i1) { // Paper - this.updateBrightness(EnumSkyBlock.SKY, new BlockPosition(i, i1, j), chunk); // Paper - } - } - - //this.a(i, k, j, i, l, j); // Akarin - } - - public void a(BlockPosition blockposition, BlockPosition blockposition1) { - this.a(blockposition.getX(), blockposition.getY(), blockposition.getZ(), blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); - } - - public void a(int i, int j, int k, int l, int i1, int j1) { - for (int k1 = 0; k1 < this.v.size(); ++k1) { - ((IWorldAccess) this.v.get(k1)).a(i, j, k, l, i1, j1); - } - - } + public void b(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) {} public void applyPhysics(BlockPosition blockposition, Block block) { if (captureBlockStates) { return; } // Paper - Cancel all physics during placement @@ -687,7 +637,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc // CraftBukkit start CraftWorld world = ((WorldServer) this).getWorld(); if (world != null && ((WorldServer)this).hasPhysicsEvent) { // Paper - BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition), CraftBlockData.fromData(iblockdata), world.getBlockAt(blockposition)); // Akarin + BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata), world.getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ())); this.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -695,9 +645,9 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } } // CraftBukkit end - iblockdata.doPhysics(this, blockposition, block, blockposition1); + iblockdata.doPhysics(this, blockposition, block, blockposition1, false); // Spigot Start - } catch (StackOverflowError ex) { + } catch (StackOverflowError ex) { lastPhysicsProblem = new BlockPosition(blockposition); // Spigot End } catch (Throwable throwable) { @@ -706,7 +656,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc crashreportsystemdetails.a("Source block type", () -> { try { - return String.format("ID #%s (%s // %s)", IRegistry.BLOCK.getKey(block), block.m(), block.getClass().getCanonicalName()); + return String.format("ID #%s (%s // %s)", IRegistry.BLOCK.getKey(block), block.l(), block.getClass().getCanonicalName()); } catch (Throwable throwable1) { return "ID #" + IRegistry.BLOCK.getKey(block); } @@ -717,10 +667,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } } - public boolean e(BlockPosition blockposition) { - return this.getChunkAtWorldCoords(blockposition).c(blockposition); - } - + @Override public int getLightLevel(BlockPosition blockposition, int i) { if (blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000) { if (blockposition.getY() < 0) { @@ -738,11 +685,12 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } } - public int a(HeightMap.Type heightmap_type, int i, int j) { + public final int getHighestBlockY(final HeightMap.Type heightmap, final int x, final int z) { return this.a(heightmap, x, z); } // Paper - OBFHELPER + @Override public int a(HeightMap.Type heightmap_type, int i, int j) { // Paper - OBFHELPER int k; if (i >= -30000000 && j >= -30000000 && i < 30000000 && j < 30000000) { - if (this.isChunkLoaded(i >> 4, j >> 4, true)) { + if (this.isChunkLoaded(i >> 4, j >> 4)) { k = this.getChunkAt(i >> 4, j >> 4).a(heightmap_type, i & 15, j & 15) + 1; } else { k = 0; @@ -754,104 +702,36 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return k; } - @Deprecated - public int d(int i, int j) { - if (i >= -30000000 && j >= -30000000 && i < 30000000 && j < 30000000) { - if (!this.isChunkLoaded(i >> 4, j >> 4, true)) { - return 0; - } else { - Chunk chunk = this.getChunkAt(i >> 4, j >> 4); - - return chunk.D(); - } - } else { - return this.getSeaLevel() + 1; - } - } - + @Override public int getBrightness(EnumSkyBlock enumskyblock, BlockPosition blockposition) { - if (blockposition.getY() < 0) { - blockposition = new BlockPosition(blockposition.getX(), 0, blockposition.getZ()); - } - - Chunk chunk; // Paper - return !blockposition.isValidLocation() ? enumskyblock.c : ((chunk = this.getChunkIfLoaded(blockposition)) == null ? enumskyblock.c : chunk.getBrightness(enumskyblock, blockposition)); // Paper - optimize ifChunkLoaded + return this.getChunkProvider().getLightEngine().a(enumskyblock).b(blockposition); } - public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { - if (blockposition.isValidLocation()) { // Paper - if (this.isLoaded(blockposition)) { - this.getChunkAtWorldCoords(blockposition).a(enumskyblock, blockposition, i); - //this.m(blockposition); // Akarin - } - } - } - - public void m(BlockPosition blockposition) { - for (int i = 0; i < this.v.size(); ++i) { - ((IWorldAccess) this.v.get(i)).a(blockposition); - } - - } - - // Paper - async variant - public java.util.concurrent.CompletableFuture getTypeAsync(BlockPosition blockposition) { - int x = blockposition.getX(); - int z = blockposition.getZ(); + @Override + public IBlockData getType(BlockPosition blockposition) { + // CraftBukkit start - tree generation if (captureTreeGeneration) { Iterator it = capturedBlockStates.iterator(); while (it.hasNext()) { CraftBlockState previous = it.next(); - if (previous.getX() == x && previous.getY() == blockposition.getY() && previous.getZ() == z) { - return java.util.concurrent.CompletableFuture.completedFuture(previous.getHandle()); + if (previous.getPosition().equals(blockposition)) { + return previous.getHandle(); } } } - if (blockposition.isInvalidYLocation()) { - return java.util.concurrent.CompletableFuture.completedFuture(Blocks.VOID_AIR.getBlockData()); - } else { - java.util.concurrent.CompletableFuture future = new java.util.concurrent.CompletableFuture<>(); - ((ChunkProviderServer) chunkProvider).getChunkAt(x << 4, z << 4, true, true, (chunk) -> { - future.complete(chunk.getType(blockposition)); - }); - return future; - } - } - // Paper end - - public IBlockData getType(BlockPosition blockposition) { - // CraftBukkit start - tree generation - if (captureTreeGeneration) { // If any of this logic updates, update async variant above - Iterator it = capturedBlockStates.iterator(); - while (it.hasNext()) { // If any of this logic updates, update async variant above - CraftBlockState previous = it.next(); - if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) { - return previous.getHandle(); // If any of this logic updates, update async variant above - } - } // If any of this logic updates, update async variant above - } // CraftBukkit end - if (blockposition.isInvalidYLocation()) { // Paper + if (isOutsideWorld(blockposition)) { return Blocks.VOID_AIR.getBlockData(); } else { - Chunk chunk = this.getChunkAtWorldCoords(blockposition); + Chunk chunk = this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); return chunk.getType(blockposition); } } - // Paper start - public Fluid getFluidIfLoaded(BlockPosition blockposition) { - if (blockposition.isInvalidYLocation()) { // Paper - return getFluid(blockposition); - } else { - Chunk chunk = this.getChunkIfLoaded(blockposition); - return chunk != null ? chunk.getFluid(blockposition) : null; - } - } - // Paper end + @Override public Fluid getFluid(BlockPosition blockposition) { - if (blockposition.isInvalidYLocation()) { // Paper + if (isOutsideWorld(blockposition)) { return FluidTypes.EMPTY.i(); } else { Chunk chunk = this.getChunkAtWorldCoords(blockposition); @@ -860,684 +740,47 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } } - public boolean isDayTime() { return L(); } // Paper - OBFHELPER - public boolean L() { - return this.G < 4; + public boolean isDayTime() { return J(); } // Paper - OBFHELPER + public boolean J() { + return this.u < 4; } - @Nullable - public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1) { - return this.rayTrace(vec3d, vec3d1, FluidCollisionOption.NEVER, false, false); - } - - @Nullable - public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1, FluidCollisionOption fluidcollisionoption) { - return this.rayTrace(vec3d, vec3d1, fluidcollisionoption, false, false); - } - - @Nullable - public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1, FluidCollisionOption fluidcollisionoption, boolean flag, boolean flag1) { - double d0 = vec3d.x; - double d1 = vec3d.y; - double d2 = vec3d.z; - - if (!Double.isNaN(d0) && !Double.isNaN(d1) && !Double.isNaN(d2)) { - if (!Double.isNaN(vec3d1.x) && !Double.isNaN(vec3d1.y) && !Double.isNaN(vec3d1.z)) { - int i = MathHelper.floor(vec3d1.x); - int j = MathHelper.floor(vec3d1.y); - int k = MathHelper.floor(vec3d1.z); - int l = MathHelper.floor(d0); - int i1 = MathHelper.floor(d1); - int j1 = MathHelper.floor(d2); - BlockPosition blockposition = new BlockPosition(l, i1, j1); - IBlockData iblockdata = this.getTypeIfLoaded(blockposition); // Paper - if (iblockdata == null) return null; // Paper - Fluid fluid = this.getFluid(blockposition); - boolean flag2; - boolean flag3; - - if (!flag || !iblockdata.getCollisionShape(this, blockposition).isEmpty()) { - flag2 = iblockdata.getBlock().isCollidable(iblockdata); - flag3 = fluidcollisionoption.predicate.test(fluid); - if (flag2 || flag3) { - MovingObjectPosition movingobjectposition = null; - - if (flag2) { - movingobjectposition = Block.rayTrace(iblockdata, this, blockposition, vec3d, vec3d1); - } - - if (movingobjectposition == null && flag3) { - movingobjectposition = VoxelShapes.create(0.0D, 0.0D, 0.0D, 1.0D, (double) fluid.getHeight(), 1.0D).rayTrace(vec3d, vec3d1, blockposition); - } - - if (movingobjectposition != null) { - return movingobjectposition; - } - } - } - - MovingObjectPosition movingobjectposition1 = null; - int k1 = 200; - - while (k1-- >= 0) { - if (Double.isNaN(d0) || Double.isNaN(d1) || Double.isNaN(d2)) { - return null; - } - - if (l == i && i1 == j && j1 == k) { - return flag1 ? movingobjectposition1 : null; - } - - flag2 = true; - flag3 = true; - boolean flag4 = true; - double d3 = 999.0D; - double d4 = 999.0D; - double d5 = 999.0D; - - if (i > l) { - d3 = (double) l + 1.0D; - } else if (i < l) { - d3 = (double) l + 0.0D; - } else { - flag2 = false; - } - - if (j > i1) { - d4 = (double) i1 + 1.0D; - } else if (j < i1) { - d4 = (double) i1 + 0.0D; - } else { - flag3 = false; - } - - if (k > j1) { - d5 = (double) j1 + 1.0D; - } else if (k < j1) { - d5 = (double) j1 + 0.0D; - } else { - flag4 = false; - } - - double d6 = 999.0D; - double d7 = 999.0D; - double d8 = 999.0D; - double d9 = vec3d1.x - d0; - double d10 = vec3d1.y - d1; - double d11 = vec3d1.z - d2; - - if (flag2) { - d6 = (d3 - d0) / d9; - } - - if (flag3) { - d7 = (d4 - d1) / d10; - } - - if (flag4) { - d8 = (d5 - d2) / d11; - } - - if (d6 == -0.0D) { - d6 = -1.0E-4D; - } - - if (d7 == -0.0D) { - d7 = -1.0E-4D; - } - - if (d8 == -0.0D) { - d8 = -1.0E-4D; - } - - EnumDirection enumdirection; - - if (d6 < d7 && d6 < d8) { - enumdirection = i > l ? EnumDirection.WEST : EnumDirection.EAST; - d0 = d3; - d1 += d10 * d6; - d2 += d11 * d6; - } else if (d7 < d8) { - enumdirection = j > i1 ? EnumDirection.DOWN : EnumDirection.UP; - d0 += d9 * d7; - d1 = d4; - d2 += d11 * d7; - } else { - enumdirection = k > j1 ? EnumDirection.NORTH : EnumDirection.SOUTH; - d0 += d9 * d8; - d1 += d10 * d8; - d2 = d5; - } - - l = MathHelper.floor(d0) - (enumdirection == EnumDirection.EAST ? 1 : 0); - i1 = MathHelper.floor(d1) - (enumdirection == EnumDirection.UP ? 1 : 0); - j1 = MathHelper.floor(d2) - (enumdirection == EnumDirection.SOUTH ? 1 : 0); - blockposition = new BlockPosition(l, i1, j1); - IBlockData iblockdata1 = this.getTypeIfLoaded(blockposition); // Paper - if (iblockdata1 == null) return null; // Paper - Fluid fluid1 = this.getFluid(blockposition); - - if (!flag || iblockdata1.getMaterial() == Material.PORTAL || !iblockdata1.getCollisionShape(this, blockposition).isEmpty()) { - boolean flag5 = iblockdata1.getBlock().isCollidable(iblockdata1); - boolean flag6 = fluidcollisionoption.predicate.test(fluid1); - - if (!flag5 && !flag6) { - movingobjectposition1 = new MovingObjectPosition(MovingObjectPosition.EnumMovingObjectType.MISS, new Vec3D(d0, d1, d2), enumdirection, blockposition); - } else { - MovingObjectPosition movingobjectposition2 = null; - - if (flag5) { - movingobjectposition2 = Block.rayTrace(iblockdata1, this, blockposition, vec3d, vec3d1); - } - - if (movingobjectposition2 == null && flag6) { - movingobjectposition2 = VoxelShapes.create(0.0D, 0.0D, 0.0D, 1.0D, (double) fluid1.getHeight(), 1.0D).rayTrace(vec3d, vec3d1, blockposition); - } - - if (movingobjectposition2 != null) { - return movingobjectposition2; - } - } - } - } - - return flag1 ? movingobjectposition1 : null; - } else { - return null; - } - } else { - return null; - } - } - - public void a(@Nullable EntityHuman entityhuman, BlockPosition blockposition, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) { - this.a(entityhuman, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, soundeffect, soundcategory, f, f1); + @Override + public void playSound(@Nullable EntityHuman entityhuman, BlockPosition blockposition, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) { + this.playSound(entityhuman, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, soundeffect, soundcategory, f, f1); } // Paper start - OBFHELPER public final void sendSoundEffect(@Nullable EntityHuman fromEntity, double x, double y, double z, SoundEffect soundeffect, SoundCategory soundcategory, float volume, float pitch) { - this.a(fromEntity, x, y, z, soundeffect, soundcategory, volume, pitch); + this.playSound(fromEntity, x, y, z, soundeffect, soundcategory, volume, pitch); } // Paper end + public abstract void playSound(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1); - public void a(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) { - // Akarin start - /* - for (int i = 0; i < this.v.size(); ++i) { - ((IWorldAccess) this.v.get(i)).a(entityhuman, soundeffect, soundcategory, d0, d1, d2, f, f1); - } - */ - worldAccessor.a(entityhuman, soundeffect, soundcategory, d0, d1, d2, f, f1); - // Akarin end - - } + public abstract void playSound(@Nullable EntityHuman entityhuman, Entity entity, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1); public void a(double d0, double d1, double d2, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1, boolean flag) {} - public void a(BlockPosition blockposition, @Nullable SoundEffect soundeffect) { - for (int i = 0; i < this.v.size(); ++i) { - ((IWorldAccess) this.v.get(i)).a(soundeffect, blockposition); - } + @Override + public void addParticle(ParticleParam particleparam, double d0, double d1, double d2, double d3, double d4, double d5) {} - } + public void b(ParticleParam particleparam, double d0, double d1, double d2, double d3, double d4, double d5) {} - public void addParticle(ParticleParam particleparam, double d0, double d1, double d2, double d3, double d4, double d5) { - for (int i = 0; i < this.v.size(); ++i) { - ((IWorldAccess) this.v.get(i)).a(particleparam, particleparam.b().e(), d0, d1, d2, d3, d4, d5); - } + public void b(ParticleParam particleparam, boolean flag, double d0, double d1, double d2, double d3, double d4, double d5) {} - } - - public void b(ParticleParam particleparam, double d0, double d1, double d2, double d3, double d4, double d5) { - for (int i = 0; i < this.v.size(); ++i) { - ((IWorldAccess) this.v.get(i)).a(particleparam, false, true, d0, d1, d2, d3, d4, d5); - } - - } - - public boolean strikeLightning(Entity entity) { - this.k.add(entity); - return true; - } - - public boolean addEntity(Entity entity) { - // CraftBukkit start - Used for entities other than creatures - return addEntity(entity, SpawnReason.DEFAULT); - } - - public boolean addEntity(Entity entity, SpawnReason spawnReason) { // Changed signature, added SpawnReason - // Paper start - if (entity.spawnReason == null) entity.spawnReason = spawnReason; - if (regionLimited != null) { - return regionLimited.addEntity(entity, spawnReason); - } - // Paper end - //org.spigotmc.AsyncCatcher.catchOp( "entity add"); // Spigot // Akarin - if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable()); return true; } // Paper - if (!CraftEventFactory.doEntityAddEventCalling(this, entity, spawnReason)) { - return false; - } - // CraftBukkit end - - int i = MathHelper.floor(entity.locX / 16.0D); - int j = MathHelper.floor(entity.locZ / 16.0D); - boolean flag = true; // Paper - always load chunks for entity adds - - // Paper start - Set origin location when the entity is being added to the world - if (entity.origin == null) { - entity.origin = entity.getBukkitEntity().getLocation(); - } - // Paper end - - if (entity instanceof EntityHuman) { - flag = true; - } - - if (!flag && !this.isChunkLoaded(i, j, false)) { - return false; - } else { - if (entity instanceof EntityHuman) { - EntityHuman entityhuman = (EntityHuman) entity; - - this.players.add(entityhuman); - this.playersByName.put(entityhuman.getName(), entityhuman); - // Paper end - this.everyoneSleeping(); - } - - this.getChunkAt(i, j).a(entity); - if (entity.dead) return false; // Paper - don't add dead entities, chunk registration may of killed it - this.entityList.add(entity); - this.b(entity); - return true; - } - } - - protected void b(Entity entity) { - // Akarin start - /* - for (int i = 0; i < this.v.size(); ++i) { - ((IWorldAccess) this.v.get(i)).a(entity); - } - */ - worldAccessor.a(entity); - // Akarin end - - entity.valid = true; // CraftBukkit - entity.shouldBeRemoved = false; // Paper - shouldn't be removed after being re-added - new com.destroystokyo.paper.event.entity.EntityAddToWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid - } - - protected void c(Entity entity) { - // Akarin start - /* - for (int i = 0; i < this.v.size(); ++i) { - ((IWorldAccess) this.v.get(i)).b(entity); - } - */ - worldAccessor.b(entity); - // Akarin end - - new com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid - entity.valid = false; // CraftBukkit - } - - public void kill(Entity entity) { - //org.spigotmc.AsyncCatcher.catchOp( "entity kill"); // Spigot // Akarin - if (entity.isVehicle()) { - entity.ejectPassengers(); - } - - if (entity.isPassenger()) { - entity.stopRiding(); - } - - entity.die(); - if (entity instanceof EntityHuman) { - this.players.remove(entity); - this.playersByName.remove(entity.getName()); // Paper - World EntityHuman Lookup Optimizations - // Spigot start - for ( WorldPersistentData worldData : worldMaps.worldMap.values() ) - { - for (Object o : worldData.data.values() ) - { - if ( o instanceof WorldMap ) - { - WorldMap map = (WorldMap) o; - map.humans.remove( (EntityHuman) entity ); - for ( Iterator iter = (Iterator) map.h.iterator(); iter.hasNext(); ) - { - if ( iter.next().trackee == entity ) - { - map.decorations.remove(entity.getDisplayName().getString()); // Paper - iter.remove(); - } - } - } - } - } - // Spigot end - this.everyoneSleeping(); - this.c(entity); - } - - } - - public void removeEntity(Entity entity) { - //org.spigotmc.AsyncCatcher.catchOp( "entity remove"); // Spigot // Akarin - entity.b(false); - entity.die(); - if (entity instanceof EntityHuman) { - this.players.remove(entity); - this.playersByName.remove(entity.getName()); // Paper - World EntityHuman Lookup Optimizations - this.everyoneSleeping(); - } - - // if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking // Paper - move down - int i = entity.chunkX; - int j = entity.chunkZ; - - Chunk chunk = entity.getCurrentChunk(); // Paper - if (chunk != null) chunk.removeEntity(entity); // Paper - entity.shouldBeRemoved = true; // Paper - ((com.destroystokyo.paper.PaperWorldEntityList) entityList).updateEntityCount(entity, -1); // Paper - - if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking // Paper - always remove from current chunk above - // CraftBukkit start - Decrement loop variable field if we've already ticked this entity - int index = this.entityList.indexOf(entity); - if (index != -1) { - if (index <= this.tickPosition) { - this.tickPosition--; - } - this.entityList.remove(index); - } - // CraftBukkit end - } // Spigot - this.c(entity); - } - - public void addIWorldAccess(IWorldAccess iworldaccess) { - // Akarin start - if (worldAccessor != null) - worldAccessor.add(iworldaccess); - else if (iworldaccess instanceof WorldManager) - worldAccessor = new AkarinWorldAccessor((WorldManager) iworldaccess, this.u); - else - worldAccessor = new AkarinWorldAccessor(this.u); - //this.v.add(iworldaccess); - // Akarin end - } - - public int a(float f) { - float f1 = this.k(f); - float f2 = 1.0F - (MathHelper.cos(f1 * 6.2831855F) * 2.0F + 0.5F); - - f2 = MathHelper.a(f2, 0.0F, 1.0F); - f2 = 1.0F - f2; - f2 = (float) ((double) f2 * (1.0D - (double) (this.i(f) * 5.0F) / 16.0D)); - f2 = (float) ((double) f2 * (1.0D - (double) (this.g(f) * 5.0F) / 16.0D)); - f2 = 1.0F - f2; - return (int) (f2 * 11.0F); - } - - public float c(float f) { - float f1 = this.k(f); + public float b(float f) { + float f1 = this.j(f); return f1 * 6.2831855F; } - public void tickEntities() { - //this.methodProfiler.enter(* // Akarin - remove caller - //this.methodProfiler.enter(* // Akarin - remove caller - - Entity entity; - int i; - - for (i = 0; i < this.k.size(); ++i) { - entity = (Entity) this.k.get(i); - // CraftBukkit start - Fixed an NPE - if (entity == null) { - continue; - } - // CraftBukkit end - - try { - if (!entity.dead) { // Akarin start - do not tick dead entity - ++entity.ticksLived; - entity.tick(); - } // Akarin end - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Ticking entity"); - CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being ticked"); - - if (entity == null) { - crashreportsystemdetails.a("Entity", (Object) "~~NULL~~"); - } else { - entity.appendEntityCrashDetails(crashreportsystemdetails); - } - - throw new ReportedException(crashreport); - } - - if (entity.dead) { - this.k.remove(i--); - } - } - - //this.methodProfiler.exitEnter("remove"); // Akarin - remove caller - timings.entityRemoval.startTimingUnsafe(); // Paper // Akarin - this.entityList.removeAll(this.g); - - int j; - // Paper start - Set based removal lists - for (Iterator it = this.g.iterator(); it.hasNext() ; ) { - entity = it.next(); // Paper - int k = entity.chunkX; - - j = entity.chunkZ; - Chunk chunk = entity.getCurrentChunk(); // Paper - if (chunk != null) chunk.removeEntity(entity); // Paper - //} // Paper - merge - - //for (Entity e : this.g) { // Paper - merge - this.c(entity); // Paper use entity - } - // Paper end - - this.g.clear(); - this.p_(); - timings.entityRemoval.stopTimingUnsafe(); // Paper // Akarin - //this.methodProfiler.exitEnter("regular");// Akarin - remove caller - - CrashReport crashreport1; - CrashReportSystemDetails crashreportsystemdetails1; - - org.spigotmc.ActivationRange.activateEntities(this); // Spigot - timings.entityTick.startTimingUnsafe(); // Spigot // Akarin - guardEntityList = true; // Spigot - // CraftBukkit start - Use field for loop variable - co.aikar.timings.TimingHistory.entityTicks += this.entityList.size(); // Paper - int entitiesThisCycle = 0; - // Paper start - Disable tick limiters - //if (tickPosition < 0) tickPosition = 0; - for (tickPosition = 0; tickPosition < entityList.size(); tickPosition++) { - // Paper end - tickPosition = (tickPosition < entityList.size()) ? tickPosition : 0; - entity = (Entity) this.entityList.get(this.tickPosition); - // CraftBukkit end - Entity entity1 = entity.getVehicle(); - - if (entity1 != null) { - if (!entity1.dead && entity1.w(entity)) { - continue; - } - - entity.stopRiding(); - } - - //this.methodProfiler.enter(* // Akarin - remove caller - if (!entity.dead && !(entity instanceof EntityPlayer)) { - try { - entity.tickTimer.startTimingUnsafe(); // Paper - this.g(entity); - entity.tickTimer.stopTimingUnsafe(); // Paper - } catch (Throwable throwable1) { - entity.tickTimer.stopTimingUnsafe(); - // Paper start - Prevent tile entity and entity crashes - String msg = "Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX + "," + entity.locY + "," + entity.locZ; - System.err.println(msg); - throwable1.printStackTrace(); - getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable1))); - entity.dead = true; - continue; - // Paper end - } - } - - //this.methodProfiler.exit(); // Akarin - remove caller - //this.methodProfiler.enter(* // Akarin - remove caller - if (entity.dead) { - j = entity.chunkX; - int l = entity.chunkZ; - - // Paper start - Chunk chunk = entity.getCurrentChunk(); - if (chunk != null) chunk.removeEntity(entity); - // Paper end - - guardEntityList = false; // Spigot - this.entityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable - guardEntityList = true; // Spigot - this.c(entity); - } - - //this.methodProfiler.exit(); // Akarin - remove caller - } - guardEntityList = false; // Spigot - - timings.entityTick.stopTimingUnsafe(); // Spigot // Akarin - //this.methodProfiler.exitEnter("blockEntities");// Akarin - remove caller - timings.tileEntityTick.startTimingUnsafe(); // Spigot // Akarin - if (!this.tileEntityListUnload.isEmpty()) { - // Paper start - Use alternate implementation with faster contains - java.util.Set toRemove = com.koloboke.collect.set.hash.HashObjSets.getDefaultFactory().withNullKeyAllowed(true).withEquivalence(com.koloboke.collect.Equivalence.identity()).newImmutableSet(tileEntityListUnload); // Akarin - koloboke - //toRemove.addAll(tileEntityListUnload); // Akarin - koloboke - this.tileEntityListTick.removeAll(toRemove); - // Paper end - //this.tileEntityList.removeAll(this.tileEntityListUnload); // Paper - remove unused list - this.tileEntityListUnload.clear(); - } - - this.J = true; - // Spigot start - // Iterator iterator = this.tileEntityListTick.iterator(); - int tilesThisCycle = 0; - for (tileTickPosition = 0; tileTickPosition < tileEntityListTick.size(); tileTickPosition++) { // Paper - Disable tick limiters - tileTickPosition = (tileTickPosition < tileEntityListTick.size()) ? tileTickPosition : 0; - TileEntity tileentity = (TileEntity) this.tileEntityListTick.get(tileTickPosition); - // Spigot start - if (tileentity == null) { - getServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash"); - tilesThisCycle--; - this.tileEntityListTick.remove(tileTickPosition--); - continue; - } - // Spigot end - - if (!tileentity.x() && tileentity.hasWorld()) { - BlockPosition blockposition = tileentity.getPosition(); - - // Paper start - Skip ticking in chunks scheduled for unload - net.minecraft.server.Chunk chunk = tileentity.getCurrentChunk(); - boolean shouldTick = chunk != null; - if(this.paperConfig.skipEntityTickingInChunksScheduledForUnload) - shouldTick = shouldTick && chunk.scheduledForUnload == null; - if (shouldTick && this.K.a(blockposition)) { - // Paper end - try { - // Akarin start - //this.methodProfiler.a(() -> { - // return String.valueOf(TileEntityTypes.a(tileentity.C())); - //}); - // Akarin end - tileentity.tickTimer.startTimingUnsafe(); // Spigot - ((ITickable) tileentity).tick(); - //this.methodProfiler.exit(); // Akarin - remove caller - } catch (Throwable throwable2) { - // Paper start - Prevent tile entity and entity crashes - String msg = "TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ(); - System.err.println(msg); - throwable2.printStackTrace(); - getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable2))); - tilesThisCycle--; - this.tileEntityListTick.remove(tileTickPosition--); - continue; - // Paper end - } - // Spigot start - finally { - tileentity.tickTimer.stopTimingUnsafe(); - } - // Spigot end - } - } - - if (tileentity.x()) { - tilesThisCycle--; - this.tileEntityListTick.remove(tileTickPosition--); - //this.tileEntityList.remove(tileentity); // Paper - remove unused list - // Paper start - net.minecraft.server.Chunk chunk = tileentity.getCurrentChunk(); - if (chunk != null) { - chunk.removeTileEntity(tileentity.getPosition()); - // Paper end - } - } - } - - timings.tileEntityTick.stopTimingUnsafe(); // Spigot // Akarin - timings.tileEntityPending.startTimingUnsafe(); // Spigot // Akarin - this.J = false; - this.methodProfiler.exitEnter("pendingBlockEntities"); - if (!this.c.isEmpty()) { - for (int i1 = 0; i1 < this.c.size(); ++i1) { - TileEntity tileentity1 = (TileEntity) this.c.get(i1); - - if (!tileentity1.x()) { - /* CraftBukkit start - Order matters, moved down - if (!this.tileEntityList.contains(tileentity1)) { - this.a(tileentity1); - } - // CraftBukkit end */ - - if (this.isLoaded(tileentity1.getPosition())) { - Chunk chunk = this.getChunkAtWorldCoords(tileentity1.getPosition()); - IBlockData iblockdata = chunk.getType(tileentity1.getPosition()); - - chunk.a(tileentity1.getPosition(), tileentity1); - this.notify(tileentity1.getPosition(), iblockdata, iblockdata, 3); - // CraftBukkit start - // From above, don't screw this up - SPIGOT-1746 - if (true) { // Paper - remove unused list - this.a(tileentity1); - } - // CraftBukkit end - } - } - } - - this.c.clear(); - } - - timings.tileEntityPending.stopTimingUnsafe(); // Spigot // Akarin - co.aikar.timings.TimingHistory.tileEntityTicks += this.tileEntityListTick.size(); // Paper - //this.methodProfiler.exit(); // Akarin - remove caller - //this.methodProfiler.exit(); // Akarin - remove caller - } - - protected void p_() {} - public boolean a(TileEntity tileentity) { + if (this.tickingTileEntities) { + World.LOGGER.error("Adding block entity while ticking: {} @ {}", new Supplier[]{() -> { + return IRegistry.BLOCK_ENTITY_TYPE.getKey(tileentity.q()); + }, tileentity::getPosition}); + } + boolean flag = true; // Paper - remove unused list if (flag && tileentity instanceof ITickable && !this.tileEntityListTick.contains(tileentity)) { // Paper @@ -1555,8 +798,8 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } public void a(Collection collection) { - if (this.J) { - this.c.addAll(collection); + if (this.tickingTileEntities) { + this.tileEntityListPending.addAll(collection); } else { Iterator iterator = collection.iterator(); @@ -1569,147 +812,137 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } - public void g(Entity entity) { - this.entityJoinedWorld(entity, true); - } + public void tickBlockEntities() { + GameProfilerFiller gameprofilerfiller = this.getMethodProfiler(); - public void entityJoinedWorld(Entity entity, boolean flag) { - int i; - int j; + gameprofilerfiller.enter("blockEntities"); + timings.tileEntityTick.startTiming(); // Spigot + if (!this.tileEntityListUnload.isEmpty()) { + // Paper start - Use alternate implementation with faster contains + java.util.Set toRemove = java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<>()); + toRemove.addAll(tileEntityListUnload); + this.tileEntityListTick.removeAll(toRemove); + // Paper end + //this.tileEntityList.removeAll(this.tileEntityListUnload); // Paper - remove unused list + this.tileEntityListUnload.clear(); + } - // CraftBukkit start - check if chunks are loaded as done in previous versions - // TODO: Go back to Vanilla behaviour when comfortable + this.tickingTileEntities = true; // Spigot start - // Chunk startingChunk = this.getChunkIfLoaded(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4); - if (flag && !org.spigotmc.ActivationRange.checkIfActive(entity)) { - entity.ticksLived++; - entity.inactiveTick(); + // Iterator iterator = this.tileEntityListTick.iterator(); + int tilesThisCycle = 0; + for (tileTickPosition = 0; tileTickPosition < tileEntityListTick.size(); tileTickPosition++) { // Paper - Disable tick limiters + tileTickPosition = (tileTickPosition < tileEntityListTick.size()) ? tileTickPosition : 0; + TileEntity tileentity = (TileEntity) this.tileEntityListTick.get(tileTickPosition); + // Spigot start + if (tileentity == null) { + getServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash"); + tilesThisCycle--; + this.tileEntityListTick.remove(tileTickPosition--); + continue; + } // Spigot end - return; - } - // CraftBukkit end - entity.N = entity.locX; - entity.O = entity.locY; - entity.P = entity.locZ; - entity.lastYaw = entity.yaw; - entity.lastPitch = entity.pitch; - if (flag && entity.inChunk) { - ++entity.ticksLived; - ++co.aikar.timings.TimingHistory.activatedEntityTicks; // Paper - if (entity.isPassenger()) { - entity.aH(); - } else { - // Akarin start - //this.methodProfiler.a(() -> { - // return IRegistry.ENTITY_TYPE.getKey(entity.P()).toString(); - //}); - // Akarin end - entity.tick(); - entity.postTick(); // CraftBukkit - //this.methodProfiler.exit(); // Akarin - remove caller - } - } + if (!tileentity.isRemoved() && tileentity.hasWorld()) { + BlockPosition blockposition = tileentity.getPosition(); - //this.methodProfiler.enter(* // Akarin - remove caller - if (Double.isNaN(entity.locX) || Double.isInfinite(entity.locX)) { - entity.locX = entity.N; - } + if (this.chunkProvider.a(blockposition) && this.getWorldBorder().a(blockposition)) { + try { + gameprofilerfiller.a(() -> { + return String.valueOf(TileEntityTypes.a(tileentity.q())); + }); + tileentity.tickTimer.startTiming(); // Spigot + if (tileentity.q().a(this.getType(blockposition).getBlock())) { + ((ITickable) tileentity).tick(); + } else { + tileentity.r(); + } - if (Double.isNaN(entity.locY) || Double.isInfinite(entity.locY)) { - entity.locY = entity.O; - } - - if (Double.isNaN(entity.locZ) || Double.isInfinite(entity.locZ)) { - entity.locZ = entity.P; - } - - if (Double.isNaN((double) entity.pitch) || Double.isInfinite((double) entity.pitch)) { - entity.pitch = entity.lastPitch; - } - - if (Double.isNaN((double) entity.yaw) || Double.isInfinite((double) entity.yaw)) { - entity.yaw = entity.lastYaw; - } - - i = MathHelper.floor(entity.locX / 16.0D); - j = Math.min(15, Math.max(0, MathHelper.floor(entity.locY / 16.0D))); // Paper - stay consistent with chunk add/remove behavior - int k = MathHelper.floor(entity.locZ / 16.0D); - - if (!entity.inChunk || entity.chunkX != i || entity.chunkY != j || entity.chunkZ != k) { - if (entity.inChunk && this.isChunkLoaded(entity.chunkX, entity.chunkZ, true)) { - this.getChunkAt(entity.chunkX, entity.chunkZ).a(entity, entity.chunkY); + gameprofilerfiller.exit(); + } catch (Throwable throwable) { + // Paper start - Prevent tile entity and entity crashes + String msg = "TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ(); + System.err.println(msg); + throwable.printStackTrace(); + getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable))); + // Paper end + tilesThisCycle--; + this.tileEntityListTick.remove(tileTickPosition--); + continue; + // Paper end + } + // Spigot start + finally { + tileentity.tickTimer.stopTiming(); + } + // Spigot end + } } - if (!entity.valid && !entity.bN() && !this.isChunkLoaded(i, k, true)) { // Paper - always load chunks to register valid entities location - entity.inChunk = false; - } else { - this.getChunkAt(i, k).a(entity); - } - } - - //this.methodProfiler.exit(); // Akarin - remove caller - if (flag && entity.inChunk) { - Iterator iterator = entity.bP().iterator(); - - while (iterator.hasNext()) { - Entity entity1 = (Entity) iterator.next(); - - if (!entity1.dead && entity1.getVehicle() == entity) { - this.g(entity1); - } else { - entity1.stopRiding(); + if (tileentity.isRemoved()) { + // Spigot start + tilesThisCycle--; + this.tileEntityListTick.remove(tileTickPosition--); + // Spigot end + //this.tileEntityList.remove(tileentity); // Paper - remove unused list + if (this.isLoaded(tileentity.getPosition())) { + this.getChunkAtWorldCoords(tileentity.getPosition()).removeTileEntity(tileentity.getPosition()); } } } - } - // Paper start - Based on method below - /** - * @param entity causing the action ex. block placer - * @param voxelshape area to search within - * @return if there are no visible players colliding - */ - public boolean checkNoVisiblePlayerCollisions(@Nullable Entity entity, VoxelShape voxelshape) { - if (voxelshape.isEmpty()) { - return true; - } else { - List list = this.getEntities((Entity) null, voxelshape.getBoundingBox()); + timings.tileEntityTick.stopTiming(); // Spigot + timings.tileEntityPending.startTiming(); // Spigot + this.tickingTileEntities = false; + gameprofilerfiller.exitEnter("pendingBlockEntities"); + if (!this.tileEntityListPending.isEmpty()) { + for (int i = 0; i < this.tileEntityListPending.size(); ++i) { + TileEntity tileentity1 = (TileEntity) this.tileEntityListPending.get(i); - for (int i = 0; i < list.size(); ++i) { - Entity entity1 = (Entity) list.get(i); + if (!tileentity1.isRemoved()) { + /* CraftBukkit start - Order matters, moved down + if (!this.tileEntityList.contains(tileentity1)) { + this.a(tileentity1); + } + // CraftBukkit end */ - if (entity instanceof EntityPlayer && entity1 instanceof EntityPlayer) { - if (!((EntityPlayer) entity).getBukkitEntity().canSee(((EntityPlayer) entity1).getBukkitEntity())) { - continue; + if (this.isLoaded(tileentity1.getPosition())) { + Chunk chunk = this.getChunkAtWorldCoords(tileentity1.getPosition()); + IBlockData iblockdata = chunk.getType(tileentity1.getPosition()); + + chunk.setTileEntity(tileentity1.getPosition(), tileentity1); + this.notify(tileentity1.getPosition(), iblockdata, iblockdata, 3); + // CraftBukkit start + // From above, don't screw this up - SPIGOT-1746 + if (true) { // Paper - remove unused list + this.a(tileentity1); + } + // CraftBukkit end } } - - if (!entity1.dead && entity1.blocksEntitySpawning()) { - return false; - } } - return true; + this.tileEntityListPending.clear(); } + + timings.tileEntityPending.stopTiming(); // Spigot + co.aikar.timings.TimingHistory.tileEntityTicks += this.tileEntityListTick.size(); // Paper + gameprofilerfiller.exit(); + spigotConfig.currentPrimedTnt = 0; // Spigot } - // Paper end - public boolean a(@Nullable Entity entity, VoxelShape voxelshape) { - if (voxelshape.isEmpty()) { - return true; - } else { - List list = this.getEntities((Entity) null, voxelshape.getBoundingBox()); - - for (int i = 0; i < list.size(); ++i) { - Entity entity1 = (Entity) list.get(i); - - if (!entity1.dead && entity1.j && entity1 != entity && (entity == null || !entity1.x(entity)) && VoxelShapes.c(voxelshape, VoxelShapes.a(entity1.getBoundingBox()), OperatorBoolean.AND)) { - return false; - } - } - - return true; + public void a(Consumer consumer, Entity entity) { + try { + consumer.accept(entity); + } catch (Throwable throwable) { + // Paper start - Prevent tile entity and entity crashes + String msg = "Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX + "," + entity.locY + "," + entity.locZ; + System.err.println(msg); + throwable.printStackTrace(); + getServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable))); + entity.dead = true; + return; + // Paper end } } @@ -1735,7 +968,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc for (int k1 = i; k1 < j; ++k1) { for (int l1 = k; l1 < l; ++l1) { for (int i2 = i1; i2 < j1; ++i2) { - IBlockData iblockdata = this.getType(blockposition_pooledblockposition.c(k1, l1, i2)); + IBlockData iblockdata = this.getType(blockposition_pooledblockposition.d(k1, l1, i2)); if (!iblockdata.isAir()) { boolean flag = true; @@ -1774,7 +1007,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc int i1 = MathHelper.floor(axisalignedbb.minZ); int j1 = MathHelper.f(axisalignedbb.maxZ); - if (this.isAreaLoaded(i, k, i1, j, l, j1, true)) { + if (this.isAreaLoaded(i, k, i1, j, l, j1)) { BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); Throwable throwable = null; @@ -1782,7 +1015,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc for (int k1 = i; k1 < j; ++k1) { for (int l1 = k; l1 < l; ++l1) { for (int i2 = i1; i2 < j1; ++i2) { - Block block = this.getType(blockposition_pooledblockposition.c(k1, l1, i2)).getBlock(); + Block block = this.getType(blockposition_pooledblockposition.d(k1, l1, i2)).getBlock(); if (block == Blocks.FIRE || block == Blocks.LAVA) { boolean flag = true; @@ -1816,57 +1049,6 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } } - @Nullable - public IBlockData a(AxisAlignedBB axisalignedbb, Block block) { - int i = MathHelper.floor(axisalignedbb.minX); - int j = MathHelper.f(axisalignedbb.maxX); - int k = MathHelper.floor(axisalignedbb.minY); - int l = MathHelper.f(axisalignedbb.maxY); - int i1 = MathHelper.floor(axisalignedbb.minZ); - int j1 = MathHelper.f(axisalignedbb.maxZ); - - if (this.isAreaLoaded(i, k, i1, j, l, j1, true)) { - BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); - Throwable throwable = null; - - try { - for (int k1 = i; k1 < j; ++k1) { - for (int l1 = k; l1 < l; ++l1) { - for (int i2 = i1; i2 < j1; ++i2) { - IBlockData iblockdata = this.getType(blockposition_pooledblockposition.c(k1, l1, i2)); - - if (iblockdata.getBlock() == block) { - IBlockData iblockdata1 = iblockdata; - - return iblockdata1; - } - } - } - } - - return null; - } catch (Throwable throwable1) { - throwable = throwable1; - throw throwable1; - } finally { - if (blockposition_pooledblockposition != null) { - if (throwable != null) { - try { - blockposition_pooledblockposition.close(); - } catch (Throwable throwable2) { - throwable.addSuppressed(throwable2); - } - } else { - blockposition_pooledblockposition.close(); - } - } - - } - } else { - return null; - } - } - public boolean a(AxisAlignedBB axisalignedbb, Material material) { int i = MathHelper.floor(axisalignedbb.minX); int j = MathHelper.f(axisalignedbb.maxX); @@ -1875,52 +1057,22 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc int i1 = MathHelper.floor(axisalignedbb.minZ); int j1 = MathHelper.f(axisalignedbb.maxZ); MaterialPredicate materialpredicate = MaterialPredicate.a(material); - BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); - Throwable throwable = null; - try { - for (int k1 = i; k1 < j; ++k1) { - for (int l1 = k; l1 < l; ++l1) { - for (int i2 = i1; i2 < j1; ++i2) { - if (materialpredicate.test(this.getType(blockposition_pooledblockposition.c(k1, l1, i2)))) { - boolean flag = true; - - return flag; - } - } - } - } - - return false; - } catch (Throwable throwable1) { - throwable = throwable1; - throw throwable1; - } finally { - if (blockposition_pooledblockposition != null) { - if (throwable != null) { - try { - blockposition_pooledblockposition.close(); - } catch (Throwable throwable2) { - throwable.addSuppressed(throwable2); - } - } else { - blockposition_pooledblockposition.close(); - } - } - - } + return BlockPosition.a(i, k, i1, j - 1, l - 1, j1 - 1).anyMatch((blockposition) -> { + return materialpredicate.test(this.getType(blockposition)); + }); } - public Explosion explode(@Nullable Entity entity, double d0, double d1, double d2, float f, boolean flag) { - return this.createExplosion(entity, (DamageSource) null, d0, d1, d2, f, false, flag); + public Explosion explode(@Nullable Entity entity, double d0, double d1, double d2, float f, Explosion.Effect explosion_effect) { + return this.createExplosion(entity, (DamageSource) null, d0, d1, d2, f, false, explosion_effect); } - public Explosion createExplosion(@Nullable Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) { - return this.createExplosion(entity, (DamageSource) null, d0, d1, d2, f, flag, flag1); + public Explosion createExplosion(@Nullable Entity entity, double d0, double d1, double d2, float f, boolean flag, Explosion.Effect explosion_effect) { + return this.createExplosion(entity, (DamageSource) null, d0, d1, d2, f, flag, explosion_effect); } - public Explosion createExplosion(@Nullable Entity entity, @Nullable DamageSource damagesource, double d0, double d1, double d2, float f, boolean flag, boolean flag1) { - Explosion explosion = new Explosion(this, entity, d0, d1, d2, f, flag, flag1); + public Explosion createExplosion(@Nullable Entity entity, @Nullable DamageSource damagesource, double d0, double d1, double d2, float f, boolean flag, Explosion.Effect explosion_effect) { + Explosion explosion = new Explosion(this, entity, d0, d1, d2, f, flag, explosion_effect); if (damagesource != null) { explosion.a(damagesource); @@ -1931,44 +1083,11 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return explosion; } - public float a(Vec3D vec3d, AxisAlignedBB axisalignedbb) { - double d0 = 1.0D / ((axisalignedbb.maxX - axisalignedbb.minX) * 2.0D + 1.0D); - double d1 = 1.0D / ((axisalignedbb.maxY - axisalignedbb.minY) * 2.0D + 1.0D); - double d2 = 1.0D / ((axisalignedbb.maxZ - axisalignedbb.minZ) * 2.0D + 1.0D); - double d3 = (1.0D - Math.floor(1.0D / d0) * d0) / 2.0D; - double d4 = (1.0D - Math.floor(1.0D / d2) * d2) / 2.0D; - - if (d0 >= 0.0D && d1 >= 0.0D && d2 >= 0.0D) { - int i = 0; - int j = 0; - - for (float f = 0.0F; f <= 1.0F; f = (float) ((double) f + d0)) { - for (float f1 = 0.0F; f1 <= 1.0F; f1 = (float) ((double) f1 + d1)) { - for (float f2 = 0.0F; f2 <= 1.0F; f2 = (float) ((double) f2 + d2)) { - double d5 = axisalignedbb.minX + (axisalignedbb.maxX - axisalignedbb.minX) * (double) f; - double d6 = axisalignedbb.minY + (axisalignedbb.maxY - axisalignedbb.minY) * (double) f1; - double d7 = axisalignedbb.minZ + (axisalignedbb.maxZ - axisalignedbb.minZ) * (double) f2; - - if (this.rayTrace(new Vec3D(d5 + d3, d6, d7 + d4), vec3d) == null) { - ++i; - } - - ++j; - } - } - } - - return (float) i / (float) j; - } else { - return 0.0F; - } - } - public boolean douseFire(@Nullable EntityHuman entityhuman, BlockPosition blockposition, EnumDirection enumdirection) { blockposition = blockposition.shift(enumdirection); if (this.getType(blockposition).getBlock() == Blocks.FIRE) { this.a(entityhuman, 1009, blockposition, 0); - this.setAir(blockposition); + this.a(blockposition, false); return true; } else { return false; @@ -1977,8 +1096,11 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc public Map capturedTileEntities = Maps.newHashMap(); @Nullable + @Override public TileEntity getTileEntity(BlockPosition blockposition) { - if (blockposition.isInvalidYLocation()) { // Paper + if (isOutsideWorld(blockposition)) { + return null; + } else if (!this.isClientSide && Thread.currentThread() != this.serverThread) { return null; } else { // CraftBukkit start @@ -1990,8 +1112,8 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc //TileEntity tileentity = null; // Paper - move up - if (this.J) { - tileentity = this.E(blockposition); + if (this.tickingTileEntities) { + tileentity = this.A(blockposition); } if (tileentity == null) { @@ -1999,7 +1121,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } if (tileentity == null) { - tileentity = this.E(blockposition); + tileentity = this.A(blockposition); } return tileentity; @@ -2007,11 +1129,11 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } @Nullable - private TileEntity E(BlockPosition blockposition) { - for (int i = 0; i < this.c.size(); ++i) { - TileEntity tileentity = (TileEntity) this.c.get(i); + private TileEntity A(BlockPosition blockposition) { + for (int i = 0; i < this.tileEntityListPending.size(); ++i) { + TileEntity tileentity = (TileEntity) this.tileEntityListPending.get(i); - if (!tileentity.x() && tileentity.getPosition().equals(blockposition)) { + if (!tileentity.isRemoved() && tileentity.getPosition().equals(blockposition)) { return tileentity; } } @@ -2020,8 +1142,8 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } public void setTileEntity(BlockPosition blockposition, @Nullable TileEntity tileentity) { - if (!blockposition.isInvalidYLocation()) { // Paper - if (tileentity != null && !tileentity.x()) { + if (!isOutsideWorld(blockposition)) { + if (tileentity != null && !tileentity.isRemoved()) { // CraftBukkit start if (captureBlockStates) { tileentity.setWorld(this); @@ -2030,23 +1152,23 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return; } // CraftBukkit end - if (this.J) { + if (this.tickingTileEntities) { tileentity.setPosition(blockposition); - Iterator iterator = this.c.iterator(); + Iterator iterator = this.tileEntityListPending.iterator(); while (iterator.hasNext()) { TileEntity tileentity1 = (TileEntity) iterator.next(); if (tileentity1.getPosition().equals(blockposition)) { - tileentity1.y(); + tileentity1.V_(); iterator.remove(); } } tileentity.setWorld(this); // Spigot - No null worlds - this.c.add(tileentity); + this.tileEntityListPending.add(tileentity); } else { - this.getChunkAtWorldCoords(blockposition).a(blockposition, tileentity); + this.getChunkAtWorldCoords(blockposition).setTileEntity(blockposition, tileentity); this.a(tileentity); } } @@ -2054,392 +1176,70 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } } - public void n(BlockPosition blockposition) { + public void removeTileEntity(BlockPosition blockposition) { TileEntity tileentity = this.getTileEntity(blockposition); - if (tileentity != null && this.J) { - tileentity.y(); - this.c.remove(tileentity); + if (tileentity != null && this.tickingTileEntities) { + tileentity.V_(); + this.tileEntityListPending.remove(tileentity); } else { if (tileentity != null) { - this.c.remove(tileentity); + this.tileEntityListPending.remove(tileentity); //this.tileEntityList.remove(tileentity); // Paper - remove unused list this.tileEntityListTick.remove(tileentity); } - this.getChunkAtWorldCoords(blockposition).d(blockposition); + this.getChunkAtWorldCoords(blockposition).removeTileEntity(blockposition); } } - public void b(TileEntity tileentity) { - this.tileEntityListUnload.add(tileentity); + public boolean n(BlockPosition blockposition) { + return isOutsideWorld(blockposition) ? false : this.isLoaded(blockposition); // Paper - reduce sync loads } - public boolean o(BlockPosition blockposition) { - return Block.a(this.getType(blockposition).getCollisionShape(this, blockposition)); - } - - public boolean p(BlockPosition blockposition) { - if (blockposition.isInvalidYLocation()) { // Paper + public boolean a(BlockPosition blockposition, Entity entity) { + if (isOutsideWorld(blockposition)) { return false; } else { - Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper - optimize ifLoaded + IChunkAccess ichunkaccess = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper - reduce sync loads - return chunk != null && !chunk.isEmpty(); + return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).a((IBlockAccess) this, blockposition, entity); } } - public boolean q(BlockPosition blockposition) { - return this.p(blockposition) && this.getType(blockposition).q(); - } - - public void P() { - int i = this.a(1.0F); - - if (i != this.G) { - this.G = i; - } + public void M() { + double d0 = 1.0D - (double) (this.h(1.0F) * 5.0F) / 16.0D; + double d1 = 1.0D - (double) (this.f(1.0F) * 5.0F) / 16.0D; + double d2 = 0.5D + 2.0D * MathHelper.a((double) MathHelper.cos(this.j(1.0F) * 6.2831855F), -0.25D, 0.25D); + this.u = (int) ((1.0D - d2 * d0 * d1) * 11.0D); } public void setSpawnFlags(boolean flag, boolean flag1) { - this.allowMonsters = flag; - this.allowAnimals = flag1; + this.getChunkProvider().a(flag, flag1); } - public void doTick(BooleanSupplier booleansupplier) { - this.K.r(); - this.w(); - } - - protected void Q() { + protected void N() { if (this.worldData.hasStorm()) { - this.p = 1.0F; + this.rainLevel = 1.0F; if (this.worldData.isThundering()) { - this.r = 1.0F; + this.thunderLevel = 1.0F; } } } - public void close() { + public void close() throws IOException { this.chunkProvider.close(); } - protected void w() { - if (this.worldProvider.g()) { - if (!this.isClientSide) { - boolean flag = this.getGameRules().getBoolean("doWeatherCycle"); - - if (flag) { - int i = this.worldData.z(); - - if (i > 0) { - --i; - this.worldData.g(i); - this.worldData.setThunderDuration(this.worldData.isThundering() ? 1 : 2); - this.worldData.setWeatherDuration(this.worldData.hasStorm() ? 1 : 2); - } - - int j = this.worldData.getThunderDuration(); - - if (j <= 0) { - if (this.worldData.isThundering()) { - this.worldData.setThunderDuration(this.random.nextInt(12000) + 3600); - } else { - this.worldData.setThunderDuration(this.random.nextInt(168000) + 12000); - } - } else { - --j; - this.worldData.setThunderDuration(j); - if (j <= 0) { - this.worldData.setThundering(!this.worldData.isThundering()); - } - } - - int k = this.worldData.getWeatherDuration(); - - if (k <= 0) { - if (this.worldData.hasStorm()) { - this.worldData.setWeatherDuration(this.random.nextInt(12000) + 12000); - } else { - this.worldData.setWeatherDuration(this.random.nextInt(168000) + 12000); - } - } else { - --k; - this.worldData.setWeatherDuration(k); - if (k <= 0) { - this.worldData.setStorm(!this.worldData.hasStorm()); - } - } - } - - this.q = this.r; - if (this.worldData.isThundering()) { - this.r = (float) ((double) this.r + 0.01D); - } else { - this.r = (float) ((double) this.r - 0.01D); - } - - this.r = MathHelper.a(this.r, 0.0F, 1.0F); - this.o = this.p; - if (this.worldData.hasStorm()) { - this.p = (float) ((double) this.p + 0.01D); - } else { - this.p = (float) ((double) this.p - 0.01D); - } - - this.p = MathHelper.a(this.p, 0.0F, 1.0F); - - // CraftBukkit start - for (int idx = 0; idx < this.players.size(); ++idx) { - if (((EntityPlayer) this.players.get(idx)).world == this) { - ((EntityPlayer) this.players.get(idx)).tickWeather(); - } - } - // CraftBukkit end - } - } - } - - protected void n_() {} - - public boolean r(BlockPosition blockposition) { - boolean flag = false; - - if (this.worldProvider.g()) { - flag |= this.c(EnumSkyBlock.SKY, blockposition); - } - - flag |= this.c(EnumSkyBlock.BLOCK, blockposition); - return flag; - } - - private int a(BlockPosition blockposition, EnumSkyBlock enumskyblock) { - if (enumskyblock == EnumSkyBlock.SKY && this.e(blockposition)) { - return 15; - } else { - IBlockData iblockdata = this.getType(blockposition); - int i = enumskyblock == EnumSkyBlock.SKY ? 0 : iblockdata.e(); - int j = iblockdata.b(this, blockposition); - - if (j >= 15 && iblockdata.e() > 0) { - j = 1; - } - - if (j < 1) { - j = 1; - } - - if (j >= 15) { - return 0; - } else if (i >= 14) { - return i; - } else { - BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); - Throwable throwable = null; - - try { - EnumDirection[] aenumdirection = World.a; - int k = aenumdirection.length; - - for (int l = 0; l < k; ++l) { - EnumDirection enumdirection = aenumdirection[l]; - - blockposition_pooledblockposition.g(blockposition).c(enumdirection); - int i1 = this.getBrightness(enumskyblock, blockposition_pooledblockposition) - j; - - if (i1 > i) { - i = i1; - } - - if (i >= 14) { - int j1 = i; - - return j1; - } - } - - return i; - } catch (Throwable throwable1) { - throwable = throwable1; - throw throwable1; - } finally { - if (blockposition_pooledblockposition != null) { - if (throwable != null) { - try { - blockposition_pooledblockposition.close(); - } catch (Throwable throwable2) { - throwable.addSuppressed(throwable2); - } - } else { - blockposition_pooledblockposition.close(); - } - } - - } - } - } - } - - public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition) { - // CraftBukkit start - Use neighbor cache instead of looking up - Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); - // Paper start - optimize light updates where chunk is known - return updateBrightness(enumskyblock, blockposition, chunk); - } - public boolean updateBrightness(EnumSkyBlock enumskyblock, BlockPosition blockposition, Chunk chunk) { - // Paper end - if (chunk == null || !chunk.areNeighborsLoaded(1) /*!this.areChunksLoaded(blockposition, 17, false)*/) { - // CraftBukkit end - return false; - } else { - int i = 0; - int j = 0; - - //this.methodProfiler.enter(* // Akarin - remove caller - int k = this.getBrightness(enumskyblock, blockposition); - int l = this.a(blockposition, enumskyblock); - int i1 = blockposition.getX(); - int j1 = blockposition.getY(); - int k1 = blockposition.getZ(); - int l1; - int i2; - int j2; - int k2; - int l2; - int i3; - int j3; - int k3; - - if (l > k) { - this.E[j++] = 133152; - } else if (l < k) { - this.E[j++] = 133152 | k << 18; - - while (i < j) { - l1 = this.E[i++]; - i2 = (l1 & 63) - 32 + i1; - j2 = (l1 >> 6 & 63) - 32 + j1; - k2 = (l1 >> 12 & 63) - 32 + k1; - int l3 = l1 >> 18 & 15; - BlockPosition blockposition1 = new BlockPosition(i2, j2, k2); - - l2 = this.getBrightness(enumskyblock, blockposition1); - if (l2 == l3) { - this.a(enumskyblock, blockposition1, 0); - if (l3 > 0) { - i3 = MathHelper.a(i2 - i1); - j3 = MathHelper.a(j2 - j1); - k3 = MathHelper.a(k2 - k1); - if (i3 + j3 + k3 < 17) { - BlockPosition.PooledBlockPosition blockposition_pooledblockposition = BlockPosition.PooledBlockPosition.r(); - Throwable throwable = null; - - try { - EnumDirection[] aenumdirection = World.a; - int i4 = aenumdirection.length; - - for (int j4 = 0; j4 < i4; ++j4) { - EnumDirection enumdirection = aenumdirection[j4]; - int k4 = i2 + enumdirection.getAdjacentX(); - int l4 = j2 + enumdirection.getAdjacentY(); - int i5 = k2 + enumdirection.getAdjacentZ(); - - blockposition_pooledblockposition.c(k4, l4, i5); - int j5 = Math.max(1, this.getType(blockposition_pooledblockposition).b(this, blockposition_pooledblockposition)); - - l2 = this.getBrightness(enumskyblock, blockposition_pooledblockposition); - if (l2 == l3 - j5 && j < this.E.length) { - this.E[j++] = k4 - i1 + 32 | l4 - j1 + 32 << 6 | i5 - k1 + 32 << 12 | l3 - j5 << 18; - } - } - } catch (Throwable throwable1) { - throwable = throwable1; - throw throwable1; - } finally { - if (blockposition_pooledblockposition != null) { - if (throwable != null) { - try { - blockposition_pooledblockposition.close(); - } catch (Throwable throwable2) { - throwable.addSuppressed(throwable2); - } - } else { - blockposition_pooledblockposition.close(); - } - } - - } - } - } - } - } - - i = 0; - } - - //this.methodProfiler.exit(); // Akarin - remove caller - //this.methodProfiler.enter(* // Akarin - remove caller - - while (i < j) { - l1 = this.E[i++]; - i2 = (l1 & 63) - 32 + i1; - j2 = (l1 >> 6 & 63) - 32 + j1; - k2 = (l1 >> 12 & 63) - 32 + k1; - BlockPosition blockposition2 = new BlockPosition(i2, j2, k2); - int k5 = this.getBrightness(enumskyblock, blockposition2); - - l2 = this.a(blockposition2, enumskyblock); - if (l2 != k5) { - this.a(enumskyblock, blockposition2, l2); - if (l2 > k5) { - i3 = Math.abs(i2 - i1); - j3 = Math.abs(j2 - j1); - k3 = Math.abs(k2 - k1); - boolean flag = j < this.E.length - 6; - - if (i3 + j3 + k3 < 17 && flag) { - if (this.getBrightness(enumskyblock, blockposition2.west()) < l2) { - this.E[j++] = i2 - 1 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); - } - - if (this.getBrightness(enumskyblock, blockposition2.east()) < l2) { - this.E[j++] = i2 + 1 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); - } - - if (this.getBrightness(enumskyblock, blockposition2.down()) < l2) { - this.E[j++] = i2 - i1 + 32 + (j2 - 1 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); - } - - if (this.getBrightness(enumskyblock, blockposition2.up()) < l2) { - this.E[j++] = i2 - i1 + 32 + (j2 + 1 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); - } - - if (this.getBrightness(enumskyblock, blockposition2.north()) < l2) { - this.E[j++] = i2 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - 1 - k1 + 32 << 12); - } - - if (this.getBrightness(enumskyblock, blockposition2.south()) < l2) { - this.E[j++] = i2 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 + 1 - k1 + 32 << 12); - } - } - } - } - } - - //this.methodProfiler.exit(); // Akarin - remove caller - return true; - } - } - - public Stream a(@Nullable Entity entity, VoxelShape voxelshape, VoxelShape voxelshape1, Set set) { - Stream stream = IIBlockAccess.super.a(entity, voxelshape, voxelshape1, set); // CraftBukkit - decompile error - - return entity == null ? stream : Stream.concat(stream, this.a(entity, voxelshape, set)); + @Override + public ChunkStatus O() { + return ChunkStatus.FULL; } + @Override public List getEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate) { List list = Lists.newArrayList(); int i = MathHelper.floor((axisalignedbb.minX - 2.0D) / 16.0D); @@ -2449,8 +1249,10 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc for (int i1 = i; i1 <= j; ++i1) { for (int j1 = k; j1 <= l; ++j1) { - if (this.isChunkLoaded(i1, j1, true)) { - this.getChunkAt(i1, j1).a(entity, axisalignedbb, list, predicate); + Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper + + if (chunk != null) { + chunk.a(entity, axisalignedbb, list, predicate); } } } @@ -2458,52 +1260,63 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return list; } - public List a(Class oclass, Predicate predicate) { - List list = Lists.newArrayList(); - Iterator iterator = this.entityList.iterator(); + public List a(@Nullable EntityTypes entitytypes, AxisAlignedBB axisalignedbb, Predicate predicate) { + int i = MathHelper.floor((axisalignedbb.minX - 2.0D) / 16.0D); + int j = MathHelper.f((axisalignedbb.maxX + 2.0D) / 16.0D); + int k = MathHelper.floor((axisalignedbb.minZ - 2.0D) / 16.0D); + int l = MathHelper.f((axisalignedbb.maxZ + 2.0D) / 16.0D); + List list = Lists.newArrayList(); - while (iterator.hasNext()) { - Entity entity = (Entity) iterator.next(); - if (entity.shouldBeRemoved) continue; // Paper + for (int i1 = i; i1 < j; ++i1) { + for (int j1 = k; j1 < l; ++j1) { + Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper - if (oclass.isAssignableFrom(entity.getClass()) && predicate.test((T) entity)) { // CraftBukkit - decompile error - list.add((T) entity); // CraftBukkit - decompile error + if (chunk != null) { + chunk.a(entitytypes, axisalignedbb, list, predicate); + } } } return list; } - public List b(Class oclass, Predicate predicate) { - List list = Lists.newArrayList(); - Iterator iterator = this.players.iterator(); - - while (iterator.hasNext()) { - Entity entity = (Entity) iterator.next(); - - if (oclass.isAssignableFrom(entity.getClass()) && predicate.test((T) entity)) { // CraftBukkit - decompile error - list.add((T) entity); // CraftBukkit - decompile error - } - } - - return list; - } - - public List a(Class oclass, AxisAlignedBB axisalignedbb) { - return this.a(oclass, axisalignedbb, IEntitySelector.f); - } - + @Override public List a(Class oclass, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate) { int i = MathHelper.floor((axisalignedbb.minX - 2.0D) / 16.0D); int j = MathHelper.f((axisalignedbb.maxX + 2.0D) / 16.0D); int k = MathHelper.floor((axisalignedbb.minZ - 2.0D) / 16.0D); int l = MathHelper.f((axisalignedbb.maxZ + 2.0D) / 16.0D); List list = Lists.newArrayList(); + IChunkProvider ichunkprovider = this.getChunkProvider(); for (int i1 = i; i1 < j; ++i1) { for (int j1 = k; j1 < l; ++j1) { - if (this.isChunkLoaded(i1, j1, true)) { - this.getChunkAt(i1, j1).a(oclass, axisalignedbb, list, predicate); + Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper + + if (chunk != null) { + chunk.a(oclass, axisalignedbb, list, predicate); + } + } + } + + return list; + } + + @Override + public List b(Class oclass, AxisAlignedBB axisalignedbb, @Nullable Predicate predicate) { + int i = MathHelper.floor((axisalignedbb.minX - 2.0D) / 16.0D); + int j = MathHelper.f((axisalignedbb.maxX + 2.0D) / 16.0D); + int k = MathHelper.floor((axisalignedbb.minZ - 2.0D) / 16.0D); + int l = MathHelper.f((axisalignedbb.maxZ + 2.0D) / 16.0D); + List list = Lists.newArrayList(); + IChunkProvider ichunkprovider = this.getChunkProvider(); + + for (int i1 = i; i1 < j; ++i1) { + for (int j1 = k; j1 < l; ++j1) { + Chunk chunk = ichunkprovider.a(i1, j1); + + if (chunk != null) { + chunk.a(oclass, axisalignedbb, list, predicate); } } } @@ -2512,31 +1325,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } @Nullable - public T a(Class oclass, AxisAlignedBB axisalignedbb, T t0) { - List list = this.a(oclass, axisalignedbb); - T t1 = null; - double d0 = Double.MAX_VALUE; - - for (int i = 0; i < list.size(); ++i) { - T t2 = (T) list.get(i); // CraftBukkit - decompile error - - if (t2 != t0 && IEntitySelector.f.test(t2)) { - double d1 = t0.h(t2); - - if (d1 <= d0) { - t1 = t2; - d0 = d1; - } - } - } - - return t1; - } - - @Nullable - public Entity getEntity(int i) { - return (Entity) this.entitiesById.get(i); - } + public abstract Entity getEntity(int i); public void b(BlockPosition blockposition, TileEntity tileentity) { if (this.isLoaded(blockposition)) { @@ -2545,96 +1334,44 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } - public int a(Class oclass, int i) { - int j = 0; - Iterator iterator = this.entityList.iterator(); - - while (iterator.hasNext()) { - Entity entity = (Entity) iterator.next(); - if (entity.shouldBeRemoved) continue; // Paper - // CraftBukkit start - Split out persistent check, don't apply it to special persistent mobs - if (entity instanceof EntityInsentient) { - EntityInsentient entityinsentient = (EntityInsentient) entity; - if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) { - continue; - } - } - - if (true || !(entity instanceof EntityInsentient) || !((EntityInsentient) entity).isPersistent()) { - // CraftBukkit end - if (oclass.isAssignableFrom(entity.getClass())) { - ++j; - } - - if (j > i) { - return j; - } - } - } - - return j; - } - - public void addChunkEntities(Stream collection) { a(collection); } // Paper - OBFHELPER - public void a(Stream stream) { - //org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot // Akarin - stream.forEach((entity) -> { - if (entity == null || entity.dead || entity.valid) { // Paper - prevent adding already added or dead entities - return; - } - this.entityList.add(entity); - this.b(entity); - }); - } - - public void b(Collection collection) { - this.g.addAll(collection); - } - + @Override public int getSeaLevel() { - return this.b; + return 63; } + @Override public World getMinecraftWorld() { return this; } - public void b(int i) { - this.b = i; - } - - public int a(BlockPosition blockposition, EnumDirection enumdirection) { - return this.getType(blockposition).b((IBlockAccess) this, blockposition, enumdirection); - } - - public WorldType S() { + public WorldType P() { return this.worldData.getType(); } public int getBlockPower(BlockPosition blockposition) { byte b0 = 0; - int i = Math.max(b0, this.a(blockposition.down(), EnumDirection.DOWN)); + int i = Math.max(b0, this.c(blockposition.down(), EnumDirection.DOWN)); if (i >= 15) { return i; } else { - i = Math.max(i, this.a(blockposition.up(), EnumDirection.UP)); + i = Math.max(i, this.c(blockposition.up(), EnumDirection.UP)); if (i >= 15) { return i; } else { - i = Math.max(i, this.a(blockposition.north(), EnumDirection.NORTH)); + i = Math.max(i, this.c(blockposition.north(), EnumDirection.NORTH)); if (i >= 15) { return i; } else { - i = Math.max(i, this.a(blockposition.south(), EnumDirection.SOUTH)); + i = Math.max(i, this.c(blockposition.south(), EnumDirection.SOUTH)); if (i >= 15) { return i; } else { - i = Math.max(i, this.a(blockposition.west(), EnumDirection.WEST)); + i = Math.max(i, this.c(blockposition.west(), EnumDirection.WEST)); if (i >= 15) { return i; } else { - i = Math.max(i, this.a(blockposition.east(), EnumDirection.EAST)); + i = Math.max(i, this.c(blockposition.east(), EnumDirection.EAST)); return i >= 15 ? i : i; } } @@ -2650,15 +1387,15 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc public int getBlockFacePower(BlockPosition blockposition, EnumDirection enumdirection) { IBlockData iblockdata = this.getType(blockposition); - return iblockdata.isOccluding() ? this.getBlockPower(blockposition) : iblockdata.a((IBlockAccess) this, blockposition, enumdirection); + return iblockdata.isOccluding(this, blockposition) ? this.getBlockPower(blockposition) : iblockdata.b((IBlockAccess) this, blockposition, enumdirection); } public boolean isBlockIndirectlyPowered(BlockPosition blockposition) { return this.getBlockFacePower(blockposition.down(), EnumDirection.DOWN) > 0 ? true : (this.getBlockFacePower(blockposition.up(), EnumDirection.UP) > 0 ? true : (this.getBlockFacePower(blockposition.north(), EnumDirection.NORTH) > 0 ? true : (this.getBlockFacePower(blockposition.south(), EnumDirection.SOUTH) > 0 ? true : (this.getBlockFacePower(blockposition.west(), EnumDirection.WEST) > 0 ? true : this.getBlockFacePower(blockposition.east(), EnumDirection.EAST) > 0)))); } - public int isBlockIndirectlyGettingPowered(BlockPosition pos) { return u(pos); } // Paper - OBFHELPER - public int u(BlockPosition blockposition) { + public int isBlockIndirectlyGettingPowered(BlockPosition pos) { return this.q(pos); } // Paper - OBFHELPER + public int q(BlockPosition blockposition) { int i = 0; EnumDirection[] aenumdirection = World.a; int j = aenumdirection.length; @@ -2679,189 +1416,11 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return i; } - @Nullable - public EntityHuman a(double d0, double d1, double d2, double d3, Predicate predicate) { - double d4 = -1.0D; - EntityHuman entityhuman = null; - - for (int i = 0; i < this.players.size(); ++i) { - EntityHuman entityhuman1 = (EntityHuman) this.players.get(i); - // CraftBukkit start - Fixed an NPE - if (entityhuman1 == null || entityhuman1.dead) { - continue; - } - // CraftBukkit end - - if (predicate.test(entityhuman1)) { - double d5 = entityhuman1.d(d0, d1, d2); - - if ((d3 < 0.0D || d5 < d3 * d3) && (d4 == -1.0D || d5 < d4)) { - d4 = d5; - entityhuman = entityhuman1; - } - } - } - - return entityhuman; - } - - public boolean isPlayerNearby(double d0, double d1, double d2, double d3) { - for (int i = 0; i < this.players.size(); ++i) { - EntityHuman entityhuman = (EntityHuman) this.players.get(i); - - if (IEntitySelector.f.test(entityhuman) && entityhuman.affectsSpawning) { // Paper - Affects Spawning API - double d4 = entityhuman.d(d0, d1, d2); - - if (d3 < 0.0D || d4 < d3 * d3) { - return true; - } - } - } - - return false; - } - - public boolean b(double d0, double d1, double d2, double d3) { - Iterator iterator = this.players.iterator(); - - double d4; - - do { - EntityHuman entityhuman; - - do { - do { - if (!iterator.hasNext()) { - return false; - } - - entityhuman = (EntityHuman) iterator.next(); - } while (!IEntitySelector.f.test(entityhuman)); - } while (!IEntitySelector.b.test(entityhuman)); - - d4 = entityhuman.d(d0, d1, d2); - } while (d3 >= 0.0D && d4 >= d3 * d3); - - return true; - } - - @Nullable - public EntityHuman a(double d0, double d1, double d2) { - double d3 = -1.0D; - EntityHuman entityhuman = null; - - for (int i = 0; i < this.players.size(); ++i) { - EntityHuman entityhuman1 = (EntityHuman) this.players.get(i); - - if (IEntitySelector.f.test(entityhuman1)) { - double d4 = entityhuman1.d(d0, entityhuman1.locY, d1); - - if ((d2 < 0.0D || d4 < d2 * d2) && (d3 == -1.0D || d4 < d3)) { - d3 = d4; - entityhuman = entityhuman1; - } - } - } - - return entityhuman; - } - - @Nullable - public EntityHuman a(Entity entity, double d0, double d1) { - return this.a(entity.locX, entity.locY, entity.locZ, d0, d1, (Function) null, (Predicate) null); - } - - @Nullable - public EntityHuman a(BlockPosition blockposition, double d0, double d1) { - return this.a((double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), d0, d1, (Function) null, (Predicate) null); - } - - @Nullable - public EntityHuman a(double d0, double d1, double d2, double d3, double d4, @Nullable Function function, @Nullable Predicate predicate) { - double d5 = -1.0D; - EntityHuman entityhuman = null; - - for (int i = 0; i < this.players.size(); ++i) { - EntityHuman entityhuman1 = (EntityHuman) this.players.get(i); - - // Paper start - // move distance check up, if set, check distance^2 is less than XZlimit^2, continue - // 4th method param is XZlimit (at least at the time of commit) - double d6 = entityhuman1.d(d0, entityhuman1.locY, d2); - if (d3 < 0.0D || d6 < d3 * d3) - if (!entityhuman1.abilities.isInvulnerable && entityhuman1.isAlive() && !entityhuman1.isSpectator() && (predicate == null || predicate.test(entityhuman1))) { - // Paper end - double d7 = d3; - - if (entityhuman1.isSneaking()) { - d7 = d3 * 0.800000011920929D; - } - - if (entityhuman1.isInvisible()) { - float f = entityhuman1.dk(); - - if (f < 0.1F) { - f = 0.1F; - } - - d7 *= (double) (0.7F * f); - } - - if (function != null) { - d7 *= (Double) MoreObjects.firstNonNull(function.apply(entityhuman1), 1.0D); - } - - if ((d4 < 0.0D || Math.abs(entityhuman1.locY - d1) < d4 * d4) && (d3 < 0.0D || d6 < d7 * d7) && (d5 == -1.0D || d6 < d5)) { - d5 = d6; - entityhuman = entityhuman1; - } - } - } - - return entityhuman; - } - - @Nullable - public EntityHuman a(String s) { - // Paper start - World EntityHuman Lookup Optimizations - /* - for (int i = 0; i < this.players.size(); ++i) { - EntityHuman entityhuman = (EntityHuman) this.players.get(i); - - if (s.equals(entityhuman.getDisplayName().getString())) { - return entityhuman; - } - } - - return null; - */ - return this.playersByName.get(s); - // Paper end - } - - @Nullable - public EntityHuman b(UUID uuid) { - // Paper start - World EntityHuman Lookup Optimizations - /* - for (int i = 0; i < this.players.size(); ++i) { - EntityHuman entityhuman = (EntityHuman) this.players.get(i); - - if (uuid.equals(entityhuman.getUniqueID())) { - return entityhuman; - } - } - - return null; - */ - Entity entity = ((WorldServer)this).entitiesByUUID.get(uuid); - return entity instanceof EntityHuman ? (EntityHuman) entity : null; - // Paper end - } - - public void checkSession() throws ExceptionWorldConflict { - this.dataManager.checkSession(); + public void a(long i) { + this.worldData.setTime(i); } + @Override public long getSeed() { return this.worldData.getSeed(); } @@ -2878,6 +1437,14 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc this.worldData.setDayTime(i); } + protected void a() { + this.a(this.worldData.getTime() + 1L); + if (this.worldData.v().getBoolean(GameRules.DO_DAYLIGHT_CYCLE)) { + this.setDayTime(this.worldData.getDayTime() + 1L); + } + + } + public BlockPosition getSpawn() { BlockPosition blockposition = new BlockPosition(this.worldData.b(), this.worldData.c(), this.worldData.d()); @@ -2888,7 +1455,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return blockposition; } - public void v(BlockPosition blockposition) { + public void a_(BlockPosition blockposition) { this.worldData.setSpawn(blockposition); } @@ -2898,6 +1465,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc public void broadcastEntityEffect(Entity entity, byte b0) {} + @Override public IChunkProvider getChunkProvider() { return this.chunkProvider; } @@ -2906,117 +1474,66 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc this.getType(blockposition).a(this, blockposition, i, j); } - public IDataManager getDataManager() { - return this.dataManager; - } - + @Override public WorldData getWorldData() { return this.worldData; } public GameRules getGameRules() { - return this.worldData.w(); + return this.worldData.v(); } - public void everyoneSleeping() {} - - // CraftBukkit start - // Calls the method that checks to see if players are sleeping - // Called by CraftPlayer.setPermanentSleeping() - public void checkSleepStatus() { - if (!this.isClientSide) { - this.everyoneSleeping(); - } - } - // CraftBukkit end - - public float g(float f) { - return (this.q + (this.r - this.q) * f) * this.i(f); + public float f(float f) { + return MathHelper.g(f, this.lastThunderLevel, this.thunderLevel) * this.h(f); } - public float i(float f) { - return this.o + (this.p - this.o) * f; + public float h(float f) { + return MathHelper.g(f, this.lastRainLevel, this.rainLevel); } - public boolean Y() { - return this.worldProvider.g() && !this.worldProvider.h() ? (double) this.g(1.0F) > 0.9D : false; + public boolean U() { + return this.worldProvider.g() && !this.worldProvider.h() ? (double) this.f(1.0F) > 0.9D : false; } public boolean isRaining() { - return (double) this.i(1.0F) > 0.2D; + return (double) this.h(1.0F) > 0.2D; } public boolean isRainingAt(BlockPosition blockposition) { - return !this.isRaining() ? false : (!this.e(blockposition) ? false : (this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, blockposition).getY() > blockposition.getY() ? false : this.getBiome(blockposition).c() == BiomeBase.Precipitation.RAIN)); + return !this.isRaining() ? false : (!this.f(blockposition) ? false : (this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, blockposition).getY() > blockposition.getY() ? false : this.getBiome(blockposition).b() == BiomeBase.Precipitation.RAIN)); } - public boolean x(BlockPosition blockposition) { + public boolean s(BlockPosition blockposition) { BiomeBase biomebase = this.getBiome(blockposition); - return biomebase.d(); + return biomebase.c(); } @Nullable - public PersistentCollection h() { - return this.worldMaps; - } + public abstract WorldMap a(String s); - public void a(int i, BlockPosition blockposition, int j) { - // Akarin start - /* - for (int k = 0; k < this.v.size(); ++k) { - ((IWorldAccess) this.v.get(k)).a(i, blockposition, j); - } - */ - worldAccessor.a(i, blockposition, j); - // Akarin end + public abstract void a(WorldMap worldmap); - } + public abstract int getWorldMapCount(); - public void triggerEffect(int i, BlockPosition blockposition, int j) { - this.a((EntityHuman) null, i, blockposition, j); - } - - public void a(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { - try { - // Akarin start - /* - for (int k = 0; k < this.v.size(); ++k) { - ((IWorldAccess) this.v.get(k)).a(entityhuman, i, blockposition, j); - } - */ - worldAccessor.a(entityhuman, i, blockposition, j); - // Akarin end - - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Playing level event"); - CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Level event being played"); - - crashreportsystemdetails.a("Block coordinates", (Object) CrashReportSystemDetails.a(blockposition)); - crashreportsystemdetails.a("Event source", (Object) entityhuman); - crashreportsystemdetails.a("Event type", (Object) i); - crashreportsystemdetails.a("Event data", (Object) j); - throw new ReportedException(crashreport); - } - } + public void b(int i, BlockPosition blockposition, int j) {} public int getHeight() { - return 256; - } - - public int ab() { return this.worldProvider.h() ? 128 : 256; } public CrashReportSystemDetails a(CrashReport crashreport) { CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Affected level", 1); - crashreportsystemdetails.a("Level name", (Object) (this.worldData == null ? "????" : this.worldData.getName())); crashreportsystemdetails.a("All players", () -> { - return this.players.size() + " total; " + this.players; + return this.getPlayers().size() + " total; " + this.getPlayers(); }); - crashreportsystemdetails.a("Chunk stats", () -> { - return this.chunkProvider.getName(); + IChunkProvider ichunkprovider = this.chunkProvider; + + this.chunkProvider.getClass(); + crashreportsystemdetails.a("Chunk stats", ichunkprovider::getName); + crashreportsystemdetails.a("Level dimension", () -> { + return this.worldProvider.getDimensionManager().toString(); }); try { @@ -3028,19 +1545,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return crashreportsystemdetails; } - public void c(int i, BlockPosition blockposition, int j) { - // Akarin start - /* - for (int k = 0; k < this.v.size(); ++k) { - IWorldAccess iworldaccess = (IWorldAccess) this.v.get(k); - - iworldaccess.b(i, blockposition, j); - } - */ - worldAccessor.b(i, blockposition, j); - // Akarin end - - } + public abstract void a(int i, BlockPosition blockposition, int j); public abstract Scoreboard getScoreboard(); @@ -3055,12 +1560,12 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc IBlockData iblockdata = this.getType(blockposition1); if (iblockdata.getBlock() == Blocks.COMPARATOR) { - iblockdata.doPhysics(this, blockposition1, block, blockposition); - } else if (iblockdata.isOccluding()) { + iblockdata.doPhysics(this, blockposition1, block, blockposition, false); + } else if (iblockdata.isOccluding(this, blockposition1)) { blockposition1 = blockposition1.shift(enumdirection); iblockdata = this.getType(blockposition1); if (iblockdata.getBlock() == Blocks.COMPARATOR) { - iblockdata.doPhysics(this, blockposition1, block, blockposition); + iblockdata.doPhysics(this, blockposition1, block, blockposition, false); } } } @@ -3068,85 +1573,31 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc } + @Override public DifficultyDamageScaler getDamageScaler(BlockPosition blockposition) { long i = 0L; float f = 0.0F; if (this.isLoaded(blockposition)) { - f = this.ah(); - i = this.getChunkAtWorldCoords(blockposition).m(); + f = this.aa(); + i = this.getChunkAtWorldCoords(blockposition).q(); } return new DifficultyDamageScaler(this.getDifficulty(), this.getDayTime(), i, f); } + @Override public int c() { - return this.G; + return this.u; } public void c(int i) { - this.G = i; - } - - public void d(int i) { - this.H = i; - } - - public PersistentVillage getPersistentVillage() { return af(); } // Akarin - OBFHELPER - public PersistentVillage af() { - return this.villages; + this.v = i; } + @Override public WorldBorder getWorldBorder() { - return this.K; - } - - public boolean isSpawnChunk(int i, int j) { return e(i, j); } // Paper - OBFHELPER - public boolean e(int i, int j) { - BlockPosition blockposition = this.getSpawn(); - int k = i * 16 + 8 - blockposition.getX(); - int l = j * 16 + 8 - blockposition.getZ(); - boolean flag = true; - short keepLoadedRange = paperConfig.keepLoadedRange; // Paper - - return k >= -keepLoadedRange && k <= keepLoadedRange && l >= -keepLoadedRange && l <= keepLoadedRange && this.keepSpawnInMemory; // CraftBukkit - Added 'this.keepSpawnInMemory' // Paper - Re-add range var - } - - public LongSet ag() { - ForcedChunk forcedchunk = (ForcedChunk) this.a(this.worldProvider.getDimensionManager(), ForcedChunk::new, "chunks"); - - return (LongSet) (forcedchunk != null ? LongSets.unmodifiable(forcedchunk.a()) : LongSets.EMPTY_SET); - } - - public boolean isForceLoaded(int i, int j) { - ForcedChunk forcedchunk = (ForcedChunk) this.a(this.worldProvider.getDimensionManager(), ForcedChunk::new, "chunks"); - - return forcedchunk != null && forcedchunk.a().contains(ChunkCoordIntPair.a(i, j)); - } - - public boolean setForceLoaded(int i, int j, boolean flag) { - String s = "chunks"; - ForcedChunk forcedchunk = (ForcedChunk) this.a(this.worldProvider.getDimensionManager(), ForcedChunk::new, "chunks"); - - if (forcedchunk == null) { - forcedchunk = new ForcedChunk("chunks"); - this.a(this.worldProvider.getDimensionManager(), "chunks", (PersistentBase) forcedchunk); - } - - long k = ChunkCoordIntPair.a(i, j); - boolean flag1; - - if (flag) { - flag1 = forcedchunk.a().add(k); - if (flag1) { - this.getChunkAt(i, j); - } - } else { - flag1 = forcedchunk.a().remove(k); - } - - forcedchunk.a(flag1); - return flag1; + return this.worldBorder; } public void a(Packet packet) { @@ -3158,15 +1609,42 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc return null; } - public WorldProvider o() { + @Override + public WorldProvider getWorldProvider() { return this.worldProvider; } - public Random m() { + @Override + public Random getRandom() { return this.random; } + @Override + public boolean a(BlockPosition blockposition, Predicate predicate) { + return predicate.test(this.getType(blockposition)); + } + public abstract CraftingManager getCraftingManager(); - public abstract TagRegistry F(); + public abstract TagRegistry t(); + + public BlockPosition a(int i, int j, int k, int l) { + this.i = this.i * 3 + 1013904223; + int i1 = this.i >> 2; + + return new BlockPosition(i + (i1 & 15), j + (i1 >> 16 & l), k + (i1 >> 8 & 15)); + } + + public boolean isSavingDisabled() { + return false; + } + + public GameProfilerFiller getMethodProfiler() { + return this.methodProfiler; + } + + @Override + public BlockPosition getHighestBlockYAt(HeightMap.Type heightmap_type, BlockPosition blockposition) { + return new BlockPosition(blockposition.getX(), this.a(heightmap_type, blockposition.getX(), blockposition.getZ()), blockposition.getZ()); + } } diff --git a/src/main/java/net/minecraft/server/WorldBorder.java b/src/main/java/net/minecraft/server/WorldBorder.java index a2e856952..890258137 100644 --- a/src/main/java/net/minecraft/server/WorldBorder.java +++ b/src/main/java/net/minecraft/server/WorldBorder.java @@ -19,58 +19,63 @@ public class WorldBorder { public WorldBorder() {} - public boolean isInBounds(BlockPosition blockposition) { return a(blockposition); }public boolean a(BlockPosition blockposition) { // Paper - OBFHELPER - return (double) (blockposition.getX() + 1) > this.b() && (double) blockposition.getX() < this.d() && (double) (blockposition.getZ() + 1) > this.c() && (double) blockposition.getZ() < this.e(); + public final boolean isInBounds(BlockPosition blockposition) { return this.a(blockposition); } // Paper - OBFHELPER + public boolean a(BlockPosition blockposition) { + return (double) (blockposition.getX() + 1) > this.c() && (double) blockposition.getX() < this.e() && (double) (blockposition.getZ() + 1) > this.d() && (double) blockposition.getZ() < this.f(); } // Paper start private final BlockPosition.MutableBlockPosition mutPos = new BlockPosition.MutableBlockPosition(); public boolean isBlockInBounds(int chunkX, int chunkZ) { - mutPos.setValues(chunkX, 64, chunkZ); - return isInBounds(mutPos); + this.mutPos.setValues(chunkX, 64, chunkZ); + return this.isInBounds(this.mutPos); } public boolean isChunkInBounds(int chunkX, int chunkZ) { - mutPos.setValues(((chunkX << 4) + 15), 64, (chunkZ << 4) + 15); - return isInBounds(mutPos); + this.mutPos.setValues(((chunkX << 4) + 15), 64, (chunkZ << 4) + 15); + return this.isInBounds(this.mutPos); } // Paper end public boolean isInBounds(ChunkCoordIntPair chunkcoordintpair) { - return (double) chunkcoordintpair.f() > this.b() && (double) chunkcoordintpair.d() < this.d() && (double) chunkcoordintpair.g() > this.c() && (double) chunkcoordintpair.e() < this.e(); + return (double) chunkcoordintpair.f() > this.c() && (double) chunkcoordintpair.d() < this.e() && (double) chunkcoordintpair.g() > this.d() && (double) chunkcoordintpair.e() < this.f(); } public boolean a(AxisAlignedBB axisalignedbb) { - return axisalignedbb.maxX > this.b() && axisalignedbb.minX < this.d() && axisalignedbb.maxZ > this.c() && axisalignedbb.minZ < this.e(); + return axisalignedbb.maxX > this.c() && axisalignedbb.minX < this.e() && axisalignedbb.maxZ > this.d() && axisalignedbb.minZ < this.f(); } public double a(Entity entity) { return this.b(entity.locX, entity.locZ); } + public VoxelShape a() { + return this.i.m(); + } + public double b(double d0, double d1) { - double d2 = d1 - this.c(); - double d3 = this.e() - d1; - double d4 = d0 - this.b(); - double d5 = this.d() - d0; + double d2 = d1 - this.d(); + double d3 = this.f() - d1; + double d4 = d0 - this.c(); + double d5 = this.e() - d0; double d6 = Math.min(d4, d5); d6 = Math.min(d6, d2); return Math.min(d6, d3); } - public double b() { + public double c() { return this.i.a(); } - public double c() { + public double d() { return this.i.c(); } - public double d() { + public double e() { return this.i.b(); } - public double e() { + public double f() { return this.i.d(); } @@ -86,7 +91,7 @@ public class WorldBorder { this.f = d0; this.g = d1; this.i.k(); - Iterator iterator = this.k().iterator(); + Iterator iterator = this.l().iterator(); while (iterator.hasNext()) { IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); @@ -100,17 +105,17 @@ public class WorldBorder { return this.i.e(); } - public long i() { + public long j() { return this.i.g(); } - public double j() { + public double k() { return this.i.h(); } public void setSize(double d0) { this.i = new WorldBorder.c(d0); - Iterator iterator = this.k().iterator(); + Iterator iterator = this.l().iterator(); while (iterator.hasNext()) { IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); @@ -121,8 +126,8 @@ public class WorldBorder { } public void transitionSizeBetween(double d0, double d1, long i) { - this.i = (WorldBorder.a) (d0 != d1 ? new WorldBorder.b(d0, d1, i) : new WorldBorder.c(d1)); - Iterator iterator = this.k().iterator(); + this.i = (WorldBorder.a) (d0 == d1 ? new WorldBorder.c(d1) : new WorldBorder.b(d0, d1, i)); + Iterator iterator = this.l().iterator(); while (iterator.hasNext()) { IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); @@ -132,7 +137,7 @@ public class WorldBorder { } - protected List k() { + protected List l() { return Lists.newArrayList(this.a); } @@ -146,7 +151,7 @@ public class WorldBorder { this.i.j(); } - public int l() { + public int m() { return this.h; } @@ -156,7 +161,7 @@ public class WorldBorder { public void setDamageBuffer(double d0) { this.c = d0; - Iterator iterator = this.k().iterator(); + Iterator iterator = this.l().iterator(); while (iterator.hasNext()) { IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); @@ -172,7 +177,7 @@ public class WorldBorder { public void setDamageAmount(double d0) { this.b = d0; - Iterator iterator = this.k().iterator(); + Iterator iterator = this.l().iterator(); while (iterator.hasNext()) { IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); @@ -188,7 +193,7 @@ public class WorldBorder { public void setWarningTime(int i) { this.d = i; - Iterator iterator = this.k().iterator(); + Iterator iterator = this.l().iterator(); while (iterator.hasNext()) { IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); @@ -204,7 +209,7 @@ public class WorldBorder { public void setWarningDistance(int i) { this.e = i; - Iterator iterator = this.k().iterator(); + Iterator iterator = this.l().iterator(); while (iterator.hasNext()) { IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); @@ -214,10 +219,36 @@ public class WorldBorder { } - public void r() { + public void s() { this.i = this.i.l(); } + public void a(WorldData worlddata) { + worlddata.a(this.getSize()); + worlddata.d(this.getCenterX()); + worlddata.c(this.getCenterZ()); + worlddata.e(this.getDamageBuffer()); + worlddata.f(this.getDamageAmount()); + worlddata.h(this.getWarningDistance()); + worlddata.i(this.getWarningTime()); + worlddata.b(this.k()); + worlddata.c(this.j()); + } + + public void b(WorldData worlddata) { + this.setCenter(worlddata.B(), worlddata.C()); + this.setDamageAmount(worlddata.H()); + this.setDamageBuffer(worlddata.G()); + this.setWarningDistance(worlddata.I()); + this.setWarningTime(worlddata.J()); + if (worlddata.E() > 0L) { + this.transitionSizeBetween(worlddata.D(), worlddata.F(), worlddata.E()); + } else { + this.setSize(worlddata.D()); + } + + } + class c implements WorldBorder.a { private final double b; @@ -225,58 +256,75 @@ public class WorldBorder { private double d; private double e; private double f; + private VoxelShape g; public c(double d0) { this.b = d0; - this.m(); + this.n(); } + @Override public double a() { return this.c; } + @Override public double b() { return this.e; } + @Override public double c() { return this.d; } + @Override public double d() { return this.f; } + @Override public double e() { return this.b; } + @Override public long g() { return 0L; } + @Override public double h() { return this.b; } - private void m() { + private void n() { this.c = Math.max(WorldBorder.this.getCenterX() - this.b / 2.0D, (double) (-WorldBorder.this.h)); this.d = Math.max(WorldBorder.this.getCenterZ() - this.b / 2.0D, (double) (-WorldBorder.this.h)); this.e = Math.min(WorldBorder.this.getCenterX() + this.b / 2.0D, (double) WorldBorder.this.h); this.f = Math.min(WorldBorder.this.getCenterZ() + this.b / 2.0D, (double) WorldBorder.this.h); + this.g = VoxelShapes.a(VoxelShapes.a, VoxelShapes.create(Math.floor(this.a()), Double.NEGATIVE_INFINITY, Math.floor(this.c()), Math.ceil(this.b()), Double.POSITIVE_INFINITY, Math.ceil(this.d())), OperatorBoolean.ONLY_FIRST); } + @Override public void j() { - this.m(); + this.n(); } + @Override public void k() { - this.m(); + this.n(); } + @Override public WorldBorder.a l() { return this; } + + @Override + public VoxelShape m() { + return this.g; + } } class b implements WorldBorder.a { @@ -295,43 +343,58 @@ public class WorldBorder { this.d = this.e + i; } + @Override public double a() { return Math.max(WorldBorder.this.getCenterX() - this.e() / 2.0D, (double) (-WorldBorder.this.h)); } + @Override public double c() { return Math.max(WorldBorder.this.getCenterZ() - this.e() / 2.0D, (double) (-WorldBorder.this.h)); } + @Override public double b() { return Math.min(WorldBorder.this.getCenterX() + this.e() / 2.0D, (double) WorldBorder.this.h); } + @Override public double d() { return Math.min(WorldBorder.this.getCenterZ() + this.e() / 2.0D, (double) WorldBorder.this.h); } + @Override public double e() { double d0 = (double) (SystemUtils.getMonotonicMillis() - this.e) / this.f; - return d0 < 1.0D ? this.b + (this.c - this.b) * d0 : this.c; + return d0 < 1.0D ? MathHelper.d(d0, this.b, this.c) : this.c; } + @Override public long g() { return this.d - SystemUtils.getMonotonicMillis(); } + @Override public double h() { return this.c; } + @Override public void k() {} + @Override public void j() {} + @Override public WorldBorder.a l() { return (WorldBorder.a) (this.g() <= 0L ? WorldBorder.this.new c(this.c) : this); } + + @Override + public VoxelShape m() { + return VoxelShapes.a(VoxelShapes.a, VoxelShapes.create(Math.floor(this.a()), Double.NEGATIVE_INFINITY, Math.floor(this.c()), Math.ceil(this.b()), Double.POSITIVE_INFINITY, Math.ceil(this.d())), OperatorBoolean.ONLY_FIRST); + } } interface a { @@ -355,5 +418,7 @@ public class WorldBorder { void k(); WorldBorder.a l(); + + VoxelShape m(); } } diff --git a/src/main/java/net/minecraft/server/WorldData.java b/src/main/java/net/minecraft/server/WorldData.java index 64513a193..ca4c31458 100644 --- a/src/main/java/net/minecraft/server/WorldData.java +++ b/src/main/java/net/minecraft/server/WorldData.java @@ -2,13 +2,13 @@ package net.minecraft.server; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import com.mojang.datafixers.DataFixTypes; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.Dynamic; import com.mojang.datafixers.types.JsonOps; import java.util.Iterator; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.Map.Entry; import javax.annotation.Nullable; // CraftBukkit start @@ -40,66 +40,71 @@ public class WorldData { private final int q; private boolean r; private NBTTagCompound s; - private int t; private String levelName; - private int v; - private int w; - private boolean x; - private int y; - private boolean z; - private int A; - private EnumGamemode B; + private int u; + private int clearWeatherTime; + private boolean raining; + private int rainTime; + private boolean thundering; + private int thunderTime; + private EnumGamemode A; + private boolean B; private boolean C; private boolean D; private boolean E; - private boolean F; - private EnumDifficulty G; - private boolean H; + private EnumDifficulty F; + private boolean G; + private double H; private double I; private double J; - private double K; - private long L; + private long K; + private double L; private double M; private double N; - private double O; + private int O; private int P; - private int Q; + private final Set Q; private final Set R; - private final Set S; - private final Map T; - private NBTTagCompound U; - private final GameRules V; + private final Map S; + private NBTTagCompound T; + private int U; + private int V; + private UUID W; + private final GameRules X; + private final CustomFunctionCallbackTimerQueue Y; public WorldServer world; // CraftBukkit protected WorldData() { this.f = WorldType.NORMAL; this.g = new NBTTagCompound(); - this.K = 6.0E7D; - this.N = 5.0D; - this.O = 0.2D; - this.P = 5; - this.Q = 15; - this.R = Sets.newHashSet(); - this.S = Sets.newLinkedHashSet(); - this.T = com.koloboke.collect.map.hash.HashObjObjMaps.getDefaultFactory().withNullKeyAllowed(true).withKeyEquivalence(com.koloboke.collect.Equivalence.identity()).newUpdatableMap(); // Akarin - koloboke - this.V = new GameRules(); + this.J = 6.0E7D; + this.M = 5.0D; + this.N = 0.2D; + this.O = 5; + this.P = 15; + this.Q = Sets.newHashSet(); + this.R = Sets.newLinkedHashSet(); + this.S = Maps.newIdentityHashMap(); + this.X = new GameRules(); + this.Y = new CustomFunctionCallbackTimerQueue<>(CustomFunctionCallbackTimers.a); this.p = null; - this.q = 1631; + this.q = SharedConstants.a().getWorldVersion(); this.b(new NBTTagCompound()); } public WorldData(NBTTagCompound nbttagcompound, DataFixer datafixer, int i, @Nullable NBTTagCompound nbttagcompound1) { this.f = WorldType.NORMAL; this.g = new NBTTagCompound(); - this.K = 6.0E7D; - this.N = 5.0D; - this.O = 0.2D; - this.P = 5; - this.Q = 15; - this.R = Sets.newHashSet(); - this.S = Sets.newLinkedHashSet(); - this.T = com.koloboke.collect.map.hash.HashObjObjMaps.getDefaultFactory().withNullKeyAllowed(true).withKeyEquivalence(com.koloboke.collect.Equivalence.identity()).newUpdatableMap(); // Akarin - koloboke - this.V = new GameRules(); + this.J = 6.0E7D; + this.M = 5.0D; + this.N = 0.2D; + this.O = 5; + this.P = 15; + this.Q = Sets.newHashSet(); + this.R = Sets.newLinkedHashSet(); + this.S = Maps.newIdentityHashMap(); + this.X = new GameRules(); + this.Y = new CustomFunctionCallbackTimerQueue<>(CustomFunctionCallbackTimers.a); this.p = datafixer; NBTTagCompound nbttagcompound2; @@ -132,15 +137,15 @@ public class WorldData { this.b(nbttagcompound.getCompound("generatorOptions")); } - this.B = EnumGamemode.getById(nbttagcompound.getInt("GameType")); + this.A = EnumGamemode.getById(nbttagcompound.getInt("GameType")); if (nbttagcompound.hasKeyOfType("legacy_custom_options", 8)) { this.h = nbttagcompound.getString("legacy_custom_options"); } if (nbttagcompound.hasKeyOfType("MapFeatures", 99)) { - this.C = nbttagcompound.getBoolean("MapFeatures"); + this.B = nbttagcompound.getBoolean("MapFeatures"); } else { - this.C = true; + this.B = true; } this.i = nbttagcompound.getInt("SpawnX"); @@ -156,23 +161,23 @@ public class WorldData { this.n = nbttagcompound.getLong("LastPlayed"); this.o = nbttagcompound.getLong("SizeOnDisk"); this.levelName = nbttagcompound.getString("LevelName"); - this.v = nbttagcompound.getInt("version"); - this.w = nbttagcompound.getInt("clearWeatherTime"); - this.y = nbttagcompound.getInt("rainTime"); - this.x = nbttagcompound.getBoolean("raining"); - this.A = nbttagcompound.getInt("thunderTime"); - this.z = nbttagcompound.getBoolean("thundering"); - this.D = nbttagcompound.getBoolean("hardcore"); + this.u = nbttagcompound.getInt("version"); + this.clearWeatherTime = nbttagcompound.getInt("clearWeatherTime"); + this.rainTime = nbttagcompound.getInt("rainTime"); + this.raining = nbttagcompound.getBoolean("raining"); + this.thunderTime = nbttagcompound.getInt("thunderTime"); + this.thundering = nbttagcompound.getBoolean("thundering"); + this.C = nbttagcompound.getBoolean("hardcore"); if (nbttagcompound.hasKeyOfType("initialized", 99)) { - this.F = nbttagcompound.getBoolean("initialized"); + this.E = nbttagcompound.getBoolean("initialized"); } else { - this.F = true; + this.E = true; } if (nbttagcompound.hasKeyOfType("allowCommands", 99)) { - this.E = nbttagcompound.getBoolean("allowCommands"); + this.D = nbttagcompound.getBoolean("allowCommands"); } else { - this.E = this.B == EnumGamemode.CREATIVE; + this.D = this.A == EnumGamemode.CREATIVE; } this.q = i; @@ -181,51 +186,51 @@ public class WorldData { } if (nbttagcompound.hasKeyOfType("GameRules", 10)) { - this.V.a(nbttagcompound.getCompound("GameRules")); + this.X.a(nbttagcompound.getCompound("GameRules")); } if (nbttagcompound.hasKeyOfType("Difficulty", 99)) { - this.G = EnumDifficulty.getById(nbttagcompound.getByte("Difficulty")); + this.F = EnumDifficulty.getById(nbttagcompound.getByte("Difficulty")); } if (nbttagcompound.hasKeyOfType("DifficultyLocked", 1)) { - this.H = nbttagcompound.getBoolean("DifficultyLocked"); + this.G = nbttagcompound.getBoolean("DifficultyLocked"); } if (nbttagcompound.hasKeyOfType("BorderCenterX", 99)) { - this.I = nbttagcompound.getDouble("BorderCenterX"); + this.H = nbttagcompound.getDouble("BorderCenterX"); } if (nbttagcompound.hasKeyOfType("BorderCenterZ", 99)) { - this.J = nbttagcompound.getDouble("BorderCenterZ"); + this.I = nbttagcompound.getDouble("BorderCenterZ"); } if (nbttagcompound.hasKeyOfType("BorderSize", 99)) { - this.K = nbttagcompound.getDouble("BorderSize"); + this.J = nbttagcompound.getDouble("BorderSize"); } if (nbttagcompound.hasKeyOfType("BorderSizeLerpTime", 99)) { - this.L = nbttagcompound.getLong("BorderSizeLerpTime"); + this.K = nbttagcompound.getLong("BorderSizeLerpTime"); } if (nbttagcompound.hasKeyOfType("BorderSizeLerpTarget", 99)) { - this.M = nbttagcompound.getDouble("BorderSizeLerpTarget"); + this.L = nbttagcompound.getDouble("BorderSizeLerpTarget"); } if (nbttagcompound.hasKeyOfType("BorderSafeZone", 99)) { - this.N = nbttagcompound.getDouble("BorderSafeZone"); + this.M = nbttagcompound.getDouble("BorderSafeZone"); } if (nbttagcompound.hasKeyOfType("BorderDamagePerBlock", 99)) { - this.O = nbttagcompound.getDouble("BorderDamagePerBlock"); + this.N = nbttagcompound.getDouble("BorderDamagePerBlock"); } if (nbttagcompound.hasKeyOfType("BorderWarningBlocks", 99)) { - this.P = nbttagcompound.getInt("BorderWarningBlocks"); + this.O = nbttagcompound.getInt("BorderWarningBlocks"); } if (nbttagcompound.hasKeyOfType("BorderWarningTime", 99)) { - this.Q = nbttagcompound.getInt("BorderWarningTime"); + this.P = nbttagcompound.getInt("BorderWarningTime"); } if (nbttagcompound.hasKeyOfType("DimensionData", 10)) { @@ -235,7 +240,7 @@ public class WorldData { while (iterator.hasNext()) { String s1 = (String) iterator.next(); - this.T.put(DimensionManager.a(Integer.parseInt(s1)), nbttagcompound2.getCompound(s1)); + this.S.put(DimensionManager.a(Integer.parseInt(s1)), nbttagcompound2.getCompound(s1)); } } @@ -244,18 +249,34 @@ public class WorldData { NBTTagList nbttaglist = nbttagcompound2.getList("Disabled", 8); for (int k = 0; k < nbttaglist.size(); ++k) { - this.R.add(nbttaglist.getString(k)); + this.Q.add(nbttaglist.getString(k)); } NBTTagList nbttaglist1 = nbttagcompound2.getList("Enabled", 8); for (int l = 0; l < nbttaglist1.size(); ++l) { - this.S.add(nbttaglist1.getString(l)); + this.R.add(nbttaglist1.getString(l)); } } if (nbttagcompound.hasKeyOfType("CustomBossEvents", 10)) { - this.U = nbttagcompound.getCompound("CustomBossEvents"); + this.T = nbttagcompound.getCompound("CustomBossEvents"); + } + + if (nbttagcompound.hasKeyOfType("ScheduledEvents", 9)) { + this.Y.a(nbttagcompound.getList("ScheduledEvents", 10)); + } + + if (nbttagcompound.hasKeyOfType("WanderingTraderSpawnDelay", 99)) { + this.U = nbttagcompound.getInt("WanderingTraderSpawnDelay"); + } + + if (nbttagcompound.hasKeyOfType("WanderingTraderSpawnChance", 99)) { + this.V = nbttagcompound.getInt("WanderingTraderSpawnChance"); + } + + if (nbttagcompound.hasKeyOfType("WanderingTraderId", 8)) { + this.W = UUID.fromString(nbttagcompound.getString("WanderingTraderId")); } } @@ -263,35 +284,36 @@ public class WorldData { public WorldData(WorldSettings worldsettings, String s) { this.f = WorldType.NORMAL; this.g = new NBTTagCompound(); - this.K = 6.0E7D; - this.N = 5.0D; - this.O = 0.2D; - this.P = 5; - this.Q = 15; - this.R = Sets.newHashSet(); - this.S = Sets.newLinkedHashSet(); - this.T = com.koloboke.collect.map.hash.HashObjObjMaps.getDefaultFactory().withNullKeyAllowed(true).withKeyEquivalence(com.koloboke.collect.Equivalence.identity()).newUpdatableMap(); // Akarin - koloboke - this.V = new GameRules(); + this.J = 6.0E7D; + this.M = 5.0D; + this.N = 0.2D; + this.O = 5; + this.P = 15; + this.Q = Sets.newHashSet(); + this.R = Sets.newLinkedHashSet(); + this.S = Maps.newIdentityHashMap(); + this.X = new GameRules(); + this.Y = new CustomFunctionCallbackTimerQueue<>(CustomFunctionCallbackTimers.a); this.p = null; - this.q = 1631; + this.q = SharedConstants.a().getWorldVersion(); this.a(worldsettings); this.levelName = s; - this.G = WorldData.a; - this.F = false; + this.F = WorldData.a; + this.E = false; } public void a(WorldSettings worldsettings) { this.e = worldsettings.d(); - this.B = worldsettings.e(); - this.C = worldsettings.g(); - this.D = worldsettings.f(); + this.A = worldsettings.e(); + this.B = worldsettings.g(); + this.C = worldsettings.f(); this.f = worldsettings.h(); this.b((NBTTagCompound) Dynamic.convert(JsonOps.INSTANCE, DynamicOpsNBT.a, worldsettings.j())); - this.E = worldsettings.i(); + this.D = worldsettings.i(); } public NBTTagCompound a(@Nullable NBTTagCompound nbttagcompound) { - this.Q(); + this.T(); if (nbttagcompound == null) { nbttagcompound = this.s; } @@ -305,12 +327,11 @@ public class WorldData { private void a(NBTTagCompound nbttagcompound, NBTTagCompound nbttagcompound1) { NBTTagCompound nbttagcompound2 = new NBTTagCompound(); - nbttagcompound2.setString("Name", "1.13.2"); - nbttagcompound2.setInt("Id", 1631); - nbttagcompound2.setBoolean("Snapshot", false); + nbttagcompound2.setString("Name", SharedConstants.a().getName()); + nbttagcompound2.setInt("Id", SharedConstants.a().getWorldVersion()); + nbttagcompound2.setBoolean("Snapshot", !SharedConstants.a().isStable()); nbttagcompound.set("Version", nbttagcompound2); - nbttagcompound.setInt("DataVersion", 1631); - if (org.bukkit.craftbukkit.util.CraftMagicNumbers.INSTANCE.getDataVersion() != 1631) throw new AssertionError(); // CraftBukkit - sentinel + nbttagcompound.setInt("DataVersion", SharedConstants.a().getWorldVersion()); nbttagcompound.setLong("RandomSeed", this.e); nbttagcompound.setString("generatorName", this.f.b()); nbttagcompound.setInt("generatorVersion", this.f.getVersion()); @@ -322,8 +343,8 @@ public class WorldData { nbttagcompound.setString("legacy_custom_options", this.h); } - nbttagcompound.setInt("GameType", this.B.getId()); - nbttagcompound.setBoolean("MapFeatures", this.C); + nbttagcompound.setInt("GameType", this.A.getId()); + nbttagcompound.setBoolean("MapFeatures", this.B); nbttagcompound.setInt("SpawnX", this.i); nbttagcompound.setInt("SpawnY", this.j); nbttagcompound.setInt("SpawnZ", this.k); @@ -332,32 +353,32 @@ public class WorldData { nbttagcompound.setLong("SizeOnDisk", this.o); nbttagcompound.setLong("LastPlayed", SystemUtils.getTimeMillis()); nbttagcompound.setString("LevelName", this.levelName); - nbttagcompound.setInt("version", this.v); - nbttagcompound.setInt("clearWeatherTime", this.w); - nbttagcompound.setInt("rainTime", this.y); - nbttagcompound.setBoolean("raining", this.x); - nbttagcompound.setInt("thunderTime", this.A); - nbttagcompound.setBoolean("thundering", this.z); - nbttagcompound.setBoolean("hardcore", this.D); - nbttagcompound.setBoolean("allowCommands", this.E); - nbttagcompound.setBoolean("initialized", this.F); - nbttagcompound.setDouble("BorderCenterX", this.I); - nbttagcompound.setDouble("BorderCenterZ", this.J); - nbttagcompound.setDouble("BorderSize", this.K); - nbttagcompound.setLong("BorderSizeLerpTime", this.L); - nbttagcompound.setDouble("BorderSafeZone", this.N); - nbttagcompound.setDouble("BorderDamagePerBlock", this.O); - nbttagcompound.setDouble("BorderSizeLerpTarget", this.M); - nbttagcompound.setDouble("BorderWarningBlocks", (double) this.P); - nbttagcompound.setDouble("BorderWarningTime", (double) this.Q); - if (this.G != null) { - nbttagcompound.setByte("Difficulty", (byte) this.G.a()); + nbttagcompound.setInt("version", this.u); + nbttagcompound.setInt("clearWeatherTime", this.clearWeatherTime); + nbttagcompound.setInt("rainTime", this.rainTime); + nbttagcompound.setBoolean("raining", this.raining); + nbttagcompound.setInt("thunderTime", this.thunderTime); + nbttagcompound.setBoolean("thundering", this.thundering); + nbttagcompound.setBoolean("hardcore", this.C); + nbttagcompound.setBoolean("allowCommands", this.D); + nbttagcompound.setBoolean("initialized", this.E); + nbttagcompound.setDouble("BorderCenterX", this.H); + nbttagcompound.setDouble("BorderCenterZ", this.I); + nbttagcompound.setDouble("BorderSize", this.J); + nbttagcompound.setLong("BorderSizeLerpTime", this.K); + nbttagcompound.setDouble("BorderSafeZone", this.M); + nbttagcompound.setDouble("BorderDamagePerBlock", this.N); + nbttagcompound.setDouble("BorderSizeLerpTarget", this.L); + nbttagcompound.setDouble("BorderWarningBlocks", (double) this.O); + nbttagcompound.setDouble("BorderWarningTime", (double) this.P); + if (this.F != null) { + nbttagcompound.setByte("Difficulty", (byte) this.F.a()); } - nbttagcompound.setBoolean("DifficultyLocked", this.H); - nbttagcompound.set("GameRules", this.V.a()); + nbttagcompound.setBoolean("DifficultyLocked", this.G); + nbttagcompound.set("GameRules", this.X.a()); NBTTagCompound nbttagcompound3 = new NBTTagCompound(); - Iterator iterator = this.T.entrySet().iterator(); + Iterator iterator = this.S.entrySet().iterator(); while (iterator.hasNext()) { Entry entry = (Entry) iterator.next(); @@ -372,28 +393,35 @@ public class WorldData { NBTTagCompound nbttagcompound4 = new NBTTagCompound(); NBTTagList nbttaglist = new NBTTagList(); - Iterator iterator1 = this.S.iterator(); + Iterator iterator1 = this.R.iterator(); while (iterator1.hasNext()) { String s = (String) iterator1.next(); - nbttaglist.add((NBTBase) (new NBTTagString(s))); + nbttaglist.add(new NBTTagString(s)); } nbttagcompound4.set("Enabled", nbttaglist); NBTTagList nbttaglist1 = new NBTTagList(); - Iterator iterator2 = this.R.iterator(); + Iterator iterator2 = this.Q.iterator(); while (iterator2.hasNext()) { String s1 = (String) iterator2.next(); - nbttaglist1.add((NBTBase) (new NBTTagString(s1))); + nbttaglist1.add(new NBTTagString(s1)); } nbttagcompound4.set("Disabled", nbttaglist1); nbttagcompound.set("DataPacks", nbttagcompound4); - if (this.U != null) { - nbttagcompound.set("CustomBossEvents", this.U); + if (this.T != null) { + nbttagcompound.set("CustomBossEvents", this.T); + } + + nbttagcompound.set("ScheduledEvents", this.Y.b()); + nbttagcompound.setInt("WanderingTraderSpawnDelay", this.U); + nbttagcompound.setInt("WanderingTraderSpawnChance", this.V); + if (this.W != null) { + nbttagcompound.setString("WanderingTraderId", this.W.toString()); } nbttagcompound.setString("Bukkit.Version", Bukkit.getName() + "/" + Bukkit.getVersion() + "/" + Bukkit.getBukkitVersion()); // CraftBukkit @@ -423,9 +451,9 @@ public class WorldData { return this.m; } - private void Q() { + private void T() { if (!this.r && this.s != null) { - if (this.q < 1631) { + if (this.q < SharedConstants.a().getWorldVersion()) { if (this.p == null) { throw new NullPointerException("Fixer Upper not set inside LevelData, and the player tag is not upgraded."); } @@ -433,13 +461,12 @@ public class WorldData { this.s = GameProfileSerializer.a(this.p, DataFixTypes.PLAYER, this.s, this.q); } - this.t = this.s.getInt("Dimension"); this.r = true; } } public NBTTagCompound h() { - this.Q(); + this.T(); return this.s; } @@ -461,32 +488,36 @@ public class WorldData { return this.levelName; } - public void a(String s) { + public void setName(String s) { this.levelName = s; } - public int k() { - return this.v; + public int j() { + return this.u; } public void d(int i) { - this.v = i; + this.u = i; } public int z() { - return this.w; + return this.clearWeatherTime; } public void g(int i) { - this.w = i; + this.clearWeatherTime = i; } public boolean isThundering() { - return this.z; + return this.thundering; } public void setThundering(boolean flag) { // CraftBukkit start + if (this.thundering == flag) { + return; + } + org.bukkit.World world = Bukkit.getWorld(getName()); if (world != null) { ThunderChangeEvent thunder = new ThunderChangeEvent(world, flag); @@ -496,23 +527,27 @@ public class WorldData { } } // CraftBukkit end - this.z = flag; + this.thundering = flag; } public int getThunderDuration() { - return this.A; + return this.thunderTime; } public void setThunderDuration(int i) { - this.A = i; + this.thunderTime = i; } public boolean hasStorm() { - return this.x; + return this.raining; } public void setStorm(boolean flag) { // CraftBukkit start + if (this.raining == flag) { + return; + } + org.bukkit.World world = Bukkit.getWorld(getName()); if (world != null) { WeatherChangeEvent weather = new WeatherChangeEvent(world, flag); @@ -522,39 +557,39 @@ public class WorldData { } } // CraftBukkit end - this.x = flag; + this.raining = flag; } public int getWeatherDuration() { - return this.y; + return this.rainTime; } public void setWeatherDuration(int i) { - this.y = i; + this.rainTime = i; } public EnumGamemode getGameType() { - return this.B; + return this.A; } public boolean shouldGenerateMapFeatures() { - return this.C; + return this.B; } public void f(boolean flag) { - this.C = flag; + this.B = flag; } public void setGameType(EnumGamemode enumgamemode) { - this.B = enumgamemode; + this.A = enumgamemode; } public boolean isHardcore() { - return this.D; + return this.C; } public void g(boolean flag) { - this.D = flag; + this.C = flag; } public WorldType getType() { @@ -573,126 +608,133 @@ public class WorldData { this.g = nbttagcompound; } + public boolean t() { + return this.D; + } + + public void c(boolean flag) { + this.D = flag; + } + public boolean u() { return this.E; } - public void c(boolean flag) { + public void d(boolean flag) { this.E = flag; } - public boolean v() { - return this.F; - } - - public void d(boolean flag) { - this.F = flag; - } - - public GameRules w() { - return this.V; + public GameRules v() { + return this.X; } public double B() { - return this.I; + return this.H; } public double C() { - return this.J; + return this.I; } public double D() { - return this.K; + return this.J; } public void a(double d0) { - this.K = d0; - } - - public long E() { - return this.L; - } - - public void c(long i) { - this.L = i; - } - - public double F() { - return this.M; - } - - public void b(double d0) { - this.M = d0; - } - - public void c(double d0) { this.J = d0; } - public void d(double d0) { + public long E() { + return this.K; + } + + public void c(long i) { + this.K = i; + } + + public double F() { + return this.L; + } + + public void b(double d0) { + this.L = d0; + } + + public void c(double d0) { this.I = d0; } + public void d(double d0) { + this.H = d0; + } + public double G() { - return this.N; + return this.M; } public void e(double d0) { - this.N = d0; + this.M = d0; } public double H() { - return this.O; + return this.N; } public void f(double d0) { - this.O = d0; + this.N = d0; } public int I() { - return this.P; + return this.O; } public int J() { - return this.Q; + return this.P; } public void h(int i) { - this.P = i; + this.O = i; } public void i(int i) { - this.Q = i; + this.P = i; } public EnumDifficulty getDifficulty() { - return this.G; + return this.F; } public void setDifficulty(EnumDifficulty enumdifficulty) { - this.G = enumdifficulty; + this.F = enumdifficulty; // CraftBukkit start PacketPlayOutServerDifficulty packet = new PacketPlayOutServerDifficulty(this.getDifficulty(), this.isDifficultyLocked()); - for (EntityPlayer player : (java.util.List) (java.util.List) world.players) { + for (EntityPlayer player : (java.util.List) (java.util.List) world.getPlayers()) { player.playerConnection.sendPacket(packet); } // CraftBukkit end } public boolean isDifficultyLocked() { - return this.H; + return this.G; } public void e(boolean flag) { - this.H = flag; + this.G = flag; + } + + public CustomFunctionCallbackTimerQueue y() { + return this.Y; } public void a(CrashReportSystemDetails crashreportsystemdetails) { + crashreportsystemdetails.a("Level name", () -> { + return this.levelName; + }); crashreportsystemdetails.a("Level seed", () -> { - return String.valueOf(this.getSeed()); + return String.valueOf(this.e); }); crashreportsystemdetails.a("Level generator", () -> { - return String.format("ID %02d - %s, ver %d. Features enabled: %b", this.f.i(), this.f.name(), this.f.getVersion(), this.C); + return String.format("ID %02d - %s, ver %d. Features enabled: %b", this.f.i(), this.f.name(), this.f.getVersion(), this.B); }); crashreportsystemdetails.a("Level generator options", () -> { return this.g.toString(); @@ -703,59 +745,76 @@ public class WorldData { crashreportsystemdetails.a("Level time", () -> { return String.format("%d game time, %d day time", this.l, this.m); }); - crashreportsystemdetails.a("Level dimension", () -> { - return String.valueOf(this.t); - }); crashreportsystemdetails.a("Level storage version", () -> { String s = "Unknown?"; try { - switch (this.v) { - case 19132: - s = "McRegion"; - break; - case 19133: - s = "Anvil"; + switch (this.u) { + case 19132: + s = "McRegion"; + break; + case 19133: + s = "Anvil"; } } catch (Throwable throwable) { ; } - return String.format("0x%05X - %s", this.v, s); + return String.format("0x%05X - %s", this.u, s); }); crashreportsystemdetails.a("Level weather", () -> { - return String.format("Rain time: %d (now: %b), thunder time: %d (now: %b)", this.y, this.x, this.A, this.z); + return String.format("Rain time: %d (now: %b), thunder time: %d (now: %b)", this.rainTime, this.raining, this.thunderTime, this.thundering); }); crashreportsystemdetails.a("Level game mode", () -> { - return String.format("Game mode: %s (ID %d). Hardcore: %b. Cheats: %b", this.B.b(), this.B.getId(), this.D, this.E); + return String.format("Game mode: %s (ID %d). Hardcore: %b. Cheats: %b", this.A.b(), this.A.getId(), this.C, this.D); }); } public NBTTagCompound a(DimensionManager dimensionmanager) { - NBTTagCompound nbttagcompound = (NBTTagCompound) this.T.get(dimensionmanager); + NBTTagCompound nbttagcompound = (NBTTagCompound) this.S.get(dimensionmanager); return nbttagcompound == null ? new NBTTagCompound() : nbttagcompound; } public void a(DimensionManager dimensionmanager, NBTTagCompound nbttagcompound) { - this.T.put(dimensionmanager, nbttagcompound); + this.S.put(dimensionmanager, nbttagcompound); } public Set N() { - return this.R; + return this.Q; } public Set O() { - return this.S; + return this.R; } @Nullable - public NBTTagCompound P() { - return this.U; + public NBTTagCompound getCustomBossEvents() { + return this.T; } public void c(@Nullable NBTTagCompound nbttagcompound) { - this.U = nbttagcompound; + this.T = nbttagcompound; + } + + public int Q() { + return this.U; + } + + public void j(int i) { + this.U = i; + } + + public int R() { + return this.V; + } + + public void k(int i) { + this.V = i; + } + + public void a(UUID uuid) { + this.W = uuid; } // CraftBukkit start - Check if the name stored in NBT is the correct one diff --git a/src/main/java/net/minecraft/server/WorldGenDecoratorSpike.java b/src/main/java/net/minecraft/server/WorldGenDecoratorSpike.java deleted file mode 100644 index cf8478ca8..000000000 --- a/src/main/java/net/minecraft/server/WorldGenDecoratorSpike.java +++ /dev/null @@ -1,74 +0,0 @@ -package net.minecraft.server; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ContiguousSet; -import com.google.common.collect.DiscreteDomain; -import com.google.common.collect.Lists; -import com.google.common.collect.Range; - -import net.minecraft.server.BiomeCache.a; -import net.minecraft.server.WorldGenEnder.Spike; - -import java.util.Collections; -import java.util.List; -import java.util.Random; -import java.util.concurrent.TimeUnit; - -public class WorldGenDecoratorSpike extends WorldGenDecorator { - - private static final com.github.benmanes.caffeine.cache.LoadingCache a = com.github.benmanes.caffeine.cache.Caffeine.newBuilder().expireAfterAccess(5L, TimeUnit.MINUTES).build(new WorldGenDecoratorSpike.a()); // Akarin - caffeine - - public WorldGenDecoratorSpike() {} - - public boolean a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, Random random, BlockPosition blockposition, WorldGenFeatureDecoratorEmptyConfiguration worldgenfeaturedecoratoremptyconfiguration, WorldGenerator worldgenerator, C c0) { - WorldGenEnder.Spike[] aworldgenender_spike = a(generatoraccess); - boolean flag = false; - WorldGenEnder.Spike[] aworldgenender_spike1 = aworldgenender_spike; - int i = aworldgenender_spike.length; - - for (int j = 0; j < i; ++j) { - WorldGenEnder.Spike worldgenender_spike = aworldgenender_spike1[j]; - - if (worldgenender_spike.a(blockposition)) { - ((WorldGenEnder) worldgenerator).a(worldgenender_spike); - flag |= ((WorldGenEnder) worldgenerator).a(generatoraccess, chunkgenerator, random, new BlockPosition(worldgenender_spike.a(), 45, worldgenender_spike.b()), WorldGenFeatureConfiguration.e); - } - } - - return flag; - } - - public static WorldGenEnder.Spike[] a(GeneratorAccess generatoraccess) { - Random random = new Random(generatoraccess.getSeed()); - long i = random.nextLong() & 65535L; - - return (WorldGenEnder.Spike[]) WorldGenDecoratorSpike.a.get(i); // Akarin - caffeine - } - - static class a implements com.github.benmanes.caffeine.cache.CacheLoader { // Akarin - caffeine - - private a() {} - - public WorldGenEnder.Spike[] load(Long olong) throws Exception { - List list = Lists.newArrayList(ContiguousSet.create(Range.closedOpen(0, 10), DiscreteDomain.integers())); - - Collections.shuffle(list, new Random(olong)); - WorldGenEnder.Spike[] aworldgenender_spike = new WorldGenEnder.Spike[10]; - - for (int i = 0; i < 10; ++i) { - int j = (int) (42.0D * Math.cos(2.0D * (-3.141592653589793D + 0.3141592653589793D * (double) i))); - int k = (int) (42.0D * Math.sin(2.0D * (-3.141592653589793D + 0.3141592653589793D * (double) i))); - int l = (Integer) list.get(i); - int i1 = 2 + l / 3; - int j1 = 76 + l * 3; - boolean flag = l == 1 || l == 2; - - aworldgenender_spike[i] = new WorldGenEnder.Spike(j, k, i1, j1, flag); - } - - return aworldgenender_spike; - } - } -} diff --git a/src/main/java/net/minecraft/server/WorldGenEndCityPieces.java b/src/main/java/net/minecraft/server/WorldGenEndCityPieces.java deleted file mode 100644 index 0a223cfe5..000000000 --- a/src/main/java/net/minecraft/server/WorldGenEndCityPieces.java +++ /dev/null @@ -1,287 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import java.util.Iterator; -import java.util.List; -import java.util.Random; - -public class WorldGenEndCityPieces { - - private static final DefinedStructureInfo a = (new DefinedStructureInfo()).a(true); - private static final DefinedStructureInfo b = (new DefinedStructureInfo()).a(true).a(Blocks.AIR); - private static final WorldGenEndCityPieces.PieceGenerator c = new WorldGenEndCityPieces.PieceGenerator() { - public void a() {} - - public boolean a(DefinedStructureManager definedstructuremanager, int i, WorldGenEndCityPieces.Piece worldgenendcitypieces_piece, BlockPosition blockposition, List list, Random random) { - if (i > 8) { - return false; - } else { - EnumBlockRotation enumblockrotation = worldgenendcitypieces_piece.b.c(); - WorldGenEndCityPieces.Piece worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece, blockposition, "base_floor", enumblockrotation, true)); - int j = random.nextInt(3); - - if (j == 0) { - WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-1, 4, -1), "base_roof", enumblockrotation, true)); - } else if (j == 1) { - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-1, 0, -1), "second_floor_2", enumblockrotation, false)); - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-1, 8, -1), "second_roof", enumblockrotation, false)); - WorldGenEndCityPieces.b(definedstructuremanager, WorldGenEndCityPieces.e, i + 1, worldgenendcitypieces_piece1, (BlockPosition) null, list, random); - } else if (j == 2) { - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-1, 0, -1), "second_floor_2", enumblockrotation, false)); - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-1, 4, -1), "third_floor_2", enumblockrotation, false)); - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-1, 8, -1), "third_roof", enumblockrotation, true)); - WorldGenEndCityPieces.b(definedstructuremanager, WorldGenEndCityPieces.e, i + 1, worldgenendcitypieces_piece1, (BlockPosition) null, list, random); - } - - return true; - } - } - }; - private static final List> d = Lists.newArrayList(new Tuple[] { new Tuple<>(EnumBlockRotation.NONE, new BlockPosition(1, -1, 0)), new Tuple<>(EnumBlockRotation.CLOCKWISE_90, new BlockPosition(6, -1, 1)), new Tuple<>(EnumBlockRotation.COUNTERCLOCKWISE_90, new BlockPosition(0, -1, 5)), new Tuple<>(EnumBlockRotation.CLOCKWISE_180, new BlockPosition(5, -1, 6))}); - private static final WorldGenEndCityPieces.PieceGenerator e = new WorldGenEndCityPieces.PieceGenerator() { - public void a() {} - - public boolean a(DefinedStructureManager definedstructuremanager, int i, WorldGenEndCityPieces.Piece worldgenendcitypieces_piece, BlockPosition blockposition, List list, Random random) { - EnumBlockRotation enumblockrotation = worldgenendcitypieces_piece.b.c(); - WorldGenEndCityPieces.Piece worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece, new BlockPosition(3 + random.nextInt(2), -3, 3 + random.nextInt(2)), "tower_base", enumblockrotation, true)); - - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(0, 7, 0), "tower_piece", enumblockrotation, true)); - WorldGenEndCityPieces.Piece worldgenendcitypieces_piece2 = random.nextInt(3) == 0 ? worldgenendcitypieces_piece1 : null; - int j = 1 + random.nextInt(3); - - for (int k = 0; k < j; ++k) { - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(0, 4, 0), "tower_piece", enumblockrotation, true)); - if (k < j - 1 && random.nextBoolean()) { - worldgenendcitypieces_piece2 = worldgenendcitypieces_piece1; - } - } - - if (worldgenendcitypieces_piece2 != null) { - Iterator iterator = WorldGenEndCityPieces.d.iterator(); - - while (iterator.hasNext()) { - Tuple tuple = (Tuple) iterator.next(); - - if (random.nextBoolean()) { - WorldGenEndCityPieces.Piece worldgenendcitypieces_piece3 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece2, (BlockPosition) tuple.b(), "bridge_end", enumblockrotation.a((EnumBlockRotation) tuple.a()), true)); - - WorldGenEndCityPieces.b(definedstructuremanager, WorldGenEndCityPieces.f, i + 1, worldgenendcitypieces_piece3, (BlockPosition) null, list, random); - } - } - - WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-1, 4, -1), "tower_top", enumblockrotation, true)); - } else { - if (i != 7) { - return WorldGenEndCityPieces.b(definedstructuremanager, WorldGenEndCityPieces.h, i + 1, worldgenendcitypieces_piece1, (BlockPosition) null, list, random); - } - - WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-1, 4, -1), "tower_top", enumblockrotation, true)); - } - - return true; - } - }; - private static final WorldGenEndCityPieces.PieceGenerator f = new WorldGenEndCityPieces.PieceGenerator() { - public boolean a; - - public void a() { - this.a = false; - } - - public boolean a(DefinedStructureManager definedstructuremanager, int i, WorldGenEndCityPieces.Piece worldgenendcitypieces_piece, BlockPosition blockposition, List list, Random random) { - EnumBlockRotation enumblockrotation = worldgenendcitypieces_piece.b.c(); - int j = random.nextInt(4) + 1; - WorldGenEndCityPieces.Piece worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece, new BlockPosition(0, 0, -4), "bridge_piece", enumblockrotation, true)); - - worldgenendcitypieces_piece1.o = -1; - byte b0 = 0; - - for (int k = 0; k < j; ++k) { - if (random.nextBoolean()) { - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(0, b0, -4), "bridge_piece", enumblockrotation, true)); - b0 = 0; - } else { - if (random.nextBoolean()) { - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(0, b0, -4), "bridge_steep_stairs", enumblockrotation, true)); - } else { - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(0, b0, -8), "bridge_gentle_stairs", enumblockrotation, true)); - } - - b0 = 4; - } - } - - if (!this.a && random.nextInt(10 - i) == 0) { - WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-8 + random.nextInt(8), b0, -70 + random.nextInt(10)), "ship", enumblockrotation, true)); - this.a = true; - } else if (!WorldGenEndCityPieces.b(definedstructuremanager, WorldGenEndCityPieces.c, i + 1, worldgenendcitypieces_piece1, new BlockPosition(-3, b0 + 1, -11), list, random)) { - return false; - } - - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(4, b0, 0), "bridge_end", enumblockrotation.a(EnumBlockRotation.CLOCKWISE_180), true)); - worldgenendcitypieces_piece1.o = -1; - return true; - } - }; - private static final List> g = Lists.newArrayList(new Tuple[] { new Tuple<>(EnumBlockRotation.NONE, new BlockPosition(4, -1, 0)), new Tuple<>(EnumBlockRotation.CLOCKWISE_90, new BlockPosition(12, -1, 4)), new Tuple<>(EnumBlockRotation.COUNTERCLOCKWISE_90, new BlockPosition(0, -1, 8)), new Tuple<>(EnumBlockRotation.CLOCKWISE_180, new BlockPosition(8, -1, 12))}); - private static final WorldGenEndCityPieces.PieceGenerator h = new WorldGenEndCityPieces.PieceGenerator() { - public void a() {} - - public boolean a(DefinedStructureManager definedstructuremanager, int i, WorldGenEndCityPieces.Piece worldgenendcitypieces_piece, BlockPosition blockposition, List list, Random random) { - EnumBlockRotation enumblockrotation = worldgenendcitypieces_piece.b.c(); - WorldGenEndCityPieces.Piece worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece, new BlockPosition(-3, 4, -3), "fat_tower_base", enumblockrotation, true)); - - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(0, 4, 0), "fat_tower_middle", enumblockrotation, true)); - - for (int j = 0; j < 2 && random.nextInt(3) != 0; ++j) { - worldgenendcitypieces_piece1 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(0, 8, 0), "fat_tower_middle", enumblockrotation, true)); - Iterator iterator = WorldGenEndCityPieces.g.iterator(); - - while (iterator.hasNext()) { - Tuple tuple = (Tuple) iterator.next(); - - if (random.nextBoolean()) { - WorldGenEndCityPieces.Piece worldgenendcitypieces_piece2 = WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, (BlockPosition) tuple.b(), "bridge_end", enumblockrotation.a((EnumBlockRotation) tuple.a()), true)); - - WorldGenEndCityPieces.b(definedstructuremanager, WorldGenEndCityPieces.f, i + 1, worldgenendcitypieces_piece2, (BlockPosition) null, list, random); - } - } - } - - WorldGenEndCityPieces.b(list, WorldGenEndCityPieces.b(definedstructuremanager, worldgenendcitypieces_piece1, new BlockPosition(-2, 8, -2), "fat_tower_top", enumblockrotation, true)); - return true; - } - }; - - public static void a() { - WorldGenFactory.a(WorldGenEndCityPieces.Piece.class, "ECP"); - } - - private static WorldGenEndCityPieces.Piece b(DefinedStructureManager definedstructuremanager, WorldGenEndCityPieces.Piece worldgenendcitypieces_piece, BlockPosition blockposition, String s, EnumBlockRotation enumblockrotation, boolean flag) { - WorldGenEndCityPieces.Piece worldgenendcitypieces_piece1 = new WorldGenEndCityPieces.Piece(definedstructuremanager, s, worldgenendcitypieces_piece.c, enumblockrotation, flag); - BlockPosition blockposition1 = worldgenendcitypieces_piece.a.a(worldgenendcitypieces_piece.b, blockposition, worldgenendcitypieces_piece1.b, BlockPosition.ZERO); - - worldgenendcitypieces_piece1.a(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); - return worldgenendcitypieces_piece1; - } - - public static void a(DefinedStructureManager definedstructuremanager, BlockPosition blockposition, EnumBlockRotation enumblockrotation, List list, Random random) { - WorldGenEndCityPieces.h.a(); - WorldGenEndCityPieces.c.a(); - WorldGenEndCityPieces.f.a(); - WorldGenEndCityPieces.e.a(); - WorldGenEndCityPieces.Piece worldgenendcitypieces_piece = b(list, new WorldGenEndCityPieces.Piece(definedstructuremanager, "base_floor", blockposition, enumblockrotation, true)); - - worldgenendcitypieces_piece = b(list, b(definedstructuremanager, worldgenendcitypieces_piece, new BlockPosition(-1, 0, -1), "second_floor_1", enumblockrotation, false)); - worldgenendcitypieces_piece = b(list, b(definedstructuremanager, worldgenendcitypieces_piece, new BlockPosition(-1, 4, -1), "third_floor_1", enumblockrotation, false)); - worldgenendcitypieces_piece = b(list, b(definedstructuremanager, worldgenendcitypieces_piece, new BlockPosition(-1, 8, -1), "third_roof", enumblockrotation, true)); - b(definedstructuremanager, WorldGenEndCityPieces.e, 1, worldgenendcitypieces_piece, (BlockPosition) null, list, random); - } - - private static WorldGenEndCityPieces.Piece b(List list, WorldGenEndCityPieces.Piece worldgenendcitypieces_piece) { - list.add(worldgenendcitypieces_piece); - return worldgenendcitypieces_piece; - } - - private static boolean b(DefinedStructureManager definedstructuremanager, WorldGenEndCityPieces.PieceGenerator worldgenendcitypieces_piecegenerator, int i, WorldGenEndCityPieces.Piece worldgenendcitypieces_piece, BlockPosition blockposition, List list, Random random) { - if (i > 8) { - return false; - } else { - List list1 = Lists.newArrayList(); - - if (worldgenendcitypieces_piecegenerator.a(definedstructuremanager, i, worldgenendcitypieces_piece, blockposition, list1, random)) { - boolean flag = false; - int j = random.nextInt(); - Iterator iterator = list1.iterator(); - - while (iterator.hasNext()) { - StructurePiece structurepiece = (StructurePiece) iterator.next(); - - structurepiece.o = j; - StructurePiece structurepiece1 = StructurePiece.a(list, structurepiece.d()); - - if (structurepiece1 != null && structurepiece1.o != worldgenendcitypieces_piece.o) { - flag = true; - break; - } - } - - if (!flag) { - list.addAll(list1); - return true; - } - } - - return false; - } - } - - interface PieceGenerator { - - void a(); - - boolean a(DefinedStructureManager definedstructuremanager, int i, WorldGenEndCityPieces.Piece worldgenendcitypieces_piece, BlockPosition blockposition, List list, Random random); - } - - public static class Piece extends DefinedStructurePiece { - - private String d; - private EnumBlockRotation e; - private boolean f; - - public Piece() {} - - public Piece(DefinedStructureManager definedstructuremanager, String s, BlockPosition blockposition, EnumBlockRotation enumblockrotation, boolean flag) { - super(0); - this.d = s; - this.c = blockposition; - this.e = enumblockrotation; - this.f = flag; - this.a(definedstructuremanager); - } - - private void a(DefinedStructureManager definedstructuremanager) { - DefinedStructure definedstructure = definedstructuremanager.a(new MinecraftKey("end_city/" + this.d)); - DefinedStructureInfo definedstructureinfo = (this.f ? WorldGenEndCityPieces.a : WorldGenEndCityPieces.b).a().a(this.e); - - this.a(definedstructure, this.c, definedstructureinfo); - } - - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.setString("Template", this.d); - nbttagcompound.setString("Rot", this.e.name()); - nbttagcompound.setBoolean("OW", this.f); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.d = nbttagcompound.getString("Template"); - this.e = EnumBlockRotation.valueOf(nbttagcompound.getString("Rot")); - this.f = nbttagcompound.getBoolean("OW"); - this.a(definedstructuremanager); - } - - protected void a(String s, BlockPosition blockposition, GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - if (s.startsWith("Chest")) { - BlockPosition blockposition1 = blockposition.down(); - - if (structureboundingbox.b((BaseBlockPosition) blockposition1)) { - TileEntityLootable.a(generatoraccess, random, blockposition1, LootTables.c); - } - } else if (s.startsWith("Sentry")) { - EntityShulker entityshulker = EntityTypes.SHULKER.create(generatoraccess.getMinecraftWorld()); // Paper - - entityshulker.setPosition((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D); - entityshulker.g(blockposition); - generatoraccess.addEntity(entityshulker); - } else if (s.startsWith("Elytra")) { - EntityItemFrame entityitemframe = new EntityItemFrame(generatoraccess.getMinecraftWorld(), blockposition, this.e.a(EnumDirection.SOUTH)); - - entityitemframe.setItem(new ItemStack(Items.ELYTRA)); - generatoraccess.addEntity(entityitemframe); - } - - } - } -} diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureDesertPyramid.java b/src/main/java/net/minecraft/server/WorldGenFeatureDesertPyramid.java index d38758276..c54484631 100644 --- a/src/main/java/net/minecraft/server/WorldGenFeatureDesertPyramid.java +++ b/src/main/java/net/minecraft/server/WorldGenFeatureDesertPyramid.java @@ -1,39 +1,48 @@ package net.minecraft.server; -public class WorldGenFeatureDesertPyramid extends WorldGenFeatureRandomScattered { +import com.mojang.datafixers.Dynamic; +import java.util.function.Function; - public WorldGenFeatureDesertPyramid() {} +public class WorldGenFeatureDesertPyramid extends WorldGenFeatureRandomScattered { - protected String a() { + public WorldGenFeatureDesertPyramid(Function, ? extends WorldGenFeatureEmptyConfiguration> function) { + super(function); + } + + @Override + public String b() { return "Desert_Pyramid"; } - public int b() { + @Override + public int c() { return 3; } - protected StructureStart a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), Biomes.PLAINS); - - return new WorldGenFeatureDesertPyramid.a(generatoraccess, seededrandom, i, j, biomebase); + @Override + public StructureGenerator.a a() { + return WorldGenFeatureDesertPyramid.a::new; } + @Override // Spigot start - protected int c(World world) { + protected int getSeed(World world) { return world.spigotConfig.desertSeed; // Spigot end } public static class a extends StructureStart { - public a() {} + public a(StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); + } - public a(GeneratorAccess generatoraccess, SeededRandom seededrandom, int i, int j, BiomeBase biomebase) { - super(i, j, biomebase, seededrandom, generatoraccess.getSeed()); - WorldGenDesertPyramidPiece worldgendesertpyramidpiece = new WorldGenDesertPyramidPiece(seededrandom, i * 16, j * 16); + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + WorldGenDesertPyramidPiece worldgendesertpyramidpiece = new WorldGenDesertPyramidPiece(this.d, i * 16, j * 16); - this.a.add(worldgendesertpyramidpiece); - this.a((IBlockAccess) generatoraccess); + this.b.add(worldgendesertpyramidpiece); + this.b(); } } } diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureIgloo.java b/src/main/java/net/minecraft/server/WorldGenFeatureIgloo.java index de8be1aa9..6f8a97942 100644 --- a/src/main/java/net/minecraft/server/WorldGenFeatureIgloo.java +++ b/src/main/java/net/minecraft/server/WorldGenFeatureIgloo.java @@ -1,44 +1,52 @@ package net.minecraft.server; -public class WorldGenFeatureIgloo extends WorldGenFeatureRandomScattered { +import com.mojang.datafixers.Dynamic; +import java.util.function.Function; - public WorldGenFeatureIgloo() {} +public class WorldGenFeatureIgloo extends WorldGenFeatureRandomScattered { - protected String a() { + public WorldGenFeatureIgloo(Function, ? extends WorldGenFeatureEmptyConfiguration> function) { + super(function); + } + + @Override + public String b() { return "Igloo"; } - public int b() { + @Override + public int c() { return 3; } - protected StructureStart a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), Biomes.PLAINS); - - return new WorldGenFeatureIgloo.a(generatoraccess, chunkgenerator, seededrandom, i, j, biomebase); + @Override + public StructureGenerator.a a() { + return WorldGenFeatureIgloo.a::new; } + @Override // Spigot start - protected int c(World world) { + protected int getSeed(World world) { return world.spigotConfig.iglooSeed; // Spigot end } public static class a extends StructureStart { - public a() {} + public a(StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); + } - public a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j, BiomeBase biomebase) { - super(i, j, biomebase, seededrandom, generatoraccess.getSeed()); - WorldGenFeatureIglooConfiguration worldgenfeatureiglooconfiguration = (WorldGenFeatureIglooConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.j); + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + WorldGenFeatureEmptyConfiguration worldgenfeatureemptyconfiguration = (WorldGenFeatureEmptyConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.IGLOO); int k = i * 16; int l = j * 16; BlockPosition blockposition = new BlockPosition(k, 90, l); - EnumBlockRotation enumblockrotation = EnumBlockRotation.values()[seededrandom.nextInt(EnumBlockRotation.values().length)]; - DefinedStructureManager definedstructuremanager = generatoraccess.getDataManager().h(); + EnumBlockRotation enumblockrotation = EnumBlockRotation.values()[this.d.nextInt(EnumBlockRotation.values().length)]; - WorldGenIglooPiece.a(definedstructuremanager, blockposition, enumblockrotation, this.a, seededrandom, worldgenfeatureiglooconfiguration); - this.a((IBlockAccess) generatoraccess); + WorldGenIglooPiece.a(definedstructuremanager, blockposition, enumblockrotation, this.b, this.d, worldgenfeatureemptyconfiguration); + this.b(); } } } diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureJunglePyramid.java b/src/main/java/net/minecraft/server/WorldGenFeatureJunglePyramid.java index c10f79864..ca6b1ee8a 100644 --- a/src/main/java/net/minecraft/server/WorldGenFeatureJunglePyramid.java +++ b/src/main/java/net/minecraft/server/WorldGenFeatureJunglePyramid.java @@ -1,39 +1,48 @@ package net.minecraft.server; -public class WorldGenFeatureJunglePyramid extends WorldGenFeatureRandomScattered { +import com.mojang.datafixers.Dynamic; +import java.util.function.Function; - public WorldGenFeatureJunglePyramid() {} +public class WorldGenFeatureJunglePyramid extends WorldGenFeatureRandomScattered { - protected String a() { + public WorldGenFeatureJunglePyramid(Function, ? extends WorldGenFeatureEmptyConfiguration> function) { + super(function); + } + + @Override + public String b() { return "Jungle_Pyramid"; } - public int b() { + @Override + public int c() { return 3; } - protected StructureStart a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), Biomes.PLAINS); - - return new WorldGenFeatureJunglePyramid.a(generatoraccess, seededrandom, i, j, biomebase); + @Override + public StructureGenerator.a a() { + return WorldGenFeatureJunglePyramid.a::new; } + @Override // Spigot start - protected int c(World world) { + protected int getSeed(World world) { return world.spigotConfig.jungleSeed; // Spigot end } public static class a extends StructureStart { - public a() {} + public a(StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); + } - public a(GeneratorAccess generatoraccess, SeededRandom seededrandom, int i, int j, BiomeBase biomebase) { - super(i, j, biomebase, seededrandom, generatoraccess.getSeed()); - WorldGenJunglePyramidPiece worldgenjunglepyramidpiece = new WorldGenJunglePyramidPiece(seededrandom, i * 16, j * 16); + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + WorldGenJunglePyramidPiece worldgenjunglepyramidpiece = new WorldGenJunglePyramidPiece(this.d, i * 16, j * 16); - this.a.add(worldgenjunglepyramidpiece); - this.a((IBlockAccess) generatoraccess); + this.b.add(worldgenjunglepyramidpiece); + this.b(); } } } diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuin.java b/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuin.java index ad3dc7199..7d553ee46 100644 --- a/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuin.java +++ b/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuin.java @@ -1,61 +1,88 @@ package net.minecraft.server; +import com.mojang.datafixers.Dynamic; +import java.util.Arrays; +import java.util.Map; import java.util.Random; +import java.util.function.Function; +import java.util.stream.Collectors; public class WorldGenFeatureOceanRuin extends WorldGenFeatureRandomScattered { - public WorldGenFeatureOceanRuin() {} + public WorldGenFeatureOceanRuin(Function, ? extends WorldGenFeatureOceanRuinConfiguration> function) { + super(function); + } - public String a() { + @Override + public String b() { return "Ocean_Ruin"; } - public int b() { + @Override + public int c() { return 3; } + @Override protected int a(ChunkGenerator chunkgenerator) { return chunkgenerator.getSettings().l(); } + @Override protected int b(ChunkGenerator chunkgenerator) { return chunkgenerator.getSettings().m(); } - protected StructureStart a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), (BiomeBase) null); - - return new WorldGenFeatureOceanRuin.a(generatoraccess, chunkgenerator, seededrandom, i, j, biomebase); + @Override + public StructureGenerator.a a() { + return WorldGenFeatureOceanRuin.a::new; } + @Override // Spigot start - protected int c(World world) { + protected int getSeed(World world) { return world.spigotConfig.oceanSeed; // Spigot end } public static enum Temperature { - WARM, COLD; + WARM("warm"), COLD("cold"); - private Temperature() {} + private static final Map c = (Map) Arrays.stream(values()).collect(Collectors.toMap(WorldGenFeatureOceanRuin.Temperature::a, (worldgenfeatureoceanruin_temperature) -> { + return worldgenfeatureoceanruin_temperature; + })); + private final String d; + + private Temperature(String s) { + this.d = s; + } + + public String a() { + return this.d; + } + + public static WorldGenFeatureOceanRuin.Temperature a(String s) { + return (WorldGenFeatureOceanRuin.Temperature) WorldGenFeatureOceanRuin.Temperature.c.get(s); + } } public static class a extends StructureStart { - public a() {} + public a(StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); + } - public a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j, BiomeBase biomebase) { - super(i, j, biomebase, seededrandom, generatoraccess.getSeed()); - WorldGenFeatureOceanRuinConfiguration worldgenfeatureoceanruinconfiguration = (WorldGenFeatureOceanRuinConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.o); + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + WorldGenFeatureOceanRuinConfiguration worldgenfeatureoceanruinconfiguration = (WorldGenFeatureOceanRuinConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.OCEAN_RUIN); int k = i * 16; int l = j * 16; BlockPosition blockposition = new BlockPosition(k, 90, l); - EnumBlockRotation enumblockrotation = EnumBlockRotation.values()[seededrandom.nextInt(EnumBlockRotation.values().length)]; - DefinedStructureManager definedstructuremanager = generatoraccess.getDataManager().h(); + EnumBlockRotation enumblockrotation = EnumBlockRotation.values()[this.d.nextInt(EnumBlockRotation.values().length)]; - WorldGenFeatureOceanRuinPieces.a(definedstructuremanager, blockposition, enumblockrotation, this.a, (Random) seededrandom, worldgenfeatureoceanruinconfiguration); - this.a((IBlockAccess) generatoraccess); + WorldGenFeatureOceanRuinPieces.a(definedstructuremanager, blockposition, enumblockrotation, this.b, (Random) this.d, worldgenfeatureoceanruinconfiguration); + this.b(); } } } diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuinPieces.java b/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuinPieces.java deleted file mode 100644 index abeb4aa02..000000000 --- a/src/main/java/net/minecraft/server/WorldGenFeatureOceanRuinPieces.java +++ /dev/null @@ -1,218 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import java.util.Iterator; -import java.util.List; -import java.util.Random; - -public class WorldGenFeatureOceanRuinPieces { - - private static final MinecraftKey[] a = new MinecraftKey[] { new MinecraftKey("underwater_ruin/warm_1"), new MinecraftKey("underwater_ruin/warm_2"), new MinecraftKey("underwater_ruin/warm_3"), new MinecraftKey("underwater_ruin/warm_4"), new MinecraftKey("underwater_ruin/warm_5"), new MinecraftKey("underwater_ruin/warm_6"), new MinecraftKey("underwater_ruin/warm_7"), new MinecraftKey("underwater_ruin/warm_8")}; - private static final MinecraftKey[] b = new MinecraftKey[] { new MinecraftKey("underwater_ruin/brick_1"), new MinecraftKey("underwater_ruin/brick_2"), new MinecraftKey("underwater_ruin/brick_3"), new MinecraftKey("underwater_ruin/brick_4"), new MinecraftKey("underwater_ruin/brick_5"), new MinecraftKey("underwater_ruin/brick_6"), new MinecraftKey("underwater_ruin/brick_7"), new MinecraftKey("underwater_ruin/brick_8")}; - private static final MinecraftKey[] c = new MinecraftKey[] { new MinecraftKey("underwater_ruin/cracked_1"), new MinecraftKey("underwater_ruin/cracked_2"), new MinecraftKey("underwater_ruin/cracked_3"), new MinecraftKey("underwater_ruin/cracked_4"), new MinecraftKey("underwater_ruin/cracked_5"), new MinecraftKey("underwater_ruin/cracked_6"), new MinecraftKey("underwater_ruin/cracked_7"), new MinecraftKey("underwater_ruin/cracked_8")}; - private static final MinecraftKey[] d = new MinecraftKey[] { new MinecraftKey("underwater_ruin/mossy_1"), new MinecraftKey("underwater_ruin/mossy_2"), new MinecraftKey("underwater_ruin/mossy_3"), new MinecraftKey("underwater_ruin/mossy_4"), new MinecraftKey("underwater_ruin/mossy_5"), new MinecraftKey("underwater_ruin/mossy_6"), new MinecraftKey("underwater_ruin/mossy_7"), new MinecraftKey("underwater_ruin/mossy_8")}; - private static final MinecraftKey[] e = new MinecraftKey[] { new MinecraftKey("underwater_ruin/big_brick_1"), new MinecraftKey("underwater_ruin/big_brick_2"), new MinecraftKey("underwater_ruin/big_brick_3"), new MinecraftKey("underwater_ruin/big_brick_8")}; - private static final MinecraftKey[] f = new MinecraftKey[] { new MinecraftKey("underwater_ruin/big_mossy_1"), new MinecraftKey("underwater_ruin/big_mossy_2"), new MinecraftKey("underwater_ruin/big_mossy_3"), new MinecraftKey("underwater_ruin/big_mossy_8")}; - private static final MinecraftKey[] g = new MinecraftKey[] { new MinecraftKey("underwater_ruin/big_cracked_1"), new MinecraftKey("underwater_ruin/big_cracked_2"), new MinecraftKey("underwater_ruin/big_cracked_3"), new MinecraftKey("underwater_ruin/big_cracked_8")}; - private static final MinecraftKey[] h = new MinecraftKey[] { new MinecraftKey("underwater_ruin/big_warm_4"), new MinecraftKey("underwater_ruin/big_warm_5"), new MinecraftKey("underwater_ruin/big_warm_6"), new MinecraftKey("underwater_ruin/big_warm_7")}; - - public static void a() { - WorldGenFactory.a(WorldGenFeatureOceanRuinPieces.a.class, "ORP"); - } - - private static MinecraftKey a(Random random) { - return WorldGenFeatureOceanRuinPieces.a[random.nextInt(WorldGenFeatureOceanRuinPieces.a.length)]; - } - - private static MinecraftKey b(Random random) { - return WorldGenFeatureOceanRuinPieces.h[random.nextInt(WorldGenFeatureOceanRuinPieces.h.length)]; - } - - public static void a(DefinedStructureManager definedstructuremanager, BlockPosition blockposition, EnumBlockRotation enumblockrotation, List list, Random random, WorldGenFeatureOceanRuinConfiguration worldgenfeatureoceanruinconfiguration) { - boolean flag = random.nextFloat() <= worldgenfeatureoceanruinconfiguration.b; - float f = flag ? 0.9F : 0.8F; - - a(definedstructuremanager, blockposition, enumblockrotation, list, random, worldgenfeatureoceanruinconfiguration, flag, f); - if (flag && random.nextFloat() <= worldgenfeatureoceanruinconfiguration.c) { - a(definedstructuremanager, random, enumblockrotation, blockposition, worldgenfeatureoceanruinconfiguration, list); - } - - } - - private static void a(DefinedStructureManager definedstructuremanager, Random random, EnumBlockRotation enumblockrotation, BlockPosition blockposition, WorldGenFeatureOceanRuinConfiguration worldgenfeatureoceanruinconfiguration, List list) { - int i = blockposition.getX(); - int j = blockposition.getZ(); - BlockPosition blockposition1 = DefinedStructure.a(new BlockPosition(15, 0, 15), EnumBlockMirror.NONE, enumblockrotation, new BlockPosition(0, 0, 0)).a(i, 0, j); - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, 0, j, blockposition1.getX(), 0, blockposition1.getZ()); - BlockPosition blockposition2 = new BlockPosition(Math.min(i, blockposition1.getX()), 0, Math.min(j, blockposition1.getZ())); - List list1 = a(random, blockposition2.getX(), blockposition2.getZ()); - int k = MathHelper.nextInt(random, 4, 8); - - for (int l = 0; l < k; ++l) { - if (!list1.isEmpty()) { - int i1 = random.nextInt(list1.size()); - BlockPosition blockposition3 = (BlockPosition) list1.remove(i1); - int j1 = blockposition3.getX(); - int k1 = blockposition3.getZ(); - EnumBlockRotation enumblockrotation1 = EnumBlockRotation.values()[random.nextInt(EnumBlockRotation.values().length)]; - BlockPosition blockposition4 = DefinedStructure.a(new BlockPosition(5, 0, 6), EnumBlockMirror.NONE, enumblockrotation1, new BlockPosition(0, 0, 0)).a(j1, 0, k1); - StructureBoundingBox structureboundingbox1 = StructureBoundingBox.a(j1, 0, k1, blockposition4.getX(), 0, blockposition4.getZ()); - - if (!structureboundingbox1.a(structureboundingbox)) { - a(definedstructuremanager, blockposition3, enumblockrotation1, list, random, worldgenfeatureoceanruinconfiguration, false, 0.8F); - } - } - } - - } - - private static List a(Random random, int i, int j) { - List list = Lists.newArrayList(); - - list.add(new BlockPosition(i - 16 + MathHelper.nextInt(random, 1, 8), 90, j + 16 + MathHelper.nextInt(random, 1, 7))); - list.add(new BlockPosition(i - 16 + MathHelper.nextInt(random, 1, 8), 90, j + MathHelper.nextInt(random, 1, 7))); - list.add(new BlockPosition(i - 16 + MathHelper.nextInt(random, 1, 8), 90, j - 16 + MathHelper.nextInt(random, 4, 8))); - list.add(new BlockPosition(i + MathHelper.nextInt(random, 1, 7), 90, j + 16 + MathHelper.nextInt(random, 1, 7))); - list.add(new BlockPosition(i + MathHelper.nextInt(random, 1, 7), 90, j - 16 + MathHelper.nextInt(random, 4, 6))); - list.add(new BlockPosition(i + 16 + MathHelper.nextInt(random, 1, 7), 90, j + 16 + MathHelper.nextInt(random, 3, 8))); - list.add(new BlockPosition(i + 16 + MathHelper.nextInt(random, 1, 7), 90, j + MathHelper.nextInt(random, 1, 7))); - list.add(new BlockPosition(i + 16 + MathHelper.nextInt(random, 1, 7), 90, j - 16 + MathHelper.nextInt(random, 4, 8))); - return list; - } - - private static void a(DefinedStructureManager definedstructuremanager, BlockPosition blockposition, EnumBlockRotation enumblockrotation, List list, Random random, WorldGenFeatureOceanRuinConfiguration worldgenfeatureoceanruinconfiguration, boolean flag, float f) { - if (worldgenfeatureoceanruinconfiguration.a == WorldGenFeatureOceanRuin.Temperature.WARM) { - MinecraftKey minecraftkey = flag ? b(random) : a(random); - - list.add(new WorldGenFeatureOceanRuinPieces.a(definedstructuremanager, minecraftkey, blockposition, enumblockrotation, f, worldgenfeatureoceanruinconfiguration.a, flag)); - } else if (worldgenfeatureoceanruinconfiguration.a == WorldGenFeatureOceanRuin.Temperature.COLD) { - MinecraftKey[] aminecraftkey = flag ? WorldGenFeatureOceanRuinPieces.e : WorldGenFeatureOceanRuinPieces.b; - MinecraftKey[] aminecraftkey1 = flag ? WorldGenFeatureOceanRuinPieces.g : WorldGenFeatureOceanRuinPieces.c; - MinecraftKey[] aminecraftkey2 = flag ? WorldGenFeatureOceanRuinPieces.f : WorldGenFeatureOceanRuinPieces.d; - int i = random.nextInt(aminecraftkey.length); - - list.add(new WorldGenFeatureOceanRuinPieces.a(definedstructuremanager, aminecraftkey[i], blockposition, enumblockrotation, f, worldgenfeatureoceanruinconfiguration.a, flag)); - list.add(new WorldGenFeatureOceanRuinPieces.a(definedstructuremanager, aminecraftkey1[i], blockposition, enumblockrotation, 0.7F, worldgenfeatureoceanruinconfiguration.a, flag)); - list.add(new WorldGenFeatureOceanRuinPieces.a(definedstructuremanager, aminecraftkey2[i], blockposition, enumblockrotation, 0.5F, worldgenfeatureoceanruinconfiguration.a, flag)); - } - - } - - public static class a extends DefinedStructurePiece { - - private WorldGenFeatureOceanRuin.Temperature d; - private float e; - private MinecraftKey f; - private EnumBlockRotation g; - private boolean h; - - public a() {} - - public a(DefinedStructureManager definedstructuremanager, MinecraftKey minecraftkey, BlockPosition blockposition, EnumBlockRotation enumblockrotation, float f, WorldGenFeatureOceanRuin.Temperature worldgenfeatureoceanruin_temperature, boolean flag) { - super(0); - this.f = minecraftkey; - this.c = blockposition; - this.g = enumblockrotation; - this.e = f; - this.d = worldgenfeatureoceanruin_temperature; - this.h = flag; - this.a(definedstructuremanager); - } - - private void a(DefinedStructureManager definedstructuremanager) { - DefinedStructure definedstructure = definedstructuremanager.a(this.f); - DefinedStructureInfo definedstructureinfo = (new DefinedStructureInfo()).a(this.g).a(EnumBlockMirror.NONE).a(Blocks.AIR); - - this.a(definedstructure, this.c, definedstructureinfo); - } - - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.setString("Template", this.f.toString()); - nbttagcompound.setString("Rot", this.g.name()); - nbttagcompound.setFloat("Integrity", this.e); - nbttagcompound.setString("BiomeType", this.d.toString()); - nbttagcompound.setBoolean("IsLarge", this.h); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.f = new MinecraftKey(nbttagcompound.getString("Template")); - this.g = EnumBlockRotation.valueOf(nbttagcompound.getString("Rot")); - this.e = nbttagcompound.getFloat("Integrity"); - this.d = WorldGenFeatureOceanRuin.Temperature.valueOf(nbttagcompound.getString("BiomeType")); - this.h = nbttagcompound.getBoolean("IsLarge"); - this.a(definedstructuremanager); - } - - protected void a(String s, BlockPosition blockposition, GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - if ("chest".equals(s)) { - generatoraccess.setTypeAndData(blockposition, (IBlockData) Blocks.CHEST.getBlockData().set(BlockChest.c, generatoraccess.getFluid(blockposition).a(TagsFluid.WATER)), 2); - TileEntity tileentity = generatoraccess.getTileEntity(blockposition); - - if (tileentity instanceof TileEntityChest) { - ((TileEntityChest) tileentity).setLootTable(this.h ? LootTables.q : LootTables.p, random.nextLong()); - } - } else if ("drowned".equals(s)) { - EntityDrowned entitydrowned = EntityTypes.DROWNED.create(generatoraccess.getMinecraftWorld()); // Paper - entitydrowned.di(); - entitydrowned.setPositionRotation(blockposition, 0.0F, 0.0F); - entitydrowned.prepare(generatoraccess.getDamageScaler(blockposition), (GroupDataEntity) null, (NBTTagCompound) null); - generatoraccess.addEntity(entitydrowned); - if (blockposition.getY() > generatoraccess.getSeaLevel()) { - generatoraccess.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 2); - } else { - generatoraccess.setTypeAndData(blockposition, Blocks.WATER.getBlockData(), 2); - } - } - - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - this.b.a(this.e); - int i = generatoraccess.a(HeightMap.Type.OCEAN_FLOOR_WG, this.c.getX(), this.c.getZ()); - - this.c = new BlockPosition(this.c.getX(), i, this.c.getZ()); - BlockPosition blockposition = DefinedStructure.a(new BlockPosition(this.a.a().getX() - 1, 0, this.a.a().getZ() - 1), EnumBlockMirror.NONE, this.g, new BlockPosition(0, 0, 0)).a((BaseBlockPosition) this.c); - - this.c = new BlockPosition(this.c.getX(), this.a(this.c, (IBlockAccess) generatoraccess, blockposition), this.c.getZ()); - return super.a(generatoraccess, random, structureboundingbox, chunkcoordintpair); - } - - private int a(BlockPosition blockposition, IBlockAccess iblockaccess, BlockPosition blockposition1) { - int i = blockposition.getY(); - int j = 512; - int k = i - 1; - int l = 0; - Iterator iterator = BlockPosition.a(blockposition, blockposition1).iterator(); - - while (iterator.hasNext()) { - BlockPosition blockposition2 = (BlockPosition) iterator.next(); - int i1 = blockposition2.getX(); - int j1 = blockposition2.getZ(); - int k1 = blockposition.getY() - 1; - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(i1, k1, j1); - IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); - - for (Fluid fluid = iblockaccess.getFluid(blockposition_mutableblockposition); (iblockdata.isAir() || fluid.a(TagsFluid.WATER) || iblockdata.getBlock().a(TagsBlock.ICE)) && k1 > 1; fluid = iblockaccess.getFluid(blockposition_mutableblockposition)) { - --k1; - blockposition_mutableblockposition.c(i1, k1, j1); - iblockdata = iblockaccess.getType(blockposition_mutableblockposition); - } - - j = Math.min(j, k1); - if (k1 < k - 2) { - ++l; - } - } - - int l1 = Math.abs(blockposition.getX() - blockposition1.getX()); - - if (k - j > 2 && l > l1 - 2) { - i = j + 1; - } - - return i; - } - } -} diff --git a/src/main/java/net/minecraft/server/WorldGenFeaturePillagerOutpost.java b/src/main/java/net/minecraft/server/WorldGenFeaturePillagerOutpost.java new file mode 100644 index 000000000..5da5605cf --- /dev/null +++ b/src/main/java/net/minecraft/server/WorldGenFeaturePillagerOutpost.java @@ -0,0 +1,90 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.mojang.datafixers.Dynamic; +import java.util.List; +import java.util.Random; +import java.util.function.Function; + +public class WorldGenFeaturePillagerOutpost extends WorldGenFeatureRandomScattered { + + private static final List a = Lists.newArrayList(new BiomeBase.BiomeMeta[]{new BiomeBase.BiomeMeta(EntityTypes.PILLAGER, 1, 1, 1)}); + + public WorldGenFeaturePillagerOutpost(Function, ? extends WorldGenFeaturePillagerOutpostConfiguration> function) { + super(function); + } + + @Override + public String b() { + return "Pillager_Outpost"; + } + + @Override + public int c() { + return 3; + } + + @Override + public List e() { + return WorldGenFeaturePillagerOutpost.a; + } + + @Override + public boolean a(ChunkGenerator chunkgenerator, Random random, int i, int j) { + ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, random, i, j, 0, 0); + + if (i == chunkcoordintpair.x && j == chunkcoordintpair.z) { + int k = i >> 4; + int l = j >> 4; + + random.setSeed((long) (k ^ l << 4) ^ chunkgenerator.getSeed()); + random.nextInt(); + if (random.nextInt(5) != 0) { + return false; + } + + BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9)); + + if (chunkgenerator.canSpawnStructure(biomebase, WorldGenerator.PILLAGER_OUTPOST)) { + for (int i1 = i - 10; i1 <= i + 10; ++i1) { + for (int j1 = j - 10; j1 <= j + 10; ++j1) { + if (WorldGenerator.VILLAGE.a(chunkgenerator, random, i1, j1)) { + return false; + } + } + } + + return true; + } + } + + return false; + } + + @Override + public StructureGenerator.a a() { + return WorldGenFeaturePillagerOutpost.a::new; + } + + @Override + // Spigot start + protected int getSeed(World world) { + return world.spigotConfig.outpostSeed; + // Spigot end + } + + public static class a extends StructureAbstract { + + public a(StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); + } + + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + BlockPosition blockposition = new BlockPosition(i * 16, 90, j * 16); + + WorldGenFeaturePillagerOutpostPieces.a(chunkgenerator, definedstructuremanager, blockposition, this.b, this.d); + this.b(); + } + } +} diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureRandomScattered.java b/src/main/java/net/minecraft/server/WorldGenFeatureRandomScattered.java index c9c4e49b1..49ae612b1 100644 --- a/src/main/java/net/minecraft/server/WorldGenFeatureRandomScattered.java +++ b/src/main/java/net/minecraft/server/WorldGenFeatureRandomScattered.java @@ -1,11 +1,16 @@ package net.minecraft.server; +import com.mojang.datafixers.Dynamic; import java.util.Random; +import java.util.function.Function; public abstract class WorldGenFeatureRandomScattered extends StructureGenerator { - public WorldGenFeatureRandomScattered() {} + public WorldGenFeatureRandomScattered(Function, ? extends C> function) { + super(function); + } + @Override protected ChunkCoordIntPair a(ChunkGenerator chunkgenerator, Random random, int i, int j, int k, int l) { int i1 = this.a(chunkgenerator); int j1 = this.b(chunkgenerator); @@ -16,7 +21,7 @@ public abstract class WorldGenFeatureRandomScattered chunkgenerator, Random random, int i, int j) { + @Override + public boolean a(ChunkGenerator chunkgenerator, Random random, int i, int j) { ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, random, i, j, 0, 0); if (i == chunkcoordintpair.x && j == chunkcoordintpair.z) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition(i * 16 + 9, 0, j * 16 + 9), (BiomeBase) null); + BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition(i * 16 + 9, 0, j * 16 + 9)); if (chunkgenerator.canSpawnStructure(biomebase, this)) { return true; @@ -46,11 +52,5 @@ public abstract class WorldGenFeatureRandomScattered chunkgenerator, SeededRandom seededrandom, int i, int j); - - protected abstract int c(World world); // Spigot + protected abstract int getSeed(World world); // Spigot } diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureShipwreck.java b/src/main/java/net/minecraft/server/WorldGenFeatureShipwreck.java index f3b185d58..061eb2569 100644 --- a/src/main/java/net/minecraft/server/WorldGenFeatureShipwreck.java +++ b/src/main/java/net/minecraft/server/WorldGenFeatureShipwreck.java @@ -1,49 +1,60 @@ package net.minecraft.server; +import com.mojang.datafixers.Dynamic; +import java.util.function.Function; + public class WorldGenFeatureShipwreck extends WorldGenFeatureRandomScattered { - public WorldGenFeatureShipwreck() {} + public WorldGenFeatureShipwreck(Function, ? extends WorldGenFeatureShipwreckConfiguration> function) { + super(function); + } - protected String a() { + @Override + public String b() { return "Shipwreck"; } - public int b() { + @Override + public int c() { return 3; } - protected StructureStart a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), (BiomeBase) null); - - return new WorldGenFeatureShipwreck.a(generatoraccess, chunkgenerator, seededrandom, i, j, biomebase); + @Override + public StructureGenerator.a a() { + return WorldGenFeatureShipwreck.a::new; } + @Override // Spigot start - protected int c(World world) { + protected int getSeed(World world) { return world.spigotConfig.shipwreckSeed; // Spigot end } + @Override protected int a(ChunkGenerator chunkgenerator) { return chunkgenerator.getSettings().j(); } + @Override protected int b(ChunkGenerator chunkgenerator) { return chunkgenerator.getSettings().k(); } public static class a extends StructureStart { - public a() {} + public a(StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); + } - public a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j, BiomeBase biomebase) { - super(i, j, biomebase, seededrandom, generatoraccess.getSeed()); - WorldGenFeatureShipwreckConfiguration worldgenfeatureshipwreckconfiguration = (WorldGenFeatureShipwreckConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.k); - EnumBlockRotation enumblockrotation = EnumBlockRotation.values()[seededrandom.nextInt(EnumBlockRotation.values().length)]; + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + WorldGenFeatureShipwreckConfiguration worldgenfeatureshipwreckconfiguration = (WorldGenFeatureShipwreckConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.SHIPWRECK); + EnumBlockRotation enumblockrotation = EnumBlockRotation.values()[this.d.nextInt(EnumBlockRotation.values().length)]; BlockPosition blockposition = new BlockPosition(i * 16, 90, j * 16); - WorldGenShipwreck.a(generatoraccess.getDataManager().h(), blockposition, enumblockrotation, this.a, seededrandom, worldgenfeatureshipwreckconfiguration); - this.a((IBlockAccess) generatoraccess); + WorldGenShipwreck.a(definedstructuremanager, blockposition, enumblockrotation, this.b, this.d, worldgenfeatureshipwreckconfiguration); + this.b(); } } } diff --git a/src/main/java/net/minecraft/server/WorldGenFeatureSwampHut.java b/src/main/java/net/minecraft/server/WorldGenFeatureSwampHut.java index f0788eb5d..69f5f3ef6 100644 --- a/src/main/java/net/minecraft/server/WorldGenFeatureSwampHut.java +++ b/src/main/java/net/minecraft/server/WorldGenFeatureSwampHut.java @@ -1,42 +1,55 @@ package net.minecraft.server; import com.google.common.collect.Lists; +import com.mojang.datafixers.Dynamic; import java.util.List; +import java.util.function.Function; -public class WorldGenFeatureSwampHut extends WorldGenFeatureRandomScattered { +public class WorldGenFeatureSwampHut extends WorldGenFeatureRandomScattered { - private static final List b = Lists.newArrayList(new BiomeBase.BiomeMeta[] { new BiomeBase.BiomeMeta(EntityTypes.WITCH, 1, 1, 1)}); + private static final List a = Lists.newArrayList(new BiomeBase.BiomeMeta[]{new BiomeBase.BiomeMeta(EntityTypes.WITCH, 1, 1, 1)}); + private static final List aS = Lists.newArrayList(new BiomeBase.BiomeMeta[]{new BiomeBase.BiomeMeta(EntityTypes.CAT, 1, 1, 1)}); - public WorldGenFeatureSwampHut() {} + public WorldGenFeatureSwampHut(Function, ? extends WorldGenFeatureEmptyConfiguration> function) { + super(function); + } - protected String a() { + @Override + public String b() { return "Swamp_Hut"; } - public int b() { + @Override + public int c() { return 3; } - protected StructureStart a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), Biomes.PLAINS); - - return new WorldGenFeatureSwampHut.a(generatoraccess, seededrandom, i, j, biomebase); + @Override + public StructureGenerator.a a() { + return WorldGenFeatureSwampHut.a::new; } + @Override // Spigot start - protected int c(World world) { + protected int getSeed(World world) { return world.spigotConfig.swampSeed; // Spigot end } - public List d() { - return WorldGenFeatureSwampHut.b; + @Override + public List e() { + return WorldGenFeatureSwampHut.a; } - public boolean d(GeneratorAccess generatoraccess, BlockPosition blockposition) { - StructureStart structurestart = this.a(generatoraccess, blockposition); + @Override + public List f() { + return WorldGenFeatureSwampHut.aS; + } - if (structurestart != WorldGenFeatureSwampHut.a && structurestart instanceof WorldGenFeatureSwampHut.a && !structurestart.d().isEmpty()) { + public boolean c(GeneratorAccess generatoraccess, BlockPosition blockposition) { + StructureStart structurestart = this.a(generatoraccess, blockposition, true); + + if (structurestart != StructureStart.a && structurestart instanceof WorldGenFeatureSwampHut.a && !structurestart.d().isEmpty()) { StructurePiece structurepiece = (StructurePiece) structurestart.d().get(0); return structurepiece instanceof WorldGenWitchHut; @@ -47,14 +60,16 @@ public class WorldGenFeatureSwampHut extends WorldGenFeatureRandomScattered structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); + } - public a(GeneratorAccess generatoraccess, SeededRandom seededrandom, int i, int j, BiomeBase biomebase) { - super(i, j, biomebase, seededrandom, generatoraccess.getSeed()); - WorldGenWitchHut worldgenwitchhut = new WorldGenWitchHut(seededrandom, i * 16, j * 16); + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + WorldGenWitchHut worldgenwitchhut = new WorldGenWitchHut(this.d, i * 16, j * 16); - this.a.add(worldgenwitchhut); - this.a((IBlockAccess) generatoraccess); + this.b.add(worldgenwitchhut); + this.b(); } } } diff --git a/src/main/java/net/minecraft/server/WorldGenGroundBush.java b/src/main/java/net/minecraft/server/WorldGenGroundBush.java index 14dc3af54..fc70a3855 100644 --- a/src/main/java/net/minecraft/server/WorldGenGroundBush.java +++ b/src/main/java/net/minecraft/server/WorldGenGroundBush.java @@ -1,29 +1,27 @@ package net.minecraft.server; +import com.mojang.datafixers.Dynamic; import java.util.Random; import java.util.Set; +import java.util.function.Function; public class WorldGenGroundBush extends WorldGenTreeAbstract { private final IBlockData a; - private final IBlockData b; + private final IBlockData aS; - public WorldGenGroundBush(IBlockData iblockdata, IBlockData iblockdata1) { - super(false); - this.b = iblockdata; + public WorldGenGroundBush(Function, ? extends WorldGenFeatureEmptyConfiguration> function, IBlockData iblockdata, IBlockData iblockdata1) { + super(function, false); + this.aS = iblockdata; this.a = iblockdata1; } - public boolean a(Set set, GeneratorAccess generatoraccess, Random random, BlockPosition blockposition) { - for (IBlockData iblockdata = generatoraccess.getType(blockposition); (iblockdata.isAir() || iblockdata.a(TagsBlock.LEAVES)) && blockposition.getY() > 0; iblockdata = generatoraccess.getType(blockposition)) { - blockposition = blockposition.down(); - } - - Block block = generatoraccess.getType(blockposition).getBlock(); - - if (Block.d(block) || block == Blocks.GRASS_BLOCK) { + @Override + public boolean a(Set set, VirtualLevelWritable virtuallevelwritable, Random random, BlockPosition blockposition, StructureBoundingBox structureboundingbox) { + blockposition = virtuallevelwritable.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, blockposition).down(); + if (h(virtuallevelwritable, blockposition)) { blockposition = blockposition.up(); - this.a(set, generatoraccess, blockposition, this.b); + this.a(set, (IWorldWriter) virtuallevelwritable, blockposition, this.aS, structureboundingbox); for (int i = blockposition.getY(); i <= blockposition.getY() + 2; ++i) { int j = i - blockposition.getY(); @@ -37,10 +35,9 @@ public class WorldGenGroundBush extends WorldGenTreeAbstract= -1; --i) { for (int j = 0; j >= -1; --j) { @@ -31,17 +32,17 @@ public abstract class WorldGenMegaTreeProvider extends WorldGenTreeProvider { setTreeType(worldgentreeabstract); // CraftBukkit IBlockData iblockdata1 = Blocks.AIR.getBlockData(); - generatoraccess.setTypeAndData(blockposition.a(i, 0, j), iblockdata1, 4); - generatoraccess.setTypeAndData(blockposition.a(i + 1, 0, j), iblockdata1, 4); - generatoraccess.setTypeAndData(blockposition.a(i, 0, j + 1), iblockdata1, 4); - generatoraccess.setTypeAndData(blockposition.a(i + 1, 0, j + 1), iblockdata1, 4); - if (worldgentreeabstract.generate(generatoraccess, generatoraccess.getChunkProvider().getChunkGenerator(), random, blockposition.a(i, 0, j), WorldGenFeatureConfiguration.e)) { + generatoraccess.setTypeAndData(blockposition.b(i, 0, j), iblockdata1, 4); + generatoraccess.setTypeAndData(blockposition.b(i + 1, 0, j), iblockdata1, 4); + generatoraccess.setTypeAndData(blockposition.b(i, 0, j + 1), iblockdata1, 4); + generatoraccess.setTypeAndData(blockposition.b(i + 1, 0, j + 1), iblockdata1, 4); + if (worldgentreeabstract.generate(generatoraccess, generatoraccess.getChunkProvider().getChunkGenerator(), random, blockposition.b(i, 0, j), WorldGenFeatureConfiguration.e)) { return true; } else { - generatoraccess.setTypeAndData(blockposition.a(i, 0, j), iblockdata, 4); - generatoraccess.setTypeAndData(blockposition.a(i + 1, 0, j), iblockdata, 4); - generatoraccess.setTypeAndData(blockposition.a(i, 0, j + 1), iblockdata, 4); - generatoraccess.setTypeAndData(blockposition.a(i + 1, 0, j + 1), iblockdata, 4); + generatoraccess.setTypeAndData(blockposition.b(i, 0, j), iblockdata, 4); + generatoraccess.setTypeAndData(blockposition.b(i + 1, 0, j), iblockdata, 4); + generatoraccess.setTypeAndData(blockposition.b(i, 0, j + 1), iblockdata, 4); + generatoraccess.setTypeAndData(blockposition.b(i + 1, 0, j + 1), iblockdata, 4); return false; } } @@ -50,6 +51,6 @@ public abstract class WorldGenMegaTreeProvider extends WorldGenTreeProvider { public static boolean a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, int i, int j) { Block block = iblockdata.getBlock(); - return block == iblockaccess.getType(blockposition.a(i, 0, j)).getBlock() && block == iblockaccess.getType(blockposition.a(i + 1, 0, j)).getBlock() && block == iblockaccess.getType(blockposition.a(i, 0, j + 1)).getBlock() && block == iblockaccess.getType(blockposition.a(i + 1, 0, j + 1)).getBlock(); + return block == iblockaccess.getType(blockposition.b(i, 0, j)).getBlock() && block == iblockaccess.getType(blockposition.b(i + 1, 0, j)).getBlock() && block == iblockaccess.getType(blockposition.b(i, 0, j + 1)).getBlock() && block == iblockaccess.getType(blockposition.b(i + 1, 0, j + 1)).getBlock(); } } diff --git a/src/main/java/net/minecraft/server/WorldGenMonument.java b/src/main/java/net/minecraft/server/WorldGenMonument.java index 9a1795ad6..0f72e94a0 100644 --- a/src/main/java/net/minecraft/server/WorldGenMonument.java +++ b/src/main/java/net/minecraft/server/WorldGenMonument.java @@ -1,18 +1,22 @@ package net.minecraft.server; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; +import com.mojang.datafixers.Dynamic; import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.function.Function; -public class WorldGenMonument extends StructureGenerator { +public class WorldGenMonument extends StructureGenerator { - private static final List b = Lists.newArrayList(new BiomeBase.BiomeMeta[] { new BiomeBase.BiomeMeta(EntityTypes.GUARDIAN, 1, 2, 4)}); + private static final List a = Lists.newArrayList(new BiomeBase.BiomeMeta[]{new BiomeBase.BiomeMeta(EntityTypes.GUARDIAN, 1, 2, 4)}); - public WorldGenMonument() {} + public WorldGenMonument(Function, ? extends WorldGenFeatureEmptyConfiguration> function) { + super(function); + } + @Override protected ChunkCoordIntPair a(ChunkGenerator chunkgenerator, Random random, int i, int j, int k, int l) { int i1 = chunkgenerator.getSettings().c(); int j1 = chunkgenerator.getSettings().d(); @@ -31,7 +35,8 @@ public class WorldGenMonument extends StructureGenerator chunkgenerator, Random random, int i, int j) { + @Override + public boolean a(ChunkGenerator chunkgenerator, Random random, int i, int j) { ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, random, i, j, 0, 0); if (i == chunkcoordintpair.x && j == chunkcoordintpair.z) { @@ -53,13 +58,13 @@ public class WorldGenMonument extends StructureGenerator chunkgenerator, SeededRandom seededrandom, int i, int j) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), Biomes.b); - - return new WorldGenMonument.a(generatoraccess, seededrandom, i, j, biomebase); - } - - protected String a() { + @Override + public String b() { return "Monument"; } - public int b() { + @Override + public int c() { return 8; } - public List d() { - return WorldGenMonument.b; + @Override + public List e() { + return WorldGenMonument.a; } public static class a extends StructureStart { - private final Set e = Sets.newHashSet(); - private boolean f; + private boolean e; - public a() {} - - public a(GeneratorAccess generatoraccess, SeededRandom seededrandom, int i, int j, BiomeBase biomebase) { - super(i, j, biomebase, seededrandom, generatoraccess.getSeed()); - this.b(generatoraccess, seededrandom, i, j); + public a(StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); } - private void b(IBlockAccess iblockaccess, Random random, int i, int j) { + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + this.b(i, j); + } + + private void b(int i, int j) { int k = i * 16 - 29; int l = j * 16 - 29; - EnumDirection enumdirection = EnumDirection.EnumDirectionLimit.HORIZONTAL.a(random); + EnumDirection enumdirection = EnumDirection.EnumDirectionLimit.HORIZONTAL.a(this.d); - this.a.add(new WorldGenMonumentPieces.WorldGenMonumentPiece1(random, k, l, enumdirection)); - this.a(iblockaccess); - this.f = true; + this.b.add(new WorldGenMonumentPieces.WorldGenMonumentPiece1(this.d, k, l, enumdirection)); + this.b(); + this.e = true; } + @Override public void a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (!this.f) { - this.a.clear(); - this.b(generatoraccess, random, this.e(), this.f()); + if (!this.e) { + this.b.clear(); + this.b(this.f(), this.g()); } super.a(generatoraccess, random, structureboundingbox, chunkcoordintpair); } - - public void b(ChunkCoordIntPair chunkcoordintpair) { - super.b(chunkcoordintpair); - this.e.add(chunkcoordintpair); - } - - public void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - NBTTagList nbttaglist = new NBTTagList(); - Iterator iterator = this.e.iterator(); - - while (iterator.hasNext()) { - ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next(); - NBTTagCompound nbttagcompound1 = new NBTTagCompound(); - - nbttagcompound1.setInt("X", chunkcoordintpair.x); - nbttagcompound1.setInt("Z", chunkcoordintpair.z); - nbttaglist.add((NBTBase) nbttagcompound1); - } - - nbttagcompound.set("Processed", nbttaglist); - } - - public void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); - if (nbttagcompound.hasKeyOfType("Processed", 9)) { - NBTTagList nbttaglist = nbttagcompound.getList("Processed", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); - - this.e.add(new ChunkCoordIntPair(nbttagcompound1.getInt("X"), nbttagcompound1.getInt("Z"))); - } - } - - } } } diff --git a/src/main/java/net/minecraft/server/WorldGenMonumentPieces.java b/src/main/java/net/minecraft/server/WorldGenMonumentPieces.java deleted file mode 100644 index 493a86e1b..000000000 --- a/src/main/java/net/minecraft/server/WorldGenMonumentPieces.java +++ /dev/null @@ -1,1938 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Random; -import java.util.Set; - -public class WorldGenMonumentPieces { - - public static void a() { - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPiece1.class, "OMB"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPiece2.class, "OMCR"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPiece3.class, "OMDXR"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPiece4.class, "OMDXYR"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPiece5.class, "OMDYR"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPiece6.class, "OMDYZR"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPiece7.class, "OMDZR"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPieceEntry.class, "OMEntry"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.class, "OMPenthouse"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPieceSimple.class, "OMSimple"); - WorldGenFactory.a(WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.class, "OMSimpleT"); - } - - static class WorldGenMonumentPieceSelector4 implements WorldGenMonumentPieces.IWorldGenMonumentPieceSelector { - - private WorldGenMonumentPieceSelector4() {} - - public boolean a(WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker) { - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.NORTH.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.NORTH.a()].d && worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.UP.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()].d) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker1 = worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.NORTH.a()]; - - return worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.UP.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker1.b[EnumDirection.UP.a()].d; - } else { - return false; - } - } - - public WorldGenMonumentPieces.WorldGenMonumentPiece a(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - worldgenmonumentpieces_worldgenmonumentstatetracker.d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.NORTH.a()].d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()].d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.NORTH.a()].b[EnumDirection.UP.a()].d = true; - return new WorldGenMonumentPieces.WorldGenMonumentPiece6(enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, random); - } - } - - static class WorldGenMonumentPieceSelector6 implements WorldGenMonumentPieces.IWorldGenMonumentPieceSelector { - - private WorldGenMonumentPieceSelector6() {} - - public boolean a(WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker) { - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.EAST.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.EAST.a()].d && worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.UP.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()].d) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker1 = worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.EAST.a()]; - - return worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.UP.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker1.b[EnumDirection.UP.a()].d; - } else { - return false; - } - } - - public WorldGenMonumentPieces.WorldGenMonumentPiece a(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - worldgenmonumentpieces_worldgenmonumentstatetracker.d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.EAST.a()].d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()].d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.EAST.a()].b[EnumDirection.UP.a()].d = true; - return new WorldGenMonumentPieces.WorldGenMonumentPiece4(enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, random); - } - } - - static class WorldGenMonumentPieceSelector3 implements WorldGenMonumentPieces.IWorldGenMonumentPieceSelector { - - private WorldGenMonumentPieceSelector3() {} - - public boolean a(WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker) { - return worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.NORTH.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.NORTH.a()].d; - } - - public WorldGenMonumentPieces.WorldGenMonumentPiece a(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker1 = worldgenmonumentpieces_worldgenmonumentstatetracker; - - if (!worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.NORTH.a()] || worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.NORTH.a()].d) { - worldgenmonumentpieces_worldgenmonumentstatetracker1 = worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.SOUTH.a()]; - } - - worldgenmonumentpieces_worldgenmonumentstatetracker1.d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker1.b[EnumDirection.NORTH.a()].d = true; - return new WorldGenMonumentPieces.WorldGenMonumentPiece7(enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker1, random); - } - } - - static class WorldGenMonumentPieceSelector7 implements WorldGenMonumentPieces.IWorldGenMonumentPieceSelector { - - private WorldGenMonumentPieceSelector7() {} - - public boolean a(WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker) { - return worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.EAST.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.EAST.a()].d; - } - - public WorldGenMonumentPieces.WorldGenMonumentPiece a(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - worldgenmonumentpieces_worldgenmonumentstatetracker.d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.EAST.a()].d = true; - return new WorldGenMonumentPieces.WorldGenMonumentPiece3(enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, random); - } - } - - static class WorldGenMonumentPieceSelector5 implements WorldGenMonumentPieces.IWorldGenMonumentPieceSelector { - - private WorldGenMonumentPieceSelector5() {} - - public boolean a(WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker) { - return worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.UP.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()].d; - } - - public WorldGenMonumentPieces.WorldGenMonumentPiece a(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - worldgenmonumentpieces_worldgenmonumentstatetracker.d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()].d = true; - return new WorldGenMonumentPieces.WorldGenMonumentPiece5(enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, random); - } - } - - static class WorldGenMonumentPieceSelector1 implements WorldGenMonumentPieces.IWorldGenMonumentPieceSelector { - - private WorldGenMonumentPieceSelector1() {} - - public boolean a(WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker) { - return !worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.WEST.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.EAST.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.NORTH.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.SOUTH.a()] && !worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.UP.a()]; - } - - public WorldGenMonumentPieces.WorldGenMonumentPiece a(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - worldgenmonumentpieces_worldgenmonumentstatetracker.d = true; - return new WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT(enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, random); - } - } - - static class WorldGenMonumentPieceSelector2 implements WorldGenMonumentPieces.IWorldGenMonumentPieceSelector { - - private WorldGenMonumentPieceSelector2() {} - - public boolean a(WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker) { - return true; - } - - public WorldGenMonumentPieces.WorldGenMonumentPiece a(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - worldgenmonumentpieces_worldgenmonumentstatetracker.d = true; - return new WorldGenMonumentPieces.WorldGenMonumentPieceSimple(enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, random); - } - } - - interface IWorldGenMonumentPieceSelector { - - boolean a(WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker); - - WorldGenMonumentPieces.WorldGenMonumentPiece a(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random); - } - - static class WorldGenMonumentStateTracker { - - private final int a; - private final WorldGenMonumentPieces.WorldGenMonumentStateTracker[] b = new WorldGenMonumentPieces.WorldGenMonumentStateTracker[6]; - private final boolean[] c = new boolean[6]; - private boolean d; - private boolean e; - private int f; - - public WorldGenMonumentStateTracker(int i) { - this.a = i; - } - - public void a(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker) { - this.b[enumdirection.a()] = worldgenmonumentpieces_worldgenmonumentstatetracker; - worldgenmonumentpieces_worldgenmonumentstatetracker.b[enumdirection.opposite().a()] = this; - } - - public void a() { - for (int i = 0; i < 6; ++i) { - this.c[i] = this.b[i] != null; - } - - } - - public boolean a(int i) { - if (this.e) { - return true; - } else { - this.f = i; - - for (int j = 0; j < 6; ++j) { - if (this.b[j] != null && this.c[j] && this.b[j].f != i && this.b[j].a(i)) { - return true; - } - } - - return false; - } - } - - public boolean b() { - return this.a >= 75; - } - - public int c() { - int i = 0; - - for (int j = 0; j < 6; ++j) { - if (this.c[j]) { - ++i; - } - } - - return i; - } - } - - public static class WorldGenMonumentPiecePenthouse extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - public WorldGenMonumentPiecePenthouse() {} - - public WorldGenMonumentPiecePenthouse(EnumDirection enumdirection, StructureBoundingBox structureboundingbox) { - super(enumdirection, structureboundingbox); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - this.a(generatoraccess, structureboundingbox, 2, -1, 2, 11, -1, 11, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - this.a(generatoraccess, structureboundingbox, 0, -1, 0, 1, -1, 11, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.a, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.a, false); - this.a(generatoraccess, structureboundingbox, 12, -1, 0, 13, -1, 11, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.a, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.a, false); - this.a(generatoraccess, structureboundingbox, 2, -1, 0, 11, -1, 1, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.a, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.a, false); - this.a(generatoraccess, structureboundingbox, 2, -1, 12, 11, -1, 13, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.a, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.a, false); - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 0, 0, 13, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - this.a(generatoraccess, structureboundingbox, 13, 0, 0, 13, 0, 13, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 0, 12, 0, 0, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 13, 12, 0, 13, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - - for (int i = 2; i <= 11; i += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.e, 0, 0, i, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.e, 13, 0, i, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.e, i, 0, 0, structureboundingbox); - } - - this.a(generatoraccess, structureboundingbox, 2, 0, 3, 4, 0, 9, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - this.a(generatoraccess, structureboundingbox, 9, 0, 3, 11, 0, 9, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - this.a(generatoraccess, structureboundingbox, 4, 0, 9, 9, 0, 11, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, 5, 0, 8, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, 8, 0, 8, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, 10, 0, 10, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, 3, 0, 10, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 3, 0, 3, 3, 0, 7, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.c, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.c, false); - this.a(generatoraccess, structureboundingbox, 10, 0, 3, 10, 0, 7, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.c, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.c, false); - this.a(generatoraccess, structureboundingbox, 6, 0, 10, 7, 0, 10, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.c, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.c, false); - byte b0 = 3; - - for (int j = 0; j < 2; ++j) { - for (int k = 2; k <= 8; k += 3) { - this.a(generatoraccess, structureboundingbox, b0, 0, k, b0, 2, k, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - } - - b0 = 10; - } - - this.a(generatoraccess, structureboundingbox, 5, 0, 10, 5, 2, 10, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - this.a(generatoraccess, structureboundingbox, 8, 0, 10, 8, 2, 10, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.b, false); - this.a(generatoraccess, structureboundingbox, 6, -1, 7, 7, -1, 8, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.c, WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse.c, false); - this.a(generatoraccess, structureboundingbox, 6, -1, 3, 7, -1, 4); - this.a(generatoraccess, structureboundingbox, 6, 1, 6); - return true; - } - } - - public static class WorldGenMonumentPiece8 extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - private int p; - - public WorldGenMonumentPiece8() {} - - public WorldGenMonumentPiece8(EnumDirection enumdirection, StructureBoundingBox structureboundingbox, int i) { - super(enumdirection, structureboundingbox); - this.p = i & 1; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.p == 0) { - int i; - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, 10 - i, 3 - i, 20 - i, 12 + i, 3 - i, 20, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - } - - this.a(generatoraccess, structureboundingbox, 7, 0, 6, 15, 0, 16, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 6, 0, 6, 6, 3, 20, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 16, 0, 6, 16, 3, 20, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 7, 7, 1, 20, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 15, 1, 7, 15, 1, 20, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 6, 9, 3, 6, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 13, 1, 6, 15, 3, 6, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 8, 1, 7, 9, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 13, 1, 7, 14, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 9, 0, 5, 13, 0, 5, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 10, 0, 7, 12, 0, 7, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, false); - this.a(generatoraccess, structureboundingbox, 8, 0, 10, 8, 0, 12, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, false); - this.a(generatoraccess, structureboundingbox, 14, 0, 10, 14, 0, 12, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, false); - - for (i = 18; i >= 7; i -= 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 6, 3, i, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 16, 3, i, structureboundingbox); - } - - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 10, 0, 10, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 12, 0, 10, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 10, 0, 12, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 12, 0, 12, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 8, 3, 6, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 14, 3, 6, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 4, 2, 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 4, 1, 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 4, 0, 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 18, 2, 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 18, 1, 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 18, 0, 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 4, 2, 18, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 4, 1, 18, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 4, 0, 18, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 18, 2, 18, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, 18, 1, 18, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 18, 0, 18, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 9, 7, 20, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, 13, 7, 20, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 6, 0, 21, 7, 4, 21, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 15, 0, 21, 16, 4, 21, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 11, 2, 16); - } else if (this.p == 1) { - this.a(generatoraccess, structureboundingbox, 9, 3, 18, 13, 3, 20, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 9, 0, 18, 9, 2, 18, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, 13, 0, 18, 13, 2, 18, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - byte b0 = 9; - boolean flag = true; - boolean flag1 = true; - - int j; - - for (j = 0; j < 2; ++j) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, b0, 6, 20, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, b0, 5, 20, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, b0, 4, 20, structureboundingbox); - b0 = 13; - } - - this.a(generatoraccess, structureboundingbox, 7, 3, 7, 15, 3, 14, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - b0 = 10; - - for (j = 0; j < 2; ++j) { - this.a(generatoraccess, structureboundingbox, b0, 0, 10, b0, 6, 10, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, b0, 0, 12, b0, 6, 12, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, b0, 0, 10, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, b0, 0, 12, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, b0, 4, 10, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece8.e, b0, 4, 12, structureboundingbox); - b0 = 12; - } - - b0 = 8; - - for (j = 0; j < 2; ++j) { - this.a(generatoraccess, structureboundingbox, b0, 0, 7, b0, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - this.a(generatoraccess, structureboundingbox, b0, 0, 14, b0, 2, 14, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, WorldGenMonumentPieces.WorldGenMonumentPiece8.b, false); - b0 = 14; - } - - this.a(generatoraccess, structureboundingbox, 8, 3, 8, 8, 3, 13, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, false); - this.a(generatoraccess, structureboundingbox, 14, 3, 8, 14, 3, 13, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, WorldGenMonumentPieces.WorldGenMonumentPiece8.c, false); - this.a(generatoraccess, structureboundingbox, 11, 5, 13); - } - - return true; - } - } - - public static class WorldGenMonumentPiece2 extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - public WorldGenMonumentPiece2() {} - - public WorldGenMonumentPiece2(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - super(1, enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, 2, 2, 2); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - this.a(generatoraccess, structureboundingbox, 1, 8, 0, 14, 8, 14, WorldGenMonumentPieces.WorldGenMonumentPiece2.a); - boolean flag = true; - IBlockData iblockdata = WorldGenMonumentPieces.WorldGenMonumentPiece2.b; - - this.a(generatoraccess, structureboundingbox, 0, 7, 0, 0, 7, 15, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 15, 7, 0, 15, 7, 15, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 7, 0, 15, 7, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 7, 15, 14, 7, 15, iblockdata, iblockdata, false); - - int i; - - for (i = 1; i <= 6; ++i) { - iblockdata = WorldGenMonumentPieces.WorldGenMonumentPiece2.b; - if (i == 2 || i == 6) { - iblockdata = WorldGenMonumentPieces.WorldGenMonumentPiece2.a; - } - - for (int j = 0; j <= 15; j += 15) { - this.a(generatoraccess, structureboundingbox, j, i, 0, j, i, 1, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, j, i, 6, j, i, 9, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, j, i, 14, j, i, 15, iblockdata, iblockdata, false); - } - - this.a(generatoraccess, structureboundingbox, 1, i, 0, 1, i, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 6, i, 0, 9, i, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 14, i, 0, 14, i, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, i, 15, 14, i, 15, iblockdata, iblockdata, false); - } - - this.a(generatoraccess, structureboundingbox, 6, 3, 6, 9, 6, 9, WorldGenMonumentPieces.WorldGenMonumentPiece2.c, WorldGenMonumentPieces.WorldGenMonumentPiece2.c, false); - this.a(generatoraccess, structureboundingbox, 7, 4, 7, 8, 5, 8, Blocks.GOLD_BLOCK.getBlockData(), Blocks.GOLD_BLOCK.getBlockData(), false); - - for (i = 3; i <= 6; i += 3) { - for (int k = 6; k <= 9; k += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece2.e, k, i, 6, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece2.e, k, i, 9, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 5, 1, 6, 5, 2, 6, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 9, 5, 2, 9, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 10, 1, 6, 10, 2, 6, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 10, 1, 9, 10, 2, 9, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 5, 6, 2, 5, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 9, 1, 5, 9, 2, 5, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 10, 6, 2, 10, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 9, 1, 10, 9, 2, 10, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 5, 2, 5, 5, 6, 5, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 5, 2, 10, 5, 6, 10, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 10, 2, 5, 10, 6, 5, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 10, 2, 10, 10, 6, 10, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 5, 7, 1, 5, 7, 6, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 10, 7, 1, 10, 7, 6, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 5, 7, 9, 5, 7, 14, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 10, 7, 9, 10, 7, 14, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 1, 7, 5, 6, 7, 5, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 1, 7, 10, 6, 7, 10, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 9, 7, 5, 14, 7, 5, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 9, 7, 10, 14, 7, 10, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 2, 1, 2, 2, 1, 3, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 2, 3, 1, 2, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 13, 1, 2, 13, 1, 3, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 12, 1, 2, 12, 1, 2, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 2, 1, 12, 2, 1, 13, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 13, 3, 1, 13, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 13, 1, 12, 13, 1, 13, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - this.a(generatoraccess, structureboundingbox, 12, 1, 13, 12, 1, 13, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, WorldGenMonumentPieces.WorldGenMonumentPiece2.b, false); - return true; - } - } - - public static class WorldGenMonumentPiece6 extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - public WorldGenMonumentPiece6() {} - - public WorldGenMonumentPiece6(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - super(1, enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, 1, 2, 2); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker = this.l.b[EnumDirection.NORTH.a()]; - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker1 = this.l; - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker2 = worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()]; - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker3 = worldgenmonumentpieces_worldgenmonumentstatetracker1.b[EnumDirection.UP.a()]; - - if (this.l.a / 25 > 0) { - this.a(generatoraccess, structureboundingbox, 0, 8, worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.DOWN.a()]); - this.a(generatoraccess, structureboundingbox, 0, 0, worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.DOWN.a()]); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker3.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 1, 8, 1, 6, 8, 7, WorldGenMonumentPieces.WorldGenMonumentPiece6.a); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker2.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 1, 8, 8, 6, 8, 14, WorldGenMonumentPieces.WorldGenMonumentPiece6.a); - } - - IBlockData iblockdata; - int i; - - for (i = 1; i <= 7; ++i) { - iblockdata = WorldGenMonumentPieces.WorldGenMonumentPiece6.b; - if (i == 2 || i == 6) { - iblockdata = WorldGenMonumentPieces.WorldGenMonumentPiece6.a; - } - - this.a(generatoraccess, structureboundingbox, 0, i, 0, 0, i, 15, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 7, i, 0, 7, i, 15, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, i, 0, 6, i, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, i, 15, 6, i, 15, iblockdata, iblockdata, false); - } - - for (i = 1; i <= 7; ++i) { - iblockdata = WorldGenMonumentPieces.WorldGenMonumentPiece6.c; - if (i == 2 || i == 6) { - iblockdata = WorldGenMonumentPieces.WorldGenMonumentPiece6.e; - } - - this.a(generatoraccess, structureboundingbox, 3, i, 7, 4, i, 8, iblockdata, iblockdata, false); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 4, 2, 0); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 7, 1, 3, 7, 2, 4); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 1, 3, 0, 2, 4); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 15, 4, 2, 15); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 1, 11, 0, 2, 12); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 7, 1, 11, 7, 2, 12); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker3.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 5, 0, 4, 6, 0); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker3.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 7, 5, 3, 7, 6, 4); - this.a(generatoraccess, structureboundingbox, 5, 4, 2, 6, 4, 5, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 2, 6, 3, 2, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 5, 6, 3, 5, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker3.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 5, 3, 0, 6, 4); - this.a(generatoraccess, structureboundingbox, 1, 4, 2, 2, 4, 5, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 2, 1, 3, 2, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 5, 1, 3, 5, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker2.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 5, 15, 4, 6, 15); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker2.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 5, 11, 0, 6, 12); - this.a(generatoraccess, structureboundingbox, 1, 4, 10, 2, 4, 13, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 10, 1, 3, 10, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 13, 1, 3, 13, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker2.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 7, 5, 11, 7, 6, 12); - this.a(generatoraccess, structureboundingbox, 5, 4, 10, 6, 4, 13, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 10, 6, 3, 10, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 13, 6, 3, 13, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, WorldGenMonumentPieces.WorldGenMonumentPiece6.b, false); - } - - return true; - } - } - - public static class WorldGenMonumentPiece4 extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - public WorldGenMonumentPiece4() {} - - public WorldGenMonumentPiece4(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - super(1, enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, 2, 2, 1); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker = this.l.b[EnumDirection.EAST.a()]; - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker1 = this.l; - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker2 = worldgenmonumentpieces_worldgenmonumentstatetracker1.b[EnumDirection.UP.a()]; - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker3 = worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()]; - - if (this.l.a / 25 > 0) { - this.a(generatoraccess, structureboundingbox, 8, 0, worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.DOWN.a()]); - this.a(generatoraccess, structureboundingbox, 0, 0, worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.DOWN.a()]); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker2.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 1, 8, 1, 7, 8, 6, WorldGenMonumentPieces.WorldGenMonumentPiece4.a); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker3.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 8, 8, 1, 14, 8, 6, WorldGenMonumentPieces.WorldGenMonumentPiece4.a); - } - - for (int i = 1; i <= 7; ++i) { - IBlockData iblockdata = WorldGenMonumentPieces.WorldGenMonumentPiece4.b; - - if (i == 2 || i == 6) { - iblockdata = WorldGenMonumentPieces.WorldGenMonumentPiece4.a; - } - - this.a(generatoraccess, structureboundingbox, 0, i, 0, 0, i, 7, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 15, i, 0, 15, i, 7, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, i, 0, 15, i, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, i, 7, 14, i, 7, iblockdata, iblockdata, false); - } - - this.a(generatoraccess, structureboundingbox, 2, 1, 3, 2, 7, 4, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 2, 4, 7, 2, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 5, 4, 7, 5, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 13, 1, 3, 13, 7, 4, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 11, 1, 2, 12, 7, 2, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 11, 1, 5, 12, 7, 5, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 3, 5, 3, 4, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 10, 1, 3, 10, 3, 4, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 5, 7, 2, 10, 7, 5, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 5, 5, 2, 5, 7, 2, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 10, 5, 2, 10, 7, 2, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 5, 5, 5, 5, 7, 5, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 10, 5, 5, 10, 7, 5, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, 6, 6, 2, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, 9, 6, 2, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, 6, 6, 5, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, 9, 6, 5, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 5, 4, 3, 6, 4, 4, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, structureboundingbox, 9, 4, 3, 10, 4, 4, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, WorldGenMonumentPieces.WorldGenMonumentPiece4.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece4.e, 5, 4, 2, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece4.e, 5, 4, 5, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece4.e, 10, 4, 2, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece4.e, 10, 4, 5, structureboundingbox); - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 4, 2, 0); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 7, 4, 2, 7); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 1, 3, 0, 2, 4); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 11, 1, 0, 12, 2, 0); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 11, 1, 7, 12, 2, 7); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 15, 1, 3, 15, 2, 4); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker2.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 5, 0, 4, 6, 0); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker2.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 5, 7, 4, 6, 7); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker2.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 5, 3, 0, 6, 4); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker3.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 11, 5, 0, 12, 6, 0); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker3.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 11, 5, 7, 12, 6, 7); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker3.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 15, 5, 3, 15, 6, 4); - } - - return true; - } - } - - public static class WorldGenMonumentPiece7 extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - public WorldGenMonumentPiece7() {} - - public WorldGenMonumentPiece7(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - super(1, enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, 1, 1, 2); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker = this.l.b[EnumDirection.NORTH.a()]; - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker1 = this.l; - - if (this.l.a / 25 > 0) { - this.a(generatoraccess, structureboundingbox, 0, 8, worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.DOWN.a()]); - this.a(generatoraccess, structureboundingbox, 0, 0, worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.DOWN.a()]); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 1, 4, 1, 6, 4, 7, WorldGenMonumentPieces.WorldGenMonumentPiece7.a); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 1, 4, 8, 6, 4, 14, WorldGenMonumentPieces.WorldGenMonumentPiece7.a); - } - - this.a(generatoraccess, structureboundingbox, 0, 3, 0, 0, 3, 15, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 7, 3, 0, 7, 3, 15, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 0, 7, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 15, 6, 3, 15, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 0, 0, 2, 15, WorldGenMonumentPieces.WorldGenMonumentPiece7.a, WorldGenMonumentPieces.WorldGenMonumentPiece7.a, false); - this.a(generatoraccess, structureboundingbox, 7, 2, 0, 7, 2, 15, WorldGenMonumentPieces.WorldGenMonumentPiece7.a, WorldGenMonumentPieces.WorldGenMonumentPiece7.a, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 0, 7, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPiece7.a, WorldGenMonumentPieces.WorldGenMonumentPiece7.a, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 15, 6, 2, 15, WorldGenMonumentPieces.WorldGenMonumentPiece7.a, WorldGenMonumentPieces.WorldGenMonumentPiece7.a, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 0, 1, 15, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 0, 7, 1, 15, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 0, 7, 1, 0, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 15, 6, 1, 15, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 1, 1, 1, 2, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 1, 6, 1, 2, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 1, 1, 3, 2, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 6, 3, 1, 6, 3, 2, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 13, 1, 1, 14, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 13, 6, 1, 14, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 13, 1, 3, 14, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 6, 3, 13, 6, 3, 14, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 2, 1, 6, 2, 3, 6, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 6, 5, 3, 6, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 2, 1, 9, 2, 3, 9, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 9, 5, 3, 9, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 3, 2, 6, 4, 2, 6, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 3, 2, 9, 4, 2, 9, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 2, 2, 7, 2, 2, 8, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, structureboundingbox, 5, 2, 7, 5, 2, 8, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece7.e, 2, 2, 5, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece7.e, 5, 2, 5, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece7.e, 2, 2, 10, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece7.e, 5, 2, 10, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, 2, 3, 5, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, 5, 3, 5, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, 2, 3, 10, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece7.b, 5, 3, 10, structureboundingbox); - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 4, 2, 0); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 7, 1, 3, 7, 2, 4); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 1, 3, 0, 2, 4); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 15, 4, 2, 15); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 1, 11, 0, 2, 12); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 7, 1, 11, 7, 2, 12); - } - - return true; - } - } - - public static class WorldGenMonumentPiece3 extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - public WorldGenMonumentPiece3() {} - - public WorldGenMonumentPiece3(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - super(1, enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, 2, 1, 1); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker = this.l.b[EnumDirection.EAST.a()]; - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker1 = this.l; - - if (this.l.a / 25 > 0) { - this.a(generatoraccess, structureboundingbox, 8, 0, worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.DOWN.a()]); - this.a(generatoraccess, structureboundingbox, 0, 0, worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.DOWN.a()]); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 1, 4, 1, 7, 4, 6, WorldGenMonumentPieces.WorldGenMonumentPiece3.a); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 8, 4, 1, 14, 4, 6, WorldGenMonumentPieces.WorldGenMonumentPiece3.a); - } - - this.a(generatoraccess, structureboundingbox, 0, 3, 0, 0, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, structureboundingbox, 15, 3, 0, 15, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 0, 15, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 7, 14, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 0, 0, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, false); - this.a(generatoraccess, structureboundingbox, 15, 2, 0, 15, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 0, 15, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 7, 14, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 0, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, structureboundingbox, 15, 1, 0, 15, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 0, 15, 1, 0, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 7, 14, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 0, 10, 1, 4, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, structureboundingbox, 6, 2, 0, 9, 2, 3, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, WorldGenMonumentPieces.WorldGenMonumentPiece3.a, false); - this.a(generatoraccess, structureboundingbox, 5, 3, 0, 10, 3, 4, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, WorldGenMonumentPieces.WorldGenMonumentPiece3.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece3.e, 6, 2, 3, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece3.e, 9, 2, 3, structureboundingbox); - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 4, 2, 0); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 7, 4, 2, 7); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 1, 3, 0, 2, 4); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 11, 1, 0, 12, 2, 0); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 11, 1, 7, 12, 2, 7); - } - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 15, 1, 3, 15, 2, 4); - } - - return true; - } - } - - public static class WorldGenMonumentPiece5 extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - public WorldGenMonumentPiece5() {} - - public WorldGenMonumentPiece5(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - super(1, enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, 1, 2, 1); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.l.a / 25 > 0) { - this.a(generatoraccess, structureboundingbox, 0, 0, this.l.c[EnumDirection.DOWN.a()]); - } - - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker = this.l.b[EnumDirection.UP.a()]; - - if (worldgenmonumentpieces_worldgenmonumentstatetracker.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 1, 8, 1, 6, 8, 6, WorldGenMonumentPieces.WorldGenMonumentPiece5.a); - } - - this.a(generatoraccess, structureboundingbox, 0, 4, 0, 0, 4, 7, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 7, 4, 0, 7, 4, 7, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 1, 4, 0, 6, 4, 0, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 1, 4, 7, 6, 4, 7, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 2, 4, 1, 2, 4, 2, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 1, 4, 2, 1, 4, 2, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 5, 4, 1, 5, 4, 2, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 6, 4, 2, 6, 4, 2, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 2, 4, 5, 2, 4, 6, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 1, 4, 5, 1, 4, 5, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 5, 4, 5, 5, 4, 6, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 6, 4, 5, 6, 4, 5, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker1 = this.l; - - for (int i = 1; i <= 5; i += 4) { - byte b0 = 0; - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 2, i, b0, 2, i + 2, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 5, i, b0, 5, i + 2, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 3, i + 2, b0, 4, i + 2, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - } else { - this.a(generatoraccess, structureboundingbox, 0, i, b0, 7, i + 2, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 0, i + 1, b0, 7, i + 1, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.a, WorldGenMonumentPieces.WorldGenMonumentPiece5.a, false); - } - - b0 = 7; - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 2, i, b0, 2, i + 2, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 5, i, b0, 5, i + 2, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 3, i + 2, b0, 4, i + 2, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - } else { - this.a(generatoraccess, structureboundingbox, 0, i, b0, 7, i + 2, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, 0, i + 1, b0, 7, i + 1, b0, WorldGenMonumentPieces.WorldGenMonumentPiece5.a, WorldGenMonumentPieces.WorldGenMonumentPiece5.a, false); - } - - byte b1 = 0; - - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, b1, i, 2, b1, i + 2, 2, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, b1, i, 5, b1, i + 2, 5, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, b1, i + 2, 3, b1, i + 2, 4, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - } else { - this.a(generatoraccess, structureboundingbox, b1, i, 0, b1, i + 2, 7, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, b1, i + 1, 0, b1, i + 1, 7, WorldGenMonumentPieces.WorldGenMonumentPiece5.a, WorldGenMonumentPieces.WorldGenMonumentPiece5.a, false); - } - - b1 = 7; - if (worldgenmonumentpieces_worldgenmonumentstatetracker1.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, b1, i, 2, b1, i + 2, 2, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, b1, i, 5, b1, i + 2, 5, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, b1, i + 2, 3, b1, i + 2, 4, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - } else { - this.a(generatoraccess, structureboundingbox, b1, i, 0, b1, i + 2, 7, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, WorldGenMonumentPieces.WorldGenMonumentPiece5.b, false); - this.a(generatoraccess, structureboundingbox, b1, i + 1, 0, b1, i + 1, 7, WorldGenMonumentPieces.WorldGenMonumentPiece5.a, WorldGenMonumentPieces.WorldGenMonumentPiece5.a, false); - } - - worldgenmonumentpieces_worldgenmonumentstatetracker1 = worldgenmonumentpieces_worldgenmonumentstatetracker; - } - - return true; - } - } - - public static class WorldGenMonumentPieceSimpleT extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - public WorldGenMonumentPieceSimpleT() {} - - public WorldGenMonumentPieceSimpleT(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - super(1, enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, 1, 1, 1); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.l.a / 25 > 0) { - this.a(generatoraccess, structureboundingbox, 0, 0, this.l.c[EnumDirection.DOWN.a()]); - } - - if (this.l.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 1, 4, 1, 6, 4, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.a); - } - - for (int i = 1; i <= 6; ++i) { - for (int j = 1; j <= 6; ++j) { - if (random.nextInt(3) != 0) { - int k = 2 + (random.nextInt(4) == 0 ? 0 : 1); - IBlockData iblockdata = Blocks.WET_SPONGE.getBlockData(); - - this.a(generatoraccess, structureboundingbox, i, k, j, i, 3, j, iblockdata, iblockdata, false); - } - } - } - - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 0, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 0, 7, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 0, 6, 1, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 7, 6, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 0, 0, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, false); - this.a(generatoraccess, structureboundingbox, 7, 2, 0, 7, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 0, 6, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 7, 6, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, false); - this.a(generatoraccess, structureboundingbox, 0, 3, 0, 0, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, false); - this.a(generatoraccess, structureboundingbox, 7, 3, 0, 7, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 0, 6, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 7, 6, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.b, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 3, 0, 2, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 3, 7, 2, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 4, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 7, 4, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimpleT.c, false); - if (this.l.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 4, 2, 0); - } - - return true; - } - } - - public static class WorldGenMonumentPieceSimple extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - private int p; - - public WorldGenMonumentPieceSimple() {} - - public WorldGenMonumentPieceSimple(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, Random random) { - super(1, enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, 1, 1, 1); - this.p = random.nextInt(3); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.l.a / 25 > 0) { - this.a(generatoraccess, structureboundingbox, 0, 0, this.l.c[EnumDirection.DOWN.a()]); - } - - if (this.l.b[EnumDirection.UP.a()] == null) { - this.a(generatoraccess, structureboundingbox, 1, 4, 1, 6, 4, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a); - } - - boolean flag = this.p != 0 && random.nextBoolean() && !this.l.c[EnumDirection.DOWN.a()] && !this.l.c[EnumDirection.UP.a()] && this.l.c() > 1; - - if (this.p == 0) { - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 2, 1, 2, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 3, 0, 2, 3, 2, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 0, 0, 2, 2, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 0, 2, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.e, 1, 2, 1, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 5, 1, 0, 7, 1, 2, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 5, 3, 0, 7, 3, 2, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 7, 2, 0, 7, 2, 2, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 5, 2, 0, 6, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.e, 6, 2, 1, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 0, 1, 5, 2, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 3, 5, 2, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 5, 0, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 7, 2, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.e, 1, 2, 6, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 5, 1, 5, 7, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 5, 3, 5, 7, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 7, 2, 5, 7, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 5, 2, 7, 6, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.e, 6, 2, 6, structureboundingbox); - if (this.l.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 3, 0, 4, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } else { - this.a(generatoraccess, structureboundingbox, 3, 3, 0, 4, 3, 1, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 3, 2, 0, 4, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 4, 1, 1, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } - - if (this.l.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 3, 7, 4, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } else { - this.a(generatoraccess, structureboundingbox, 3, 3, 6, 4, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 3, 2, 7, 4, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 6, 4, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } - - if (this.l.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 3, 3, 0, 3, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } else { - this.a(generatoraccess, structureboundingbox, 0, 3, 3, 1, 3, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 3, 0, 2, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 3, 1, 1, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } - - if (this.l.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 7, 3, 3, 7, 3, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } else { - this.a(generatoraccess, structureboundingbox, 6, 3, 3, 7, 3, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 7, 2, 3, 7, 2, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 3, 7, 1, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } - } else if (this.p == 1) { - this.a(generatoraccess, structureboundingbox, 2, 1, 2, 2, 3, 2, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 2, 1, 5, 2, 3, 5, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 5, 5, 3, 5, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 2, 5, 3, 2, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.e, 2, 2, 2, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.e, 2, 2, 5, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.e, 5, 2, 5, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.e, 5, 2, 2, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 1, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 1, 0, 3, 1, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 7, 1, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 6, 0, 3, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 7, 7, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 6, 7, 3, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 0, 7, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 1, 7, 3, 1, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, 1, 2, 0, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, 0, 2, 1, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, 1, 2, 7, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, 0, 2, 6, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, 6, 2, 7, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, 7, 2, 6, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, 6, 2, 0, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, 7, 2, 1, structureboundingbox); - if (!this.l.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 1, 3, 0, 6, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 0, 6, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 0, 6, 1, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } - - if (!this.l.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 1, 3, 7, 6, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 7, 6, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 7, 6, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } - - if (!this.l.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 3, 1, 0, 3, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 1, 0, 2, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 1, 0, 1, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } - - if (!this.l.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 7, 3, 1, 7, 3, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 7, 2, 1, 7, 2, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 1, 7, 1, 6, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } - } else if (this.p == 2) { - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 0, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 0, 7, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 0, 6, 1, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 7, 6, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 0, 0, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, false); - this.a(generatoraccess, structureboundingbox, 7, 2, 0, 7, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 0, 6, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 7, 6, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, false); - this.a(generatoraccess, structureboundingbox, 0, 3, 0, 0, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 7, 3, 0, 7, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 0, 6, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 7, 6, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 3, 0, 2, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 3, 7, 2, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 4, 2, 0, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 7, 4, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.c, false); - if (this.l.c[EnumDirection.SOUTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 4, 2, 0); - } - - if (this.l.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 7, 4, 2, 7); - } - - if (this.l.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 1, 3, 0, 2, 4); - } - - if (this.l.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 7, 1, 3, 7, 2, 4); - } - } - - if (flag) { - this.a(generatoraccess, structureboundingbox, 3, 1, 3, 4, 1, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - this.a(generatoraccess, structureboundingbox, 3, 2, 3, 4, 2, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.a, false); - this.a(generatoraccess, structureboundingbox, 3, 3, 3, 4, 3, 4, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, WorldGenMonumentPieces.WorldGenMonumentPieceSimple.b, false); - } - - return true; - } - } - - public static class WorldGenMonumentPieceEntry extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - public WorldGenMonumentPieceEntry() {} - - public WorldGenMonumentPieceEntry(EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker) { - super(1, enumdirection, worldgenmonumentpieces_worldgenmonumentstatetracker, 1, 1, 1); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - this.a(generatoraccess, structureboundingbox, 0, 3, 0, 2, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, false); - this.a(generatoraccess, structureboundingbox, 5, 3, 0, 7, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 0, 1, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, false); - this.a(generatoraccess, structureboundingbox, 6, 2, 0, 7, 2, 7, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 0, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 0, 7, 1, 7, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 7, 7, 3, 7, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 0, 2, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 0, 6, 3, 0, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, WorldGenMonumentPieces.WorldGenMonumentPieceEntry.b, false); - if (this.l.c[EnumDirection.NORTH.a()]) { - this.a(generatoraccess, structureboundingbox, 3, 1, 7, 4, 2, 7); - } - - if (this.l.c[EnumDirection.WEST.a()]) { - this.a(generatoraccess, structureboundingbox, 0, 1, 3, 1, 2, 4); - } - - if (this.l.c[EnumDirection.EAST.a()]) { - this.a(generatoraccess, structureboundingbox, 6, 1, 3, 7, 2, 4); - } - - return true; - } - } - - public static class WorldGenMonumentPiece1 extends WorldGenMonumentPieces.WorldGenMonumentPiece { - - private WorldGenMonumentPieces.WorldGenMonumentStateTracker p; - private WorldGenMonumentPieces.WorldGenMonumentStateTracker q; - private final List r = Lists.newArrayList(); - - public WorldGenMonumentPiece1() {} - - public WorldGenMonumentPiece1(Random random, int i, int j, EnumDirection enumdirection) { - super(0); - this.a(enumdirection); - EnumDirection enumdirection1 = this.f(); - - if (enumdirection1.k() == EnumDirection.EnumAxis.Z) { - this.n = new StructureBoundingBox(i, 39, j, i + 58 - 1, 61, j + 58 - 1); - } else { - this.n = new StructureBoundingBox(i, 39, j, i + 58 - 1, 61, j + 58 - 1); - } - - List list = this.a(random); - - this.p.d = true; - this.r.add(new WorldGenMonumentPieces.WorldGenMonumentPieceEntry(enumdirection1, this.p)); - this.r.add(new WorldGenMonumentPieces.WorldGenMonumentPiece2(enumdirection1, this.q, random)); - List list1 = Lists.newArrayList(); - - list1.add(new WorldGenMonumentPieces.WorldGenMonumentPieceSelector6()); - list1.add(new WorldGenMonumentPieces.WorldGenMonumentPieceSelector4()); - list1.add(new WorldGenMonumentPieces.WorldGenMonumentPieceSelector3()); - list1.add(new WorldGenMonumentPieces.WorldGenMonumentPieceSelector7()); - list1.add(new WorldGenMonumentPieces.WorldGenMonumentPieceSelector5()); - list1.add(new WorldGenMonumentPieces.WorldGenMonumentPieceSelector1()); - list1.add(new WorldGenMonumentPieces.WorldGenMonumentPieceSelector2()); - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker = (WorldGenMonumentPieces.WorldGenMonumentStateTracker) iterator.next(); - - if (!worldgenmonumentpieces_worldgenmonumentstatetracker.d && !worldgenmonumentpieces_worldgenmonumentstatetracker.b()) { - Iterator iterator1 = list1.iterator(); - - while (iterator1.hasNext()) { - WorldGenMonumentPieces.IWorldGenMonumentPieceSelector worldgenmonumentpieces_iworldgenmonumentpieceselector = (WorldGenMonumentPieces.IWorldGenMonumentPieceSelector) iterator1.next(); - - if (worldgenmonumentpieces_iworldgenmonumentpieceselector.a(worldgenmonumentpieces_worldgenmonumentstatetracker)) { - this.r.add(worldgenmonumentpieces_iworldgenmonumentpieceselector.a(enumdirection1, worldgenmonumentpieces_worldgenmonumentstatetracker, random)); - break; - } - } - } - } - - int k = this.n.b; - int l = this.a(9, 22); - int i1 = this.b(9, 22); - Iterator iterator2 = this.r.iterator(); - - while (iterator2.hasNext()) { - WorldGenMonumentPieces.WorldGenMonumentPiece worldgenmonumentpieces_worldgenmonumentpiece = (WorldGenMonumentPieces.WorldGenMonumentPiece) iterator2.next(); - - worldgenmonumentpieces_worldgenmonumentpiece.d().a(l, k, i1); - } - - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(this.a(1, 1), this.d(1), this.b(1, 1), this.a(23, 21), this.d(8), this.b(23, 21)); - StructureBoundingBox structureboundingbox1 = StructureBoundingBox.a(this.a(34, 1), this.d(1), this.b(34, 1), this.a(56, 21), this.d(8), this.b(56, 21)); - StructureBoundingBox structureboundingbox2 = StructureBoundingBox.a(this.a(22, 22), this.d(13), this.b(22, 22), this.a(35, 35), this.d(17), this.b(35, 35)); - int j1 = random.nextInt(); - - this.r.add(new WorldGenMonumentPieces.WorldGenMonumentPiece8(enumdirection1, structureboundingbox, j1++)); - this.r.add(new WorldGenMonumentPieces.WorldGenMonumentPiece8(enumdirection1, structureboundingbox1, j1++)); - this.r.add(new WorldGenMonumentPieces.WorldGenMonumentPiecePenthouse(enumdirection1, structureboundingbox2)); - } - - private List a(Random random) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker[] aworldgenmonumentpieces_worldgenmonumentstatetracker = new WorldGenMonumentPieces.WorldGenMonumentStateTracker[75]; - - boolean flag; - int i; - int j; - int k; - - for (j = 0; j < 5; ++j) { - for (k = 0; k < 4; ++k) { - flag = false; - i = b(j, 0, k); - aworldgenmonumentpieces_worldgenmonumentstatetracker[i] = new WorldGenMonumentPieces.WorldGenMonumentStateTracker(i); - } - } - - for (j = 0; j < 5; ++j) { - for (k = 0; k < 4; ++k) { - flag = true; - i = b(j, 1, k); - aworldgenmonumentpieces_worldgenmonumentstatetracker[i] = new WorldGenMonumentPieces.WorldGenMonumentStateTracker(i); - } - } - - for (j = 1; j < 4; ++j) { - for (k = 0; k < 2; ++k) { - flag = true; - i = b(j, 2, k); - aworldgenmonumentpieces_worldgenmonumentstatetracker[i] = new WorldGenMonumentPieces.WorldGenMonumentStateTracker(i); - } - } - - this.p = aworldgenmonumentpieces_worldgenmonumentstatetracker[WorldGenMonumentPieces.WorldGenMonumentPiece1.h]; - - int l; - int i1; - int j1; - int k1; - int l1; - - for (j = 0; j < 5; ++j) { - for (k = 0; k < 5; ++k) { - for (int i2 = 0; i2 < 3; ++i2) { - i = b(j, i2, k); - if (aworldgenmonumentpieces_worldgenmonumentstatetracker[i] != null) { - EnumDirection[] aenumdirection = EnumDirection.values(); - - l = aenumdirection.length; - - for (i1 = 0; i1 < l; ++i1) { - EnumDirection enumdirection = aenumdirection[i1]; - - j1 = j + enumdirection.getAdjacentX(); - k1 = i2 + enumdirection.getAdjacentY(); - l1 = k + enumdirection.getAdjacentZ(); - if (j1 >= 0 && j1 < 5 && l1 >= 0 && l1 < 5 && k1 >= 0 && k1 < 3) { - int j2 = b(j1, k1, l1); - - if (aworldgenmonumentpieces_worldgenmonumentstatetracker[j2] != null) { - if (l1 == k) { - aworldgenmonumentpieces_worldgenmonumentstatetracker[i].a(enumdirection, aworldgenmonumentpieces_worldgenmonumentstatetracker[j2]); - } else { - aworldgenmonumentpieces_worldgenmonumentstatetracker[i].a(enumdirection.opposite(), aworldgenmonumentpieces_worldgenmonumentstatetracker[j2]); - } - } - } - } - } - } - } - } - - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker = new WorldGenMonumentPieces.WorldGenMonumentStateTracker(1003); - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker1 = new WorldGenMonumentPieces.WorldGenMonumentStateTracker(1001); - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker2 = new WorldGenMonumentPieces.WorldGenMonumentStateTracker(1002); - - aworldgenmonumentpieces_worldgenmonumentstatetracker[WorldGenMonumentPieces.WorldGenMonumentPiece1.i].a(EnumDirection.UP, worldgenmonumentpieces_worldgenmonumentstatetracker); - aworldgenmonumentpieces_worldgenmonumentstatetracker[WorldGenMonumentPieces.WorldGenMonumentPiece1.j].a(EnumDirection.SOUTH, worldgenmonumentpieces_worldgenmonumentstatetracker1); - aworldgenmonumentpieces_worldgenmonumentstatetracker[WorldGenMonumentPieces.WorldGenMonumentPiece1.k].a(EnumDirection.SOUTH, worldgenmonumentpieces_worldgenmonumentstatetracker2); - worldgenmonumentpieces_worldgenmonumentstatetracker.d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker1.d = true; - worldgenmonumentpieces_worldgenmonumentstatetracker2.d = true; - this.p.e = true; - this.q = aworldgenmonumentpieces_worldgenmonumentstatetracker[b(random.nextInt(4), 0, 2)]; - this.q.d = true; - this.q.b[EnumDirection.EAST.a()].d = true; - this.q.b[EnumDirection.NORTH.a()].d = true; - this.q.b[EnumDirection.EAST.a()].b[EnumDirection.NORTH.a()].d = true; - this.q.b[EnumDirection.UP.a()].d = true; - this.q.b[EnumDirection.EAST.a()].b[EnumDirection.UP.a()].d = true; - this.q.b[EnumDirection.NORTH.a()].b[EnumDirection.UP.a()].d = true; - this.q.b[EnumDirection.EAST.a()].b[EnumDirection.NORTH.a()].b[EnumDirection.UP.a()].d = true; - List list = Lists.newArrayList(); - WorldGenMonumentPieces.WorldGenMonumentStateTracker[] aworldgenmonumentpieces_worldgenmonumentstatetracker1 = aworldgenmonumentpieces_worldgenmonumentstatetracker; - - l = aworldgenmonumentpieces_worldgenmonumentstatetracker.length; - - for (i1 = 0; i1 < l; ++i1) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker3 = aworldgenmonumentpieces_worldgenmonumentstatetracker1[i1]; - - if (worldgenmonumentpieces_worldgenmonumentstatetracker3 != null) { - worldgenmonumentpieces_worldgenmonumentstatetracker3.a(); - list.add(worldgenmonumentpieces_worldgenmonumentstatetracker3); - } - } - - worldgenmonumentpieces_worldgenmonumentstatetracker.a(); - Collections.shuffle(list, random); - int k2 = 1; - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker4 = (WorldGenMonumentPieces.WorldGenMonumentStateTracker) iterator.next(); - int l2 = 0; - - j1 = 0; - - while (l2 < 2 && j1 < 5) { - ++j1; - k1 = random.nextInt(6); - if (worldgenmonumentpieces_worldgenmonumentstatetracker4.c[k1]) { - l1 = EnumDirection.fromType1(k1).opposite().a(); - worldgenmonumentpieces_worldgenmonumentstatetracker4.c[k1] = false; - worldgenmonumentpieces_worldgenmonumentstatetracker4.b[k1].c[l1] = false; - if (worldgenmonumentpieces_worldgenmonumentstatetracker4.a(k2++) && worldgenmonumentpieces_worldgenmonumentstatetracker4.b[k1].a(k2++)) { - ++l2; - } else { - worldgenmonumentpieces_worldgenmonumentstatetracker4.c[k1] = true; - worldgenmonumentpieces_worldgenmonumentstatetracker4.b[k1].c[l1] = true; - } - } - } - } - - list.add(worldgenmonumentpieces_worldgenmonumentstatetracker); - list.add(worldgenmonumentpieces_worldgenmonumentstatetracker1); - list.add(worldgenmonumentpieces_worldgenmonumentstatetracker2); - return list; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - int i = Math.max(generatoraccess.getSeaLevel(), 64) - this.n.b; - - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 58, i, 58); - this.a(false, 0, generatoraccess, random, structureboundingbox); - this.a(true, 33, generatoraccess, random, structureboundingbox); - this.a(generatoraccess, random, structureboundingbox); - this.b(generatoraccess, random, structureboundingbox); - this.c(generatoraccess, random, structureboundingbox); - this.d(generatoraccess, random, structureboundingbox); - this.e(generatoraccess, random, structureboundingbox); - this.f(generatoraccess, random, structureboundingbox); - - int j; - - for (j = 0; j < 7; ++j) { - int k = 0; - - while (k < 7) { - if (k == 0 && j == 3) { - k = 6; - } - - int l = j * 9; - int i1 = k * 9; - - for (int j1 = 0; j1 < 4; ++j1) { - for (int k1 = 0; k1 < 4; ++k1) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, l + j1, 0, i1 + k1, structureboundingbox); - this.b(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, l + j1, -1, i1 + k1, structureboundingbox); - } - } - - if (j != 0 && j != 6) { - k += 6; - } else { - ++k; - } - } - } - - for (j = 0; j < 5; ++j) { - this.a(generatoraccess, structureboundingbox, -1 - j, 0 + j * 2, -1 - j, -1 - j, 23, 58 + j); - this.a(generatoraccess, structureboundingbox, 58 + j, 0 + j * 2, -1 - j, 58 + j, 23, 58 + j); - this.a(generatoraccess, structureboundingbox, 0 - j, 0 + j * 2, -1 - j, 57 + j, 23, -1 - j); - this.a(generatoraccess, structureboundingbox, 0 - j, 0 + j * 2, 58 + j, 57 + j, 23, 58 + j); - } - - Iterator iterator = this.r.iterator(); - - while (iterator.hasNext()) { - WorldGenMonumentPieces.WorldGenMonumentPiece worldgenmonumentpieces_worldgenmonumentpiece = (WorldGenMonumentPieces.WorldGenMonumentPiece) iterator.next(); - - if (worldgenmonumentpieces_worldgenmonumentpiece.d().a(structureboundingbox)) { - worldgenmonumentpieces_worldgenmonumentpiece.a(generatoraccess, random, structureboundingbox, chunkcoordintpair); - } - } - - return true; - } - - private void a(boolean flag, int i, GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - boolean flag1 = true; - - if (this.a(structureboundingbox, i, 0, i + 23, 20)) { - this.a(generatoraccess, structureboundingbox, i + 0, 0, 0, i + 24, 0, 20, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, i + 0, 1, 0, i + 24, 10, 20); - - int j; - - for (j = 0; j < 4; ++j) { - this.a(generatoraccess, structureboundingbox, i + j, j + 1, j, i + j, j + 1, 20, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, i + j + 7, j + 5, j + 7, i + j + 7, j + 5, 20, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, i + 17 - j, j + 5, j + 7, i + 17 - j, j + 5, 20, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, i + 24 - j, j + 1, j, i + 24 - j, j + 1, 20, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, i + j + 1, j + 1, j, i + 23 - j, j + 1, j, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, i + j + 8, j + 5, j + 7, i + 16 - j, j + 5, j + 7, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - this.a(generatoraccess, structureboundingbox, i + 4, 4, 4, i + 6, 4, 20, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, i + 7, 4, 4, i + 17, 4, 6, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, i + 18, 4, 4, i + 20, 4, 20, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, i + 11, 8, 11, i + 13, 8, 20, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i + 12, 9, 12, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i + 12, 9, 15, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i + 12, 9, 18, structureboundingbox); - j = i + (flag ? 19 : 5); - int k = i + (flag ? 5 : 19); - - int l; - - for (l = 20; l >= 5; l -= 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, j, 5, l, structureboundingbox); - } - - for (l = 19; l >= 7; l -= 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, k, 5, l, structureboundingbox); - } - - for (l = 0; l < 4; ++l) { - int i1 = flag ? i + 24 - (17 - l * 3) : i + 17 - l * 3; - - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i1, 5, 5, structureboundingbox); - } - - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, k, 5, 5, structureboundingbox); - this.a(generatoraccess, structureboundingbox, i + 11, 1, 12, i + 13, 7, 12, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, i + 12, 1, 11, i + 12, 7, 13, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - } - - } - - private void a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - if (this.a(structureboundingbox, 22, 5, 35, 17)) { - this.a(generatoraccess, structureboundingbox, 25, 0, 0, 32, 8, 20); - - for (int i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, 24, 2, 5 + i * 4, 24, 4, 5 + i * 4, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, 22, 4, 5 + i * 4, 23, 4, 5 + i * 4, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 25, 5, 5 + i * 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 26, 6, 5 + i * 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.e, 26, 5, 5 + i * 4, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 33, 2, 5 + i * 4, 33, 4, 5 + i * 4, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, 34, 4, 5 + i * 4, 35, 4, 5 + i * 4, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 32, 5, 5 + i * 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 31, 6, 5 + i * 4, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.e, 31, 5, 5 + i * 4, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 27, 6, 5 + i * 4, 30, 6, 5 + i * 4, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - } - } - - } - - private void b(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - if (this.a(structureboundingbox, 15, 20, 42, 21)) { - this.a(generatoraccess, structureboundingbox, 15, 0, 21, 42, 0, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 26, 1, 21, 31, 3, 21); - this.a(generatoraccess, structureboundingbox, 21, 12, 21, 36, 12, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 17, 11, 21, 40, 11, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 16, 10, 21, 41, 10, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 15, 7, 21, 42, 9, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 16, 6, 21, 41, 6, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 17, 5, 21, 40, 5, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 21, 4, 21, 36, 4, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 22, 3, 21, 26, 3, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 31, 3, 21, 35, 3, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 23, 2, 21, 25, 2, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 32, 2, 21, 34, 2, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 28, 4, 20, 29, 4, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 27, 3, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 30, 3, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 26, 2, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 31, 2, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 25, 1, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 32, 1, 21, structureboundingbox); - - int i; - - for (i = 0; i < 7; ++i) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 28 - i, 6 + i, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 29 + i, 6 + i, 21, structureboundingbox); - } - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 28 - i, 9 + i, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 29 + i, 9 + i, 21, structureboundingbox); - } - - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 28, 12, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 29, 12, 21, structureboundingbox); - - for (i = 0; i < 3; ++i) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 22 - i * 2, 8, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 22 - i * 2, 9, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 35 + i * 2, 8, 21, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.c, 35 + i * 2, 9, 21, structureboundingbox); - } - - this.a(generatoraccess, structureboundingbox, 15, 13, 21, 42, 15, 21); - this.a(generatoraccess, structureboundingbox, 15, 1, 21, 15, 6, 21); - this.a(generatoraccess, structureboundingbox, 16, 1, 21, 16, 5, 21); - this.a(generatoraccess, structureboundingbox, 17, 1, 21, 20, 4, 21); - this.a(generatoraccess, structureboundingbox, 21, 1, 21, 21, 3, 21); - this.a(generatoraccess, structureboundingbox, 22, 1, 21, 22, 2, 21); - this.a(generatoraccess, structureboundingbox, 23, 1, 21, 24, 1, 21); - this.a(generatoraccess, structureboundingbox, 42, 1, 21, 42, 6, 21); - this.a(generatoraccess, structureboundingbox, 41, 1, 21, 41, 5, 21); - this.a(generatoraccess, structureboundingbox, 37, 1, 21, 40, 4, 21); - this.a(generatoraccess, structureboundingbox, 36, 1, 21, 36, 3, 21); - this.a(generatoraccess, structureboundingbox, 33, 1, 21, 34, 1, 21); - this.a(generatoraccess, structureboundingbox, 35, 1, 21, 35, 2, 21); - } - - } - - private void c(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - if (this.a(structureboundingbox, 21, 21, 36, 36)) { - this.a(generatoraccess, structureboundingbox, 21, 0, 22, 36, 0, 36, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 21, 1, 22, 36, 23, 36); - - for (int i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, 21 + i, 13 + i, 21 + i, 36 - i, 13 + i, 21 + i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, 21 + i, 13 + i, 36 - i, 36 - i, 13 + i, 36 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, 21 + i, 13 + i, 22 + i, 21 + i, 13 + i, 35 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, 36 - i, 13 + i, 22 + i, 36 - i, 13 + i, 35 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - this.a(generatoraccess, structureboundingbox, 25, 16, 25, 32, 16, 32, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 25, 17, 25, 25, 19, 25, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, 32, 17, 25, 32, 19, 25, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, 25, 17, 32, 25, 19, 32, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, 32, 17, 32, 32, 19, 32, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 26, 20, 26, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 27, 21, 27, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.e, 27, 20, 27, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 26, 20, 31, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 27, 21, 30, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.e, 27, 20, 30, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 31, 20, 31, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 30, 21, 30, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.e, 30, 20, 30, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 31, 20, 26, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, 30, 21, 27, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.e, 30, 20, 27, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 28, 21, 27, 29, 21, 27, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 27, 21, 28, 27, 21, 29, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 28, 21, 30, 29, 21, 30, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 30, 21, 28, 30, 21, 29, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - } - - } - - private void d(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - int i; - - if (this.a(structureboundingbox, 0, 21, 6, 58)) { - this.a(generatoraccess, structureboundingbox, 0, 0, 21, 6, 0, 57, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 21, 6, 7, 57); - this.a(generatoraccess, structureboundingbox, 4, 4, 21, 6, 4, 53, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, i, i + 1, 21, i, i + 1, 57 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - for (i = 23; i < 53; i += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, 5, 5, i, structureboundingbox); - } - - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, 5, 5, 52, structureboundingbox); - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, i, i + 1, 21, i, i + 1, 57 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - this.a(generatoraccess, structureboundingbox, 4, 1, 52, 6, 3, 52, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 51, 5, 3, 53, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - } - - if (this.a(structureboundingbox, 51, 21, 58, 58)) { - this.a(generatoraccess, structureboundingbox, 51, 0, 21, 57, 0, 57, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 51, 1, 21, 57, 7, 57); - this.a(generatoraccess, structureboundingbox, 51, 4, 21, 53, 4, 53, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, 57 - i, i + 1, 21, 57 - i, i + 1, 57 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - for (i = 23; i < 53; i += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, 52, 5, i, structureboundingbox); - } - - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, 52, 5, 52, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 51, 1, 52, 53, 3, 52, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 52, 1, 51, 52, 3, 53, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - } - - if (this.a(structureboundingbox, 0, 51, 57, 57)) { - this.a(generatoraccess, structureboundingbox, 7, 0, 51, 50, 0, 57, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 51, 50, 10, 57); - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, i + 1, i + 1, 57 - i, 56 - i, i + 1, 57 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - } - - } - - private void e(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - int i; - - if (this.a(structureboundingbox, 7, 21, 13, 50)) { - this.a(generatoraccess, structureboundingbox, 7, 0, 21, 13, 0, 50, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 7, 1, 21, 13, 10, 50); - this.a(generatoraccess, structureboundingbox, 11, 8, 21, 13, 8, 53, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, i + 7, i + 5, 21, i + 7, i + 5, 54, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - for (i = 21; i <= 45; i += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, 12, 9, i, structureboundingbox); - } - } - - if (this.a(structureboundingbox, 44, 21, 50, 54)) { - this.a(generatoraccess, structureboundingbox, 44, 0, 21, 50, 0, 50, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 44, 1, 21, 50, 10, 50); - this.a(generatoraccess, structureboundingbox, 44, 8, 21, 46, 8, 53, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, 50 - i, i + 5, 21, 50 - i, i + 5, 54, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - for (i = 21; i <= 45; i += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, 45, 9, i, structureboundingbox); - } - } - - if (this.a(structureboundingbox, 8, 44, 49, 54)) { - this.a(generatoraccess, structureboundingbox, 14, 0, 44, 43, 0, 50, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 14, 1, 44, 43, 10, 50); - - for (i = 12; i <= 45; i += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 9, 45, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 9, 52, structureboundingbox); - if (i == 12 || i == 18 || i == 24 || i == 33 || i == 39 || i == 45) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 9, 47, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 9, 50, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 10, 45, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 10, 46, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 10, 51, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 10, 52, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 11, 47, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 11, 50, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 12, 48, structureboundingbox); - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 12, 49, structureboundingbox); - } - } - - for (i = 0; i < 3; ++i) { - this.a(generatoraccess, structureboundingbox, 8 + i, 5 + i, 54, 49 - i, 5 + i, 54, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - } - - this.a(generatoraccess, structureboundingbox, 11, 8, 54, 46, 8, 54, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - this.a(generatoraccess, structureboundingbox, 14, 8, 44, 43, 8, 53, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - } - - } - - private void f(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - int i; - - if (this.a(structureboundingbox, 14, 21, 20, 43)) { - this.a(generatoraccess, structureboundingbox, 14, 0, 21, 20, 0, 43, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 14, 1, 22, 20, 14, 43); - this.a(generatoraccess, structureboundingbox, 18, 12, 22, 20, 12, 39, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 18, 12, 21, 20, 12, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, i + 14, i + 9, 21, i + 14, i + 9, 43 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - for (i = 23; i <= 39; i += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, 19, 13, i, structureboundingbox); - } - } - - if (this.a(structureboundingbox, 37, 21, 43, 43)) { - this.a(generatoraccess, structureboundingbox, 37, 0, 21, 43, 0, 43, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 37, 1, 22, 43, 14, 43); - this.a(generatoraccess, structureboundingbox, 37, 12, 22, 39, 12, 39, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 37, 12, 21, 39, 12, 21, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, 43 - i, i + 9, 21, 43 - i, i + 9, 43 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - for (i = 23; i <= 39; i += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, 38, 13, i, structureboundingbox); - } - } - - if (this.a(structureboundingbox, 15, 37, 42, 43)) { - this.a(generatoraccess, structureboundingbox, 21, 0, 37, 36, 0, 43, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - this.a(generatoraccess, structureboundingbox, 21, 1, 37, 36, 14, 43); - this.a(generatoraccess, structureboundingbox, 21, 12, 37, 36, 12, 39, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, WorldGenMonumentPieces.WorldGenMonumentPiece1.a, false); - - for (i = 0; i < 4; ++i) { - this.a(generatoraccess, structureboundingbox, 15 + i, i + 9, 43 - i, 42 - i, i + 9, 43 - i, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, WorldGenMonumentPieces.WorldGenMonumentPiece1.b, false); - } - - for (i = 21; i <= 36; i += 3) { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece1.d, i, 13, 38, structureboundingbox); - } - } - - } - } - - public abstract static class WorldGenMonumentPiece extends StructurePiece { - - protected static final IBlockData a = Blocks.PRISMARINE.getBlockData(); - protected static final IBlockData b = Blocks.PRISMARINE_BRICKS.getBlockData(); - protected static final IBlockData c = Blocks.DARK_PRISMARINE.getBlockData(); - protected static final IBlockData d = WorldGenMonumentPieces.WorldGenMonumentPiece.b; - protected static final IBlockData e = Blocks.SEA_LANTERN.getBlockData(); - protected static final IBlockData f = Blocks.WATER.getBlockData(); - protected static final Set g = ImmutableSet.builder().add(Blocks.ICE).add(Blocks.PACKED_ICE).add(Blocks.BLUE_ICE).add(WorldGenMonumentPieces.WorldGenMonumentPiece.f.getBlock()).build(); // Paper - decompile fix - protected static final int h = b(2, 0, 0); - protected static final int i = b(2, 2, 0); - protected static final int j = b(0, 1, 0); - protected static final int k = b(4, 1, 0); - protected WorldGenMonumentPieces.WorldGenMonumentStateTracker l; - - protected static final int b(int i, int j, int k) { - return j * 25 + k * 5 + i; - } - - public WorldGenMonumentPiece() { - super(0); - } - - public WorldGenMonumentPiece(int i) { - super(i); - } - - public WorldGenMonumentPiece(EnumDirection enumdirection, StructureBoundingBox structureboundingbox) { - super(1); - this.a(enumdirection); - this.n = structureboundingbox; - } - - protected WorldGenMonumentPiece(int i, EnumDirection enumdirection, WorldGenMonumentPieces.WorldGenMonumentStateTracker worldgenmonumentpieces_worldgenmonumentstatetracker, int j, int k, int l) { - super(i); - this.a(enumdirection); - this.l = worldgenmonumentpieces_worldgenmonumentstatetracker; - int i1 = worldgenmonumentpieces_worldgenmonumentstatetracker.a; - int j1 = i1 % 5; - int k1 = i1 / 5 % 5; - int l1 = i1 / 25; - - if (enumdirection != EnumDirection.NORTH && enumdirection != EnumDirection.SOUTH) { - this.n = new StructureBoundingBox(0, 0, 0, l * 8 - 1, k * 4 - 1, j * 8 - 1); - } else { - this.n = new StructureBoundingBox(0, 0, 0, j * 8 - 1, k * 4 - 1, l * 8 - 1); - } - - switch (enumdirection) { - case NORTH: - this.n.a(j1 * 8, l1 * 4, -(k1 + l) * 8 + 1); - break; - case SOUTH: - this.n.a(j1 * 8, l1 * 4, k1 * 8); - break; - case WEST: - this.n.a(-(k1 + l) * 8 + 1, l1 * 4, j1 * 8); - break; - default: - this.n.a(k1 * 8, l1 * 4, j1 * 8); - } - - } - - protected void a(NBTTagCompound nbttagcompound) {} - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) {} - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, int i, int j, int k, int l, int i1, int j1) { - for (int k1 = j; k1 <= i1; ++k1) { - for (int l1 = i; l1 <= l; ++l1) { - for (int i2 = k; i2 <= j1; ++i2) { - IBlockData iblockdata = this.a((IBlockAccess) generatoraccess, l1, k1, i2, structureboundingbox); - - if (!WorldGenMonumentPieces.WorldGenMonumentPiece.g.contains(iblockdata.getBlock())) { - if (this.d(k1) >= generatoraccess.getSeaLevel() && iblockdata != WorldGenMonumentPieces.WorldGenMonumentPiece.f) { - this.a(generatoraccess, Blocks.AIR.getBlockData(), l1, k1, i2, structureboundingbox); - } else { - this.a(generatoraccess, WorldGenMonumentPieces.WorldGenMonumentPiece.f, l1, k1, i2, structureboundingbox); - } - } - } - } - } - - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, int i, int j, boolean flag) { - if (flag) { - this.a(generatoraccess, structureboundingbox, i + 0, 0, j + 0, i + 2, 0, j + 8 - 1, WorldGenMonumentPieces.WorldGenMonumentPiece.a, WorldGenMonumentPieces.WorldGenMonumentPiece.a, false); - this.a(generatoraccess, structureboundingbox, i + 5, 0, j + 0, i + 8 - 1, 0, j + 8 - 1, WorldGenMonumentPieces.WorldGenMonumentPiece.a, WorldGenMonumentPieces.WorldGenMonumentPiece.a, false); - this.a(generatoraccess, structureboundingbox, i + 3, 0, j + 0, i + 4, 0, j + 2, WorldGenMonumentPieces.WorldGenMonumentPiece.a, WorldGenMonumentPieces.WorldGenMonumentPiece.a, false); - this.a(generatoraccess, structureboundingbox, i + 3, 0, j + 5, i + 4, 0, j + 8 - 1, WorldGenMonumentPieces.WorldGenMonumentPiece.a, WorldGenMonumentPieces.WorldGenMonumentPiece.a, false); - this.a(generatoraccess, structureboundingbox, i + 3, 0, j + 2, i + 4, 0, j + 2, WorldGenMonumentPieces.WorldGenMonumentPiece.b, WorldGenMonumentPieces.WorldGenMonumentPiece.b, false); - this.a(generatoraccess, structureboundingbox, i + 3, 0, j + 5, i + 4, 0, j + 5, WorldGenMonumentPieces.WorldGenMonumentPiece.b, WorldGenMonumentPieces.WorldGenMonumentPiece.b, false); - this.a(generatoraccess, structureboundingbox, i + 2, 0, j + 3, i + 2, 0, j + 4, WorldGenMonumentPieces.WorldGenMonumentPiece.b, WorldGenMonumentPieces.WorldGenMonumentPiece.b, false); - this.a(generatoraccess, structureboundingbox, i + 5, 0, j + 3, i + 5, 0, j + 4, WorldGenMonumentPieces.WorldGenMonumentPiece.b, WorldGenMonumentPieces.WorldGenMonumentPiece.b, false); - } else { - this.a(generatoraccess, structureboundingbox, i + 0, 0, j + 0, i + 8 - 1, 0, j + 8 - 1, WorldGenMonumentPieces.WorldGenMonumentPiece.a, WorldGenMonumentPieces.WorldGenMonumentPiece.a, false); - } - - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, int i, int j, int k, int l, int i1, int j1, IBlockData iblockdata) { - for (int k1 = j; k1 <= i1; ++k1) { - for (int l1 = i; l1 <= l; ++l1) { - for (int i2 = k; i2 <= j1; ++i2) { - if (this.a((IBlockAccess) generatoraccess, l1, k1, i2, structureboundingbox) == WorldGenMonumentPieces.WorldGenMonumentPiece.f) { - this.a(generatoraccess, iblockdata, l1, k1, i2, structureboundingbox); - } - } - } - } - - } - - protected boolean a(StructureBoundingBox structureboundingbox, int i, int j, int k, int l) { - int i1 = this.a(i, j); - int j1 = this.b(i, j); - int k1 = this.a(k, l); - int l1 = this.b(k, l); - - return structureboundingbox.a(Math.min(i1, k1), Math.min(j1, l1), Math.max(i1, k1), Math.max(j1, l1)); - } - - protected boolean a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, int i, int j, int k) { - int l = this.a(i, k); - int i1 = this.d(j); - int j1 = this.b(i, k); - - if (structureboundingbox.b((BaseBlockPosition) (new BlockPosition(l, i1, j1)))) { - EntityGuardianElder entityguardianelder = EntityTypes.ELDER_GUARDIAN.create(generatoraccess.getMinecraftWorld()); // Paper - - entityguardianelder.heal(entityguardianelder.getMaxHealth()); - entityguardianelder.setPositionRotation((double) l + 0.5D, (double) i1, (double) j1 + 0.5D, 0.0F, 0.0F); - entityguardianelder.prepare(generatoraccess.getDamageScaler(new BlockPosition(entityguardianelder)), (GroupDataEntity) null, (NBTTagCompound) null); - generatoraccess.addEntity(entityguardianelder); - return true; - } else { - return false; - } - } - } -} diff --git a/src/main/java/net/minecraft/server/WorldGenStronghold.java b/src/main/java/net/minecraft/server/WorldGenStronghold.java index d0eaa9e9f..c2188ceef 100644 --- a/src/main/java/net/minecraft/server/WorldGenStronghold.java +++ b/src/main/java/net/minecraft/server/WorldGenStronghold.java @@ -1,37 +1,44 @@ package net.minecraft.server; import com.google.common.collect.Lists; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.objects.ObjectIterator; +import com.mojang.datafixers.Dynamic; import java.util.Iterator; import java.util.List; import java.util.Random; +import java.util.function.Function; import javax.annotation.Nullable; -public class WorldGenStronghold extends StructureGenerator { +public class WorldGenStronghold extends StructureGenerator { - // Paper start - no shared state - //private boolean b; - //private ChunkCoordIntPair[] c; - //private long d; - // Paper end + /* // Paper start - no shared state + private boolean a; + private ChunkCoordIntPair[] aS; + private final List aT = Lists.newArrayList(); + private long aU; + */ - public WorldGenStronghold() {} + public WorldGenStronghold(Function, ? extends WorldGenFeatureEmptyConfiguration> function) { + super(function); + } - protected boolean a(ChunkGenerator chunkgenerator, Random random, int i, int j) { + @Override + public boolean a(ChunkGenerator chunkgenerator, Random random, int i, int j) { // Paper start - /*if (this.d != chunkgenerator.getSeed()) { - this.c(); - }*/ + /* + if (this.aU != chunkgenerator.getSeed()) { + this.d(); + } + */ + final World world = chunkgenerator.getWorld(); - synchronized (chunkgenerator.getWorld().strongholdInit) { - if (chunkgenerator.getWorld().strongholdInit.compareAndSet(false, true)) { // Paper + synchronized (world.stuctureLock) { + if ( world.strongholdCoords == null) { this.a(chunkgenerator); - //this.b = true; - }} // Paper + // this.a = true; + }} // Paper end - ChunkCoordIntPair[] achunkcoordintpair = chunkgenerator.getWorld().strongholdCoords; // Paper + ChunkCoordIntPair[] achunkcoordintpair = world.strongholdCoords; // Paper int k = achunkcoordintpair.length; for (int l = 0; l < k; ++l) { @@ -45,69 +52,62 @@ public class WorldGenStronghold extends StructureGenerator chunkgenerator, SeededRandom seededrandom, int i, int j) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), Biomes.b); - byte b0 = 0; - int k = b0 + 1; - - WorldGenStronghold.a worldgenstronghold_a; - - for (worldgenstronghold_a = new WorldGenStronghold.a(generatoraccess, seededrandom, i, j, biomebase, b0); worldgenstronghold_a.d().isEmpty() || ((WorldGenStrongholdPieces.WorldGenStrongholdStart) worldgenstronghold_a.d().get(0)).b == null; worldgenstronghold_a = new WorldGenStronghold.a(generatoraccess, seededrandom, i, j, biomebase, k++)) { - ; - } - - return worldgenstronghold_a; - } - - protected String a() { + @Override + public String b() { return "Stronghold"; } - public int b() { + @Override + public int c() { return 8; } + @Nullable - public BlockPosition getNearestGeneratedFeature(World world, ChunkGenerator chunkgenerator, BlockPosition blockposition, int i, boolean flag) { + @Override + public synchronized BlockPosition getNearestGeneratedFeature(World world, ChunkGenerator chunkgenerator, BlockPosition blockposition, int i, boolean flag) { // CraftBukkit - synchronized if (!chunkgenerator.getWorldChunkManager().a(this)) { return null; } else { - // Paper start - /*if (this.d != chunkgenerator.getSeed()) { - this.c(); - }*/ + // Paper start - no shared state + /* + if (this.aU != world.getSeed()) { + this.d(); + } + */ - synchronized (chunkgenerator.getWorld().strongholdInit) { - if (chunkgenerator.getWorld().strongholdInit.compareAndSet(false, true)) { // Paper + synchronized (world.stuctureLock) { + if ( world.strongholdCoords == null) { this.a(chunkgenerator); - //this.b = true; - }} // Paper + //this.a = true; + } + } // Paper end BlockPosition blockposition1 = null; - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(0, 0, 0); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); double d0 = Double.MAX_VALUE; - // Paper start - /* - ChunkCoordIntPair[] achunkcoordintpair = this.c; + ChunkCoordIntPair[] achunkcoordintpair = world.strongholdCoords; // Paper int j = achunkcoordintpair.length; for (int k = 0; k < j; ++k) { - */ - for (ChunkCoordIntPair chunkcoordintpair : world.strongholdCoords) { - // Paper end + ChunkCoordIntPair chunkcoordintpair = achunkcoordintpair[k]; - blockposition_mutableblockposition.c((chunkcoordintpair.x << 4) + 8, 32, (chunkcoordintpair.z << 4) + 8); - double d1 = blockposition_mutableblockposition.n(blockposition); + blockposition_mutableblockposition.d((chunkcoordintpair.x << 4) + 8, 32, (chunkcoordintpair.z << 4) + 8); + double d1 = blockposition_mutableblockposition.m(blockposition); if (blockposition1 == null) { blockposition1 = new BlockPosition(blockposition_mutableblockposition); @@ -123,14 +123,14 @@ public class WorldGenStronghold extends StructureGenerator chunkgenerator) { - //this.d = chunkgenerator.getSeed(); // Paper + //this.aU = chunkgenerator.getSeed(); // Paper List list = Lists.newArrayList(); Iterator iterator = IRegistry.BIOME.iterator(); while (iterator.hasNext()) { BiomeBase biomebase = (BiomeBase) iterator.next(); - if (biomebase != null && chunkgenerator.canSpawnStructure(biomebase, WorldGenerator.m)) { + if (biomebase != null && chunkgenerator.canSpawnStructure(biomebase, WorldGenerator.STRONGHOLD)) { list.add(biomebase); } } @@ -141,17 +141,13 @@ public class WorldGenStronghold extends StructureGenerator long2objectmap = chunkgenerator.getStructureStartCache(this); + Iterator iterator1 = chunkgenerator.getWorld().strongholdStuctures.iterator(); // Paper - synchronized (long2objectmap) { - ObjectIterator objectiterator = long2objectmap.values().iterator(); + while (iterator1.hasNext()) { + StructureStart structurestart = (StructureStart) iterator1.next(); - while (objectiterator.hasNext()) { - StructureStart structurestart = (StructureStart) objectiterator.next(); - - if (l < strongholdCoords.length) { // Paper - strongholdCoords[l++] = new ChunkCoordIntPair(structurestart.e(), structurestart.f()); // Paper - } + if (l < strongholdCoords.length) { // Paper + strongholdCoords[l++] = new ChunkCoordIntPair(structurestart.f(), structurestart.g()); // Paper } } @@ -159,9 +155,9 @@ public class WorldGenStronghold extends StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); + } - public a(GeneratorAccess generatoraccess, SeededRandom seededrandom, int i, int j, BiomeBase biomebase, int k) { - super(i, j, biomebase, seededrandom, generatoraccess.getSeed() + (long) k); - WorldGenStrongholdPieces.b(); - WorldGenStrongholdPieces.WorldGenStrongholdStart worldgenstrongholdpieces_worldgenstrongholdstart = new WorldGenStrongholdPieces.WorldGenStrongholdStart(0, seededrandom, (i << 4) + 2, (j << 4) + 2); + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + int k = 0; + long l = chunkgenerator.getSeed(); - this.a.add(worldgenstrongholdpieces_worldgenstrongholdstart); - worldgenstrongholdpieces_worldgenstrongholdstart.a((StructurePiece) worldgenstrongholdpieces_worldgenstrongholdstart, this.a, (Random) seededrandom); - List list = worldgenstrongholdpieces_worldgenstrongholdstart.c; + WorldGenStrongholdPieces.WorldGenStrongholdStart worldgenstrongholdpieces_worldgenstrongholdstart; - while (!list.isEmpty()) { - int l = seededrandom.nextInt(list.size()); - StructurePiece structurepiece = (StructurePiece) list.remove(l); + do { + this.b.clear(); + this.c = StructureBoundingBox.a(); + this.d.c(l + (long) (k++), i, j); + WorldGenStrongholdPieces.a(); + worldgenstrongholdpieces_worldgenstrongholdstart = new WorldGenStrongholdPieces.WorldGenStrongholdStart(this.d, (i << 4) + 2, (j << 4) + 2); + this.b.add(worldgenstrongholdpieces_worldgenstrongholdstart); + worldgenstrongholdpieces_worldgenstrongholdstart.a((StructurePiece) worldgenstrongholdpieces_worldgenstrongholdstart, this.b, (Random) this.d); + List list = worldgenstrongholdpieces_worldgenstrongholdstart.c; - structurepiece.a((StructurePiece) worldgenstrongholdpieces_worldgenstrongholdstart, this.a, (Random) seededrandom); - } + while (!list.isEmpty()) { + int i1 = this.d.nextInt(list.size()); + StructurePiece structurepiece = (StructurePiece) list.remove(i1); - this.a((IBlockAccess) generatoraccess); - this.a(generatoraccess, seededrandom, 10); + structurepiece.a((StructurePiece) worldgenstrongholdpieces_worldgenstrongholdstart, this.b, (Random) this.d); + } + + this.b(); + this.a(chunkgenerator.getSeaLevel(), this.d, 10); + } while (this.b.isEmpty() || worldgenstrongholdpieces_worldgenstrongholdstart.b == null); + + chunkgenerator.getWorld().strongholdStuctures.add(this); // Paper - this worries me, this is never cleared, even in vanilla (world seed never changes "world", and that appears to be the only relevant world) } } } diff --git a/src/main/java/net/minecraft/server/WorldGenVillage.java b/src/main/java/net/minecraft/server/WorldGenVillage.java index ca41a90cf..b155a73a0 100644 --- a/src/main/java/net/minecraft/server/WorldGenVillage.java +++ b/src/main/java/net/minecraft/server/WorldGenVillage.java @@ -1,25 +1,16 @@ package net.minecraft.server; -import java.util.Iterator; -import java.util.List; +import com.mojang.datafixers.Dynamic; import java.util.Random; +import java.util.function.Function; public class WorldGenVillage extends StructureGenerator { - public WorldGenVillage() {} - - public String a() { - return "Village"; - } - - public int b() { - return 8; - } - - protected boolean a(GeneratorAccess generatoraccess) { - return generatoraccess.getWorldData().shouldGenerateMapFeatures(); + public WorldGenVillage(Function, ? extends WorldGenFeatureVillageConfiguration> function) { + super(function); } + @Override protected ChunkCoordIntPair a(ChunkGenerator chunkgenerator, Random random, int i, int j, int k, int l) { int i1 = chunkgenerator.getSettings().a(); int j1 = chunkgenerator.getSettings().b(); @@ -38,84 +29,47 @@ public class WorldGenVillage extends StructureGenerator chunkgenerator, Random random, int i, int j) { + @Override + public boolean a(ChunkGenerator chunkgenerator, Random random, int i, int j) { ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, random, i, j, 0, 0); if (i == chunkcoordintpair.x && j == chunkcoordintpair.z) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), Biomes.b); + BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9)); - return chunkgenerator.canSpawnStructure(biomebase, WorldGenerator.e); + return chunkgenerator.canSpawnStructure(biomebase, WorldGenerator.VILLAGE); } else { return false; } } - protected StructureStart a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j) { - BiomeBase biomebase = chunkgenerator.getWorldChunkManager().getBiome(new BlockPosition((i << 4) + 9, 0, (j << 4) + 9), Biomes.b); - - return new WorldGenVillage.a(generatoraccess, chunkgenerator, seededrandom, i, j, biomebase); + @Override + public StructureGenerator.a a() { + return WorldGenVillage.a::new; } - public static class a extends StructureStart { + @Override + public String b() { + return "Village"; + } - private boolean e; + @Override + public int c() { + return 8; + } - public a() {} + public static class a extends StructureAbstract { - public a(GeneratorAccess generatoraccess, ChunkGenerator chunkgenerator, SeededRandom seededrandom, int i, int j, BiomeBase biomebase) { - super(i, j, biomebase, seededrandom, generatoraccess.getSeed()); - WorldGenFeatureVillageConfiguration worldgenfeaturevillageconfiguration = (WorldGenFeatureVillageConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.e); - List list = WorldGenVillagePieces.a(seededrandom, worldgenfeaturevillageconfiguration.a); - WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece = new WorldGenVillagePieces.WorldGenVillageStartPiece(0, seededrandom, (i << 4) + 2, (j << 4) + 2, list, worldgenfeaturevillageconfiguration); - - this.a.add(worldgenvillagepieces_worldgenvillagestartpiece); - worldgenvillagepieces_worldgenvillagestartpiece.a((StructurePiece) worldgenvillagepieces_worldgenvillagestartpiece, this.a, (Random) seededrandom); - List list1 = worldgenvillagepieces_worldgenvillagestartpiece.e; - List list2 = worldgenvillagepieces_worldgenvillagestartpiece.d; - - int k; - - while (!list1.isEmpty() || !list2.isEmpty()) { - StructurePiece structurepiece; - - if (list1.isEmpty()) { - k = seededrandom.nextInt(list2.size()); - structurepiece = (StructurePiece) list2.remove(k); - structurepiece.a((StructurePiece) worldgenvillagepieces_worldgenvillagestartpiece, this.a, (Random) seededrandom); - } else { - k = seededrandom.nextInt(list1.size()); - structurepiece = (StructurePiece) list1.remove(k); - structurepiece.a((StructurePiece) worldgenvillagepieces_worldgenvillagestartpiece, this.a, (Random) seededrandom); - } - } - - this.a((IBlockAccess) generatoraccess); - k = 0; - Iterator iterator = this.a.iterator(); - - while (iterator.hasNext()) { - StructurePiece structurepiece1 = (StructurePiece) iterator.next(); - - if (!(structurepiece1 instanceof WorldGenVillagePieces.WorldGenVillageRoadPiece)) { - ++k; - } - } - - this.e = k > 2; + public a(StructureGenerator structuregenerator, int i, int j, BiomeBase biomebase, StructureBoundingBox structureboundingbox, int k, long l) { + super(structuregenerator, i, j, biomebase, structureboundingbox, k, l); } - public boolean b() { - return this.e; - } + @Override + public void a(ChunkGenerator chunkgenerator, DefinedStructureManager definedstructuremanager, int i, int j, BiomeBase biomebase) { + WorldGenFeatureVillageConfiguration worldgenfeaturevillageconfiguration = (WorldGenFeatureVillageConfiguration) chunkgenerator.getFeatureConfiguration(biomebase, WorldGenerator.VILLAGE); + BlockPosition blockposition = new BlockPosition(i * 16, 0, j * 16); - public void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.setBoolean("Valid", this.e); - } - - public void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); - this.e = nbttagcompound.getBoolean("Valid"); + NewVillagePieces.a(chunkgenerator, definedstructuremanager, blockposition, this.b, this.d, worldgenfeaturevillageconfiguration); + this.b(); } } } diff --git a/src/main/java/net/minecraft/server/WorldGenVillagePieces.java b/src/main/java/net/minecraft/server/WorldGenVillagePieces.java deleted file mode 100644 index 967e33b3d..000000000 --- a/src/main/java/net/minecraft/server/WorldGenVillagePieces.java +++ /dev/null @@ -1,1814 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import java.util.Iterator; -import java.util.List; -import java.util.Random; -import javax.annotation.Nullable; - -public class WorldGenVillagePieces { - - public static void a() { - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageLibrary.class, "ViBH"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageFarm2.class, "ViDF"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageFarm.class, "ViF"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageLight.class, "ViL"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageButcher.class, "ViPH"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageHouse.class, "ViSH"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageHut.class, "ViSmH"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageTemple.class, "ViST"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageBlacksmith.class, "ViS"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageStartPiece.class, "ViStart"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageRoad.class, "ViSR"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageHouse2.class, "ViTRH"); - WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageWell.class, "ViW"); - } - - public static List a(Random random, int i) { - List list = Lists.newArrayList(); - - list.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageHouse.class, 4, MathHelper.nextInt(random, 2 + i, 4 + i * 2))); - list.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageTemple.class, 20, MathHelper.nextInt(random, 0 + i, 1 + i))); - list.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageLibrary.class, 20, MathHelper.nextInt(random, 0 + i, 2 + i))); - list.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageHut.class, 3, MathHelper.nextInt(random, 2 + i, 5 + i * 3))); - list.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageButcher.class, 15, MathHelper.nextInt(random, 0 + i, 2 + i))); - list.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageFarm2.class, 3, MathHelper.nextInt(random, 1 + i, 4 + i))); - list.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageFarm.class, 3, MathHelper.nextInt(random, 2 + i, 4 + i * 2))); - list.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageBlacksmith.class, 15, MathHelper.nextInt(random, 0, 1 + i))); - list.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageHouse2.class, 8, MathHelper.nextInt(random, 0 + i, 3 + i * 2))); - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - if (((WorldGenVillagePieces.WorldGenVillagePieceWeight) iterator.next()).d == 0) { - iterator.remove(); - } - } - - return list; - } - - private static int a(List list) { - boolean flag = false; - int i = 0; - - WorldGenVillagePieces.WorldGenVillagePieceWeight worldgenvillagepieces_worldgenvillagepieceweight; - - for (Iterator iterator = list.iterator(); iterator.hasNext(); i += worldgenvillagepieces_worldgenvillagepieceweight.b) { - worldgenvillagepieces_worldgenvillagepieceweight = (WorldGenVillagePieces.WorldGenVillagePieceWeight) iterator.next(); - if (worldgenvillagepieces_worldgenvillagepieceweight.d > 0 && worldgenvillagepieces_worldgenvillagepieceweight.c < worldgenvillagepieces_worldgenvillagepieceweight.d) { - flag = true; - } - } - - return flag ? i : -1; - } - - private static WorldGenVillagePieces.WorldGenVillagePiece a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, WorldGenVillagePieces.WorldGenVillagePieceWeight worldgenvillagepieces_worldgenvillagepieceweight, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - Class oclass = worldgenvillagepieces_worldgenvillagepieceweight.a; - Object object = null; - - if (oclass == WorldGenVillagePieces.WorldGenVillageHouse.class) { - object = WorldGenVillagePieces.WorldGenVillageHouse.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); - } else if (oclass == WorldGenVillagePieces.WorldGenVillageTemple.class) { - object = WorldGenVillagePieces.WorldGenVillageTemple.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); - } else if (oclass == WorldGenVillagePieces.WorldGenVillageLibrary.class) { - object = WorldGenVillagePieces.WorldGenVillageLibrary.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); - } else if (oclass == WorldGenVillagePieces.WorldGenVillageHut.class) { - object = WorldGenVillagePieces.WorldGenVillageHut.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); - } else if (oclass == WorldGenVillagePieces.WorldGenVillageButcher.class) { - object = WorldGenVillagePieces.WorldGenVillageButcher.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); - } else if (oclass == WorldGenVillagePieces.WorldGenVillageFarm2.class) { - object = WorldGenVillagePieces.WorldGenVillageFarm2.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); - } else if (oclass == WorldGenVillagePieces.WorldGenVillageFarm.class) { - object = WorldGenVillagePieces.WorldGenVillageFarm.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); - } else if (oclass == WorldGenVillagePieces.WorldGenVillageBlacksmith.class) { - object = WorldGenVillagePieces.WorldGenVillageBlacksmith.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); - } else if (oclass == WorldGenVillagePieces.WorldGenVillageHouse2.class) { - object = WorldGenVillagePieces.WorldGenVillageHouse2.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); - } - - return (WorldGenVillagePieces.WorldGenVillagePiece) object; - } - - private static WorldGenVillagePieces.WorldGenVillagePiece c(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - int i1 = a(worldgenvillagepieces_worldgenvillagestartpiece.c); - - if (i1 <= 0) { - return null; - } else { - int j1 = 0; - - while (j1 < 5) { - ++j1; - int k1 = random.nextInt(i1); - Iterator iterator = worldgenvillagepieces_worldgenvillagestartpiece.c.iterator(); - - while (iterator.hasNext()) { - WorldGenVillagePieces.WorldGenVillagePieceWeight worldgenvillagepieces_worldgenvillagepieceweight = (WorldGenVillagePieces.WorldGenVillagePieceWeight) iterator.next(); - - k1 -= worldgenvillagepieces_worldgenvillagepieceweight.b; - if (k1 < 0) { - if (!worldgenvillagepieces_worldgenvillagepieceweight.a(l) || worldgenvillagepieces_worldgenvillagepieceweight == worldgenvillagepieces_worldgenvillagestartpiece.b && worldgenvillagepieces_worldgenvillagestartpiece.c.size() > 1) { - break; - } - - WorldGenVillagePieces.WorldGenVillagePiece worldgenvillagepieces_worldgenvillagepiece = a(worldgenvillagepieces_worldgenvillagestartpiece, worldgenvillagepieces_worldgenvillagepieceweight, list, random, i, j, k, enumdirection, l); - - if (worldgenvillagepieces_worldgenvillagepiece != null) { - ++worldgenvillagepieces_worldgenvillagepieceweight.c; - worldgenvillagepieces_worldgenvillagestartpiece.b = worldgenvillagepieces_worldgenvillagepieceweight; - if (!worldgenvillagepieces_worldgenvillagepieceweight.a()) { - worldgenvillagepieces_worldgenvillagestartpiece.c.remove(worldgenvillagepieces_worldgenvillagepieceweight); - } - - return worldgenvillagepieces_worldgenvillagepiece; - } - } - } - } - - StructureBoundingBox structureboundingbox = WorldGenVillagePieces.WorldGenVillageLight.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection); - - if (structureboundingbox != null) { - return new WorldGenVillagePieces.WorldGenVillageLight(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection); - } else { - return null; - } - } - } - - private static StructurePiece d(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - if (l > 50) { - return null; - } else if (Math.abs(i - worldgenvillagepieces_worldgenvillagestartpiece.d().a) <= 112 && Math.abs(k - worldgenvillagepieces_worldgenvillagestartpiece.d().c) <= 112) { - WorldGenVillagePieces.WorldGenVillagePiece worldgenvillagepieces_worldgenvillagepiece = c(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l + 1); - - if (worldgenvillagepieces_worldgenvillagepiece != null) { - list.add(worldgenvillagepieces_worldgenvillagepiece); - worldgenvillagepieces_worldgenvillagestartpiece.d.add(worldgenvillagepieces_worldgenvillagepiece); - return worldgenvillagepieces_worldgenvillagepiece; - } else { - return null; - } - } else { - return null; - } - } - - private static StructurePiece e(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - if (l > 3 + worldgenvillagepieces_worldgenvillagestartpiece.a) { - return null; - } else if (Math.abs(i - worldgenvillagepieces_worldgenvillagestartpiece.d().a) <= 112 && Math.abs(k - worldgenvillagepieces_worldgenvillagestartpiece.d().c) <= 112) { - StructureBoundingBox structureboundingbox = WorldGenVillagePieces.WorldGenVillageRoad.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection); - - if (structureboundingbox != null && structureboundingbox.b > 10) { - WorldGenVillagePieces.WorldGenVillageRoad worldgenvillagepieces_worldgenvillageroad = new WorldGenVillagePieces.WorldGenVillageRoad(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection); - - list.add(worldgenvillagepieces_worldgenvillageroad); - worldgenvillagepieces_worldgenvillagestartpiece.e.add(worldgenvillagepieces_worldgenvillageroad); - return worldgenvillagepieces_worldgenvillageroad; - } else { - return null; - } - } else { - return null; - } - } - - public static class WorldGenVillageLight extends WorldGenVillagePieces.WorldGenVillagePiece { - - public WorldGenVillageLight() {} - - public WorldGenVillageLight(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - } - - public static StructureBoundingBox a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 3, 4, 2, enumdirection); - - return StructurePiece.a(list, structureboundingbox) != null ? null : structureboundingbox; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 4 - 1, 0); - } - - IBlockData iblockdata = this.a(Blocks.OAK_FENCE.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 2, 3, 1, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, iblockdata, 1, 0, 0, structureboundingbox); - this.a(generatoraccess, iblockdata, 1, 1, 0, structureboundingbox); - this.a(generatoraccess, iblockdata, 1, 2, 0, structureboundingbox); - this.a(generatoraccess, Blocks.BLACK_WOOL.getBlockData(), 1, 3, 0, structureboundingbox); - this.a(generatoraccess, EnumDirection.EAST, 2, 3, 0, structureboundingbox); - this.a(generatoraccess, EnumDirection.NORTH, 1, 3, 1, structureboundingbox); - this.a(generatoraccess, EnumDirection.WEST, 0, 3, 0, structureboundingbox); - this.a(generatoraccess, EnumDirection.SOUTH, 1, 3, -1, structureboundingbox); - return true; - } - } - - public static class WorldGenVillageFarm2 extends WorldGenVillagePieces.WorldGenVillagePiece { - - private IBlockData a; - private IBlockData b; - private IBlockData c; - private IBlockData d; - - public WorldGenVillageFarm2() {} - - public WorldGenVillageFarm2(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - this.a = WorldGenVillagePieces.WorldGenVillageFarm.b(random); - this.b = WorldGenVillagePieces.WorldGenVillageFarm.b(random); - this.c = WorldGenVillagePieces.WorldGenVillageFarm.b(random); - this.d = WorldGenVillagePieces.WorldGenVillageFarm.b(random); - } - - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.set("CA", GameProfileSerializer.a(this.a)); - nbttagcompound.set("CB", GameProfileSerializer.a(this.b)); - nbttagcompound.set("CC", GameProfileSerializer.a(this.c)); - nbttagcompound.set("CD", GameProfileSerializer.a(this.d)); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.a = GameProfileSerializer.d(nbttagcompound.getCompound("CA")); - this.b = GameProfileSerializer.d(nbttagcompound.getCompound("CB")); - this.c = GameProfileSerializer.d(nbttagcompound.getCompound("CC")); - this.d = GameProfileSerializer.d(nbttagcompound.getCompound("CD")); - if (!(this.a.getBlock() instanceof BlockCrops)) { - this.a = Blocks.WHEAT.getBlockData(); - } - - if (!(this.b.getBlock() instanceof BlockCrops)) { - this.b = Blocks.CARROTS.getBlockData(); - } - - if (!(this.c.getBlock() instanceof BlockCrops)) { - this.c = Blocks.POTATOES.getBlockData(); - } - - if (!(this.d.getBlock() instanceof BlockCrops)) { - this.d = Blocks.BEETROOTS.getBlockData(); - } - - } - - public static WorldGenVillagePieces.WorldGenVillageFarm2 a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 13, 4, 9, enumdirection); - - return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageFarm2(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 4 - 1, 0); - } - - IBlockData iblockdata = this.a(Blocks.OAK_LOG.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 12, 4, 8, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 1, 0, 1, 2, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 4, 0, 1, 5, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 7, 0, 1, 8, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 10, 0, 1, 11, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 0, 0, 8, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 6, 0, 0, 6, 0, 8, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 12, 0, 0, 12, 0, 8, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 0, 11, 0, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 8, 11, 0, 8, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 3, 0, 1, 3, 0, 7, Blocks.WATER.getBlockData(), Blocks.WATER.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 9, 0, 1, 9, 0, 7, Blocks.WATER.getBlockData(), Blocks.WATER.getBlockData(), false); - - int i; - - for (i = 1; i <= 7; ++i) { - BlockCrops blockcrops = (BlockCrops) this.a.getBlock(); - int j = blockcrops.e(); - int k = j / 3; - - this.a(generatoraccess, (IBlockData) this.a.set(blockcrops.d(), MathHelper.nextInt(random, k, j)), 1, 1, i, structureboundingbox); - this.a(generatoraccess, (IBlockData) this.a.set(blockcrops.d(), MathHelper.nextInt(random, k, j)), 2, 1, i, structureboundingbox); - blockcrops = (BlockCrops) this.b.getBlock(); - int l = blockcrops.e(); - int i1 = l / 3; - - this.a(generatoraccess, (IBlockData) this.b.set(blockcrops.d(), MathHelper.nextInt(random, i1, l)), 4, 1, i, structureboundingbox); - this.a(generatoraccess, (IBlockData) this.b.set(blockcrops.d(), MathHelper.nextInt(random, i1, l)), 5, 1, i, structureboundingbox); - blockcrops = (BlockCrops) this.c.getBlock(); - int j1 = blockcrops.e(); - int k1 = j1 / 3; - - this.a(generatoraccess, (IBlockData) this.c.set(blockcrops.d(), MathHelper.nextInt(random, k1, j1)), 7, 1, i, structureboundingbox); - this.a(generatoraccess, (IBlockData) this.c.set(blockcrops.d(), MathHelper.nextInt(random, k1, j1)), 8, 1, i, structureboundingbox); - blockcrops = (BlockCrops) this.d.getBlock(); - int l1 = blockcrops.e(); - int i2 = l1 / 3; - - this.a(generatoraccess, (IBlockData) this.d.set(blockcrops.d(), MathHelper.nextInt(random, i2, l1)), 10, 1, i, structureboundingbox); - this.a(generatoraccess, (IBlockData) this.d.set(blockcrops.d(), MathHelper.nextInt(random, i2, l1)), 11, 1, i, structureboundingbox); - } - - for (i = 0; i < 9; ++i) { - for (int j2 = 0; j2 < 13; ++j2) { - this.a(generatoraccess, j2, 4, i, structureboundingbox); - this.b(generatoraccess, Blocks.DIRT.getBlockData(), j2, -1, i, structureboundingbox); - } - } - - return true; - } - } - - public static class WorldGenVillageFarm extends WorldGenVillagePieces.WorldGenVillagePiece { - - private IBlockData a; - private IBlockData b; - - public WorldGenVillageFarm() {} - - public WorldGenVillageFarm(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - this.a = b(random); - this.b = b(random); - } - - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.set("CA", GameProfileSerializer.a(this.a)); - nbttagcompound.set("CB", GameProfileSerializer.a(this.b)); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.a = GameProfileSerializer.d(nbttagcompound.getCompound("CA")); - this.b = GameProfileSerializer.d(nbttagcompound.getCompound("CB")); - } - - private static IBlockData b(Random random) { - switch (random.nextInt(10)) { - case 0: - case 1: - return Blocks.CARROTS.getBlockData(); - case 2: - case 3: - return Blocks.POTATOES.getBlockData(); - case 4: - return Blocks.BEETROOTS.getBlockData(); - default: - return Blocks.WHEAT.getBlockData(); - } - } - - public static WorldGenVillagePieces.WorldGenVillageFarm a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 7, 4, 9, enumdirection); - - return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageFarm(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 4 - 1, 0); - } - - IBlockData iblockdata = this.a(Blocks.OAK_LOG.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 6, 4, 8, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 1, 0, 1, 2, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 4, 0, 1, 5, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 0, 0, 8, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 6, 0, 0, 6, 0, 8, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 0, 5, 0, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 8, 5, 0, 8, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 3, 0, 1, 3, 0, 7, Blocks.WATER.getBlockData(), Blocks.WATER.getBlockData(), false); - - int i; - - for (i = 1; i <= 7; ++i) { - BlockCrops blockcrops = (BlockCrops) this.a.getBlock(); - int j = blockcrops.e(); - int k = j / 3; - - this.a(generatoraccess, (IBlockData) this.a.set(blockcrops.d(), MathHelper.nextInt(random, k, j)), 1, 1, i, structureboundingbox); - this.a(generatoraccess, (IBlockData) this.a.set(blockcrops.d(), MathHelper.nextInt(random, k, j)), 2, 1, i, structureboundingbox); - blockcrops = (BlockCrops) this.b.getBlock(); - int l = blockcrops.e(); - int i1 = l / 3; - - this.a(generatoraccess, (IBlockData) this.b.set(blockcrops.d(), MathHelper.nextInt(random, i1, l)), 4, 1, i, structureboundingbox); - this.a(generatoraccess, (IBlockData) this.b.set(blockcrops.d(), MathHelper.nextInt(random, i1, l)), 5, 1, i, structureboundingbox); - } - - for (i = 0; i < 9; ++i) { - for (int j1 = 0; j1 < 7; ++j1) { - this.a(generatoraccess, j1, 4, i, structureboundingbox); - this.b(generatoraccess, Blocks.DIRT.getBlockData(), j1, -1, i, structureboundingbox); - } - } - - return true; - } - } - - public static class WorldGenVillageBlacksmith extends WorldGenVillagePieces.WorldGenVillagePiece { - - private boolean a; - - public WorldGenVillageBlacksmith() {} - - public WorldGenVillageBlacksmith(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - } - - public static WorldGenVillagePieces.WorldGenVillageBlacksmith a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 10, 6, 7, enumdirection); - - return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageBlacksmith(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; - } - - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.setBoolean("Chest", this.a); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.a = nbttagcompound.getBoolean("Chest"); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 6 - 1, 0); - } - - IBlockData iblockdata = Blocks.COBBLESTONE.getBlockData(); - IBlockData iblockdata1 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.NORTH)); - IBlockData iblockdata2 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.WEST)); - IBlockData iblockdata3 = this.a(Blocks.OAK_PLANKS.getBlockData()); - IBlockData iblockdata4 = this.a((IBlockData) Blocks.COBBLESTONE_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.NORTH)); - IBlockData iblockdata5 = this.a(Blocks.OAK_LOG.getBlockData()); - IBlockData iblockdata6 = this.a(Blocks.OAK_FENCE.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 9, 4, 6, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 9, 0, 6, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 4, 0, 9, 4, 6, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 5, 0, 9, 5, 6, Blocks.STONE_SLAB.getBlockData(), Blocks.STONE_SLAB.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 1, 5, 1, 8, 5, 5, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 1, 1, 0, 2, 3, 0, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 0, 4, 0, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 3, 4, 0, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 6, 0, 4, 6, iblockdata5, iblockdata5, false); - this.a(generatoraccess, iblockdata3, 3, 3, 1, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 3, 1, 2, 3, 3, 2, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 4, 1, 3, 5, 3, 3, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 1, 0, 3, 5, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 6, 5, 3, 6, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 5, 1, 0, 5, 3, 0, iblockdata6, iblockdata6, false); - this.a(generatoraccess, structureboundingbox, 9, 1, 0, 9, 3, 0, iblockdata6, iblockdata6, false); - this.a(generatoraccess, structureboundingbox, 6, 1, 4, 9, 4, 6, iblockdata, iblockdata, false); - this.a(generatoraccess, Blocks.LAVA.getBlockData(), 7, 1, 5, structureboundingbox); - this.a(generatoraccess, Blocks.LAVA.getBlockData(), 8, 1, 5, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.IRON_BARS.getBlockData().set(BlockIronBars.NORTH, true)).set(BlockIronBars.SOUTH, true), 9, 2, 5, structureboundingbox); - this.a(generatoraccess, (IBlockData) Blocks.IRON_BARS.getBlockData().set(BlockIronBars.NORTH, true), 9, 2, 4, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 7, 2, 4, 8, 2, 5, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, iblockdata, 6, 1, 3, structureboundingbox); - this.a(generatoraccess, (IBlockData) Blocks.FURNACE.getBlockData().set(BlockFurnace.FACING, EnumDirection.SOUTH), 6, 2, 3, structureboundingbox); - this.a(generatoraccess, (IBlockData) Blocks.FURNACE.getBlockData().set(BlockFurnace.FACING, EnumDirection.SOUTH), 6, 3, 3, structureboundingbox); - this.a(generatoraccess, (IBlockData) Blocks.STONE_SLAB.getBlockData().set(BlockStepAbstract.a, BlockPropertySlabType.DOUBLE), 8, 1, 1, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 4, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 2, 2, 6, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 4, 2, 6, structureboundingbox); - this.a(generatoraccess, iblockdata6, 2, 1, 4, structureboundingbox); - this.a(generatoraccess, Blocks.OAK_PRESSURE_PLATE.getBlockData(), 2, 2, 4, structureboundingbox); - this.a(generatoraccess, iblockdata3, 1, 1, 5, structureboundingbox); - this.a(generatoraccess, iblockdata1, 2, 1, 5, structureboundingbox); - this.a(generatoraccess, iblockdata2, 1, 1, 4, structureboundingbox); - if (!this.a && structureboundingbox.b((BaseBlockPosition) (new BlockPosition(this.a(5, 5), this.d(1), this.b(5, 5))))) { - this.a = true; - this.a(generatoraccess, structureboundingbox, random, 5, 1, 5, LootTables.e); - } - - int i; - - for (i = 6; i <= 8; ++i) { - if (this.a((IBlockAccess) generatoraccess, i, 0, -1, structureboundingbox).isAir() && !this.a((IBlockAccess) generatoraccess, i, -1, -1, structureboundingbox).isAir()) { - this.a(generatoraccess, iblockdata4, i, 0, -1, structureboundingbox); - if (this.a((IBlockAccess) generatoraccess, i, -1, -1, structureboundingbox).getBlock() == Blocks.GRASS_PATH) { - this.a(generatoraccess, Blocks.GRASS_BLOCK.getBlockData(), i, -1, -1, structureboundingbox); - } - } - } - - for (i = 0; i < 7; ++i) { - for (int j = 0; j < 10; ++j) { - this.a(generatoraccess, j, 6, i, structureboundingbox); - this.b(generatoraccess, iblockdata, j, -1, i, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 7, 1, 1, 1); - return true; - } - - protected int c(int i, int j) { - return 3; - } - } - - public static class WorldGenVillageHouse2 extends WorldGenVillagePieces.WorldGenVillagePiece { - - public WorldGenVillageHouse2() {} - - public WorldGenVillageHouse2(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - } - - public static WorldGenVillagePieces.WorldGenVillageHouse2 a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 9, 7, 12, enumdirection); - - return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageHouse2(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 7 - 1, 0); - } - - IBlockData iblockdata = this.a(Blocks.COBBLESTONE.getBlockData()); - IBlockData iblockdata1 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.NORTH)); - IBlockData iblockdata2 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.SOUTH)); - IBlockData iblockdata3 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.EAST)); - IBlockData iblockdata4 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.WEST)); - IBlockData iblockdata5 = this.a(Blocks.OAK_PLANKS.getBlockData()); - IBlockData iblockdata6 = this.a(Blocks.OAK_LOG.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 1, 1, 1, 7, 4, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 2, 1, 6, 8, 4, 10, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 2, 0, 5, 8, 0, 10, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 1, 7, 0, 4, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 0, 3, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 8, 0, 0, 8, 3, 10, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 0, 7, 2, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 5, 2, 1, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 2, 0, 6, 2, 3, 10, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 3, 0, 10, 7, 3, 10, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 0, 7, 3, 0, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 5, 2, 3, 5, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 0, 4, 1, 8, 4, 1, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 0, 4, 4, 3, 4, 4, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 0, 5, 2, 8, 5, 3, iblockdata5, iblockdata5, false); - this.a(generatoraccess, iblockdata5, 0, 4, 2, structureboundingbox); - this.a(generatoraccess, iblockdata5, 0, 4, 3, structureboundingbox); - this.a(generatoraccess, iblockdata5, 8, 4, 2, structureboundingbox); - this.a(generatoraccess, iblockdata5, 8, 4, 3, structureboundingbox); - this.a(generatoraccess, iblockdata5, 8, 4, 4, structureboundingbox); - IBlockData iblockdata7 = iblockdata1; - IBlockData iblockdata8 = iblockdata2; - IBlockData iblockdata9 = iblockdata4; - IBlockData iblockdata10 = iblockdata3; - - int i; - int j; - - for (j = -1; j <= 2; ++j) { - for (i = 0; i <= 8; ++i) { - this.a(generatoraccess, iblockdata7, i, 4 + j, j, structureboundingbox); - if ((j > -1 || i <= 1) && (j > 0 || i <= 3) && (j > 1 || i <= 4 || i >= 6)) { - this.a(generatoraccess, iblockdata8, i, 4 + j, 5 - j, structureboundingbox); - } - } - } - - this.a(generatoraccess, structureboundingbox, 3, 4, 5, 3, 4, 10, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 7, 4, 2, 7, 4, 10, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 4, 5, 4, 4, 5, 10, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 6, 5, 4, 6, 5, 10, iblockdata5, iblockdata5, false); - this.a(generatoraccess, structureboundingbox, 5, 6, 3, 5, 6, 10, iblockdata5, iblockdata5, false); - - for (j = 4; j >= 1; --j) { - this.a(generatoraccess, iblockdata5, j, 2 + j, 7 - j, structureboundingbox); - - for (i = 8 - j; i <= 10; ++i) { - this.a(generatoraccess, iblockdata10, j, 2 + j, i, structureboundingbox); - } - } - - this.a(generatoraccess, iblockdata5, 6, 6, 3, structureboundingbox); - this.a(generatoraccess, iblockdata5, 7, 5, 4, structureboundingbox); - this.a(generatoraccess, iblockdata4, 6, 6, 4, structureboundingbox); - - for (j = 6; j <= 8; ++j) { - for (i = 5; i <= 10; ++i) { - this.a(generatoraccess, iblockdata9, j, 12 - j, i, structureboundingbox); - } - } - - this.a(generatoraccess, iblockdata6, 0, 2, 1, structureboundingbox); - this.a(generatoraccess, iblockdata6, 0, 2, 4, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 3, structureboundingbox); - this.a(generatoraccess, iblockdata6, 4, 2, 0, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 5, 2, 0, structureboundingbox); - this.a(generatoraccess, iblockdata6, 6, 2, 0, structureboundingbox); - this.a(generatoraccess, iblockdata6, 8, 2, 1, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 2, 3, structureboundingbox); - this.a(generatoraccess, iblockdata6, 8, 2, 4, structureboundingbox); - this.a(generatoraccess, iblockdata5, 8, 2, 5, structureboundingbox); - this.a(generatoraccess, iblockdata6, 8, 2, 6, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 2, 7, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 2, 8, structureboundingbox); - this.a(generatoraccess, iblockdata6, 8, 2, 9, structureboundingbox); - this.a(generatoraccess, iblockdata6, 2, 2, 6, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 2, 2, 7, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 2, 2, 8, structureboundingbox); - this.a(generatoraccess, iblockdata6, 2, 2, 9, structureboundingbox); - this.a(generatoraccess, iblockdata6, 4, 4, 10, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 5, 4, 10, structureboundingbox); - this.a(generatoraccess, iblockdata6, 6, 4, 10, structureboundingbox); - this.a(generatoraccess, iblockdata5, 5, 5, 10, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 2, 1, 0, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 2, 2, 0, structureboundingbox); - this.a(generatoraccess, EnumDirection.NORTH, 2, 3, 1, structureboundingbox); - this.a(generatoraccess, structureboundingbox, random, 2, 1, 0, EnumDirection.NORTH); - this.a(generatoraccess, structureboundingbox, 1, 0, -1, 3, 2, -1, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - if (this.a((IBlockAccess) generatoraccess, 2, 0, -1, structureboundingbox).isAir() && !this.a((IBlockAccess) generatoraccess, 2, -1, -1, structureboundingbox).isAir()) { - this.a(generatoraccess, iblockdata7, 2, 0, -1, structureboundingbox); - if (this.a((IBlockAccess) generatoraccess, 2, -1, -1, structureboundingbox).getBlock() == Blocks.GRASS_PATH) { - this.a(generatoraccess, Blocks.GRASS_BLOCK.getBlockData(), 2, -1, -1, structureboundingbox); - } - } - - for (j = 0; j < 5; ++j) { - for (i = 0; i < 9; ++i) { - this.a(generatoraccess, i, 7, j, structureboundingbox); - this.b(generatoraccess, iblockdata, i, -1, j, structureboundingbox); - } - } - - for (j = 5; j < 11; ++j) { - for (i = 2; i < 9; ++i) { - this.a(generatoraccess, i, 7, j, structureboundingbox); - this.b(generatoraccess, iblockdata, i, -1, j, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 4, 1, 2, 2); - return true; - } - } - - public static class WorldGenVillageButcher extends WorldGenVillagePieces.WorldGenVillagePiece { - - public WorldGenVillageButcher() {} - - public WorldGenVillageButcher(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - } - - public static WorldGenVillagePieces.WorldGenVillageButcher a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 9, 7, 11, enumdirection); - - return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageButcher(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 7 - 1, 0); - } - - IBlockData iblockdata = this.a(Blocks.COBBLESTONE.getBlockData()); - IBlockData iblockdata1 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.NORTH)); - IBlockData iblockdata2 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.SOUTH)); - IBlockData iblockdata3 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.WEST)); - IBlockData iblockdata4 = this.a(Blocks.OAK_PLANKS.getBlockData()); - IBlockData iblockdata5 = this.a(Blocks.OAK_LOG.getBlockData()); - IBlockData iblockdata6 = this.a(Blocks.OAK_FENCE.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 1, 1, 1, 7, 4, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 2, 1, 6, 8, 4, 10, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 2, 0, 6, 8, 0, 10, Blocks.DIRT.getBlockData(), Blocks.DIRT.getBlockData(), false); - this.a(generatoraccess, iblockdata, 6, 0, 6, structureboundingbox); - IBlockData iblockdata7 = (IBlockData) ((IBlockData) iblockdata6.set(BlockFence.NORTH, true)).set(BlockFence.SOUTH, true); - IBlockData iblockdata8 = (IBlockData) ((IBlockData) iblockdata6.set(BlockFence.WEST, true)).set(BlockFence.EAST, true); - - this.a(generatoraccess, structureboundingbox, 2, 1, 6, 2, 1, 9, iblockdata7, iblockdata7, false); - this.a(generatoraccess, (IBlockData) ((IBlockData) iblockdata6.set(BlockFence.SOUTH, true)).set(BlockFence.EAST, true), 2, 1, 10, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 8, 1, 6, 8, 1, 9, iblockdata7, iblockdata7, false); - this.a(generatoraccess, (IBlockData) ((IBlockData) iblockdata6.set(BlockFence.SOUTH, true)).set(BlockFence.WEST, true), 8, 1, 10, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 3, 1, 10, 7, 1, 10, iblockdata8, iblockdata8, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 1, 7, 0, 4, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 0, 3, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 8, 0, 0, 8, 3, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 0, 7, 1, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 5, 7, 1, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 0, 7, 3, 0, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 5, 7, 3, 5, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 0, 4, 1, 8, 4, 1, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 0, 4, 4, 8, 4, 4, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 0, 5, 2, 8, 5, 3, iblockdata4, iblockdata4, false); - this.a(generatoraccess, iblockdata4, 0, 4, 2, structureboundingbox); - this.a(generatoraccess, iblockdata4, 0, 4, 3, structureboundingbox); - this.a(generatoraccess, iblockdata4, 8, 4, 2, structureboundingbox); - this.a(generatoraccess, iblockdata4, 8, 4, 3, structureboundingbox); - IBlockData iblockdata9 = iblockdata1; - IBlockData iblockdata10 = iblockdata2; - - int i; - - for (int j = -1; j <= 2; ++j) { - for (i = 0; i <= 8; ++i) { - this.a(generatoraccess, iblockdata9, i, 4 + j, j, structureboundingbox); - this.a(generatoraccess, iblockdata10, i, 4 + j, 5 - j, structureboundingbox); - } - } - - this.a(generatoraccess, iblockdata5, 0, 2, 1, structureboundingbox); - this.a(generatoraccess, iblockdata5, 0, 2, 4, structureboundingbox); - this.a(generatoraccess, iblockdata5, 8, 2, 1, structureboundingbox); - this.a(generatoraccess, iblockdata5, 8, 2, 4, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 3, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 2, 3, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 2, 2, 5, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 3, 2, 5, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 5, 2, 0, structureboundingbox); - this.a(generatoraccess, iblockdata6, 2, 1, 3, structureboundingbox); - this.a(generatoraccess, Blocks.OAK_PRESSURE_PLATE.getBlockData(), 2, 2, 3, structureboundingbox); - this.a(generatoraccess, iblockdata4, 1, 1, 4, structureboundingbox); - this.a(generatoraccess, iblockdata9, 2, 1, 4, structureboundingbox); - this.a(generatoraccess, iblockdata3, 1, 1, 3, structureboundingbox); - IBlockData iblockdata11 = (IBlockData) Blocks.STONE_SLAB.getBlockData().set(BlockStepAbstract.a, BlockPropertySlabType.DOUBLE); - - this.a(generatoraccess, structureboundingbox, 5, 0, 1, 7, 0, 3, iblockdata11, iblockdata11, false); - this.a(generatoraccess, iblockdata11, 6, 1, 1, structureboundingbox); - this.a(generatoraccess, iblockdata11, 6, 1, 2, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 2, 1, 0, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 2, 2, 0, structureboundingbox); - this.a(generatoraccess, EnumDirection.NORTH, 2, 3, 1, structureboundingbox); - this.a(generatoraccess, structureboundingbox, random, 2, 1, 0, EnumDirection.NORTH); - if (this.a((IBlockAccess) generatoraccess, 2, 0, -1, structureboundingbox).isAir() && !this.a((IBlockAccess) generatoraccess, 2, -1, -1, structureboundingbox).isAir()) { - this.a(generatoraccess, iblockdata9, 2, 0, -1, structureboundingbox); - if (this.a((IBlockAccess) generatoraccess, 2, -1, -1, structureboundingbox).getBlock() == Blocks.GRASS_PATH) { - this.a(generatoraccess, Blocks.GRASS_BLOCK.getBlockData(), 2, -1, -1, structureboundingbox); - } - } - - this.a(generatoraccess, Blocks.AIR.getBlockData(), 6, 1, 5, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 6, 2, 5, structureboundingbox); - this.a(generatoraccess, EnumDirection.SOUTH, 6, 3, 4, structureboundingbox); - this.a(generatoraccess, structureboundingbox, random, 6, 1, 5, EnumDirection.SOUTH); - - for (i = 0; i < 5; ++i) { - for (int k = 0; k < 9; ++k) { - this.a(generatoraccess, k, 7, i, structureboundingbox); - this.b(generatoraccess, iblockdata, k, -1, i, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 4, 1, 2, 2); - return true; - } - - protected int c(int i, int j) { - return i == 0 ? 4 : super.c(i, j); - } - } - - public static class WorldGenVillageHut extends WorldGenVillagePieces.WorldGenVillagePiece { - - private boolean a; - private int b; - - public WorldGenVillageHut() {} - - public WorldGenVillageHut(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - this.a = random.nextBoolean(); - this.b = random.nextInt(3); - } - - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.setInt("T", this.b); - nbttagcompound.setBoolean("C", this.a); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.b = nbttagcompound.getInt("T"); - this.a = nbttagcompound.getBoolean("C"); - } - - public static WorldGenVillagePieces.WorldGenVillageHut a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 4, 6, 5, enumdirection); - - return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageHut(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 6 - 1, 0); - } - - IBlockData iblockdata = this.a(Blocks.COBBLESTONE.getBlockData()); - IBlockData iblockdata1 = this.a(Blocks.OAK_PLANKS.getBlockData()); - IBlockData iblockdata2 = this.a((IBlockData) Blocks.COBBLESTONE_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.NORTH)); - IBlockData iblockdata3 = this.a(Blocks.OAK_LOG.getBlockData()); - IBlockData iblockdata4 = this.a(Blocks.OAK_FENCE.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 1, 1, 1, 3, 5, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 3, 0, 4, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 0, 1, 2, 0, 3, Blocks.DIRT.getBlockData(), Blocks.DIRT.getBlockData(), false); - if (this.a) { - this.a(generatoraccess, structureboundingbox, 1, 4, 1, 2, 4, 3, iblockdata3, iblockdata3, false); - } else { - this.a(generatoraccess, structureboundingbox, 1, 5, 1, 2, 5, 3, iblockdata3, iblockdata3, false); - } - - this.a(generatoraccess, iblockdata3, 1, 4, 0, structureboundingbox); - this.a(generatoraccess, iblockdata3, 2, 4, 0, structureboundingbox); - this.a(generatoraccess, iblockdata3, 1, 4, 4, structureboundingbox); - this.a(generatoraccess, iblockdata3, 2, 4, 4, structureboundingbox); - this.a(generatoraccess, iblockdata3, 0, 4, 1, structureboundingbox); - this.a(generatoraccess, iblockdata3, 0, 4, 2, structureboundingbox); - this.a(generatoraccess, iblockdata3, 0, 4, 3, structureboundingbox); - this.a(generatoraccess, iblockdata3, 3, 4, 1, structureboundingbox); - this.a(generatoraccess, iblockdata3, 3, 4, 2, structureboundingbox); - this.a(generatoraccess, iblockdata3, 3, 4, 3, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 0, 3, 0, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 0, 3, 3, 0, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 4, 0, 3, 4, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 4, 3, 3, 4, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 1, 0, 3, 3, iblockdata1, iblockdata1, false); - this.a(generatoraccess, structureboundingbox, 3, 1, 1, 3, 3, 3, iblockdata1, iblockdata1, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 0, 2, 3, 0, iblockdata1, iblockdata1, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 4, 2, 3, 4, iblockdata1, iblockdata1, false); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 3, 2, 2, structureboundingbox); - if (this.b > 0) { - this.a(generatoraccess, (IBlockData) ((IBlockData) iblockdata4.set(BlockFence.NORTH, true)).set(this.b == 1 ? BlockFence.WEST : BlockFence.EAST, true), this.b, 1, 3, structureboundingbox); - this.a(generatoraccess, Blocks.OAK_PRESSURE_PLATE.getBlockData(), this.b, 2, 3, structureboundingbox); - } - - this.a(generatoraccess, Blocks.AIR.getBlockData(), 1, 1, 0, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 1, 2, 0, structureboundingbox); - this.a(generatoraccess, structureboundingbox, random, 1, 1, 0, EnumDirection.NORTH); - if (this.a((IBlockAccess) generatoraccess, 1, 0, -1, structureboundingbox).isAir() && !this.a((IBlockAccess) generatoraccess, 1, -1, -1, structureboundingbox).isAir()) { - this.a(generatoraccess, iblockdata2, 1, 0, -1, structureboundingbox); - if (this.a((IBlockAccess) generatoraccess, 1, -1, -1, structureboundingbox).getBlock() == Blocks.GRASS_PATH) { - this.a(generatoraccess, Blocks.GRASS_BLOCK.getBlockData(), 1, -1, -1, structureboundingbox); - } - } - - for (int i = 0; i < 5; ++i) { - for (int j = 0; j < 4; ++j) { - this.a(generatoraccess, j, 6, i, structureboundingbox); - this.b(generatoraccess, iblockdata, j, -1, i, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 1, 1, 2, 1); - return true; - } - } - - public static class WorldGenVillageLibrary extends WorldGenVillagePieces.WorldGenVillagePiece { - - public WorldGenVillageLibrary() {} - - public WorldGenVillageLibrary(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - } - - public static WorldGenVillagePieces.WorldGenVillageLibrary a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 9, 9, 6, enumdirection); - - return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageLibrary(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 9 - 1, 0); - } - - IBlockData iblockdata = this.a(Blocks.COBBLESTONE.getBlockData()); - IBlockData iblockdata1 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.NORTH)); - IBlockData iblockdata2 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.SOUTH)); - IBlockData iblockdata3 = this.a((IBlockData) Blocks.OAK_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.EAST)); - IBlockData iblockdata4 = this.a(Blocks.OAK_PLANKS.getBlockData()); - IBlockData iblockdata5 = this.a((IBlockData) Blocks.COBBLESTONE_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.NORTH)); - IBlockData iblockdata6 = this.a(Blocks.OAK_FENCE.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 1, 1, 1, 7, 5, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 8, 0, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 5, 0, 8, 5, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 6, 1, 8, 6, 4, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 7, 2, 8, 7, 3, iblockdata, iblockdata, false); - - int i; - - for (int j = -1; j <= 2; ++j) { - for (i = 0; i <= 8; ++i) { - this.a(generatoraccess, iblockdata1, i, 6 + j, j, structureboundingbox); - this.a(generatoraccess, iblockdata2, i, 6 + j, 5 - j, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 0, 1, 0, 0, 1, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 5, 8, 1, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 8, 1, 0, 8, 1, 4, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 2, 1, 0, 7, 1, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 0, 0, 4, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 5, 0, 4, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 8, 2, 5, 8, 4, 5, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 8, 2, 0, 8, 4, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 2, 1, 0, 4, 4, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 5, 7, 4, 5, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 8, 2, 1, 8, 4, 4, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 1, 2, 0, 7, 4, 0, iblockdata4, iblockdata4, false); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 4, 2, 0, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 5, 2, 0, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 6, 2, 0, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 4, 3, 0, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 5, 3, 0, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 6, 3, 0, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 3, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 3, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 3, 3, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 2, 3, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 3, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 8, 3, 3, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 2, 2, 5, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 3, 2, 5, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 5, 2, 5, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 6, 2, 5, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 1, 4, 1, 7, 4, 1, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 1, 4, 4, 7, 4, 4, iblockdata4, iblockdata4, false); - this.a(generatoraccess, structureboundingbox, 1, 3, 4, 7, 3, 4, Blocks.BOOKSHELF.getBlockData(), Blocks.BOOKSHELF.getBlockData(), false); - this.a(generatoraccess, iblockdata4, 7, 1, 4, structureboundingbox); - this.a(generatoraccess, iblockdata3, 7, 1, 3, structureboundingbox); - this.a(generatoraccess, iblockdata1, 6, 1, 4, structureboundingbox); - this.a(generatoraccess, iblockdata1, 5, 1, 4, structureboundingbox); - this.a(generatoraccess, iblockdata1, 4, 1, 4, structureboundingbox); - this.a(generatoraccess, iblockdata1, 3, 1, 4, structureboundingbox); - this.a(generatoraccess, iblockdata6, 6, 1, 3, structureboundingbox); - this.a(generatoraccess, Blocks.OAK_PRESSURE_PLATE.getBlockData(), 6, 2, 3, structureboundingbox); - this.a(generatoraccess, iblockdata6, 4, 1, 3, structureboundingbox); - this.a(generatoraccess, Blocks.OAK_PRESSURE_PLATE.getBlockData(), 4, 2, 3, structureboundingbox); - this.a(generatoraccess, Blocks.CRAFTING_TABLE.getBlockData(), 7, 1, 1, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 1, 1, 0, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 1, 2, 0, structureboundingbox); - this.a(generatoraccess, structureboundingbox, random, 1, 1, 0, EnumDirection.NORTH); - if (this.a((IBlockAccess) generatoraccess, 1, 0, -1, structureboundingbox).isAir() && !this.a((IBlockAccess) generatoraccess, 1, -1, -1, structureboundingbox).isAir()) { - this.a(generatoraccess, iblockdata5, 1, 0, -1, structureboundingbox); - if (this.a((IBlockAccess) generatoraccess, 1, -1, -1, structureboundingbox).getBlock() == Blocks.GRASS_PATH) { - this.a(generatoraccess, Blocks.GRASS_BLOCK.getBlockData(), 1, -1, -1, structureboundingbox); - } - } - - for (i = 0; i < 6; ++i) { - for (int k = 0; k < 9; ++k) { - this.a(generatoraccess, k, 9, i, structureboundingbox); - this.b(generatoraccess, iblockdata, k, -1, i, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 2, 1, 2, 1); - return true; - } - - protected int c(int i, int j) { - return 1; - } - } - - public static class WorldGenVillageTemple extends WorldGenVillagePieces.WorldGenVillagePiece { - - public WorldGenVillageTemple() {} - - public WorldGenVillageTemple(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - } - - public static WorldGenVillagePieces.WorldGenVillageTemple a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 5, 12, 9, enumdirection); - - return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageTemple(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 12 - 1, 0); - } - - IBlockData iblockdata = Blocks.COBBLESTONE.getBlockData(); - IBlockData iblockdata1 = this.a((IBlockData) Blocks.COBBLESTONE_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.NORTH)); - IBlockData iblockdata2 = this.a((IBlockData) Blocks.COBBLESTONE_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.WEST)); - IBlockData iblockdata3 = this.a((IBlockData) Blocks.COBBLESTONE_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.EAST)); - - this.a(generatoraccess, structureboundingbox, 1, 1, 1, 3, 3, 7, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 1, 5, 1, 3, 9, 3, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - this.a(generatoraccess, structureboundingbox, 1, 0, 0, 3, 0, 8, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 0, 3, 10, 0, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 1, 1, 0, 10, 3, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 4, 1, 1, 4, 10, 3, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 0, 4, 0, 4, 7, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 4, 0, 4, 4, 4, 7, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 8, 3, 4, 8, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 5, 4, 3, 10, 4, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 1, 5, 5, 3, 5, 7, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 9, 0, 4, 9, 4, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 4, 0, 4, 4, 4, iblockdata, iblockdata, false); - this.a(generatoraccess, iblockdata, 0, 11, 2, structureboundingbox); - this.a(generatoraccess, iblockdata, 4, 11, 2, structureboundingbox); - this.a(generatoraccess, iblockdata, 2, 11, 0, structureboundingbox); - this.a(generatoraccess, iblockdata, 2, 11, 4, structureboundingbox); - this.a(generatoraccess, iblockdata, 1, 1, 6, structureboundingbox); - this.a(generatoraccess, iblockdata, 1, 1, 7, structureboundingbox); - this.a(generatoraccess, iblockdata, 2, 1, 7, structureboundingbox); - this.a(generatoraccess, iblockdata, 3, 1, 6, structureboundingbox); - this.a(generatoraccess, iblockdata, 3, 1, 7, structureboundingbox); - this.a(generatoraccess, iblockdata1, 1, 1, 5, structureboundingbox); - this.a(generatoraccess, iblockdata1, 2, 1, 6, structureboundingbox); - this.a(generatoraccess, iblockdata1, 3, 1, 5, structureboundingbox); - this.a(generatoraccess, iblockdata2, 1, 2, 7, structureboundingbox); - this.a(generatoraccess, iblockdata3, 3, 2, 7, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 3, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 4, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 4, 3, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 6, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 7, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 4, 6, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 4, 7, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 2, 6, 0, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 2, 7, 0, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 2, 6, 4, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 2, 7, 4, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 3, 6, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 4, 3, 6, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 2, 3, 8, structureboundingbox); - this.a(generatoraccess, EnumDirection.SOUTH, 2, 4, 7, structureboundingbox); - this.a(generatoraccess, EnumDirection.EAST, 1, 4, 6, structureboundingbox); - this.a(generatoraccess, EnumDirection.WEST, 3, 4, 6, structureboundingbox); - this.a(generatoraccess, EnumDirection.NORTH, 2, 4, 5, structureboundingbox); - IBlockData iblockdata4 = (IBlockData) Blocks.LADDER.getBlockData().set(BlockLadder.FACING, EnumDirection.WEST); - - int i; - - for (i = 1; i <= 9; ++i) { - this.a(generatoraccess, iblockdata4, 3, i, 3, structureboundingbox); - } - - this.a(generatoraccess, Blocks.AIR.getBlockData(), 2, 1, 0, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 2, 2, 0, structureboundingbox); - this.a(generatoraccess, structureboundingbox, random, 2, 1, 0, EnumDirection.NORTH); - if (this.a((IBlockAccess) generatoraccess, 2, 0, -1, structureboundingbox).isAir() && !this.a((IBlockAccess) generatoraccess, 2, -1, -1, structureboundingbox).isAir()) { - this.a(generatoraccess, iblockdata1, 2, 0, -1, structureboundingbox); - if (this.a((IBlockAccess) generatoraccess, 2, -1, -1, structureboundingbox).getBlock() == Blocks.GRASS_PATH) { - this.a(generatoraccess, Blocks.GRASS_BLOCK.getBlockData(), 2, -1, -1, structureboundingbox); - } - } - - for (i = 0; i < 9; ++i) { - for (int j = 0; j < 5; ++j) { - this.a(generatoraccess, j, 12, i, structureboundingbox); - this.b(generatoraccess, iblockdata, j, -1, i, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 2, 1, 2, 1); - return true; - } - - protected int c(int i, int j) { - return 2; - } - } - - public static class WorldGenVillageHouse extends WorldGenVillagePieces.WorldGenVillagePiece { - - private boolean a; - - public WorldGenVillageHouse() {} - - public WorldGenVillageHouse(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - this.a = random.nextBoolean(); - } - - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.setBoolean("Terrace", this.a); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.a = nbttagcompound.getBoolean("Terrace"); - } - - public static WorldGenVillagePieces.WorldGenVillageHouse a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 5, 6, 5, enumdirection); - - return StructurePiece.a(list, structureboundingbox) != null ? null : new WorldGenVillagePieces.WorldGenVillageHouse(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 6 - 1, 0); - } - - IBlockData iblockdata = this.a(Blocks.COBBLESTONE.getBlockData()); - IBlockData iblockdata1 = this.a(Blocks.OAK_PLANKS.getBlockData()); - IBlockData iblockdata2 = this.a((IBlockData) Blocks.COBBLESTONE_STAIRS.getBlockData().set(BlockStairs.FACING, EnumDirection.NORTH)); - IBlockData iblockdata3 = this.a(Blocks.OAK_LOG.getBlockData()); - IBlockData iblockdata4 = this.a(Blocks.OAK_FENCE.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 0, 0, 0, 4, 0, 4, iblockdata, iblockdata, false); - this.a(generatoraccess, structureboundingbox, 0, 4, 0, 4, 4, 4, iblockdata3, iblockdata3, false); - this.a(generatoraccess, structureboundingbox, 1, 4, 1, 3, 4, 3, iblockdata1, iblockdata1, false); - this.a(generatoraccess, iblockdata, 0, 1, 0, structureboundingbox); - this.a(generatoraccess, iblockdata, 0, 2, 0, structureboundingbox); - this.a(generatoraccess, iblockdata, 0, 3, 0, structureboundingbox); - this.a(generatoraccess, iblockdata, 4, 1, 0, structureboundingbox); - this.a(generatoraccess, iblockdata, 4, 2, 0, structureboundingbox); - this.a(generatoraccess, iblockdata, 4, 3, 0, structureboundingbox); - this.a(generatoraccess, iblockdata, 0, 1, 4, structureboundingbox); - this.a(generatoraccess, iblockdata, 0, 2, 4, structureboundingbox); - this.a(generatoraccess, iblockdata, 0, 3, 4, structureboundingbox); - this.a(generatoraccess, iblockdata, 4, 1, 4, structureboundingbox); - this.a(generatoraccess, iblockdata, 4, 2, 4, structureboundingbox); - this.a(generatoraccess, iblockdata, 4, 3, 4, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 0, 1, 1, 0, 3, 3, iblockdata1, iblockdata1, false); - this.a(generatoraccess, structureboundingbox, 4, 1, 1, 4, 3, 3, iblockdata1, iblockdata1, false); - this.a(generatoraccess, structureboundingbox, 1, 1, 4, 3, 3, 4, iblockdata1, iblockdata1, false); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 0, 2, 2, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.EAST, true)).set(BlockGlassPane.WEST, true), 2, 2, 4, structureboundingbox); - this.a(generatoraccess, (IBlockData) ((IBlockData) Blocks.GLASS_PANE.getBlockData().set(BlockGlassPane.SOUTH, true)).set(BlockGlassPane.NORTH, true), 4, 2, 2, structureboundingbox); - this.a(generatoraccess, iblockdata1, 1, 1, 0, structureboundingbox); - this.a(generatoraccess, iblockdata1, 1, 2, 0, structureboundingbox); - this.a(generatoraccess, iblockdata1, 1, 3, 0, structureboundingbox); - this.a(generatoraccess, iblockdata1, 2, 3, 0, structureboundingbox); - this.a(generatoraccess, iblockdata1, 3, 3, 0, structureboundingbox); - this.a(generatoraccess, iblockdata1, 3, 2, 0, structureboundingbox); - this.a(generatoraccess, iblockdata1, 3, 1, 0, structureboundingbox); - if (this.a((IBlockAccess) generatoraccess, 2, 0, -1, structureboundingbox).isAir() && !this.a((IBlockAccess) generatoraccess, 2, -1, -1, structureboundingbox).isAir()) { - this.a(generatoraccess, iblockdata2, 2, 0, -1, structureboundingbox); - if (this.a((IBlockAccess) generatoraccess, 2, -1, -1, structureboundingbox).getBlock() == Blocks.GRASS_PATH) { - this.a(generatoraccess, Blocks.GRASS_BLOCK.getBlockData(), 2, -1, -1, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 1, 1, 1, 3, 3, 3, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); - if (this.a) { - boolean flag = false; - boolean flag1 = true; - - for (int i = 0; i <= 4; ++i) { - for (int j = 0; j <= 4; ++j) { - boolean flag2 = i == 0 || i == 4; - boolean flag3 = j == 0 || j == 4; - - if (flag2 || flag3) { - boolean flag4 = i == 0 || i == 4; - boolean flag5 = j == 0 || j == 4; - IBlockData iblockdata5 = (IBlockData) ((IBlockData) ((IBlockData) ((IBlockData) iblockdata4.set(BlockFence.SOUTH, flag4 && j != 0)).set(BlockFence.NORTH, flag4 && j != 4)).set(BlockFence.WEST, flag5 && i != 0)).set(BlockFence.EAST, flag5 && i != 4); - - this.a(generatoraccess, iblockdata5, i, 5, j, structureboundingbox); - } - } - } - } - - if (this.a) { - IBlockData iblockdata6 = (IBlockData) Blocks.LADDER.getBlockData().set(BlockLadder.FACING, EnumDirection.SOUTH); - - this.a(generatoraccess, iblockdata6, 3, 1, 3, structureboundingbox); - this.a(generatoraccess, iblockdata6, 3, 2, 3, structureboundingbox); - this.a(generatoraccess, iblockdata6, 3, 3, 3, structureboundingbox); - this.a(generatoraccess, iblockdata6, 3, 4, 3, structureboundingbox); - } - - this.a(generatoraccess, EnumDirection.NORTH, 2, 3, 1, structureboundingbox); - - for (int k = 0; k < 5; ++k) { - for (int l = 0; l < 5; ++l) { - this.a(generatoraccess, l, 6, k, structureboundingbox); - this.b(generatoraccess, iblockdata, l, -1, k, structureboundingbox); - } - } - - this.a(generatoraccess, structureboundingbox, 1, 1, 2, 1); - return true; - } - } - - public static class WorldGenVillageRoad extends WorldGenVillagePieces.WorldGenVillageRoadPiece { - - private int a; - - public WorldGenVillageRoad() {} - - public WorldGenVillageRoad(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(enumdirection); - this.n = structureboundingbox; - this.a = Math.max(structureboundingbox.c(), structureboundingbox.e()); - } - - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.setInt("Length", this.a); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.a = nbttagcompound.getInt("Length"); - } - - public void a(StructurePiece structurepiece, List list, Random random) { - boolean flag = false; - - StructurePiece structurepiece1; - int i; - - for (i = random.nextInt(5); i < this.a - 8; i += 2 + random.nextInt(5)) { - structurepiece1 = this.a((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, 0, i); - if (structurepiece1 != null) { - i += Math.max(structurepiece1.n.c(), structurepiece1.n.e()); - flag = true; - } - } - - for (i = random.nextInt(5); i < this.a - 8; i += 2 + random.nextInt(5)) { - structurepiece1 = this.b((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, 0, i); - if (structurepiece1 != null) { - i += Math.max(structurepiece1.n.c(), structurepiece1.n.e()); - flag = true; - } - } - - EnumDirection enumdirection = this.f(); - - if (flag && random.nextInt(3) > 0 && enumdirection != null) { - switch (enumdirection) { - case NORTH: - default: - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.a - 1, this.n.b, this.n.c, EnumDirection.WEST, this.e()); - break; - case SOUTH: - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.a - 1, this.n.b, this.n.f - 2, EnumDirection.WEST, this.e()); - break; - case WEST: - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.a, this.n.b, this.n.c - 1, EnumDirection.NORTH, this.e()); - break; - case EAST: - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.d - 2, this.n.b, this.n.c - 1, EnumDirection.NORTH, this.e()); - } - } - - if (flag && random.nextInt(3) > 0 && enumdirection != null) { - switch (enumdirection) { - case NORTH: - default: - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.d + 1, this.n.b, this.n.c, EnumDirection.EAST, this.e()); - break; - case SOUTH: - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.d + 1, this.n.b, this.n.f - 2, EnumDirection.EAST, this.e()); - break; - case WEST: - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.a, this.n.b, this.n.f + 1, EnumDirection.SOUTH, this.e()); - break; - case EAST: - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.d - 2, this.n.b, this.n.f + 1, EnumDirection.SOUTH, this.e()); - } - } - - } - - public static StructureBoundingBox a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection) { - for (int l = 7 * MathHelper.nextInt(random, 3, 5); l >= 7; l -= 7) { - StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 3, 3, l, enumdirection); - - if (StructurePiece.a(list, structureboundingbox) == null) { - return structureboundingbox; - } - } - - return null; - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - IBlockData iblockdata = this.a(Blocks.GRASS_PATH.getBlockData()); - IBlockData iblockdata1 = this.a(Blocks.OAK_PLANKS.getBlockData()); - IBlockData iblockdata2 = this.a(Blocks.GRAVEL.getBlockData()); - IBlockData iblockdata3 = this.a(Blocks.COBBLESTONE.getBlockData()); - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - - this.n.b = 1000; - this.n.e = 0; - - for (int i = this.n.a; i <= this.n.d; ++i) { - for (int j = this.n.c; j <= this.n.f; ++j) { - blockposition_mutableblockposition.c(i, 64, j); - if (structureboundingbox.b((BaseBlockPosition) blockposition_mutableblockposition)) { - int k = generatoraccess.a(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, blockposition_mutableblockposition.getX(), blockposition_mutableblockposition.getZ()); - - blockposition_mutableblockposition.c(blockposition_mutableblockposition.getX(), k, blockposition_mutableblockposition.getZ()).c(EnumDirection.DOWN); - if (blockposition_mutableblockposition.getY() < generatoraccess.getSeaLevel()) { - blockposition_mutableblockposition.p(generatoraccess.getSeaLevel() - 1); - } - - while (blockposition_mutableblockposition.getY() >= generatoraccess.getSeaLevel() - 1) { - IBlockData iblockdata4 = generatoraccess.getType(blockposition_mutableblockposition); - Block block = iblockdata4.getBlock(); - - if (block == Blocks.GRASS_BLOCK && generatoraccess.isEmpty(blockposition_mutableblockposition.up())) { - generatoraccess.setTypeAndData(blockposition_mutableblockposition, iblockdata, 2); - break; - } - - if (iblockdata4.getMaterial().isLiquid()) { - generatoraccess.setTypeAndData(new BlockPosition(blockposition_mutableblockposition), iblockdata1, 2); - break; - } - - if (block == Blocks.SAND || block == Blocks.RED_SAND || block == Blocks.SANDSTONE || block == Blocks.CHISELED_SANDSTONE || block == Blocks.CUT_SANDSTONE || block == Blocks.RED_SANDSTONE || block == Blocks.CHISELED_SANDSTONE || block == Blocks.CUT_SANDSTONE) { - generatoraccess.setTypeAndData(blockposition_mutableblockposition, iblockdata2, 2); - generatoraccess.setTypeAndData(blockposition_mutableblockposition.down(), iblockdata3, 2); - break; - } - - blockposition_mutableblockposition.c(EnumDirection.DOWN); - } - - this.n.b = Math.min(this.n.b, blockposition_mutableblockposition.getY()); - this.n.e = Math.max(this.n.e, blockposition_mutableblockposition.getY()); - } - } - } - - return true; - } - } - - public abstract static class WorldGenVillageRoadPiece extends WorldGenVillagePieces.WorldGenVillagePiece { - - public WorldGenVillageRoadPiece() {} - - protected WorldGenVillageRoadPiece(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - } - } - - public static class WorldGenVillageStartPiece extends WorldGenVillagePieces.WorldGenVillageWell { - - public int a; - public WorldGenVillagePieces.WorldGenVillagePieceWeight b; - public List c; - public List d = Lists.newArrayList(); - public List e = Lists.newArrayList(); - - public WorldGenVillageStartPiece() {} - - public WorldGenVillageStartPiece(int i, Random random, int j, int k, List list, WorldGenFeatureVillageConfiguration worldgenfeaturevillageconfiguration) { - super((WorldGenVillagePieces.WorldGenVillageStartPiece) null, 0, random, j, k); - this.c = list; - this.a = worldgenfeaturevillageconfiguration.a; - this.g = worldgenfeaturevillageconfiguration.b; - this.a(this.g); - this.h = random.nextInt(50) == 0; - } - } - - public static class WorldGenVillageWell extends WorldGenVillagePieces.WorldGenVillagePiece { - - public WorldGenVillageWell() {} - - public WorldGenVillageWell(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, int j, int k) { - super(worldgenvillagepieces_worldgenvillagestartpiece, i); - this.a(EnumDirection.EnumDirectionLimit.HORIZONTAL.a(random)); - if (this.f().k() == EnumDirection.EnumAxis.Z) { - this.n = new StructureBoundingBox(j, 64, k, j + 6 - 1, 78, k + 6 - 1); - } else { - this.n = new StructureBoundingBox(j, 64, k, j + 6 - 1, 78, k + 6 - 1); - } - - } - - public void a(StructurePiece structurepiece, List list, Random random) { - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.a - 1, this.n.e - 4, this.n.c + 1, EnumDirection.WEST, this.e()); - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.d + 1, this.n.e - 4, this.n.c + 1, EnumDirection.EAST, this.e()); - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.a + 1, this.n.e - 4, this.n.c - 1, EnumDirection.NORTH, this.e()); - WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.n.a + 1, this.n.e - 4, this.n.f + 1, EnumDirection.SOUTH, this.e()); - } - - public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { - if (this.f < 0) { - this.f = this.a(generatoraccess, structureboundingbox); - if (this.f < 0) { - return true; - } - - this.n.a(0, this.f - this.n.e + 3, 0); - } - - IBlockData iblockdata = this.a(Blocks.COBBLESTONE.getBlockData()); - IBlockData iblockdata1 = this.a(Blocks.OAK_FENCE.getBlockData()); - - this.a(generatoraccess, structureboundingbox, 1, 0, 1, 4, 12, 4, iblockdata, Blocks.WATER.getBlockData(), false); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 2, 12, 2, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 3, 12, 2, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 2, 12, 3, structureboundingbox); - this.a(generatoraccess, Blocks.AIR.getBlockData(), 3, 12, 3, structureboundingbox); - this.a(generatoraccess, iblockdata1, 1, 13, 1, structureboundingbox); - this.a(generatoraccess, iblockdata1, 1, 14, 1, structureboundingbox); - this.a(generatoraccess, iblockdata1, 4, 13, 1, structureboundingbox); - this.a(generatoraccess, iblockdata1, 4, 14, 1, structureboundingbox); - this.a(generatoraccess, iblockdata1, 1, 13, 4, structureboundingbox); - this.a(generatoraccess, iblockdata1, 1, 14, 4, structureboundingbox); - this.a(generatoraccess, iblockdata1, 4, 13, 4, structureboundingbox); - this.a(generatoraccess, iblockdata1, 4, 14, 4, structureboundingbox); - this.a(generatoraccess, structureboundingbox, 1, 15, 1, 4, 15, 4, iblockdata, iblockdata, false); - - for (int i = 0; i <= 5; ++i) { - for (int j = 0; j <= 5; ++j) { - if (j == 0 || j == 5 || i == 0 || i == 5) { - this.a(generatoraccess, iblockdata, j, 11, i, structureboundingbox); - this.a(generatoraccess, j, 12, i, structureboundingbox); - } - } - } - - return true; - } - } - - abstract static class WorldGenVillagePiece extends StructurePiece { - - protected int f = -1; - private int a; - protected WorldGenVillagePieces.Material g; - protected boolean h; - - public WorldGenVillagePiece() {} - - protected WorldGenVillagePiece(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i) { - super(i); - if (worldgenvillagepieces_worldgenvillagestartpiece != null) { - this.g = worldgenvillagepieces_worldgenvillagestartpiece.g; - this.h = worldgenvillagepieces_worldgenvillagestartpiece.h; - } - - } - - protected void a(NBTTagCompound nbttagcompound) { - nbttagcompound.setInt("HPos", this.f); - nbttagcompound.setInt("VCount", this.a); - nbttagcompound.setByte("Type", (byte) this.g.a()); - nbttagcompound.setBoolean("Zombie", this.h); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - this.f = nbttagcompound.getInt("HPos"); - this.a = nbttagcompound.getInt("VCount"); - this.g = WorldGenVillagePieces.Material.a(nbttagcompound.getByte("Type")); - if (nbttagcompound.getBoolean("Desert")) { - this.g = WorldGenVillagePieces.Material.SANDSTONE; - } - - this.h = nbttagcompound.getBoolean("Zombie"); - } - - @Nullable - protected StructurePiece a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j) { - EnumDirection enumdirection = this.f(); - - if (enumdirection != null) { - switch (enumdirection) { - case NORTH: - default: - return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.n.a - 1, this.n.b + i, this.n.c + j, EnumDirection.WEST, this.e()); - case SOUTH: - return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.n.a - 1, this.n.b + i, this.n.c + j, EnumDirection.WEST, this.e()); - case WEST: - return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.n.a + j, this.n.b + i, this.n.c - 1, EnumDirection.NORTH, this.e()); - case EAST: - return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.n.a + j, this.n.b + i, this.n.c - 1, EnumDirection.NORTH, this.e()); - } - } else { - return null; - } - } - - @Nullable - protected StructurePiece b(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j) { - EnumDirection enumdirection = this.f(); - - if (enumdirection != null) { - switch (enumdirection) { - case NORTH: - default: - return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.n.d + 1, this.n.b + i, this.n.c + j, EnumDirection.EAST, this.e()); - case SOUTH: - return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.n.d + 1, this.n.b + i, this.n.c + j, EnumDirection.EAST, this.e()); - case WEST: - return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.n.a + j, this.n.b + i, this.n.f + 1, EnumDirection.SOUTH, this.e()); - case EAST: - return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.n.a + j, this.n.b + i, this.n.f + 1, EnumDirection.SOUTH, this.e()); - } - } else { - return null; - } - } - - protected int a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox) { - int i = 0; - int j = 0; - BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); - - for (int k = this.n.c; k <= this.n.f; ++k) { - for (int l = this.n.a; l <= this.n.d; ++l) { - blockposition_mutableblockposition.c(l, 64, k); - if (structureboundingbox.b((BaseBlockPosition) blockposition_mutableblockposition)) { - i += generatoraccess.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, blockposition_mutableblockposition).getY(); - ++j; - } - } - } - - if (j == 0) { - return -1; - } else { - return i / j; - } - } - - protected static boolean a(StructureBoundingBox structureboundingbox) { - return structureboundingbox != null && structureboundingbox.b > 10; - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, int i, int j, int k, int l) { - if (this.a < l) { - for (int i1 = this.a; i1 < l; ++i1) { - int j1 = this.a(i + i1, k); - int k1 = this.d(j); - int l1 = this.b(i + i1, k); - - if (!structureboundingbox.b((BaseBlockPosition) (new BlockPosition(j1, k1, l1)))) { - break; - } - - ++this.a; - if (this.h) { - EntityZombieVillager entityzombievillager = EntityTypes.ZOMBIE_VILLAGER.create(generatoraccess.getMinecraftWorld()); // Paper - - entityzombievillager.setPositionRotation((double) j1 + 0.5D, (double) k1, (double) l1 + 0.5D, 0.0F, 0.0F); - entityzombievillager.prepare(generatoraccess.getDamageScaler(new BlockPosition(entityzombievillager)), (GroupDataEntity) null, (NBTTagCompound) null); - entityzombievillager.setProfession(this.c(i1, 0)); - entityzombievillager.di(); - generatoraccess.addEntity(entityzombievillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason - } else { - EntityVillager entityvillager = EntityTypes.VILLAGER.create(generatoraccess.getMinecraftWorld()); // Paper - - entityvillager.setPositionRotation((double) j1 + 0.5D, (double) k1, (double) l1 + 0.5D, 0.0F, 0.0F); - entityvillager.setProfession(this.c(i1, generatoraccess.m().nextInt(6))); - entityvillager.a(generatoraccess.getDamageScaler(new BlockPosition(entityvillager)), (GroupDataEntity) null, (NBTTagCompound) null, false); - generatoraccess.addEntity(entityvillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason - } - } - - } - } - - protected int c(int i, int j) { - return j; - } - - protected IBlockData a(IBlockData iblockdata) { - Block block = iblockdata.getBlock(); - - if (this.g == WorldGenVillagePieces.Material.SANDSTONE) { - if (block.a(TagsBlock.LOGS) || block == Blocks.COBBLESTONE) { - return Blocks.SANDSTONE.getBlockData(); - } - - if (block.a(TagsBlock.PLANKS)) { - return Blocks.CUT_SANDSTONE.getBlockData(); - } - - if (block == Blocks.OAK_STAIRS) { - return (IBlockData) Blocks.SANDSTONE_STAIRS.getBlockData().set(BlockStairs.FACING, iblockdata.get(BlockStairs.FACING)); - } - - if (block == Blocks.COBBLESTONE_STAIRS) { - return (IBlockData) Blocks.SANDSTONE_STAIRS.getBlockData().set(BlockStairs.FACING, iblockdata.get(BlockStairs.FACING)); - } - - if (block == Blocks.GRAVEL) { - return Blocks.SANDSTONE.getBlockData(); - } - - if (block == Blocks.OAK_PRESSURE_PLATE) { - return Blocks.BIRCH_PRESSURE_PLATE.getBlockData(); - } - } else if (this.g == WorldGenVillagePieces.Material.SPRUCE) { - if (block.a(TagsBlock.LOGS)) { - return (IBlockData) Blocks.SPRUCE_LOG.getBlockData().set(BlockLogAbstract.AXIS, iblockdata.get(BlockLogAbstract.AXIS)); - } - - if (block.a(TagsBlock.PLANKS)) { - return Blocks.SPRUCE_PLANKS.getBlockData(); - } - - if (block == Blocks.OAK_STAIRS) { - return (IBlockData) Blocks.SPRUCE_STAIRS.getBlockData().set(BlockStairs.FACING, iblockdata.get(BlockStairs.FACING)); - } - - if (block == Blocks.OAK_FENCE) { - return Blocks.SPRUCE_FENCE.getBlockData(); - } - - if (block == Blocks.OAK_PRESSURE_PLATE) { - return Blocks.SPRUCE_PRESSURE_PLATE.getBlockData(); - } - } else if (this.g == WorldGenVillagePieces.Material.ACACIA) { - if (block.a(TagsBlock.LOGS)) { - return (IBlockData) Blocks.ACACIA_LOG.getBlockData().set(BlockLogAbstract.AXIS, iblockdata.get(BlockLogAbstract.AXIS)); - } - - if (block.a(TagsBlock.PLANKS)) { - return Blocks.ACACIA_PLANKS.getBlockData(); - } - - if (block == Blocks.OAK_STAIRS) { - return (IBlockData) Blocks.ACACIA_STAIRS.getBlockData().set(BlockStairs.FACING, iblockdata.get(BlockStairs.FACING)); - } - - if (block == Blocks.COBBLESTONE) { - return (IBlockData) Blocks.ACACIA_LOG.getBlockData().set(BlockLogAbstract.AXIS, EnumDirection.EnumAxis.Y); - } - - if (block == Blocks.OAK_FENCE) { - return Blocks.ACACIA_FENCE.getBlockData(); - } - - if (block == Blocks.OAK_PRESSURE_PLATE) { - return Blocks.ACACIA_PRESSURE_PLATE.getBlockData(); - } - } - - return iblockdata; - } - - protected BlockDoor b() { - return this.g == WorldGenVillagePieces.Material.ACACIA ? (BlockDoor) Blocks.ACACIA_DOOR : (this.g == WorldGenVillagePieces.Material.SPRUCE ? (BlockDoor) Blocks.SPRUCE_DOOR : (BlockDoor) Blocks.OAK_DOOR); - } - - protected void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox, Random random, int i, int j, int k, EnumDirection enumdirection) { - if (!this.h) { - this.a(generatoraccess, structureboundingbox, random, i, j, k, EnumDirection.NORTH, this.b()); - } - - } - - protected void a(GeneratorAccess generatoraccess, EnumDirection enumdirection, int i, int j, int k, StructureBoundingBox structureboundingbox) { - if (!this.h) { - this.a(generatoraccess, (IBlockData) Blocks.WALL_TORCH.getBlockData().set(BlockTorchWall.a, enumdirection), i, j, k, structureboundingbox); - } - - } - - protected void b(GeneratorAccess generatoraccess, IBlockData iblockdata, int i, int j, int k, StructureBoundingBox structureboundingbox) { - IBlockData iblockdata1 = this.a(iblockdata); - - super.b(generatoraccess, iblockdata1, i, j, k, structureboundingbox); - } - - protected void a(WorldGenVillagePieces.Material worldgenvillagepieces_material) { - this.g = worldgenvillagepieces_material; - } - } - - public static class WorldGenVillagePieceWeight { - - public Class a; - public final int b; - public int c; - public int d; - - public WorldGenVillagePieceWeight(Class oclass, int i, int j) { - this.a = oclass; - this.b = i; - this.d = j; - } - - public boolean a(int i) { - return this.d == 0 || this.c < this.d; - } - - public boolean a() { - return this.d == 0 || this.c < this.d; - } - } - - public static enum Material { - - OAK(0), SANDSTONE(1), ACACIA(2), SPRUCE(3); - - private final int e; - - private Material(int i) { - this.e = i; - } - - public int a() { - return this.e; - } - - public static WorldGenVillagePieces.Material a(int i) { - WorldGenVillagePieces.Material[] aworldgenvillagepieces_material = values(); - - return i >= 0 && i < aworldgenvillagepieces_material.length ? aworldgenvillagepieces_material[i] : WorldGenVillagePieces.Material.OAK; - } - } -} diff --git a/src/main/java/net/minecraft/server/WorldGenWitchHut.java b/src/main/java/net/minecraft/server/WorldGenWitchHut.java index 3d8193c47..e39228cc8 100644 --- a/src/main/java/net/minecraft/server/WorldGenWitchHut.java +++ b/src/main/java/net/minecraft/server/WorldGenWitchHut.java @@ -5,27 +5,26 @@ import java.util.Random; public class WorldGenWitchHut extends WorldGenScatteredPiece { private boolean e; - - public static void b() { - WorldGenFactory.a(WorldGenWitchHut.class, "TeSH"); - } - - public WorldGenWitchHut() {} + private boolean f; public WorldGenWitchHut(Random random, int i, int j) { - super(random, i, 64, j, 7, 7, 9); + super(WorldGenFeatureStructurePieceType.L, random, i, 64, j, 7, 7, 9); } + public WorldGenWitchHut(DefinedStructureManager definedstructuremanager, NBTTagCompound nbttagcompound) { + super(WorldGenFeatureStructurePieceType.L, nbttagcompound); + this.e = nbttagcompound.getBoolean("Witch"); + this.f = nbttagcompound.getBoolean("Cat"); + } + + @Override protected void a(NBTTagCompound nbttagcompound) { super.a(nbttagcompound); nbttagcompound.setBoolean("Witch", this.e); + nbttagcompound.setBoolean("Cat", this.f); } - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.e = nbttagcompound.getBoolean("Witch"); - } - + @Override public boolean a(GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox, ChunkCoordIntPair chunkcoordintpair) { if (!this.a(generatoraccess, structureboundingbox, 0)) { return false; @@ -81,16 +80,36 @@ public class WorldGenWitchHut extends WorldGenScatteredPiece { if (structureboundingbox.b((BaseBlockPosition) (new BlockPosition(j, i, k)))) { this.e = true; - EntityWitch entitywitch = EntityTypes.WITCH.create(generatoraccess.getMinecraftWorld()); // Paper + EntityWitch entitywitch = (EntityWitch) EntityTypes.WITCH.a(generatoraccess.getMinecraftWorld()); - entitywitch.di(); + entitywitch.setPersistent(); entitywitch.setPositionRotation((double) j + 0.5D, (double) i, (double) k + 0.5D, 0.0F, 0.0F); - entitywitch.prepare(generatoraccess.getDamageScaler(new BlockPosition(j, i, k)), (GroupDataEntity) null, (NBTTagCompound) null); + entitywitch.prepare(generatoraccess, generatoraccess.getDamageScaler(new BlockPosition(j, i, k)), EnumMobSpawn.STRUCTURE, (GroupDataEntity) null, (NBTTagCompound) null); generatoraccess.addEntity(entitywitch, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason } } + this.a(generatoraccess, structureboundingbox); return true; } } + + private void a(GeneratorAccess generatoraccess, StructureBoundingBox structureboundingbox) { + if (!this.f) { + int i = this.a(2, 5); + int j = this.d(2); + int k = this.b(2, 5); + + if (structureboundingbox.b((BaseBlockPosition) (new BlockPosition(i, j, k)))) { + this.f = true; + EntityCat entitycat = (EntityCat) EntityTypes.CAT.a(generatoraccess.getMinecraftWorld()); + + entitycat.setPersistent(); + entitycat.setPositionRotation((double) i + 0.5D, (double) j, (double) k + 0.5D, 0.0F, 0.0F); + entitycat.prepare(generatoraccess, generatoraccess.getDamageScaler(new BlockPosition(i, j, k)), EnumMobSpawn.STRUCTURE, (GroupDataEntity) null, (NBTTagCompound) null); + generatoraccess.addEntity(entitycat); + } + } + + } } diff --git a/src/main/java/net/minecraft/server/WorldGenWoodlandMansionPieces.java b/src/main/java/net/minecraft/server/WorldGenWoodlandMansionPieces.java deleted file mode 100644 index 4eb746ebb..000000000 --- a/src/main/java/net/minecraft/server/WorldGenWoodlandMansionPieces.java +++ /dev/null @@ -1,1084 +0,0 @@ -package net.minecraft.server; - -import com.google.common.collect.Lists; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Random; -import javax.annotation.Nullable; - -public class WorldGenWoodlandMansionPieces { - - public static void a() { - WorldGenFactory.a(WorldGenWoodlandMansionPieces.i.class, "WMP"); - } - - public static void a(DefinedStructureManager definedstructuremanager, BlockPosition blockposition, EnumBlockRotation enumblockrotation, List list, Random random) { - WorldGenWoodlandMansionPieces.c worldgenwoodlandmansionpieces_c = new WorldGenWoodlandMansionPieces.c(random); - WorldGenWoodlandMansionPieces.d worldgenwoodlandmansionpieces_d = new WorldGenWoodlandMansionPieces.d(definedstructuremanager, random); - - worldgenwoodlandmansionpieces_d.a(blockposition, enumblockrotation, list, worldgenwoodlandmansionpieces_c); - } - - static class h extends WorldGenWoodlandMansionPieces.f { - - private h() { - super(); // Paper - decompile fix - } - } - - static class f extends WorldGenWoodlandMansionPieces.b { - - private f() { - super(); // Paper - decompile fix - } - - public String a(Random random) { - return "1x1_b" + (random.nextInt(4) + 1); - } - - public String b(Random random) { - return "1x1_as" + (random.nextInt(4) + 1); - } - - public String a(Random random, boolean flag) { - return flag ? "1x2_c_stairs" : "1x2_c" + (random.nextInt(4) + 1); - } - - public String b(Random random, boolean flag) { - return flag ? "1x2_d_stairs" : "1x2_d" + (random.nextInt(5) + 1); - } - - public String c(Random random) { - return "1x2_se" + (random.nextInt(1) + 1); - } - - public String d(Random random) { - return "2x2_b" + (random.nextInt(5) + 1); - } - - public String e(Random random) { - return "2x2_s1"; - } - } - - static class a extends WorldGenWoodlandMansionPieces.b { - - private a() { - super(); // Paper - decompile fix - } - - public String a(Random random) { - return "1x1_a" + (random.nextInt(5) + 1); - } - - public String b(Random random) { - return "1x1_as" + (random.nextInt(4) + 1); - } - - public String a(Random random, boolean flag) { - return "1x2_a" + (random.nextInt(9) + 1); - } - - public String b(Random random, boolean flag) { - return "1x2_b" + (random.nextInt(5) + 1); - } - - public String c(Random random) { - return "1x2_s" + (random.nextInt(2) + 1); - } - - public String d(Random random) { - return "2x2_a" + (random.nextInt(4) + 1); - } - - public String e(Random random) { - return "2x2_s1"; - } - } - - abstract static class b { - - private b() {} - - public abstract String a(Random random); - - public abstract String b(Random random); - - public abstract String a(Random random, boolean flag); - - public abstract String b(Random random, boolean flag); - - public abstract String c(Random random); - - public abstract String d(Random random); - - public abstract String e(Random random); - } - - static class g { - - private final int[][] a; - private final int b; - private final int c; - private final int d; - - public g(int i, int j, int k) { - this.b = i; - this.c = j; - this.d = k; - this.a = new int[i][j]; - } - - public void a(int i, int j, int k) { - if (i >= 0 && i < this.b && j >= 0 && j < this.c) { - this.a[i][j] = k; - } - - } - - public void a(int i, int j, int k, int l, int i1) { - for (int j1 = j; j1 <= l; ++j1) { - for (int k1 = i; k1 <= k; ++k1) { - this.a(k1, j1, i1); - } - } - - } - - public int a(int i, int j) { - return i >= 0 && i < this.b && j >= 0 && j < this.c ? this.a[i][j] : this.d; - } - - public void a(int i, int j, int k, int l) { - if (this.a(i, j) == k) { - this.a(i, j, l); - } - - } - - public boolean b(int i, int j, int k) { - return this.a(i - 1, j) == k || this.a(i + 1, j) == k || this.a(i, j + 1) == k || this.a(i, j - 1) == k; - } - } - - static class c { - - private final Random a; - private final WorldGenWoodlandMansionPieces.g b; - private final WorldGenWoodlandMansionPieces.g c; - private final WorldGenWoodlandMansionPieces.g[] d; - private final int e; - private final int f; - - public c(Random random) { - this.a = random; - boolean flag = true; - - this.e = 7; - this.f = 4; - this.b = new WorldGenWoodlandMansionPieces.g(11, 11, 5); - this.b.a(this.e, this.f, this.e + 1, this.f + 1, 3); - this.b.a(this.e - 1, this.f, this.e - 1, this.f + 1, 2); - this.b.a(this.e + 2, this.f - 2, this.e + 3, this.f + 3, 5); - this.b.a(this.e + 1, this.f - 2, this.e + 1, this.f - 1, 1); - this.b.a(this.e + 1, this.f + 2, this.e + 1, this.f + 3, 1); - this.b.a(this.e - 1, this.f - 1, 1); - this.b.a(this.e - 1, this.f + 2, 1); - this.b.a(0, 0, 11, 1, 5); - this.b.a(0, 9, 11, 11, 5); - this.a(this.b, this.e, this.f - 2, EnumDirection.WEST, 6); - this.a(this.b, this.e, this.f + 3, EnumDirection.WEST, 6); - this.a(this.b, this.e - 2, this.f - 1, EnumDirection.WEST, 3); - this.a(this.b, this.e - 2, this.f + 2, EnumDirection.WEST, 3); - - while (this.a(this.b)) { - ; - } - - this.d = new WorldGenWoodlandMansionPieces.g[3]; - this.d[0] = new WorldGenWoodlandMansionPieces.g(11, 11, 5); - this.d[1] = new WorldGenWoodlandMansionPieces.g(11, 11, 5); - this.d[2] = new WorldGenWoodlandMansionPieces.g(11, 11, 5); - this.a(this.b, this.d[0]); - this.a(this.b, this.d[1]); - this.d[0].a(this.e + 1, this.f, this.e + 1, this.f + 1, 8388608); - this.d[1].a(this.e + 1, this.f, this.e + 1, this.f + 1, 8388608); - this.c = new WorldGenWoodlandMansionPieces.g(this.b.b, this.b.c, 5); - this.b(); - this.a(this.c, this.d[2]); - } - - public static boolean a(WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g, int i, int j) { - int k = worldgenwoodlandmansionpieces_g.a(i, j); - - return k == 1 || k == 2 || k == 3 || k == 4; - } - - public boolean a(WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g, int i, int j, int k, int l) { - return (this.d[k].a(i, j) & '\uffff') == l; - } - - @Nullable - public EnumDirection b(WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g, int i, int j, int k, int l) { - Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); - - EnumDirection enumdirection; - - do { - if (!iterator.hasNext()) { - return null; - } - - enumdirection = (EnumDirection) iterator.next(); - } while (!this.a(worldgenwoodlandmansionpieces_g, i + enumdirection.getAdjacentX(), j + enumdirection.getAdjacentZ(), k, l)); - - return enumdirection; - } - - private void a(WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g, int i, int j, EnumDirection enumdirection, int k) { - if (k > 0) { - worldgenwoodlandmansionpieces_g.a(i, j, 1); - worldgenwoodlandmansionpieces_g.a(i + enumdirection.getAdjacentX(), j + enumdirection.getAdjacentZ(), 0, 1); - - EnumDirection enumdirection1; - - for (int l = 0; l < 8; ++l) { - enumdirection1 = EnumDirection.fromType2(this.a.nextInt(4)); - if (enumdirection1 != enumdirection.opposite() && (enumdirection1 != EnumDirection.EAST || !this.a.nextBoolean())) { - int i1 = i + enumdirection.getAdjacentX(); - int j1 = j + enumdirection.getAdjacentZ(); - - if (worldgenwoodlandmansionpieces_g.a(i1 + enumdirection1.getAdjacentX(), j1 + enumdirection1.getAdjacentZ()) == 0 && worldgenwoodlandmansionpieces_g.a(i1 + enumdirection1.getAdjacentX() * 2, j1 + enumdirection1.getAdjacentZ() * 2) == 0) { - this.a(worldgenwoodlandmansionpieces_g, i + enumdirection.getAdjacentX() + enumdirection1.getAdjacentX(), j + enumdirection.getAdjacentZ() + enumdirection1.getAdjacentZ(), enumdirection1, k - 1); - break; - } - } - } - - EnumDirection enumdirection2 = enumdirection.e(); - - enumdirection1 = enumdirection.f(); - worldgenwoodlandmansionpieces_g.a(i + enumdirection2.getAdjacentX(), j + enumdirection2.getAdjacentZ(), 0, 2); - worldgenwoodlandmansionpieces_g.a(i + enumdirection1.getAdjacentX(), j + enumdirection1.getAdjacentZ(), 0, 2); - worldgenwoodlandmansionpieces_g.a(i + enumdirection.getAdjacentX() + enumdirection2.getAdjacentX(), j + enumdirection.getAdjacentZ() + enumdirection2.getAdjacentZ(), 0, 2); - worldgenwoodlandmansionpieces_g.a(i + enumdirection.getAdjacentX() + enumdirection1.getAdjacentX(), j + enumdirection.getAdjacentZ() + enumdirection1.getAdjacentZ(), 0, 2); - worldgenwoodlandmansionpieces_g.a(i + enumdirection.getAdjacentX() * 2, j + enumdirection.getAdjacentZ() * 2, 0, 2); - worldgenwoodlandmansionpieces_g.a(i + enumdirection2.getAdjacentX() * 2, j + enumdirection2.getAdjacentZ() * 2, 0, 2); - worldgenwoodlandmansionpieces_g.a(i + enumdirection1.getAdjacentX() * 2, j + enumdirection1.getAdjacentZ() * 2, 0, 2); - } - } - - private boolean a(WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g) { - boolean flag = false; - - for (int i = 0; i < worldgenwoodlandmansionpieces_g.c; ++i) { - for (int j = 0; j < worldgenwoodlandmansionpieces_g.b; ++j) { - if (worldgenwoodlandmansionpieces_g.a(j, i) == 0) { - byte b0 = 0; - int k = b0 + (a(worldgenwoodlandmansionpieces_g, j + 1, i) ? 1 : 0); - - k += a(worldgenwoodlandmansionpieces_g, j - 1, i) ? 1 : 0; - k += a(worldgenwoodlandmansionpieces_g, j, i + 1) ? 1 : 0; - k += a(worldgenwoodlandmansionpieces_g, j, i - 1) ? 1 : 0; - if (k >= 3) { - worldgenwoodlandmansionpieces_g.a(j, i, 2); - flag = true; - } else if (k == 2) { - byte b1 = 0; - int l = b1 + (a(worldgenwoodlandmansionpieces_g, j + 1, i + 1) ? 1 : 0); - - l += a(worldgenwoodlandmansionpieces_g, j - 1, i + 1) ? 1 : 0; - l += a(worldgenwoodlandmansionpieces_g, j + 1, i - 1) ? 1 : 0; - l += a(worldgenwoodlandmansionpieces_g, j - 1, i - 1) ? 1 : 0; - if (l <= 1) { - worldgenwoodlandmansionpieces_g.a(j, i, 2); - flag = true; - } - } - } - } - } - - return flag; - } - - private void b() { - List> list = Lists.newArrayList(); - WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g = this.d[1]; - - int i; - int j; - - for (int k = 0; k < this.c.c; ++k) { - for (i = 0; i < this.c.b; ++i) { - int l = worldgenwoodlandmansionpieces_g.a(i, k); - - j = l & 983040; - if (j == 131072 && (l & 2097152) == 2097152) { - list.add(new Tuple<>(i, k)); - } - } - } - - if (list.isEmpty()) { - this.c.a(0, 0, this.c.b, this.c.c, 5); - } else { - Tuple tuple = (Tuple) list.get(this.a.nextInt(list.size())); - - i = worldgenwoodlandmansionpieces_g.a((Integer) tuple.a(), (Integer) tuple.b()); - worldgenwoodlandmansionpieces_g.a((Integer) tuple.a(), (Integer) tuple.b(), i | 4194304); - EnumDirection enumdirection = this.b(this.b, (Integer) tuple.a(), (Integer) tuple.b(), 1, i & '\uffff'); - - j = (Integer) tuple.a() + enumdirection.getAdjacentX(); - int i1 = (Integer) tuple.b() + enumdirection.getAdjacentZ(); - - for (int j1 = 0; j1 < this.c.c; ++j1) { - for (int k1 = 0; k1 < this.c.b; ++k1) { - if (!a(this.b, k1, j1)) { - this.c.a(k1, j1, 5); - } else if (k1 == (Integer) tuple.a() && j1 == (Integer) tuple.b()) { - this.c.a(k1, j1, 3); - } else if (k1 == j && j1 == i1) { - this.c.a(k1, j1, 3); - this.d[2].a(k1, j1, 8388608); - } - } - } - - List list1 = Lists.newArrayList(); - Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); - - while (iterator.hasNext()) { - EnumDirection enumdirection1 = (EnumDirection) iterator.next(); - - if (this.c.a(j + enumdirection1.getAdjacentX(), i1 + enumdirection1.getAdjacentZ()) == 0) { - list1.add(enumdirection1); - } - } - - if (list1.isEmpty()) { - this.c.a(0, 0, this.c.b, this.c.c, 5); - worldgenwoodlandmansionpieces_g.a((Integer) tuple.a(), (Integer) tuple.b(), i); - } else { - EnumDirection enumdirection2 = (EnumDirection) list1.get(this.a.nextInt(list1.size())); - - this.a(this.c, j + enumdirection2.getAdjacentX(), i1 + enumdirection2.getAdjacentZ(), enumdirection2, 4); - - while (this.a(this.c)) { - ; - } - - } - } - } - - private void a(WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g, WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g1) { - List> list = Lists.newArrayList(); - - int i; - - for (i = 0; i < worldgenwoodlandmansionpieces_g.c; ++i) { - for (int j = 0; j < worldgenwoodlandmansionpieces_g.b; ++j) { - if (worldgenwoodlandmansionpieces_g.a(j, i) == 2) { - list.add(new Tuple<>(j, i)); - } - } - } - - Collections.shuffle(list, this.a); - i = 10; - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - Tuple tuple = (Tuple) iterator.next(); - int k = (Integer) tuple.a(); - int l = (Integer) tuple.b(); - - if (worldgenwoodlandmansionpieces_g1.a(k, l) == 0) { - int i1 = k; - int j1 = k; - int k1 = l; - int l1 = l; - int i2 = 65536; - - if (worldgenwoodlandmansionpieces_g1.a(k + 1, l) == 0 && worldgenwoodlandmansionpieces_g1.a(k, l + 1) == 0 && worldgenwoodlandmansionpieces_g1.a(k + 1, l + 1) == 0 && worldgenwoodlandmansionpieces_g.a(k + 1, l) == 2 && worldgenwoodlandmansionpieces_g.a(k, l + 1) == 2 && worldgenwoodlandmansionpieces_g.a(k + 1, l + 1) == 2) { - j1 = k + 1; - l1 = l + 1; - i2 = 262144; - } else if (worldgenwoodlandmansionpieces_g1.a(k - 1, l) == 0 && worldgenwoodlandmansionpieces_g1.a(k, l + 1) == 0 && worldgenwoodlandmansionpieces_g1.a(k - 1, l + 1) == 0 && worldgenwoodlandmansionpieces_g.a(k - 1, l) == 2 && worldgenwoodlandmansionpieces_g.a(k, l + 1) == 2 && worldgenwoodlandmansionpieces_g.a(k - 1, l + 1) == 2) { - i1 = k - 1; - l1 = l + 1; - i2 = 262144; - } else if (worldgenwoodlandmansionpieces_g1.a(k - 1, l) == 0 && worldgenwoodlandmansionpieces_g1.a(k, l - 1) == 0 && worldgenwoodlandmansionpieces_g1.a(k - 1, l - 1) == 0 && worldgenwoodlandmansionpieces_g.a(k - 1, l) == 2 && worldgenwoodlandmansionpieces_g.a(k, l - 1) == 2 && worldgenwoodlandmansionpieces_g.a(k - 1, l - 1) == 2) { - i1 = k - 1; - k1 = l - 1; - i2 = 262144; - } else if (worldgenwoodlandmansionpieces_g1.a(k + 1, l) == 0 && worldgenwoodlandmansionpieces_g.a(k + 1, l) == 2) { - j1 = k + 1; - i2 = 131072; - } else if (worldgenwoodlandmansionpieces_g1.a(k, l + 1) == 0 && worldgenwoodlandmansionpieces_g.a(k, l + 1) == 2) { - l1 = l + 1; - i2 = 131072; - } else if (worldgenwoodlandmansionpieces_g1.a(k - 1, l) == 0 && worldgenwoodlandmansionpieces_g.a(k - 1, l) == 2) { - i1 = k - 1; - i2 = 131072; - } else if (worldgenwoodlandmansionpieces_g1.a(k, l - 1) == 0 && worldgenwoodlandmansionpieces_g.a(k, l - 1) == 2) { - k1 = l - 1; - i2 = 131072; - } - - int j2 = this.a.nextBoolean() ? i1 : j1; - int k2 = this.a.nextBoolean() ? k1 : l1; - int l2 = 2097152; - - if (!worldgenwoodlandmansionpieces_g.b(j2, k2, 1)) { - j2 = j2 == i1 ? j1 : i1; - k2 = k2 == k1 ? l1 : k1; - if (!worldgenwoodlandmansionpieces_g.b(j2, k2, 1)) { - k2 = k2 == k1 ? l1 : k1; - if (!worldgenwoodlandmansionpieces_g.b(j2, k2, 1)) { - j2 = j2 == i1 ? j1 : i1; - k2 = k2 == k1 ? l1 : k1; - if (!worldgenwoodlandmansionpieces_g.b(j2, k2, 1)) { - l2 = 0; - j2 = i1; - k2 = k1; - } - } - } - } - - for (int i3 = k1; i3 <= l1; ++i3) { - for (int j3 = i1; j3 <= j1; ++j3) { - if (j3 == j2 && i3 == k2) { - worldgenwoodlandmansionpieces_g1.a(j3, i3, 1048576 | l2 | i2 | i); - } else { - worldgenwoodlandmansionpieces_g1.a(j3, i3, i2 | i); - } - } - } - - ++i; - } - } - - } - } - - static class d { - - private final DefinedStructureManager a; - private final Random b; - private int c; - private int d; - - public d(DefinedStructureManager definedstructuremanager, Random random) { - this.a = definedstructuremanager; - this.b = random; - } - - public void a(BlockPosition blockposition, EnumBlockRotation enumblockrotation, List list, WorldGenWoodlandMansionPieces.c worldgenwoodlandmansionpieces_c) { - WorldGenWoodlandMansionPieces.e worldgenwoodlandmansionpieces_e = new WorldGenWoodlandMansionPieces.e(); - - worldgenwoodlandmansionpieces_e.b = blockposition; - worldgenwoodlandmansionpieces_e.a = enumblockrotation; - worldgenwoodlandmansionpieces_e.c = "wall_flat"; - WorldGenWoodlandMansionPieces.e worldgenwoodlandmansionpieces_e1 = new WorldGenWoodlandMansionPieces.e(); - - this.a(list, worldgenwoodlandmansionpieces_e); - worldgenwoodlandmansionpieces_e1.b = worldgenwoodlandmansionpieces_e.b.up(8); - worldgenwoodlandmansionpieces_e1.a = worldgenwoodlandmansionpieces_e.a; - worldgenwoodlandmansionpieces_e1.c = "wall_window"; - if (!list.isEmpty()) { - ; - } - - WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g = worldgenwoodlandmansionpieces_c.b; - WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g1 = worldgenwoodlandmansionpieces_c.c; - - this.c = worldgenwoodlandmansionpieces_c.e + 1; - this.d = worldgenwoodlandmansionpieces_c.f + 1; - int i = worldgenwoodlandmansionpieces_c.e + 1; - int j = worldgenwoodlandmansionpieces_c.f; - - this.a(list, worldgenwoodlandmansionpieces_e, worldgenwoodlandmansionpieces_g, EnumDirection.SOUTH, this.c, this.d, i, j); - this.a(list, worldgenwoodlandmansionpieces_e1, worldgenwoodlandmansionpieces_g, EnumDirection.SOUTH, this.c, this.d, i, j); - WorldGenWoodlandMansionPieces.e worldgenwoodlandmansionpieces_e2 = new WorldGenWoodlandMansionPieces.e(); - - worldgenwoodlandmansionpieces_e2.b = worldgenwoodlandmansionpieces_e.b.up(19); - worldgenwoodlandmansionpieces_e2.a = worldgenwoodlandmansionpieces_e.a; - worldgenwoodlandmansionpieces_e2.c = "wall_window"; - boolean flag = false; - - int k; - - for (int l = 0; l < worldgenwoodlandmansionpieces_g1.c && !flag; ++l) { - for (k = worldgenwoodlandmansionpieces_g1.b - 1; k >= 0 && !flag; --k) { - if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g1, k, l)) { - worldgenwoodlandmansionpieces_e2.b = worldgenwoodlandmansionpieces_e2.b.shift(enumblockrotation.a(EnumDirection.SOUTH), 8 + (l - this.d) * 8); - worldgenwoodlandmansionpieces_e2.b = worldgenwoodlandmansionpieces_e2.b.shift(enumblockrotation.a(EnumDirection.EAST), (k - this.c) * 8); - this.b(list, worldgenwoodlandmansionpieces_e2); - this.a(list, worldgenwoodlandmansionpieces_e2, worldgenwoodlandmansionpieces_g1, EnumDirection.SOUTH, k, l, k, l); - flag = true; - } - } - } - - this.a(list, blockposition.up(16), enumblockrotation, worldgenwoodlandmansionpieces_g, worldgenwoodlandmansionpieces_g1); - this.a(list, blockposition.up(27), enumblockrotation, worldgenwoodlandmansionpieces_g1, (WorldGenWoodlandMansionPieces.g) null); - if (!list.isEmpty()) { - ; - } - - WorldGenWoodlandMansionPieces.b[] aworldgenwoodlandmansionpieces_b = new WorldGenWoodlandMansionPieces.b[] { new WorldGenWoodlandMansionPieces.a(), new WorldGenWoodlandMansionPieces.f(), new WorldGenWoodlandMansionPieces.h()}; - - for (k = 0; k < 3; ++k) { - BlockPosition blockposition1 = blockposition.up(8 * k + (k == 2 ? 3 : 0)); - WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g2 = worldgenwoodlandmansionpieces_c.d[k]; - WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g3 = k == 2 ? worldgenwoodlandmansionpieces_g1 : worldgenwoodlandmansionpieces_g; - String s = k == 0 ? "carpet_south_1" : "carpet_south_2"; - String s1 = k == 0 ? "carpet_west_1" : "carpet_west_2"; - - for (int i1 = 0; i1 < worldgenwoodlandmansionpieces_g3.c; ++i1) { - for (int j1 = 0; j1 < worldgenwoodlandmansionpieces_g3.b; ++j1) { - if (worldgenwoodlandmansionpieces_g3.a(j1, i1) == 1) { - BlockPosition blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.SOUTH), 8 + (i1 - this.d) * 8); - - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.EAST), (j1 - this.c) * 8); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "corridor_floor", blockposition2, enumblockrotation)); - if (worldgenwoodlandmansionpieces_g3.a(j1, i1 - 1) == 1 || (worldgenwoodlandmansionpieces_g2.a(j1, i1 - 1) & 8388608) == 8388608) { - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "carpet_north", blockposition2.shift(enumblockrotation.a(EnumDirection.EAST), 1).up(), enumblockrotation)); - } - - if (worldgenwoodlandmansionpieces_g3.a(j1 + 1, i1) == 1 || (worldgenwoodlandmansionpieces_g2.a(j1 + 1, i1) & 8388608) == 8388608) { - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "carpet_east", blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 1).shift(enumblockrotation.a(EnumDirection.EAST), 5).up(), enumblockrotation)); - } - - if (worldgenwoodlandmansionpieces_g3.a(j1, i1 + 1) == 1 || (worldgenwoodlandmansionpieces_g2.a(j1, i1 + 1) & 8388608) == 8388608) { - list.add(new WorldGenWoodlandMansionPieces.i(this.a, s, blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 5).shift(enumblockrotation.a(EnumDirection.WEST), 1), enumblockrotation)); - } - - if (worldgenwoodlandmansionpieces_g3.a(j1 - 1, i1) == 1 || (worldgenwoodlandmansionpieces_g2.a(j1 - 1, i1) & 8388608) == 8388608) { - list.add(new WorldGenWoodlandMansionPieces.i(this.a, s1, blockposition2.shift(enumblockrotation.a(EnumDirection.WEST), 1).shift(enumblockrotation.a(EnumDirection.NORTH), 1), enumblockrotation)); - } - } - } - } - - String s2 = k == 0 ? "indoors_wall_1" : "indoors_wall_2"; - String s3 = k == 0 ? "indoors_door_1" : "indoors_door_2"; - List list1 = Lists.newArrayList(); - - for (int k1 = 0; k1 < worldgenwoodlandmansionpieces_g3.c; ++k1) { - for (int l1 = 0; l1 < worldgenwoodlandmansionpieces_g3.b; ++l1) { - boolean flag1 = k == 2 && worldgenwoodlandmansionpieces_g3.a(l1, k1) == 3; - - if (worldgenwoodlandmansionpieces_g3.a(l1, k1) == 2 || flag1) { - int i2 = worldgenwoodlandmansionpieces_g2.a(l1, k1); - int j2 = i2 & 983040; - int k2 = i2 & '\uffff'; - - flag1 = flag1 && (i2 & 8388608) == 8388608; - list1.clear(); - if ((i2 & 2097152) == 2097152) { - Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); - - while (iterator.hasNext()) { - EnumDirection enumdirection = (EnumDirection) iterator.next(); - - if (worldgenwoodlandmansionpieces_g3.a(l1 + enumdirection.getAdjacentX(), k1 + enumdirection.getAdjacentZ()) == 1) { - list1.add(enumdirection); - } - } - } - - EnumDirection enumdirection1 = null; - - if (!list1.isEmpty()) { - enumdirection1 = (EnumDirection) list1.get(this.b.nextInt(list1.size())); - } else if ((i2 & 1048576) == 1048576) { - enumdirection1 = EnumDirection.UP; - } - - BlockPosition blockposition3 = blockposition1.shift(enumblockrotation.a(EnumDirection.SOUTH), 8 + (k1 - this.d) * 8); - - blockposition3 = blockposition3.shift(enumblockrotation.a(EnumDirection.EAST), -1 + (l1 - this.c) * 8); - if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g3, l1 - 1, k1) && !worldgenwoodlandmansionpieces_c.a(worldgenwoodlandmansionpieces_g3, l1 - 1, k1, k, k2)) { - list.add(new WorldGenWoodlandMansionPieces.i(this.a, enumdirection1 == EnumDirection.WEST ? s3 : s2, blockposition3, enumblockrotation)); - } - - BlockPosition blockposition4; - - if (worldgenwoodlandmansionpieces_g3.a(l1 + 1, k1) == 1 && !flag1) { - blockposition4 = blockposition3.shift(enumblockrotation.a(EnumDirection.EAST), 8); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, enumdirection1 == EnumDirection.EAST ? s3 : s2, blockposition4, enumblockrotation)); - } - - if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g3, l1, k1 + 1) && !worldgenwoodlandmansionpieces_c.a(worldgenwoodlandmansionpieces_g3, l1, k1 + 1, k, k2)) { - blockposition4 = blockposition3.shift(enumblockrotation.a(EnumDirection.SOUTH), 7); - blockposition4 = blockposition4.shift(enumblockrotation.a(EnumDirection.EAST), 7); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, enumdirection1 == EnumDirection.SOUTH ? s3 : s2, blockposition4, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } - - if (worldgenwoodlandmansionpieces_g3.a(l1, k1 - 1) == 1 && !flag1) { - blockposition4 = blockposition3.shift(enumblockrotation.a(EnumDirection.NORTH), 1); - blockposition4 = blockposition4.shift(enumblockrotation.a(EnumDirection.EAST), 7); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, enumdirection1 == EnumDirection.NORTH ? s3 : s2, blockposition4, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } - - if (j2 == 65536) { - this.a(list, blockposition3, enumblockrotation, enumdirection1, aworldgenwoodlandmansionpieces_b[k]); - } else { - EnumDirection enumdirection2; - - if (j2 == 131072 && enumdirection1 != null) { - enumdirection2 = worldgenwoodlandmansionpieces_c.b(worldgenwoodlandmansionpieces_g3, l1, k1, k, k2); - boolean flag2 = (i2 & 4194304) == 4194304; - - this.a(list, blockposition3, enumblockrotation, enumdirection2, enumdirection1, aworldgenwoodlandmansionpieces_b[k], flag2); - } else if (j2 == 262144 && enumdirection1 != null && enumdirection1 != EnumDirection.UP) { - enumdirection2 = enumdirection1.e(); - if (!worldgenwoodlandmansionpieces_c.a(worldgenwoodlandmansionpieces_g3, l1 + enumdirection2.getAdjacentX(), k1 + enumdirection2.getAdjacentZ(), k, k2)) { - enumdirection2 = enumdirection2.opposite(); - } - - this.a(list, blockposition3, enumblockrotation, enumdirection2, enumdirection1, aworldgenwoodlandmansionpieces_b[k]); - } else if (j2 == 262144 && enumdirection1 == EnumDirection.UP) { - this.a(list, blockposition3, enumblockrotation, aworldgenwoodlandmansionpieces_b[k]); - } - } - } - } - } - } - - } - - private void a(List list, WorldGenWoodlandMansionPieces.e worldgenwoodlandmansionpieces_e, WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g, EnumDirection enumdirection, int i, int j, int k, int l) { - int i1 = i; - int j1 = j; - EnumDirection enumdirection1 = enumdirection; - - do { - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, i1 + enumdirection.getAdjacentX(), j1 + enumdirection.getAdjacentZ())) { - this.c(list, worldgenwoodlandmansionpieces_e); - enumdirection = enumdirection.e(); - if (i1 != k || j1 != l || enumdirection1 != enumdirection) { - this.b(list, worldgenwoodlandmansionpieces_e); - } - } else if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, i1 + enumdirection.getAdjacentX(), j1 + enumdirection.getAdjacentZ()) && WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, i1 + enumdirection.getAdjacentX() + enumdirection.f().getAdjacentX(), j1 + enumdirection.getAdjacentZ() + enumdirection.f().getAdjacentZ())) { - this.d(list, worldgenwoodlandmansionpieces_e); - i1 += enumdirection.getAdjacentX(); - j1 += enumdirection.getAdjacentZ(); - enumdirection = enumdirection.f(); - } else { - i1 += enumdirection.getAdjacentX(); - j1 += enumdirection.getAdjacentZ(); - if (i1 != k || j1 != l || enumdirection1 != enumdirection) { - this.b(list, worldgenwoodlandmansionpieces_e); - } - } - } while (i1 != k || j1 != l || enumdirection1 != enumdirection); - - } - - private void a(List list, BlockPosition blockposition, EnumBlockRotation enumblockrotation, WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g, @Nullable WorldGenWoodlandMansionPieces.g worldgenwoodlandmansionpieces_g1) { - BlockPosition blockposition1; - int i; - int j; - boolean flag; - BlockPosition blockposition2; - - for (i = 0; i < worldgenwoodlandmansionpieces_g.c; ++i) { - for (j = 0; j < worldgenwoodlandmansionpieces_g.b; ++j) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.SOUTH), 8 + (i - this.d) * 8); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), (j - this.c) * 8); - flag = worldgenwoodlandmansionpieces_g1 != null && WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g1, j, i); - if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i) && !flag) { - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof", blockposition1.up(3), enumblockrotation)); - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j + 1, i)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_front", blockposition2, enumblockrotation)); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j - 1, i)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 0); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 7); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_front", blockposition2, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_180))); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i - 1)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.WEST), 1); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_front", blockposition2, enumblockrotation.a(EnumBlockRotation.COUNTERCLOCKWISE_90))); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i + 1)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 6); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_front", blockposition2, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } - } - } - } - - if (worldgenwoodlandmansionpieces_g1 != null) { - for (i = 0; i < worldgenwoodlandmansionpieces_g.c; ++i) { - for (j = 0; j < worldgenwoodlandmansionpieces_g.b; ++j) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.SOUTH), 8 + (i - this.d) * 8); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), (j - this.c) * 8); - flag = WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g1, j, i); - if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i) && flag) { - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j + 1, i)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 7); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "small_wall", blockposition2, enumblockrotation)); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j - 1, i)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.WEST), 1); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "small_wall", blockposition2, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_180))); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i - 1)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.WEST), 0); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.NORTH), 1); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "small_wall", blockposition2, enumblockrotation.a(EnumBlockRotation.COUNTERCLOCKWISE_90))); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i + 1)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 6); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 7); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "small_wall", blockposition2, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j + 1, i)) { - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i - 1)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 7); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.NORTH), 2); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "small_wall_corner", blockposition2, enumblockrotation)); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i + 1)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 8); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 7); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "small_wall_corner", blockposition2, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j - 1, i)) { - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i - 1)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.WEST), 2); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.NORTH), 1); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "small_wall_corner", blockposition2, enumblockrotation.a(EnumBlockRotation.COUNTERCLOCKWISE_90))); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i + 1)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.WEST), 1); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 8); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "small_wall_corner", blockposition2, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_180))); - } - } - } - } - } - } - - for (i = 0; i < worldgenwoodlandmansionpieces_g.c; ++i) { - for (j = 0; j < worldgenwoodlandmansionpieces_g.b; ++j) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.SOUTH), 8 + (i - this.d) * 8); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), (j - this.c) * 8); - flag = worldgenwoodlandmansionpieces_g1 != null && WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g1, j, i); - if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i) && !flag) { - BlockPosition blockposition3; - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j + 1, i)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 6); - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i + 1)) { - blockposition3 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_corner", blockposition3, enumblockrotation)); - } else if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j + 1, i + 1)) { - blockposition3 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 5); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_inner_corner", blockposition3, enumblockrotation)); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i - 1)) { - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_corner", blockposition2, enumblockrotation.a(EnumBlockRotation.COUNTERCLOCKWISE_90))); - } else if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j + 1, i - 1)) { - blockposition3 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 9); - blockposition3 = blockposition3.shift(enumblockrotation.a(EnumDirection.NORTH), 2); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_inner_corner", blockposition3, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j - 1, i)) { - blockposition2 = blockposition1.shift(enumblockrotation.a(EnumDirection.EAST), 0); - blockposition2 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 0); - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i + 1)) { - blockposition3 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_corner", blockposition3, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } else if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j - 1, i + 1)) { - blockposition3 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 8); - blockposition3 = blockposition3.shift(enumblockrotation.a(EnumDirection.WEST), 3); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_inner_corner", blockposition3, enumblockrotation.a(EnumBlockRotation.COUNTERCLOCKWISE_90))); - } - - if (!WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j, i - 1)) { - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_corner", blockposition2, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_180))); - } else if (WorldGenWoodlandMansionPieces.c.a(worldgenwoodlandmansionpieces_g, j - 1, i - 1)) { - blockposition3 = blockposition2.shift(enumblockrotation.a(EnumDirection.SOUTH), 1); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "roof_inner_corner", blockposition3, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_180))); - } - } - } - } - } - - } - - private void a(List list, WorldGenWoodlandMansionPieces.e worldgenwoodlandmansionpieces_e) { - EnumDirection enumdirection = worldgenwoodlandmansionpieces_e.a.a(EnumDirection.WEST); - - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "entrance", worldgenwoodlandmansionpieces_e.b.shift(enumdirection, 9), worldgenwoodlandmansionpieces_e.a)); - worldgenwoodlandmansionpieces_e.b = worldgenwoodlandmansionpieces_e.b.shift(worldgenwoodlandmansionpieces_e.a.a(EnumDirection.SOUTH), 16); - } - - private void b(List list, WorldGenWoodlandMansionPieces.e worldgenwoodlandmansionpieces_e) { - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_e.c, worldgenwoodlandmansionpieces_e.b.shift(worldgenwoodlandmansionpieces_e.a.a(EnumDirection.EAST), 7), worldgenwoodlandmansionpieces_e.a)); - worldgenwoodlandmansionpieces_e.b = worldgenwoodlandmansionpieces_e.b.shift(worldgenwoodlandmansionpieces_e.a.a(EnumDirection.SOUTH), 8); - } - - private void c(List list, WorldGenWoodlandMansionPieces.e worldgenwoodlandmansionpieces_e) { - worldgenwoodlandmansionpieces_e.b = worldgenwoodlandmansionpieces_e.b.shift(worldgenwoodlandmansionpieces_e.a.a(EnumDirection.SOUTH), -1); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, "wall_corner", worldgenwoodlandmansionpieces_e.b, worldgenwoodlandmansionpieces_e.a)); - worldgenwoodlandmansionpieces_e.b = worldgenwoodlandmansionpieces_e.b.shift(worldgenwoodlandmansionpieces_e.a.a(EnumDirection.SOUTH), -7); - worldgenwoodlandmansionpieces_e.b = worldgenwoodlandmansionpieces_e.b.shift(worldgenwoodlandmansionpieces_e.a.a(EnumDirection.WEST), -6); - worldgenwoodlandmansionpieces_e.a = worldgenwoodlandmansionpieces_e.a.a(EnumBlockRotation.CLOCKWISE_90); - } - - private void d(List list, WorldGenWoodlandMansionPieces.e worldgenwoodlandmansionpieces_e) { - worldgenwoodlandmansionpieces_e.b = worldgenwoodlandmansionpieces_e.b.shift(worldgenwoodlandmansionpieces_e.a.a(EnumDirection.SOUTH), 6); - worldgenwoodlandmansionpieces_e.b = worldgenwoodlandmansionpieces_e.b.shift(worldgenwoodlandmansionpieces_e.a.a(EnumDirection.EAST), 8); - worldgenwoodlandmansionpieces_e.a = worldgenwoodlandmansionpieces_e.a.a(EnumBlockRotation.COUNTERCLOCKWISE_90); - } - - private void a(List list, BlockPosition blockposition, EnumBlockRotation enumblockrotation, EnumDirection enumdirection, WorldGenWoodlandMansionPieces.b worldgenwoodlandmansionpieces_b) { - EnumBlockRotation enumblockrotation1 = EnumBlockRotation.NONE; - String s = worldgenwoodlandmansionpieces_b.a(this.b); - - if (enumdirection != EnumDirection.EAST) { - if (enumdirection == EnumDirection.NORTH) { - enumblockrotation1 = enumblockrotation1.a(EnumBlockRotation.COUNTERCLOCKWISE_90); - } else if (enumdirection == EnumDirection.WEST) { - enumblockrotation1 = enumblockrotation1.a(EnumBlockRotation.CLOCKWISE_180); - } else if (enumdirection == EnumDirection.SOUTH) { - enumblockrotation1 = enumblockrotation1.a(EnumBlockRotation.CLOCKWISE_90); - } else { - s = worldgenwoodlandmansionpieces_b.b(this.b); - } - } - - BlockPosition blockposition1 = DefinedStructure.a(new BlockPosition(1, 0, 0), EnumBlockMirror.NONE, enumblockrotation1, 7, 7); - - enumblockrotation1 = enumblockrotation1.a(enumblockrotation); - blockposition1 = blockposition1.a(enumblockrotation); - BlockPosition blockposition2 = blockposition.a(blockposition1.getX(), 0, blockposition1.getZ()); - - list.add(new WorldGenWoodlandMansionPieces.i(this.a, s, blockposition2, enumblockrotation1)); - } - - private void a(List list, BlockPosition blockposition, EnumBlockRotation enumblockrotation, EnumDirection enumdirection, EnumDirection enumdirection1, WorldGenWoodlandMansionPieces.b worldgenwoodlandmansionpieces_b, boolean flag) { - BlockPosition blockposition1; - - if (enumdirection1 == EnumDirection.EAST && enumdirection == EnumDirection.SOUTH) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 1); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.a(this.b, flag), blockposition1, enumblockrotation)); - } else if (enumdirection1 == EnumDirection.EAST && enumdirection == EnumDirection.NORTH) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 1); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.SOUTH), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.a(this.b, flag), blockposition1, enumblockrotation, EnumBlockMirror.LEFT_RIGHT)); - } else if (enumdirection1 == EnumDirection.WEST && enumdirection == EnumDirection.NORTH) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 7); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.SOUTH), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.a(this.b, flag), blockposition1, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_180))); - } else if (enumdirection1 == EnumDirection.WEST && enumdirection == EnumDirection.SOUTH) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 7); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.a(this.b, flag), blockposition1, enumblockrotation, EnumBlockMirror.FRONT_BACK)); - } else if (enumdirection1 == EnumDirection.SOUTH && enumdirection == EnumDirection.EAST) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 1); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.a(this.b, flag), blockposition1, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90), EnumBlockMirror.LEFT_RIGHT)); - } else if (enumdirection1 == EnumDirection.SOUTH && enumdirection == EnumDirection.WEST) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 7); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.a(this.b, flag), blockposition1, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } else if (enumdirection1 == EnumDirection.NORTH && enumdirection == EnumDirection.WEST) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 7); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.SOUTH), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.a(this.b, flag), blockposition1, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90), EnumBlockMirror.FRONT_BACK)); - } else if (enumdirection1 == EnumDirection.NORTH && enumdirection == EnumDirection.EAST) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 1); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.SOUTH), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.a(this.b, flag), blockposition1, enumblockrotation.a(EnumBlockRotation.COUNTERCLOCKWISE_90))); - } else if (enumdirection1 == EnumDirection.SOUTH && enumdirection == EnumDirection.NORTH) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 1); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.NORTH), 8); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.b(this.b, flag), blockposition1, enumblockrotation)); - } else if (enumdirection1 == EnumDirection.NORTH && enumdirection == EnumDirection.SOUTH) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 7); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.SOUTH), 14); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.b(this.b, flag), blockposition1, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_180))); - } else if (enumdirection1 == EnumDirection.WEST && enumdirection == EnumDirection.EAST) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 15); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.b(this.b, flag), blockposition1, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } else if (enumdirection1 == EnumDirection.EAST && enumdirection == EnumDirection.WEST) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.WEST), 7); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.SOUTH), 6); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.b(this.b, flag), blockposition1, enumblockrotation.a(EnumBlockRotation.COUNTERCLOCKWISE_90))); - } else if (enumdirection1 == EnumDirection.UP && enumdirection == EnumDirection.EAST) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 15); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.c(this.b), blockposition1, enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90))); - } else if (enumdirection1 == EnumDirection.UP && enumdirection == EnumDirection.SOUTH) { - blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 1); - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.NORTH), 0); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.c(this.b), blockposition1, enumblockrotation)); - } - - } - - private void a(List list, BlockPosition blockposition, EnumBlockRotation enumblockrotation, EnumDirection enumdirection, EnumDirection enumdirection1, WorldGenWoodlandMansionPieces.b worldgenwoodlandmansionpieces_b) { - byte b0 = 0; - byte b1 = 0; - EnumBlockRotation enumblockrotation1 = enumblockrotation; - EnumBlockMirror enumblockmirror = EnumBlockMirror.NONE; - - if (enumdirection1 == EnumDirection.EAST && enumdirection == EnumDirection.SOUTH) { - b0 = -7; - } else if (enumdirection1 == EnumDirection.EAST && enumdirection == EnumDirection.NORTH) { - b0 = -7; - b1 = 6; - enumblockmirror = EnumBlockMirror.LEFT_RIGHT; - } else if (enumdirection1 == EnumDirection.NORTH && enumdirection == EnumDirection.EAST) { - b0 = 1; - b1 = 14; - enumblockrotation1 = enumblockrotation.a(EnumBlockRotation.COUNTERCLOCKWISE_90); - } else if (enumdirection1 == EnumDirection.NORTH && enumdirection == EnumDirection.WEST) { - b0 = 7; - b1 = 14; - enumblockrotation1 = enumblockrotation.a(EnumBlockRotation.COUNTERCLOCKWISE_90); - enumblockmirror = EnumBlockMirror.LEFT_RIGHT; - } else if (enumdirection1 == EnumDirection.SOUTH && enumdirection == EnumDirection.WEST) { - b0 = 7; - b1 = -8; - enumblockrotation1 = enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90); - } else if (enumdirection1 == EnumDirection.SOUTH && enumdirection == EnumDirection.EAST) { - b0 = 1; - b1 = -8; - enumblockrotation1 = enumblockrotation.a(EnumBlockRotation.CLOCKWISE_90); - enumblockmirror = EnumBlockMirror.LEFT_RIGHT; - } else if (enumdirection1 == EnumDirection.WEST && enumdirection == EnumDirection.NORTH) { - b0 = 15; - b1 = 6; - enumblockrotation1 = enumblockrotation.a(EnumBlockRotation.CLOCKWISE_180); - } else if (enumdirection1 == EnumDirection.WEST && enumdirection == EnumDirection.SOUTH) { - b0 = 15; - enumblockmirror = EnumBlockMirror.FRONT_BACK; - } - - BlockPosition blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), b0); - - blockposition1 = blockposition1.shift(enumblockrotation.a(EnumDirection.SOUTH), b1); - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.d(this.b), blockposition1, enumblockrotation1, enumblockmirror)); - } - - private void a(List list, BlockPosition blockposition, EnumBlockRotation enumblockrotation, WorldGenWoodlandMansionPieces.b worldgenwoodlandmansionpieces_b) { - BlockPosition blockposition1 = blockposition.shift(enumblockrotation.a(EnumDirection.EAST), 1); - - list.add(new WorldGenWoodlandMansionPieces.i(this.a, worldgenwoodlandmansionpieces_b.e(this.b), blockposition1, enumblockrotation, EnumBlockMirror.NONE)); - } - } - - static class e { - - public EnumBlockRotation a; - public BlockPosition b; - public String c; - - private e() {} - } - - public static class i extends DefinedStructurePiece { - - private String d; - private EnumBlockRotation e; - private EnumBlockMirror f; - - public i() {} - - public i(DefinedStructureManager definedstructuremanager, String s, BlockPosition blockposition, EnumBlockRotation enumblockrotation) { - this(definedstructuremanager, s, blockposition, enumblockrotation, EnumBlockMirror.NONE); - } - - public i(DefinedStructureManager definedstructuremanager, String s, BlockPosition blockposition, EnumBlockRotation enumblockrotation, EnumBlockMirror enumblockmirror) { - super(0); - this.d = s; - this.c = blockposition; - this.e = enumblockrotation; - this.f = enumblockmirror; - this.a(definedstructuremanager); - } - - private void a(DefinedStructureManager definedstructuremanager) { - DefinedStructure definedstructure = definedstructuremanager.a(new MinecraftKey("woodland_mansion/" + this.d)); - DefinedStructureInfo definedstructureinfo = (new DefinedStructureInfo()).a(true).a(this.e).a(this.f); - - this.a(definedstructure, this.c, definedstructureinfo); - } - - protected void a(NBTTagCompound nbttagcompound) { - super.a(nbttagcompound); - nbttagcompound.setString("Template", this.d); - nbttagcompound.setString("Rot", this.b.c().name()); - nbttagcompound.setString("Mi", this.b.b().name()); - } - - protected void a(NBTTagCompound nbttagcompound, DefinedStructureManager definedstructuremanager) { - super.a(nbttagcompound, definedstructuremanager); - this.d = nbttagcompound.getString("Template"); - this.e = EnumBlockRotation.valueOf(nbttagcompound.getString("Rot")); - this.f = EnumBlockMirror.valueOf(nbttagcompound.getString("Mi")); - this.a(definedstructuremanager); - } - - protected void a(String s, BlockPosition blockposition, GeneratorAccess generatoraccess, Random random, StructureBoundingBox structureboundingbox) { - if (s.startsWith("Chest")) { - EnumBlockRotation enumblockrotation = this.b.c(); - IBlockData iblockdata = Blocks.CHEST.getBlockData(); - - if ("ChestWest".equals(s)) { - iblockdata = (IBlockData) iblockdata.set(BlockChest.FACING, enumblockrotation.a(EnumDirection.WEST)); - } else if ("ChestEast".equals(s)) { - iblockdata = (IBlockData) iblockdata.set(BlockChest.FACING, enumblockrotation.a(EnumDirection.EAST)); - } else if ("ChestSouth".equals(s)) { - iblockdata = (IBlockData) iblockdata.set(BlockChest.FACING, enumblockrotation.a(EnumDirection.SOUTH)); - } else if ("ChestNorth".equals(s)) { - iblockdata = (IBlockData) iblockdata.set(BlockChest.FACING, enumblockrotation.a(EnumDirection.NORTH)); - } - - this.a(generatoraccess, structureboundingbox, random, blockposition, LootTables.o, iblockdata); - } else if ("Mage".equals(s)) { - EntityEvoker entityevoker = EntityTypes.EVOKER.create(generatoraccess.getMinecraftWorld()); // Paper - entityevoker.di(); - entityevoker.setPositionRotation(blockposition, 0.0F, 0.0F); - generatoraccess.addEntity(entityevoker); - generatoraccess.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 2); - } else if ("Warrior".equals(s)) { - EntityVindicator entityvindicator = EntityTypes.VINDICATOR.create(generatoraccess.getMinecraftWorld()); // Paper - entityvindicator.di(); - entityvindicator.setPositionRotation(blockposition, 0.0F, 0.0F); - entityvindicator.prepare(generatoraccess.getDamageScaler(new BlockPosition(entityvindicator)), (GroupDataEntity) null, (NBTTagCompound) null); - generatoraccess.addEntity(entityvindicator); - generatoraccess.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 2); - } - - } - } -} diff --git a/src/main/java/net/minecraft/server/WorldLoadListener.java b/src/main/java/net/minecraft/server/WorldLoadListener.java new file mode 100644 index 000000000..7b6f5b2da --- /dev/null +++ b/src/main/java/net/minecraft/server/WorldLoadListener.java @@ -0,0 +1,14 @@ +package net.minecraft.server; + +import javax.annotation.Nullable; + +public interface WorldLoadListener { + + void a(ChunkCoordIntPair chunkcoordintpair); + + void a(ChunkCoordIntPair chunkcoordintpair, @Nullable ChunkStatus chunkstatus); + + void b(); + + void setChunkRadius(int radius); // Paper - allow changing chunk radius +} diff --git a/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java b/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java new file mode 100644 index 000000000..ae77805f7 --- /dev/null +++ b/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java @@ -0,0 +1,59 @@ +package net.minecraft.server; + +import javax.annotation.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class WorldLoadListenerLogger implements WorldLoadListener { + + private static final Logger LOGGER = LogManager.getLogger(); + private int b; // Paper - remove final + private int c; + private long d; + private long e = Long.MAX_VALUE; + + public WorldLoadListenerLogger(int i) { + // Paper start - Allow changing radius later for configurable spawn patch + this.setChunkRadius(i); // Move to method + } + + @Override + public void setChunkRadius(int radius) { + // Paper - copied from above + int j = radius * 2 + 1; + + this.b = j * j; + } + // Paper end + + @Override + public void a(ChunkCoordIntPair chunkcoordintpair) { + this.e = SystemUtils.getMonotonicMillis(); + this.d = this.e; + } + + @Override + public void a(ChunkCoordIntPair chunkcoordintpair, @Nullable ChunkStatus chunkstatus) { + if (chunkstatus == ChunkStatus.FULL) { + ++this.c; + } + + int i = this.c(); + + if (SystemUtils.getMonotonicMillis() > this.e) { + this.e += 500L; + WorldLoadListenerLogger.LOGGER.info((new ChatMessage("menu.preparingSpawn", new Object[]{MathHelper.clamp(i, 0, 100)})).getString()); + } + + } + + @Override + public void b() { + WorldLoadListenerLogger.LOGGER.info("Time elapsed: {} ms", SystemUtils.getMonotonicMillis() - this.d); + this.e = Long.MAX_VALUE; + } + + public int c() { + return MathHelper.d((float) this.c * 100.0F / (float) this.b); + } +} diff --git a/src/main/java/net/minecraft/server/WorldManager.java b/src/main/java/net/minecraft/server/WorldManager.java deleted file mode 100644 index 0319e4ea7..000000000 --- a/src/main/java/net/minecraft/server/WorldManager.java +++ /dev/null @@ -1,101 +0,0 @@ -package net.minecraft.server; - -import java.util.Iterator; -import javax.annotation.Nullable; - -import io.akarin.server.core.AkarinAsyncExecutor; - -public class WorldManager implements IWorldAccess { - - private final MinecraftServer a; - private final WorldServer world; - - public WorldManager(MinecraftServer minecraftserver, WorldServer worldserver) { - this.a = minecraftserver; - this.world = worldserver; - } - - public void a(ParticleParam particleparam, boolean flag, double d0, double d1, double d2, double d3, double d4, double d5) {} - - public void a(ParticleParam particleparam, boolean flag, boolean flag1, double d0, double d1, double d2, double d3, double d4, double d5) {} - - public void a(Entity entity) { - this.world.getTracker().track(entity); - if (entity instanceof EntityPlayer) { - this.world.worldProvider.a((EntityPlayer) entity); - } - - } - - public void b(Entity entity) { - this.world.getTracker().untrackEntity(entity); - this.world.getScoreboard().a(entity); - if (entity instanceof EntityPlayer) { - this.world.worldProvider.b((EntityPlayer) entity); - } - - } - - public void a(@Nullable EntityHuman entityhuman, SoundEffect soundeffect, SoundCategory soundcategory, double d0, double d1, double d2, float f, float f1) { - // CraftBukkit - this.world.dimension, // Paper - this.world.dimension -> this.world - AkarinAsyncExecutor.scheduleAsyncTask(() -> this.a.getPlayerList().sendPacketNearby(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world, new PacketPlayOutNamedSoundEffect(soundeffect, soundcategory, d0, d1, d2, f, f1))); // Akarin; - } - - public void a(int i, int j, int k, int l, int i1, int j1) {} - - public void a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, int i) { - this.world.getPlayerChunkMap().flagDirty(blockposition); - } - - public void a(BlockPosition blockposition) {} - - public void a(SoundEffect soundeffect, BlockPosition blockposition) {} - - public void a(EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { - // CraftBukkit - this.world.dimension - AkarinAsyncExecutor.scheduleAsyncTask(() -> this.a.getPlayerList().sendPacketNearby(entityhuman, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 64.0D, this.world, new PacketPlayOutWorldEvent(i, blockposition, j, false))); // Akarin; - } - - public void a(int i, BlockPosition blockposition, int j) { - AkarinAsyncExecutor.scheduleAsyncTask(() -> this.a.getPlayerList().sendAll(new PacketPlayOutWorldEvent(i, blockposition, j, true))); // Akarin - } - - public void b(int i, BlockPosition blockposition, int j) { - // Iterator iterator = this.a.getPlayerList().v().iterator(); // Paper - AkarinAsyncExecutor.scheduleAsyncTask(() -> { // Akarin - - // CraftBukkit start - EntityHuman entityhuman = null; - Entity entity = world.getEntity(i); - if (entity instanceof EntityHuman) entityhuman = (EntityHuman) entity; - // CraftBukkit end - - // Paper start - java.util.List list = entity != null ? entity.world.players : this.a.getPlayerList().v(); - Iterator iterator = list.iterator(); - while (iterator.hasNext()) { - EntityHuman human = iterator.next(); - if (!(human instanceof EntityPlayer)) continue; - EntityPlayer entityplayer = (EntityPlayer) human; - // Paper end - - if (entityplayer != null && entityplayer.world == this.world && entityplayer.getId() != i) { - double d0 = (double) blockposition.getX() - entityplayer.locX; - double d1 = (double) blockposition.getY() - entityplayer.locY; - double d2 = (double) blockposition.getZ() - entityplayer.locZ; - - // CraftBukkit start - if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { - continue; - } - // CraftBukkit end - - if (d0 * d0 + d1 * d1 + d2 * d2 < 1024.0D) { - entityplayer.playerConnection.sendPacket(new PacketPlayOutBlockBreakAnimation(i, blockposition, j)); - } - } - } - }); // Akarin - - } -} diff --git a/src/main/java/net/minecraft/server/WorldMap.java b/src/main/java/net/minecraft/server/WorldMap.java index a819d6037..090d3dbd3 100644 --- a/src/main/java/net/minecraft/server/WorldMap.java +++ b/src/main/java/net/minecraft/server/WorldMap.java @@ -25,11 +25,12 @@ public class WorldMap extends PersistentBase { public boolean unlimitedTracking; public byte scale; public byte[] colors = new byte[16384]; - public List h = Lists.newArrayList(); + public boolean locked; + public final List i = Lists.newArrayList(); public final Map humans = Maps.newHashMap(); - private final Map k = Maps.newHashMap(); - public Map decorations = Maps.newLinkedHashMap(); - private final Map l = Maps.newHashMap(); + private final Map l = Maps.newHashMap(); + public final Map decorations = Maps.newLinkedHashMap(); + private final Map m = Maps.newHashMap(); private org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper // CraftBukkit start @@ -53,7 +54,7 @@ public class WorldMap extends PersistentBase { this.map = dimensionmanager; this.track = flag; this.unlimitedTracking = flag1; - this.c(); + this.b(); } public void a(double d0, double d1, int i) { @@ -65,11 +66,13 @@ public class WorldMap extends PersistentBase { this.centerZ = l * j + j / 2 - 64; } + @Override public void a(NBTTagCompound nbttagcompound) { + int i = nbttagcompound.getInt("dimension"); // CraftBukkit start - int dimension = nbttagcompound.getInt("dimension"); + DimensionManager dimensionmanager = null; - if (dimension >= CraftWorld.CUSTOM_DIMENSION_OFFSET) { + if (i >= CraftWorld.CUSTOM_DIMENSION_OFFSET) { long least = nbttagcompound.getLong("UUIDLeast"); long most = nbttagcompound.getLong("UUIDMost"); @@ -81,54 +84,61 @@ public class WorldMap extends PersistentBase { if (world == null) { /* All Maps which do not have their valid world loaded are set to a dimension which hopefully won't be reached. This is to prevent them being corrupted with the wrong map data. */ - this.map = new DimensionManager(127, null, null, null); + dimensionmanager = new DimensionManager(127, null, null, null, false, DimensionManager.OVERWORLD); } else { - this.map = world.getHandle().dimension; + dimensionmanager = world.getHandle().getWorldProvider().getDimensionManager(); } } } else { - this.map = DimensionManager.a(dimension); + dimensionmanager = DimensionManager.a(i); } - // CraftBukkit end - this.centerX = nbttagcompound.getInt("xCenter"); - this.centerZ = nbttagcompound.getInt("zCenter"); - this.scale = (byte) MathHelper.clamp(nbttagcompound.getByte("scale"), 0, 4); - this.track = !nbttagcompound.hasKeyOfType("trackingPosition", 1) || nbttagcompound.getBoolean("trackingPosition"); - this.unlimitedTracking = nbttagcompound.getBoolean("unlimitedTracking"); - this.colors = nbttagcompound.getByteArray("colors"); - if (this.colors.length != 16384) { - this.colors = new byte[16384]; - } - NBTTagList nbttaglist = nbttagcompound.getList("banners", 10); + if (dimensionmanager == null) { + throw new IllegalArgumentException("Invalid map dimension: " + i); + } else { + this.map = dimensionmanager; + this.centerX = nbttagcompound.getInt("xCenter"); + this.centerZ = nbttagcompound.getInt("zCenter"); + this.scale = (byte) MathHelper.clamp(nbttagcompound.getByte("scale"), 0, 4); + this.track = !nbttagcompound.hasKeyOfType("trackingPosition", 1) || nbttagcompound.getBoolean("trackingPosition"); + this.unlimitedTracking = nbttagcompound.getBoolean("unlimitedTracking"); + this.locked = nbttagcompound.getBoolean("locked"); + this.colors = nbttagcompound.getByteArray("colors"); + if (this.colors.length != 16384) { + this.colors = new byte[16384]; + } - for (int i = 0; i < nbttaglist.size(); ++i) { - MapIconBanner mapiconbanner = MapIconBanner.a(nbttaglist.getCompound(i)); + NBTTagList nbttaglist = nbttagcompound.getList("banners", 10); - this.k.put(mapiconbanner.f(), mapiconbanner); - this.a(mapiconbanner.c(), (GeneratorAccess) null, mapiconbanner.f(), (double) mapiconbanner.a().getX(), (double) mapiconbanner.a().getZ(), 180.0D, mapiconbanner.d()); - } + for (int j = 0; j < nbttaglist.size(); ++j) { + MapIconBanner mapiconbanner = MapIconBanner.a(nbttaglist.getCompound(j)); + + this.l.put(mapiconbanner.f(), mapiconbanner); + this.a(mapiconbanner.c(), (GeneratorAccess) null, mapiconbanner.f(), (double) mapiconbanner.a().getX(), (double) mapiconbanner.a().getZ(), 180.0D, mapiconbanner.d()); + } vanillaRender.buffer = colors; // Paper - NBTTagList nbttaglist1 = nbttagcompound.getList("frames", 10); + NBTTagList nbttaglist1 = nbttagcompound.getList("frames", 10); - for (int j = 0; j < nbttaglist1.size(); ++j) { - WorldMapFrame worldmapframe = WorldMapFrame.a(nbttaglist1.getCompound(j)); + for (int k = 0; k < nbttaglist1.size(); ++k) { + WorldMapFrame worldmapframe = WorldMapFrame.a(nbttaglist1.getCompound(k)); + + this.m.put(worldmapframe.e(), worldmapframe); + this.a(MapIcon.Type.FRAME, (GeneratorAccess) null, "frame-" + worldmapframe.d(), (double) worldmapframe.b().getX(), (double) worldmapframe.b().getZ(), (double) worldmapframe.c(), (IChatBaseComponent) null); + } - this.l.put(worldmapframe.e(), worldmapframe); - this.a(MapIcon.Type.FRAME, (GeneratorAccess) null, "frame-" + worldmapframe.d(), (double) worldmapframe.b().getX(), (double) worldmapframe.b().getZ(), (double) worldmapframe.c(), (IChatBaseComponent) null); } - } + @Override public NBTTagCompound b(NBTTagCompound nbttagcompound) { // CraftBukkit start if (this.map.getDimensionID() >= CraftWorld.CUSTOM_DIMENSION_OFFSET) { if (this.uniqueId == null) { for (org.bukkit.World world : server.getWorlds()) { CraftWorld cWorld = (CraftWorld) world; - if (cWorld.getHandle().dimension == this.map) { + if (cWorld.getHandle().getWorldProvider().getDimensionManager() == this.map) { this.uniqueId = cWorld.getUID(); break; } @@ -149,70 +159,81 @@ public class WorldMap extends PersistentBase { nbttagcompound.setByteArray("colors", this.colors); nbttagcompound.setBoolean("trackingPosition", this.track); nbttagcompound.setBoolean("unlimitedTracking", this.unlimitedTracking); + nbttagcompound.setBoolean("locked", this.locked); NBTTagList nbttaglist = new NBTTagList(); - Iterator iterator = this.k.values().iterator(); + Iterator iterator = this.l.values().iterator(); while (iterator.hasNext()) { MapIconBanner mapiconbanner = (MapIconBanner) iterator.next(); - nbttaglist.add((NBTBase) mapiconbanner.e()); + nbttaglist.add(mapiconbanner.e()); } nbttagcompound.set("banners", nbttaglist); NBTTagList nbttaglist1 = new NBTTagList(); - Iterator iterator1 = this.l.values().iterator(); + Iterator iterator1 = this.m.values().iterator(); while (iterator1.hasNext()) { WorldMapFrame worldmapframe = (WorldMapFrame) iterator1.next(); - nbttaglist1.add((NBTBase) worldmapframe.a()); + nbttaglist1.add(worldmapframe.a()); } nbttagcompound.set("frames", nbttaglist1); return nbttagcompound; } - public void updateSeenPlayers(EntityHuman entityhuman, ItemStack itemstack) { a(entityhuman, itemstack); } // Paper - OBFHELPER + public void a(WorldMap worldmap) { + this.locked = true; + this.centerX = worldmap.centerX; + this.centerZ = worldmap.centerZ; + this.l.putAll(worldmap.l); + this.decorations.putAll(worldmap.decorations); + System.arraycopy(worldmap.colors, 0, this.colors, 0, worldmap.colors.length); + this.b(); + } + + public void updateSeenPlayers(EntityHuman entityhuman, ItemStack itemstack) { this.a(entityhuman, itemstack); } // Paper - OBFHELPER public void a(EntityHuman entityhuman, ItemStack itemstack) { if (!this.humans.containsKey(entityhuman)) { WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker = new WorldMap.WorldMapHumanTracker(entityhuman); this.humans.put(entityhuman, worldmap_worldmaphumantracker); - this.h.add(worldmap_worldmaphumantracker); + this.i.add(worldmap_worldmaphumantracker); } if (!entityhuman.inventory.h(itemstack)) { this.decorations.remove(entityhuman.getDisplayName().getString()); } - for (int i = 0; i < this.h.size(); ++i) { - WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker1 = (WorldMap.WorldMapHumanTracker) this.h.get(i); + for (int i = 0; i < this.i.size(); ++i) { + WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker1 = (WorldMap.WorldMapHumanTracker) this.i.get(i); String s = worldmap_worldmaphumantracker1.trackee.getDisplayName().getString(); - if (!worldmap_worldmaphumantracker1.trackee.dead && (worldmap_worldmaphumantracker1.trackee.inventory.h(itemstack) || itemstack.x())) { - if (!itemstack.x() && worldmap_worldmaphumantracker1.trackee.dimension == this.map && this.track) { + if (!worldmap_worldmaphumantracker1.trackee.dead && (worldmap_worldmaphumantracker1.trackee.inventory.h(itemstack) || itemstack.y())) { + if (!itemstack.y() && worldmap_worldmaphumantracker1.trackee.dimension == this.map && this.track) { this.a(MapIcon.Type.PLAYER, worldmap_worldmaphumantracker1.trackee.world, s, worldmap_worldmaphumantracker1.trackee.locX, worldmap_worldmaphumantracker1.trackee.locZ, (double) worldmap_worldmaphumantracker1.trackee.yaw, (IChatBaseComponent) null); } } else { this.humans.remove(worldmap_worldmaphumantracker1.trackee); - this.h.remove(worldmap_worldmaphumantracker1); + this.i.remove(worldmap_worldmaphumantracker1); this.decorations.remove(s); } } - if (itemstack.x() && this.track) { - EntityItemFrame entityitemframe = itemstack.y(); + if (itemstack.y() && this.track) { + EntityItemFrame entityitemframe = itemstack.z(); BlockPosition blockposition = entityitemframe.getBlockPosition(); - WorldMapFrame worldmapframe = (WorldMapFrame) this.l.get(WorldMapFrame.a(blockposition)); + WorldMapFrame worldmapframe = (WorldMapFrame) this.m.get(WorldMapFrame.a(blockposition)); - if (worldmapframe != null && entityitemframe.getId() != worldmapframe.d() && this.l.containsKey(worldmapframe.e())) { + if (worldmapframe != null && entityitemframe.getId() != worldmapframe.d() && this.m.containsKey(worldmapframe.e())) { this.decorations.remove("frame-" + worldmapframe.d()); } - WorldMapFrame worldmapframe1 = new WorldMapFrame(blockposition, entityitemframe.direction.get2DRotationValue() * 90, entityitemframe.getId()); + WorldMapFrame worldmapframe1 = new WorldMapFrame(blockposition, entityitemframe.getDirection().get2DRotationValue() * 90, entityitemframe.getId()); - this.a(MapIcon.Type.FRAME, entityhuman.world, "frame-" + entityitemframe.getId(), (double) blockposition.getX(), (double) blockposition.getZ(), (double) (entityitemframe.direction.get2DRotationValue() * 90), (IChatBaseComponent) null); - this.l.put(worldmapframe1.e(), worldmapframe1); + this.a(MapIcon.Type.FRAME, entityhuman.world, "frame-" + entityitemframe.getId(), (double) blockposition.getX(), (double) blockposition.getZ(), (double) (entityitemframe.getDirection().get2DRotationValue() * 90), (IChatBaseComponent) null); + this.m.put(worldmapframe1.e(), worldmapframe1); } NBTTagCompound nbttagcompound = itemstack.getTag(); @@ -248,7 +269,7 @@ public class WorldMap extends PersistentBase { nbttagcompound.setDouble("x", (double) blockposition.getX()); nbttagcompound.setDouble("z", (double) blockposition.getZ()); nbttagcompound.setDouble("rot", 180.0D); - nbttaglist.add((NBTBase) nbttagcompound); + nbttaglist.add(nbttagcompound); if (mapicon_type.c()) { NBTTagCompound nbttagcompound1 = itemstack.a("display"); @@ -322,8 +343,8 @@ public class WorldMap extends PersistentBase { } public void flagDirty(int i, int j) { - this.c(); - Iterator iterator = this.h.iterator(); + this.b(); + Iterator iterator = this.i.iterator(); while (iterator.hasNext()) { WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker = (WorldMap.WorldMapHumanTracker) iterator.next(); @@ -339,7 +360,7 @@ public class WorldMap extends PersistentBase { if (worldmap_worldmaphumantracker == null) { worldmap_worldmaphumantracker = new WorldMap.WorldMapHumanTracker(entityhuman); this.humans.put(entityhuman, worldmap_worldmaphumantracker); - this.h.add(worldmap_worldmaphumantracker); + this.i.add(worldmap_worldmaphumantracker); } return worldmap_worldmaphumantracker; @@ -363,28 +384,28 @@ public class WorldMap extends PersistentBase { boolean flag2 = true; - if (this.k.containsKey(mapiconbanner.f()) && ((MapIconBanner) this.k.get(mapiconbanner.f())).equals(mapiconbanner)) { - this.k.remove(mapiconbanner.f()); + if (this.l.containsKey(mapiconbanner.f()) && ((MapIconBanner) this.l.get(mapiconbanner.f())).equals(mapiconbanner)) { + this.l.remove(mapiconbanner.f()); this.decorations.remove(mapiconbanner.f()); flag2 = false; flag1 = true; } if (flag2) { - this.k.put(mapiconbanner.f(), mapiconbanner); + this.l.put(mapiconbanner.f(), mapiconbanner); this.a(mapiconbanner.c(), generatoraccess, mapiconbanner.f(), (double) f, (double) f1, 180.0D, mapiconbanner.d()); flag1 = true; } if (flag1) { - this.c(); + this.b(); } } } public void a(IBlockAccess iblockaccess, int i, int j) { - Iterator iterator = this.k.values().iterator(); + Iterator iterator = this.l.values().iterator(); while (iterator.hasNext()) { MapIconBanner mapiconbanner = (MapIconBanner) iterator.next(); @@ -403,7 +424,7 @@ public class WorldMap extends PersistentBase { public void a(BlockPosition blockposition, int i) { this.decorations.remove("frame-" + i); - this.l.remove(WorldMapFrame.a(blockposition)); + this.m.remove(WorldMapFrame.a(blockposition)); } public class WorldMapHumanTracker { @@ -422,7 +443,7 @@ public class WorldMap extends PersistentBase { private boolean shouldUseVanillaMap() { return mapView.getRenderers().size() == 1 && mapView.getRenderers().get(0).getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class; } - // Paper stop + // Paper end public final EntityHuman trackee; private boolean d = true; private int e; @@ -455,9 +476,9 @@ public class WorldMap extends PersistentBase { if (this.d) { this.d = false; - return new PacketPlayOutMap(ItemWorldMap.e(itemstack), WorldMap.this.scale, WorldMap.this.track, icons, render.buffer, this.e, this.f, this.g + 1 - this.e, this.h + 1 - this.f); + return new PacketPlayOutMap(ItemWorldMap.e(itemstack), WorldMap.this.scale, WorldMap.this.track, WorldMap.this.locked, icons, render.buffer, this.e, this.f, this.g + 1 - this.e, this.h + 1 - this.f); } else { - return this.i++ % 5 == 0 ? new PacketPlayOutMap(ItemWorldMap.e(itemstack), WorldMap.this.scale, WorldMap.this.track, icons, render.buffer, 0, 0, 0, 0) : null; + return this.i++ % 5 == 0 ? new PacketPlayOutMap(ItemWorldMap.e(itemstack), WorldMap.this.scale, WorldMap.this.track, WorldMap.this.locked, icons, render.buffer, 0, 0, 0, 0) : null; } // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/WorldNBTStorage.java b/src/main/java/net/minecraft/server/WorldNBTStorage.java index 62cb9f02b..eaae44686 100644 --- a/src/main/java/net/minecraft/server/WorldNBTStorage.java +++ b/src/main/java/net/minecraft/server/WorldNBTStorage.java @@ -1,10 +1,6 @@ package net.minecraft.server; -import com.mojang.datafixers.DataFixTypes; import com.mojang.datafixers.DataFixer; - -import io.akarin.server.core.AkarinAsyncExecutor; - import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; @@ -22,9 +18,9 @@ import java.util.UUID; import org.bukkit.craftbukkit.entity.CraftPlayer; // CraftBukkit end -public class WorldNBTStorage implements IDataManager, IPlayerFileData { +public class WorldNBTStorage implements IPlayerFileData { - private static final Logger b = LogManager.getLogger(); + private static final Logger LOGGER = LogManager.getLogger(); private final File baseDir; private final File playerDir; private final long sessionId = SystemUtils.getMonotonicMillis(); @@ -32,7 +28,6 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { private final DefinedStructureManager g; protected final DataFixer a; private UUID uuid = null; // CraftBukkit - final Object playerFileLock = new Object(); // Akarin public WorldNBTStorage(File file, String s, @Nullable MinecraftServer minecraftserver, DataFixer datafixer) { this.a = datafixer; @@ -99,10 +94,42 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { this.g = null; } - this.j(); + this.h(); } - private void j() { + public void saveWorldData(WorldData worlddata, @Nullable NBTTagCompound nbttagcompound) { + worlddata.d(19133); + NBTTagCompound nbttagcompound1 = worlddata.a(nbttagcompound); + NBTTagCompound nbttagcompound2 = new NBTTagCompound(); + + nbttagcompound2.set("Data", nbttagcompound1); + + try { + File file = new File(this.baseDir, "level.dat_new"); + File file1 = new File(this.baseDir, "level.dat_old"); + File file2 = new File(this.baseDir, "level.dat"); + + NBTCompressedStreamTools.a(nbttagcompound2, (OutputStream) (new FileOutputStream(file))); + if (file1.exists()) { + file1.delete(); + } + + file2.renameTo(file1); + if (file2.exists()) { + file2.delete(); + } + + file.renameTo(file2); + if (file.exists()) { + file.delete(); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + + } + + private void h() { try { File file = new File(this.baseDir, "session.lock"); DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(file)); @@ -141,16 +168,12 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { } } - public IChunkLoader createChunkLoader(WorldProvider worldprovider) { - throw new RuntimeException("Old Chunk Storage is no longer supported."); - } - @Nullable public WorldData getWorldData() { File file = new File(this.baseDir, "level.dat"); if (file.exists()) { - WorldData worlddata = WorldLoader.a(file, this.a); + WorldData worlddata = Convertable.a(file, this.a); if (worlddata != null) { return worlddata; @@ -158,89 +181,43 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { } file = new File(this.baseDir, "level.dat_old"); - return file.exists() ? WorldLoader.a(file, this.a) : null; - } - - public void saveWorldData(WorldData worlddata, @Nullable NBTTagCompound nbttagcompound) { - NBTTagCompound nbttagcompound1 = worlddata.a(nbttagcompound); - NBTTagCompound nbttagcompound2 = new NBTTagCompound(); - - nbttagcompound2.set("Data", nbttagcompound1); - - try { - File file = new File(this.baseDir, "level.dat_new"); - File file1 = new File(this.baseDir, "level.dat_old"); - File file2 = new File(this.baseDir, "level.dat"); - - NBTCompressedStreamTools.a(nbttagcompound2, (OutputStream) (new FileOutputStream(file))); - if (file1.exists()) { - file1.delete(); - } - - file2.renameTo(file1); - if (file2.exists()) { - file2.delete(); - } - - file.renameTo(file2); - if (file.exists()) { - file.delete(); - } - } catch (Exception exception) { - exception.printStackTrace(); - } - + return file.exists() ? Convertable.a(file, this.a) : null; } public void saveWorldData(WorldData worlddata) { this.saveWorldData(worlddata, (NBTTagCompound) null); } - // Akarin start + @Override public void save(EntityHuman entityhuman) { - save(entityhuman, true); - } - // Akarin end - public void save(EntityHuman entityhuman, boolean async) { if(!com.destroystokyo.paper.PaperConfig.savePlayerData) return; // Paper - Make player data saving configurable - Runnable runnable = () -> { // Akarin try { NBTTagCompound nbttagcompound = entityhuman.save(new NBTTagCompound()); - File file = new File(this.playerDir, entityhuman.bu() + ".dat.tmp"); - File file1 = new File(this.playerDir, entityhuman.bu() + ".dat"); + File file = new File(this.playerDir, entityhuman.getUniqueIDString() + ".dat.tmp"); + File file1 = new File(this.playerDir, entityhuman.getUniqueIDString() + ".dat"); - synchronized (playerFileLock) { // Akarin NBTCompressedStreamTools.a(nbttagcompound, (OutputStream) (new FileOutputStream(file))); if (file1.exists()) { file1.delete(); } file.renameTo(file1); - } // Akarin } catch (Exception exception) { - WorldNBTStorage.b.error("Failed to save player data for {}", entityhuman.getName(), exception); // Paper + WorldNBTStorage.LOGGER.error("Failed to save player data for {}", entityhuman.getName(), exception); // Paper } - // Akarin start - }; - if (async) - AkarinAsyncExecutor.scheduleSingleAsyncTask(runnable); - else - runnable.run(); - // Akarin end } @Nullable + @Override public NBTTagCompound load(EntityHuman entityhuman) { NBTTagCompound nbttagcompound = null; try { - File file = new File(this.playerDir, entityhuman.bu() + ".dat"); + File file = new File(this.playerDir, entityhuman.getUniqueIDString() + ".dat"); // Spigot Start boolean usingWrongFile = false; - synchronized (playerFileLock) { // Akarin - boolean normalFile = file.exists() && file.isFile(); // Akarin - ensures normal file - if ( org.bukkit.Bukkit.getOnlineMode() && !normalFile ) // Paper - Check online mode first // Akarin - ensures normal file + if ( org.bukkit.Bukkit.getOnlineMode() && !file.exists() ) // Paper - Check online mode first { file = new File( this.playerDir, UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + entityhuman.getName() ).getBytes( "UTF-8" ) ).toString() + ".dat"); if ( file.exists() ) @@ -251,7 +228,7 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { } // Spigot End - if (normalFile) { // Akarin - avoid double I/O operation + if (file.exists() && file.isFile()) { nbttagcompound = NBTCompressedStreamTools.a((InputStream) (new FileInputStream(file))); } // Spigot Start @@ -259,10 +236,9 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { { file.renameTo( new File( file.getPath() + ".offline-read" ) ); } - } // Akarin // Spigot End } catch (Exception exception) { - WorldNBTStorage.b.warn("Failed to load player data for {}", entityhuman.getDisplayName().getString()); + WorldNBTStorage.LOGGER.warn("Failed to load player data for {}", entityhuman.getDisplayName().getString()); } if (nbttagcompound != null) { @@ -287,25 +263,19 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { // CraftBukkit start public NBTTagCompound getPlayerData(String s) { try { - synchronized (playerFileLock) { // Akarin File file1 = new File(this.playerDir, s + ".dat"); if (file1.exists()) { return NBTCompressedStreamTools.a((InputStream) (new FileInputStream(file1))); } - } // Akarin } catch (Exception exception) { - b.warn("Failed to load player data for " + s); + LOGGER.warn("Failed to load player data for " + s); } return null; } // CraftBukkit end - public IPlayerFileData getPlayerFileData() { - return this; - } - public String[] getSeenPlayers() { String[] astring = this.playerDir.list(); @@ -322,20 +292,11 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { return astring; } - public void a() {} - - public File getDataFile(DimensionManager dimensionmanager, String s) { - File file = new File(dimensionmanager.a(this.baseDir), "data"); - - file.mkdirs(); - return new File(file, s + ".dat"); - } - - public DefinedStructureManager h() { + public DefinedStructureManager f() { return this.g; } - public DataFixer i() { + public DataFixer getDataFixer() { return this.a; } @@ -349,7 +310,7 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { dis = new DataInputStream(new FileInputStream(file1)); return uuid = new UUID(dis.readLong(), dis.readLong()); } catch (IOException ex) { - b.warn("Failed to read " + file1 + ", generating new random UUID", ex); + LOGGER.warn("Failed to read " + file1 + ", generating new random UUID", ex); } finally { if (dis != null) { try { @@ -367,7 +328,7 @@ public class WorldNBTStorage implements IDataManager, IPlayerFileData { dos.writeLong(uuid.getMostSignificantBits()); dos.writeLong(uuid.getLeastSignificantBits()); } catch (IOException ex) { - b.warn("Failed to write " + file1, ex); + LOGGER.warn("Failed to write " + file1, ex); } finally { if (dos != null) { try { diff --git a/src/main/java/net/minecraft/server/WorldPersistentData.java b/src/main/java/net/minecraft/server/WorldPersistentData.java index e86d382c8..00e9a1735 100644 --- a/src/main/java/net/minecraft/server/WorldPersistentData.java +++ b/src/main/java/net/minecraft/server/WorldPersistentData.java @@ -1,159 +1,138 @@ package net.minecraft.server; import com.google.common.collect.Maps; -import com.mojang.datafixers.DataFixTypes; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectIterator; -import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry; +import com.mojang.datafixers.DataFixer; import java.io.DataInputStream; -import java.io.DataOutput; -import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; +import java.io.PushbackInputStream; import java.util.Iterator; import java.util.Map; -import java.util.function.Function; +import java.util.function.Supplier; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class WorldPersistentData { - private static final Logger a = LogManager.getLogger(); - private final DimensionManager b; - public Map data = Maps.newHashMap(); - private final Object2IntMap d = new Object2IntOpenHashMap(); - @Nullable - private final IDataManager e; + private static final Logger LOGGER = LogManager.getLogger(); + public final Map data = Maps.newHashMap(); + private final DataFixer c; + private final File d; - public WorldPersistentData(DimensionManager dimensionmanager, @Nullable IDataManager idatamanager) { - this.b = dimensionmanager; - this.e = idatamanager; - this.d.defaultReturnValue(-1); + public WorldPersistentData(File file, DataFixer datafixer) { + this.c = datafixer; + this.d = file; + } + + private File a(String s) { + return new File(this.d, s + ".dat"); + } + + public T a(Supplier supplier, String s) { + T t0 = this.b(supplier, s); + + if (t0 != null) { + return t0; + } else { + T t1 = supplier.get(); // Paper - decompile fix + + this.a(t1); + return t1; + } } @Nullable - public T a(Function function, String s) { - if ("Mineshaft_index".equals(s) || "Mineshaft".equals(s)) return null; // Paper - mineshaft is useless data + public T b(Supplier supplier, String s) { T persistentbase = (T) this.data.get(s); // Paper - decompile fix - if (persistentbase == null && this.e != null) { - try { - File file = this.e.getDataFile(this.b, s); - - if (file != null && file.exists()) { - persistentbase = function.apply(s); // Paper - decompile fix - persistentbase.a(a(this.e, this.b, s, 1631).getCompound("data")); - this.data.put(s, persistentbase); - } else this.data.put(s, NO_RESULT); // Paper - } catch (Exception exception) { - WorldPersistentData.a.error("Error loading saved data: {}", s, exception); - } + if (persistentbase == null && !this.data.containsKey(s)) { + persistentbase = this.c(supplier, s); + this.data.put(s, persistentbase); } - return persistentbase == NO_RESULT ? null : persistentbase; // Paper - } - private static final PersistentBase NO_RESULT = new ForcedChunk("chunks"); // Paper - - public void a(String s, PersistentBase persistentbase) { - this.data.put(s, persistentbase); + return persistentbase; } - public void a() { + @Nullable + private T c(Supplier supplier, String s) { try { - this.d.clear(); - if (this.e == null) { - return; - } + File file = this.a(s); - File file = this.e.getDataFile(this.b, "idcounts"); + if (file.exists()) { + T t0 = supplier.get(); // Paper - decompile fix + NBTTagCompound nbttagcompound = this.a(s, SharedConstants.a().getWorldVersion()); - if (file != null && file.exists()) { - DataInputStream datainputstream = new DataInputStream(new FileInputStream(file)); - NBTTagCompound nbttagcompound = NBTCompressedStreamTools.a(datainputstream); - - datainputstream.close(); - Iterator iterator = nbttagcompound.getKeys().iterator(); - - while (iterator.hasNext()) { - String s = (String) iterator.next(); - - if (nbttagcompound.hasKeyOfType(s, 99)) { - this.d.put(s, nbttagcompound.getInt(s)); - } - } + t0.a(nbttagcompound.getCompound("data")); + return t0; } } catch (Exception exception) { - WorldPersistentData.a.error("Could not load aux values", exception); + WorldPersistentData.LOGGER.error("Error loading saved data: {}", s, exception); } + return null; } - public int a(String s) { - int i = this.d.getInt(s) + 1; - - this.d.put(s, i); - if (this.e == null) { - return i; - } else { - try { - File file = this.e.getDataFile(this.b, "idcounts"); - - if (file != null) { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - ObjectIterator objectiterator = this.d.object2IntEntrySet().iterator(); - - while (objectiterator.hasNext()) { - Entry entry = (Entry) objectiterator.next(); - - nbttagcompound.setInt((String) entry.getKey(), entry.getIntValue()); - } - - DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(file)); - - NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream); - dataoutputstream.close(); - } - } catch (Exception exception) { - WorldPersistentData.a.error("Could not get free aux value {}", s, exception); - } - - return i; - } + public void a(PersistentBase persistentbase) { + this.data.put(persistentbase.getId(), persistentbase); } - public static NBTTagCompound a(IDataManager idatamanager, DimensionManager dimensionmanager, String s, int i) throws IOException { - if ("Mineshaft".equals(s) || "Mineshaft_index".equals(s)) return new NBTTagCompound(); // Paper - File file = idatamanager.getDataFile(dimensionmanager, s); - FileInputStream fileinputstream = new FileInputStream(file); + public NBTTagCompound a(String s, int i) throws IOException { + File file = this.a(s); + PushbackInputStream pushbackinputstream = new PushbackInputStream(new FileInputStream(file), 2); Throwable throwable = null; NBTTagCompound nbttagcompound; try { - NBTTagCompound nbttagcompound1 = NBTCompressedStreamTools.a((InputStream) fileinputstream); + NBTTagCompound nbttagcompound1; + + if (this.a(pushbackinputstream)) { + nbttagcompound1 = NBTCompressedStreamTools.a((InputStream) pushbackinputstream); + } else { + DataInputStream datainputstream = new DataInputStream(pushbackinputstream); + Throwable throwable1 = null; + + try { + nbttagcompound1 = NBTCompressedStreamTools.a(datainputstream); + } catch (Throwable throwable2) { + throwable1 = throwable2; + throw throwable2; + } finally { + if (datainputstream != null) { + if (throwable1 != null) { + try { + datainputstream.close(); + } catch (Throwable throwable3) { + throwable1.addSuppressed(throwable3); + } + } else { + datainputstream.close(); + } + } + + } + } + int j = nbttagcompound1.hasKeyOfType("DataVersion", 99) ? nbttagcompound1.getInt("DataVersion") : 1343; - nbttagcompound = GameProfileSerializer.a(idatamanager.i(), DataFixTypes.SAVED_DATA, nbttagcompound1, j, i); - } catch (Throwable throwable1) { - com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(throwable1); // Paper - throwable = throwable1; - throw throwable1; + nbttagcompound = GameProfileSerializer.a(this.c, DataFixTypes.SAVED_DATA, nbttagcompound1, j, i); + } catch (Throwable throwable4) { + throwable = throwable4; + com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(throwable); // Paper + throw throwable4; } finally { - if (fileinputstream != null) { + if (pushbackinputstream != null) { if (throwable != null) { try { - fileinputstream.close(); - } catch (Throwable throwable2) { - throwable.addSuppressed(throwable2); + pushbackinputstream.close(); + } catch (Throwable throwable5) { + throwable.addSuppressed(throwable5); } } else { - fileinputstream.close(); + pushbackinputstream.close(); } } @@ -162,41 +141,36 @@ public class WorldPersistentData { return nbttagcompound; } - public void b() { - if (this.e != null) { - Iterator iterator = this.data.values().iterator(); + private boolean a(PushbackInputStream pushbackinputstream) throws IOException { + byte[] abyte = new byte[2]; + boolean flag = false; + int i = pushbackinputstream.read(abyte, 0, 2); - while (iterator.hasNext()) { - PersistentBase persistentbase = (PersistentBase) iterator.next(); + if (i == 2) { + int j = (abyte[1] & 255) << 8 | abyte[0] & 255; - if (persistentbase.d()) { - this.a(persistentbase); - persistentbase.a(false); - } + if (j == 35615) { + flag = true; } - } + + if (i != 0) { + pushbackinputstream.unread(abyte, 0, i); + } + + return flag; } - private void a(PersistentBase persistentbase) { - if (this.e != null) { - try { - File file = this.e.getDataFile(this.b, persistentbase.getId()); + public void a() { + Iterator iterator = this.data.values().iterator(); - if (file != null) { - NBTTagCompound nbttagcompound = new NBTTagCompound(); + while (iterator.hasNext()) { + PersistentBase persistentbase = (PersistentBase) iterator.next(); - nbttagcompound.set("data", persistentbase.b(new NBTTagCompound())); - nbttagcompound.setInt("DataVersion", 1631); - FileOutputStream fileoutputstream = new FileOutputStream(file); - - NBTCompressedStreamTools.a(nbttagcompound, (OutputStream) fileoutputstream); - fileoutputstream.close(); - } - } catch (Exception exception) { - WorldPersistentData.a.error("Could not save data {}", persistentbase, exception); + if (persistentbase != null) { + persistentbase.a(this.a(persistentbase.getId())); } - } + } } diff --git a/src/main/java/net/minecraft/server/WorldProvider.java b/src/main/java/net/minecraft/server/WorldProvider.java index 3911e4947..d65e10cb4 100644 --- a/src/main/java/net/minecraft/server/WorldProvider.java +++ b/src/main/java/net/minecraft/server/WorldProvider.java @@ -4,19 +4,17 @@ import javax.annotation.Nullable; public abstract class WorldProvider { - public static final float[] a = new float[] { 1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F}; - protected World b; + public static final float[] a = new float[]{1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F}; + protected final World b; + private final DimensionManager f; protected boolean c; protected boolean d; - protected boolean e; - protected final float[] f = new float[16]; + protected final float[] e = new float[16]; private final float[] g = new float[4]; - public WorldProvider() {} - - public final void a(World world) { + public WorldProvider(World world, DimensionManager dimensionmanager) { this.b = world; - this.m(); + this.f = dimensionmanager; this.a(); } @@ -26,7 +24,7 @@ public abstract class WorldProvider { for (int i = 0; i <= 15; ++i) { float f1 = 1.0F - (float) i / 15.0F; - this.f[i] = (1.0F - f1) / (f1 * 3.0F + 1.0F) * 1.0F + 0.0F; + this.e[i] = (1.0F - f1) / (f1 * 3.0F + 1.0F) * 1.0F + 0.0F; } } @@ -45,7 +43,7 @@ public abstract class WorldProvider { } public boolean g() { - return this.e; + return this.f.hasSkyLight(); } public boolean h() { @@ -53,27 +51,17 @@ public abstract class WorldProvider { } public float[] i() { - return this.f; + return this.e; } public WorldBorder getWorldBorder() { return new WorldBorder(); } - public void a(EntityPlayer entityplayer) {} - - public void b(EntityPlayer entityplayer) {} - public void k() {} public void l() {} - public boolean a(int i, int j) { - return !this.b.isSpawnChunk(i, j) && !this.b.isForceLoaded(i, j); // Paper - Use spawn chunks check for all worlds - } - - protected abstract void m(); - public abstract ChunkGenerator getChunkGenerator(); @Nullable @@ -88,5 +76,5 @@ public abstract class WorldProvider { public abstract boolean canRespawn(); - public abstract DimensionManager getDimensionManager(); + public DimensionManager getDimensionManager() { return this.f; } // CraftBukkit } diff --git a/src/main/java/net/minecraft/server/WorldProviderHell.java b/src/main/java/net/minecraft/server/WorldProviderHell.java index 77fe71f24..d0c9526c1 100644 --- a/src/main/java/net/minecraft/server/WorldProviderHell.java +++ b/src/main/java/net/minecraft/server/WorldProviderHell.java @@ -4,68 +4,81 @@ import javax.annotation.Nullable; public class WorldProviderHell extends WorldProvider { - public WorldProviderHell() {} - - public void m() { + public WorldProviderHell(World world, DimensionManager dimensionmanager) { + super(world, dimensionmanager); this.c = true; this.d = true; - this.e = false; } + @Override protected void a() { float f = 0.1F; for (int i = 0; i <= 15; ++i) { float f1 = 1.0F - (float) i / 15.0F; - this.f[i] = (1.0F - f1) / (f1 * 3.0F + 1.0F) * 0.9F + 0.1F; + this.e[i] = (1.0F - f1) / (f1 * 3.0F + 1.0F) * 0.9F + 0.1F; } } + @Override public ChunkGenerator getChunkGenerator() { - GeneratorSettingsNether generatorsettingsnether = (GeneratorSettingsNether) ChunkGeneratorType.b.b(); + GeneratorSettingsNether generatorsettingsnether = (GeneratorSettingsNether) ChunkGeneratorType.b.a(); generatorsettingsnether.a(Blocks.NETHERRACK.getBlockData()); generatorsettingsnether.b(Blocks.LAVA.getBlockData()); - return ChunkGeneratorType.b.create(this.b, BiomeLayout.b.a(((BiomeLayoutFixedConfiguration) BiomeLayout.b.b()).a(Biomes.NETHER)), generatorsettingsnether); + return ChunkGeneratorType.b.create(this.b, BiomeLayout.b.a(((BiomeLayoutFixedConfiguration) BiomeLayout.b.a()).a(Biomes.NETHER)), generatorsettingsnether); } + @Override public boolean isOverworld() { return false; } @Nullable + @Override public BlockPosition a(ChunkCoordIntPair chunkcoordintpair, boolean flag) { return null; } @Nullable + @Override public BlockPosition a(int i, int j, boolean flag) { return null; } + @Override public float a(long i, float f) { return 0.5F; } + @Override public boolean canRespawn() { return false; } + @Override public WorldBorder getWorldBorder() { return new WorldBorder() { + @Override public double getCenterX() { return super.getCenterX(); // CraftBukkit } + @Override public double getCenterZ() { return super.getCenterZ(); // CraftBukkit } }; } + // CraftBukkit start + /* + @Override public DimensionManager getDimensionManager() { return DimensionManager.NETHER; } + */ + // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/WorldProviderNormal.java b/src/main/java/net/minecraft/server/WorldProviderNormal.java new file mode 100644 index 000000000..861887117 --- /dev/null +++ b/src/main/java/net/minecraft/server/WorldProviderNormal.java @@ -0,0 +1,213 @@ +package net.minecraft.server; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.JsonOps; +import javax.annotation.Nullable; + +public class WorldProviderNormal extends WorldProvider { + + public WorldProviderNormal(World world, DimensionManager dimensionmanager) { + super(world, dimensionmanager); + } + + // CraftBukkit start + /* + @Override + public DimensionManager getDimensionManager() { + return DimensionManager.OVERWORLD; + } + */ + // CraftBukkit end + + @Override + public ChunkGenerator getChunkGenerator() { + WorldType worldtype = this.b.getWorldData().getType(); + ChunkGeneratorType chunkgeneratortype = ChunkGeneratorType.e; + ChunkGeneratorType chunkgeneratortype1 = ChunkGeneratorType.d; + ChunkGeneratorType chunkgeneratortype2 = ChunkGeneratorType.b; + ChunkGeneratorType chunkgeneratortype3 = ChunkGeneratorType.c; + ChunkGeneratorType chunkgeneratortype4 = ChunkGeneratorType.a; + BiomeLayout biomelayout = BiomeLayout.b; + BiomeLayout biomelayout1 = BiomeLayout.c; + BiomeLayout biomelayout2 = BiomeLayout.a; + + if (worldtype == WorldType.FLAT) { + GeneratorSettingsFlat generatorsettingsflat = GeneratorSettingsFlat.a(new Dynamic(DynamicOpsNBT.a, this.b.getWorldData().getGeneratorOptions())); + BiomeLayoutFixedConfiguration biomelayoutfixedconfiguration = ((BiomeLayoutFixedConfiguration) biomelayout.a()).a(generatorsettingsflat.v()); + + return chunkgeneratortype.create(this.b, biomelayout.a(biomelayoutfixedconfiguration), generatorsettingsflat); + } else if (worldtype == WorldType.DEBUG_ALL_BLOCK_STATES) { + BiomeLayoutFixedConfiguration biomelayoutfixedconfiguration1 = ((BiomeLayoutFixedConfiguration) biomelayout.a()).a(Biomes.PLAINS); + + return chunkgeneratortype1.create(this.b, biomelayout.a(biomelayoutfixedconfiguration1), chunkgeneratortype1.a()); + } else if (worldtype != WorldType.g) { + GeneratorSettingsOverworld generatorsettingsoverworld = (GeneratorSettingsOverworld) chunkgeneratortype4.a(); + BiomeLayoutOverworldConfiguration biomelayoutoverworldconfiguration = ((BiomeLayoutOverworldConfiguration) biomelayout1.a()).a(this.b.getWorldData()).a(generatorsettingsoverworld); + + return chunkgeneratortype4.create(this.b, biomelayout1.a(biomelayoutoverworldconfiguration), generatorsettingsoverworld); + } else { + WorldChunkManager worldchunkmanager = null; + JsonElement jsonelement = (JsonElement) Dynamic.convert(DynamicOpsNBT.a, JsonOps.INSTANCE, this.b.getWorldData().getGeneratorOptions()); + JsonObject jsonobject = jsonelement.getAsJsonObject(); + JsonObject jsonobject1 = jsonobject.getAsJsonObject("biome_source"); + + if (jsonobject1 != null && jsonobject1.has("type") && jsonobject1.has("options")) { + BiomeLayout biomelayout3 = (BiomeLayout) IRegistry.BIOME_SOURCE_TYPE.get(new MinecraftKey(jsonobject1.getAsJsonPrimitive("type").getAsString())); + JsonObject jsonobject2 = jsonobject1.getAsJsonObject("options"); + BiomeBase[] abiomebase = new BiomeBase[]{Biomes.OCEAN}; + + if (jsonobject2.has("biomes")) { + JsonArray jsonarray = jsonobject2.getAsJsonArray("biomes"); + + abiomebase = jsonarray.size() > 0 ? new BiomeBase[jsonarray.size()] : new BiomeBase[]{Biomes.OCEAN}; + + for (int i = 0; i < jsonarray.size(); ++i) { + abiomebase[i] = (BiomeBase) IRegistry.BIOME.getOptional(new MinecraftKey(jsonarray.get(i).getAsString())).orElse(Biomes.OCEAN); + } + } + + if (BiomeLayout.b == biomelayout3) { + BiomeLayoutFixedConfiguration biomelayoutfixedconfiguration2 = ((BiomeLayoutFixedConfiguration) biomelayout.a()).a(abiomebase[0]); + + worldchunkmanager = biomelayout.a(biomelayoutfixedconfiguration2); + } + + if (BiomeLayout.a == biomelayout3) { + int j = jsonobject2.has("size") ? jsonobject2.getAsJsonPrimitive("size").getAsInt() : 2; + BiomeLayoutCheckerboardConfiguration biomelayoutcheckerboardconfiguration = ((BiomeLayoutCheckerboardConfiguration) biomelayout2.a()).a(abiomebase).a(j); + + worldchunkmanager = biomelayout2.a(biomelayoutcheckerboardconfiguration); + } + + if (BiomeLayout.c == biomelayout3) { + BiomeLayoutOverworldConfiguration biomelayoutoverworldconfiguration1 = ((BiomeLayoutOverworldConfiguration) biomelayout1.a()).a(new GeneratorSettingsOverworld()).a(this.b.getWorldData()); + + worldchunkmanager = biomelayout1.a(biomelayoutoverworldconfiguration1); + } + } + + if (worldchunkmanager == null) { + worldchunkmanager = biomelayout.a(((BiomeLayoutFixedConfiguration) biomelayout.a()).a(Biomes.OCEAN)); + } + + IBlockData iblockdata = Blocks.STONE.getBlockData(); + IBlockData iblockdata1 = Blocks.WATER.getBlockData(); + JsonObject jsonobject3 = jsonobject.getAsJsonObject("chunk_generator"); + + if (jsonobject3 != null && jsonobject3.has("options")) { + JsonObject jsonobject4 = jsonobject3.getAsJsonObject("options"); + String s; + + if (jsonobject4.has("default_block")) { + s = jsonobject4.getAsJsonPrimitive("default_block").getAsString(); + iblockdata = ((Block) IRegistry.BLOCK.get(new MinecraftKey(s))).getBlockData(); + } + + if (jsonobject4.has("default_fluid")) { + s = jsonobject4.getAsJsonPrimitive("default_fluid").getAsString(); + iblockdata1 = ((Block) IRegistry.BLOCK.get(new MinecraftKey(s))).getBlockData(); + } + } + + if (jsonobject3 != null && jsonobject3.has("type")) { + ChunkGeneratorType chunkgeneratortype5 = (ChunkGeneratorType) IRegistry.CHUNK_GENERATOR_TYPE.get(new MinecraftKey(jsonobject3.getAsJsonPrimitive("type").getAsString())); + + if (ChunkGeneratorType.b == chunkgeneratortype5) { + GeneratorSettingsNether generatorsettingsnether = (GeneratorSettingsNether) chunkgeneratortype2.a(); + + generatorsettingsnether.a(iblockdata); + generatorsettingsnether.b(iblockdata1); + return chunkgeneratortype2.create(this.b, worldchunkmanager, generatorsettingsnether); + } + + if (ChunkGeneratorType.c == chunkgeneratortype5) { + GeneratorSettingsEnd generatorsettingsend = (GeneratorSettingsEnd) chunkgeneratortype3.a(); + + generatorsettingsend.a(new BlockPosition(0, 64, 0)); + generatorsettingsend.a(iblockdata); + generatorsettingsend.b(iblockdata1); + return chunkgeneratortype3.create(this.b, worldchunkmanager, generatorsettingsend); + } + } + + GeneratorSettingsOverworld generatorsettingsoverworld1 = (GeneratorSettingsOverworld) chunkgeneratortype4.a(); + + generatorsettingsoverworld1.a(iblockdata); + generatorsettingsoverworld1.b(iblockdata1); + return chunkgeneratortype4.create(this.b, worldchunkmanager, generatorsettingsoverworld1); + } + } + + @Nullable + @Override + public BlockPosition a(ChunkCoordIntPair chunkcoordintpair, boolean flag) { + for (int i = chunkcoordintpair.d(); i <= chunkcoordintpair.f(); ++i) { + for (int j = chunkcoordintpair.e(); j <= chunkcoordintpair.g(); ++j) { + BlockPosition blockposition = this.a(i, j, flag); + + if (blockposition != null) { + return blockposition; + } + } + } + + return null; + } + + @Nullable + @Override + public BlockPosition a(int i, int j, boolean flag) { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(i, 0, j); + BiomeBase biomebase = this.b.getBiome(blockposition_mutableblockposition); + IBlockData iblockdata = biomebase.q().a(); + + if (flag && !iblockdata.getBlock().a(TagsBlock.VALID_SPAWN)) { + return null; + } else { + Chunk chunk = this.b.getChunkAt(i >> 4, j >> 4); + int k = chunk.a(HeightMap.Type.MOTION_BLOCKING, i & 15, j & 15); + + if (k < 0) { + return null; + } else if (chunk.a(HeightMap.Type.WORLD_SURFACE, i & 15, j & 15) > chunk.a(HeightMap.Type.OCEAN_FLOOR, i & 15, j & 15)) { + return null; + } else { + for (int l = k + 1; l >= 0; --l) { + blockposition_mutableblockposition.d(i, l, j); + IBlockData iblockdata1 = this.b.getType(blockposition_mutableblockposition); + + if (!iblockdata1.p().isEmpty()) { + break; + } + + if (iblockdata1.equals(iblockdata)) { + return blockposition_mutableblockposition.up().immutableCopy(); + } + } + + return null; + } + } + } + + @Override + public float a(long i, float f) { + double d0 = MathHelper.h((double) i / 24000.0D - 0.25D); + double d1 = 0.5D - Math.cos(d0 * 3.141592653589793D) / 2.0D; + + return (float) (d0 * 2.0D + d1) / 3.0F; + } + + @Override + public boolean isOverworld() { + return true; + } + + @Override + public boolean canRespawn() { + return true; + } +} diff --git a/src/main/java/net/minecraft/server/WorldProviderTheEnd.java b/src/main/java/net/minecraft/server/WorldProviderTheEnd.java index 4d692b7e0..b97408cff 100644 --- a/src/main/java/net/minecraft/server/WorldProviderTheEnd.java +++ b/src/main/java/net/minecraft/server/WorldProviderTheEnd.java @@ -5,40 +5,43 @@ import javax.annotation.Nullable; public class WorldProviderTheEnd extends WorldProvider { - public static final BlockPosition g = new BlockPosition(100, 50, 0); - private EnderDragonBattle h; + public static final BlockPosition f = new BlockPosition(100, 50, 0); + private final EnderDragonBattle g; - public WorldProviderTheEnd() {} + public WorldProviderTheEnd(World world, DimensionManager dimensionmanager) { + super(world, dimensionmanager); + NBTTagCompound nbttagcompound = world.getWorldData().a(DimensionManager.THE_END); - public void m() { - NBTTagCompound nbttagcompound = this.b.getWorldData().a(DimensionManager.THE_END); - - this.h = this.b instanceof WorldServer ? new EnderDragonBattle((WorldServer) this.b, nbttagcompound.getCompound("DragonFight")) : null; - this.e = false; + this.g = world instanceof WorldServer ? new EnderDragonBattle((WorldServer) world, nbttagcompound.getCompound("DragonFight")) : null; } + @Override public ChunkGenerator getChunkGenerator() { - GeneratorSettingsEnd generatorsettingsend = (GeneratorSettingsEnd) ChunkGeneratorType.c.b(); + GeneratorSettingsEnd generatorsettingsend = (GeneratorSettingsEnd) ChunkGeneratorType.c.a(); generatorsettingsend.a(Blocks.END_STONE.getBlockData()); generatorsettingsend.b(Blocks.AIR.getBlockData()); generatorsettingsend.a(this.d()); - return ChunkGeneratorType.c.create(this.b, BiomeLayout.d.a(((BiomeLayoutTheEndConfiguration) BiomeLayout.d.b()).a(this.b.getSeed())), generatorsettingsend); + return ChunkGeneratorType.c.create(this.b, BiomeLayout.d.a(((BiomeLayoutTheEndConfiguration) BiomeLayout.d.a()).a(this.b.getSeed())), generatorsettingsend); } + @Override public float a(long i, float f) { return 0.5F; // Paper - fix MC-93764 } + @Override public boolean canRespawn() { return false; } + @Override public boolean isOverworld() { return false; } @Nullable + @Override public BlockPosition a(ChunkCoordIntPair chunkcoordintpair, boolean flag) { Random random = new Random(this.b.getSeed()); BlockPosition blockposition = new BlockPosition(chunkcoordintpair.d() + random.nextInt(15), 0, chunkcoordintpair.g() + random.nextInt(15)); @@ -46,38 +49,47 @@ public class WorldProviderTheEnd extends WorldProvider { return this.b.i(blockposition).getMaterial().isSolid() ? blockposition : null; } + @Override public BlockPosition d() { - return WorldProviderTheEnd.g; + return WorldProviderTheEnd.f; } @Nullable + @Override public BlockPosition a(int i, int j, boolean flag) { return this.a(new ChunkCoordIntPair(i >> 4, j >> 4), flag); } + // CraftBukkit start + /* + @Override public DimensionManager getDimensionManager() { return DimensionManager.THE_END; } + */ + // CraftBukkit end + @Override public void k() { NBTTagCompound nbttagcompound = new NBTTagCompound(); - if (this.h != null) { - nbttagcompound.set("DragonFight", this.h.a()); + if (this.g != null) { + nbttagcompound.set("DragonFight", this.g.a()); } this.b.getWorldData().a(DimensionManager.THE_END, nbttagcompound); } + @Override public void l() { - if (this.h != null) { - this.h.b(); + if (this.g != null) { + this.g.b(); } } @Nullable - public EnderDragonBattle r() { - return this.h; + public EnderDragonBattle q() { + return this.g; } } diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java index a44d64b92..5b18f4bd5 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -1,23 +1,38 @@ package net.minecraft.server; +import co.aikar.timings.TimingHistory; import co.aikar.timings.Timings; -import io.akarin.server.core.AkarinAsyncExecutor; +import com.destroystokyo.paper.PaperWorldConfig; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListenableFutureTask; - +import com.google.common.collect.Queues; +import com.google.common.collect.Sets; +import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap.Entry; +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.longs.LongSets; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectIterator; import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.Writer; +import java.nio.file.Files; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Queue; import java.util.Random; +import java.util.Set; import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.Executor; import java.util.function.BooleanSupplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import java.util.function.Predicate; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.apache.logging.log4j.LogManager; @@ -25,386 +40,604 @@ import org.apache.logging.log4j.Logger; // CraftBukkit start import java.util.logging.Level; - +import org.bukkit.Bukkit; import org.bukkit.WeatherType; -import org.bukkit.block.BlockState; -import org.bukkit.craftbukkit.util.HashTreeSet; - -import org.bukkit.event.block.BlockFormEvent; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.server.MapInitializeEvent; import org.bukkit.event.weather.LightningStrikeEvent; // CraftBukkit end -public class WorldServer extends World implements IAsyncTaskHandler { +public class WorldServer extends World { - private static final Logger a = LogManager.getLogger(); - boolean hasPhysicsEvent = true; // Paper + private static final Logger LOGGER = LogManager.getLogger(); + private final List globalEntityList = Lists.newArrayList(); + public final Int2ObjectMap entitiesById = new Int2ObjectLinkedOpenHashMap(); + private final Map entitiesByUUID = Maps.newHashMap(); + private final Queue entitiesToAdd = Queues.newArrayDeque(); + public final List players = Lists.newArrayList(); // Paper - private -> public + boolean tickingEntities; private final MinecraftServer server; - public EntityTracker tracker; - private final PlayerChunkMap manager; - public final Map entitiesByUUID = Maps.newHashMap(); // Paper + private final WorldNBTStorage dataManager; public boolean savingDisabled; - private boolean J; + private boolean C; private int emptyTime; private final PortalTravelAgent portalTravelAgent; - private final SpawnerCreature spawnerCreature = new SpawnerCreature(); private final TickListServer nextTickListBlock; private final TickListServer nextTickListFluid; - protected final VillageSiege siegeManager; - ObjectLinkedOpenHashSet d; - private boolean P; + private final Set H; + protected final PersistentRaid c; + private final ObjectLinkedOpenHashSet I; + private boolean ticking; + @Nullable + private final MobSpawnerTrader mobSpawnerTrader; // CraftBukkit start - public final DimensionManager dimension; + private int tickPosition; + boolean hasPhysicsEvent = true; // Paper private static Throwable getAddToWorldStackTrace(Entity entity) { return new Throwable(entity + " Added to world at " + new java.util.Date()); } + // Paper start - Asynchronous IO + public final com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController poiDataController = new com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController() { + @Override + public void writeData(int x, int z, NBTTagCompound compound) throws java.io.IOException { + WorldServer.this.getChunkProvider().playerChunkMap.getVillagePlace().write(new ChunkCoordIntPair(x, z), compound); + } + + @Override + public NBTTagCompound readData(int x, int z) throws java.io.IOException { + return WorldServer.this.getChunkProvider().playerChunkMap.getVillagePlace().read(new ChunkCoordIntPair(x, z)); + } + + @Override + public T computeForRegionFile(int chunkX, int chunkZ, java.util.function.Function function) { + synchronized (WorldServer.this.getChunkProvider().playerChunkMap.getVillagePlace()) { + RegionFile file; + + try { + file = WorldServer.this.getChunkProvider().playerChunkMap.getVillagePlace().getRegionFile(new ChunkCoordIntPair(chunkX, chunkZ), false); + } catch (java.io.IOException ex) { + throw new RuntimeException(ex); + } + + return function.apply(file); + } + } + + @Override + public T computeForRegionFileIfLoaded(int chunkX, int chunkZ, java.util.function.Function function) { + synchronized (WorldServer.this.getChunkProvider().playerChunkMap.getVillagePlace()) { + RegionFile file = WorldServer.this.getChunkProvider().playerChunkMap.getVillagePlace().getRegionFileIfLoaded(new ChunkCoordIntPair(chunkX, chunkZ)); + return function.apply(file); + } + } + }; + + public final com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController chunkDataController = new com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController() { + @Override + public void writeData(int x, int z, NBTTagCompound compound) throws java.io.IOException { + WorldServer.this.getChunkProvider().playerChunkMap.write(new ChunkCoordIntPair(x, z), compound); + } + + @Override + public NBTTagCompound readData(int x, int z) throws java.io.IOException { + return WorldServer.this.getChunkProvider().playerChunkMap.read(new ChunkCoordIntPair(x, z)); + } + + @Override + public T computeForRegionFile(int chunkX, int chunkZ, java.util.function.Function function) { + synchronized (WorldServer.this.getChunkProvider().playerChunkMap) { + RegionFile file; + + try { + file = WorldServer.this.getChunkProvider().playerChunkMap.getRegionFile(new ChunkCoordIntPair(chunkX, chunkZ), false); + } catch (java.io.IOException ex) { + throw new RuntimeException(ex); + } + + return function.apply(file); + } + } + + @Override + public T computeForRegionFileIfLoaded(int chunkX, int chunkZ, java.util.function.Function function) { + synchronized (WorldServer.this.getChunkProvider().playerChunkMap) { + RegionFile file = WorldServer.this.getChunkProvider().playerChunkMap.getRegionFileIfLoaded(new ChunkCoordIntPair(chunkX, chunkZ)); + return function.apply(file); + } + } + }; + public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager; + // Paper end + // Paper start + @Override + public boolean isChunkLoaded(int x, int z) { + return this.getChunkProvider().getChunkAtIfLoadedImmediately(x, z) != null; + } + // Paper end + // Add env and gen to constructor - public WorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, PersistentCollection persistentcollection, WorldData worlddata, DimensionManager dimensionmanager, MethodProfiler methodprofiler, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { - super(idatamanager, persistentcollection, worlddata, DimensionManager.a(env.getId()).e(), methodprofiler, false, gen, env); - this.dimension = dimensionmanager; + public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + super(worlddata, dimensionmanager, (world, worldprovider) -> { + // CraftBukkit start + ChunkGenerator chunkGenerator; + + if (gen != null) { + chunkGenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(world, world.getSeed(), gen); + } else { + chunkGenerator = worldprovider.getChunkGenerator(); + } + + return new ChunkProviderServer((WorldServer) world, worldnbtstorage.getDirectory(), worldnbtstorage.getDataFixer(), worldnbtstorage.f(), executor, chunkGenerator, world.spigotConfig.viewDistance, worldloadlistener, () -> { // Spigot + return minecraftserver.getWorldServer(DimensionManager.OVERWORLD).getWorldPersistentData(); + }); + // CraftBukkit end + }, gameprofilerfiller, false, gen, env); this.pvpMode = minecraftserver.getPVP(); worlddata.world = this; // CraftBukkit end this.nextTickListBlock = new TickListServer<>(this, (block) -> { return block == null || block.getBlockData().isAir(); - }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::getOrDefault, this::b, "Blocks"); // Paper - timings - + }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> { return fluidtype == null || fluidtype == FluidTypes.EMPTY; - }, IRegistry.FLUID::getKey, IRegistry.FLUID::getOrDefault, this::a, "Fluids"); // Paper - timings - this.siegeManager = new VillageSiege(this); - this.d = new ObjectLinkedOpenHashSet(); + }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings + this.H = Sets.newHashSet(); + this.I = new ObjectLinkedOpenHashSet(); + this.dataManager = worldnbtstorage; this.server = minecraftserver; - this.tracker = new EntityTracker(this); - this.manager = new PlayerChunkMap(this); - this.worldProvider.a((World) this); - this.chunkProvider = this.r(); - this.portalTravelAgent = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit - this.P(); - this.Q(); - this.getWorldBorder().a(minecraftserver.au()); - MCUtil.scheduleAsyncTask(() -> this.getChunkProvider().chunkLoader.getPersistentStructureLegacy(worldProvider.getDimensionManager(), worldMaps)); // Paper - } - - public WorldServer i_() { - String s = PersistentVillage.a(this.worldProvider); - PersistentVillage persistentvillage = (PersistentVillage) this.a(DimensionManager.OVERWORLD, PersistentVillage::new, s); - - if (persistentvillage == null) { - this.villages = new PersistentVillage(this); - this.a(DimensionManager.OVERWORLD, s, (PersistentBase) this.villages); - } else { - this.villages = persistentvillage; - this.villages.a((World) this); + this.portalTravelAgent = new PortalTravelAgent(this); + this.M(); + this.N(); + this.getWorldBorder().a(minecraftserver.aw()); + this.c = (PersistentRaid) this.getWorldPersistentData().a(() -> { + return new PersistentRaid(this); + }, PersistentRaid.a(this.worldProvider)); + if (!minecraftserver.isEmbeddedServer()) { + this.getWorldData().setGameType(minecraftserver.getGamemode()); } - if (getServer().getScoreboardManager() == null) { // CraftBukkit - PersistentScoreboard persistentscoreboard = (PersistentScoreboard) this.a(DimensionManager.OVERWORLD, PersistentScoreboard::new, "scoreboard"); + this.mobSpawnerTrader = this.worldProvider.getDimensionManager().getType() == DimensionManager.OVERWORLD ? new MobSpawnerTrader(this) : null; // CraftBukkit - getType() + this.getServer().addWorld(this.getWorld()); // CraftBukkit - if (persistentscoreboard == null) { - persistentscoreboard = new PersistentScoreboard(); - this.a(DimensionManager.OVERWORLD, "scoreboard", (PersistentBase) persistentscoreboard); - } - - persistentscoreboard.a((Scoreboard) this.server.getScoreboard()); - this.server.getScoreboard().a((Runnable) (new RunnableSaveScoreboard(persistentscoreboard))); - } // CraftBukkit - this.getWorldBorder().setCenter(this.worldData.B(), this.worldData.C()); - this.getWorldBorder().setDamageAmount(this.worldData.H()); - this.getWorldBorder().setDamageBuffer(this.worldData.G()); - this.getWorldBorder().setWarningDistance(this.worldData.I()); - this.getWorldBorder().setWarningTime(this.worldData.J()); - if (this.worldData.E() > 0L) { - this.getWorldBorder().transitionSizeBetween(this.worldData.D(), this.worldData.F(), this.worldData.E()); - } else { - this.getWorldBorder().setSize(this.worldData.D()); - } - - // CraftBukkit start - if (generator != null) { - getWorld().getPopulators().addAll(generator.getDefaultPopulators(getWorld())); - } - // CraftBukkit end - - return this; + this.asyncChunkTaskManager = new com.destroystokyo.paper.io.chunk.ChunkTaskManager(this); // Paper } // CraftBukkit start @Override public TileEntity getTileEntity(BlockPosition pos) { TileEntity result = super.getTileEntity(pos); + if (Thread.currentThread() != this.serverThread) { + // SPIGOT-5378: avoid deadlock, this can be called in loading logic (i.e lighting) but getType() will block on chunk load + return result; + } Block type = getType(pos).getBlock(); - if (type == Blocks.CHEST || type == Blocks.TRAPPED_CHEST) { // Spigot - if (!(result instanceof TileEntityChest)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.FURNACE) { - if (!(result instanceof TileEntityFurnace)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.DROPPER) { - if (!(result instanceof TileEntityDropper)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.DISPENSER) { - if (!(result instanceof TileEntityDispenser)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.JUKEBOX) { - if (!(result instanceof TileEntityJukeBox)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.SPAWNER) { - if (!(result instanceof TileEntityMobSpawner)) { - result = fixTileEntity(pos, type, result); - } - } else if ((type == Blocks.SIGN) || (type == Blocks.WALL_SIGN)) { - if (!(result instanceof TileEntitySign)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.ENDER_CHEST) { - if (!(result instanceof TileEntityEnderChest)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.BREWING_STAND) { - if (!(result instanceof TileEntityBrewingStand)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.BEACON) { - if (!(result instanceof TileEntityBeacon)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.HOPPER) { - if (!(result instanceof TileEntityHopper)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.ENCHANTING_TABLE) { - if (!(result instanceof TileEntityEnchantTable)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.END_PORTAL) { - if (!(result instanceof TileEntityEnderPortal)) { - result = fixTileEntity(pos, type, result); - } - } else if (type instanceof BlockSkullAbstract) { - if (!(result instanceof TileEntitySkull)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.DAYLIGHT_DETECTOR) { - if (!(result instanceof TileEntityLightDetector)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.COMPARATOR) { - if (!(result instanceof TileEntityComparator)) { - result = fixTileEntity(pos, type, result); - } - }else if (type instanceof BlockBannerAbstract) { - if (!(result instanceof TileEntityBanner)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.STRUCTURE_BLOCK) { - if (!(result instanceof TileEntityStructure)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.END_GATEWAY) { - if (!(result instanceof TileEntityEndGateway)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.COMMAND_BLOCK) { - if (!(result instanceof TileEntityCommand)) { - result = fixTileEntity(pos, type, result); - } - } else if (type == Blocks.STRUCTURE_BLOCK) { - if (!(result instanceof TileEntityStructure)) { - result = fixTileEntity(pos, type, result); - } - } else if (type instanceof BlockBed) { - if (!(result instanceof TileEntityBed)) { + if (result != null && type != Blocks.AIR) { + if (!result.q().a(type)) { result = fixTileEntity(pos, type, result); } } - // Paper Start - add TE fix checks for shulkers, see nms.BlockShulkerBox - else if (type instanceof BlockShulkerBox) { - if (!(result instanceof TileEntityShulkerBox)) { - result = fixTileEntity(pos, type, result); - } - } - // Paper end return result; } private TileEntity fixTileEntity(BlockPosition pos, Block type, TileEntity found) { - this.getServer().getLogger().log(Level.SEVERE, "Block at {0},{1},{2} is {3} but has {4}" + ". " + this.getServer().getLogger().log(Level.SEVERE, "Block at {0}, {1}, {2} is {3} but has {4}" + ". " + "Bukkit will attempt to fix this, but there may be additional damage that we cannot recover.", new Object[]{pos.getX(), pos.getY(), pos.getZ(), type, found}); if (type instanceof ITileEntity) { - TileEntity replacement = ((ITileEntity) type).a(this); + TileEntity replacement = ((ITileEntity) type).createTile(this); replacement.world = this; this.setTileEntity(pos, replacement); return replacement; } else { - this.getServer().getLogger().severe("Don't know how to fix for this type... Can't do anything! :("); return found; } } // CraftBukkit end public void doTick(BooleanSupplier booleansupplier) { - this.P = true; - super.doTick(booleansupplier); - // Akarin start - /* + GameProfilerFiller gameprofilerfiller = this.getMethodProfiler(); + + this.ticking = true; + gameprofilerfiller.enter("world border"); + this.getWorldBorder().s(); + gameprofilerfiller.exitEnter("weather"); + boolean flag = this.isRaining(); + int i; + + if (this.worldProvider.g()) { + if (this.getGameRules().getBoolean(GameRules.DO_WEATHER_CYCLE)) { + int j = this.worldData.z(); + + i = this.worldData.getThunderDuration(); + int k = this.worldData.getWeatherDuration(); + boolean flag1 = this.worldData.isThundering(); + boolean flag2 = this.worldData.hasStorm(); + + if (j > 0) { + --j; + i = flag1 ? 0 : 1; + k = flag2 ? 0 : 1; + flag1 = false; + flag2 = false; + } else { + if (i > 0) { + --i; + if (i == 0) { + flag1 = !flag1; + } + } else if (flag1) { + i = this.random.nextInt(12000) + 3600; + } else { + i = this.random.nextInt(168000) + 12000; + } + + if (k > 0) { + --k; + if (k == 0) { + flag2 = !flag2; + } + } else if (flag2) { + k = this.random.nextInt(12000) + 12000; + } else { + k = this.random.nextInt(168000) + 12000; + } + } + + this.worldData.setThunderDuration(i); + this.worldData.setWeatherDuration(k); + this.worldData.g(j); + this.worldData.setThundering(flag1); + this.worldData.setStorm(flag2); + } + + this.lastThunderLevel = this.thunderLevel; + if (this.worldData.isThundering()) { + this.thunderLevel = (float) ((double) this.thunderLevel + 0.01D); + } else { + this.thunderLevel = (float) ((double) this.thunderLevel - 0.01D); + } + + this.thunderLevel = MathHelper.a(this.thunderLevel, 0.0F, 1.0F); + this.lastRainLevel = this.rainLevel; + if (this.worldData.hasStorm()) { + this.rainLevel = (float) ((double) this.rainLevel + 0.01D); + } else { + this.rainLevel = (float) ((double) this.rainLevel - 0.01D); + } + + this.rainLevel = MathHelper.a(this.rainLevel, 0.0F, 1.0F); + } + + /* CraftBukkit start + if (this.lastRainLevel != this.rainLevel) { + this.server.getPlayerList().a((Packet) (new PacketPlayOutGameStateChange(7, this.rainLevel)), this.worldProvider.getDimensionManager()); + } + + if (this.lastThunderLevel != this.thunderLevel) { + this.server.getPlayerList().a((Packet) (new PacketPlayOutGameStateChange(8, this.thunderLevel)), this.worldProvider.getDimensionManager()); + } + + if (flag != this.isRaining()) { + if (flag) { + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(2, 0.0F)); + } else { + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(1, 0.0F)); + } + + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(7, this.rainLevel)); + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(8, this.thunderLevel)); + } + // */ + for (int idx = 0; idx < this.players.size(); ++idx) { + if (((EntityPlayer) this.players.get(idx)).world == this) { + ((EntityPlayer) this.players.get(idx)).tickWeather(); + } + } + + if (flag != this.isRaining()) { + // Only send weather packets to those affected + for (int idx = 0; idx < this.players.size(); ++idx) { + if (((EntityPlayer) this.players.get(idx)).world == this) { + ((EntityPlayer) this.players.get(idx)).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); + } + } + } + for (int idx = 0; idx < this.players.size(); ++idx) { + if (((EntityPlayer) this.players.get(idx)).world == this) { + ((EntityPlayer) this.players.get(idx)).updateWeather(this.lastRainLevel, this.rainLevel, this.lastThunderLevel, this.thunderLevel); + } + } + // CraftBukkit end + if (this.getWorldData().isHardcore() && this.getDifficulty() != EnumDifficulty.HARD) { this.getWorldData().setDifficulty(EnumDifficulty.HARD); } - */ - // Akarin end - this.chunkProvider.getChunkGenerator().getWorldChunkManager().tick(); - if (this.everyoneDeeplySleeping()) { - // Akarin start - /* - if (this.getGameRules().getBoolean("doDaylightCycle")) { - long i = this.worldData.getDayTime() + 24000L; + if (this.C && this.players.stream().noneMatch((entityplayer) -> { + return !entityplayer.isSpectator() && !entityplayer.isDeeplySleeping() && !entityplayer.fauxSleeping; // CraftBukkit + })) { + this.C = false; + if (this.getGameRules().getBoolean(GameRules.DO_DAYLIGHT_CYCLE)) { + long l = this.worldData.getDayTime() + 24000L; - this.worldData.setDayTime(i - i % 24000L); + this.setDayTime(l - l % 24000L); } - */ - // Akarin end - this.i(); + this.players.stream().filter(EntityLiving::isSleeping).forEach((entityplayer) -> { + entityplayer.wakeup(false, false, true); + }); + if (this.getGameRules().getBoolean(GameRules.DO_WEATHER_CYCLE)) { + this.clearWeather(); + } } - //this.methodProfiler.enter(* // Akarin - remove caller - // CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals - long time = this.worldData.getTime(); - if (this.getGameRules().getBoolean("doMobSpawning") && this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES && (this.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.players.size() > 0)) { - timings.mobSpawn.startTimingUnsafe(); // Spigot - this.spawnerCreature.a(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldData.getTime() % 400L == 0L); - this.getChunkProvider().a(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L)); - timings.mobSpawn.stopTimingUnsafe(); // Spigot - // CraftBukkit end + this.M(); + this.a(); + gameprofilerfiller.exitEnter("chunkSource"); + this.timings.chunkProviderTick.startTiming(); // Paper - timings + this.getChunkProvider().tick(booleansupplier); + this.timings.chunkProviderTick.stopTiming(); // Paper - timings + gameprofilerfiller.exitEnter("tickPending"); + timings.scheduledBlocks.startTiming(); // Spigot + if (this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) { + this.nextTickListBlock.b(); + this.nextTickListFluid.b(); } + timings.scheduledBlocks.stopTiming(); // Spigot - timings.doChunkUnload.startTimingUnsafe(); // Spigot // Akarin - //this.methodProfiler.exitEnter("chunkSource"); // Akarin - remove caller - this.chunkProvider.unloadChunks(booleansupplier); - int j = this.a(1.0F); - - if (j != this.c()) { - this.c(j); - } - - this.worldData.setTime(this.worldData.getTime() + 1L); - if (this.getGameRules().getBoolean("doDaylightCycle")) { - this.worldData.setDayTime(this.worldData.getDayTime() + 1L); - } - - timings.doChunkUnload.stopTimingUnsafe(); // Spigot // Akarin - //this.methodProfiler.exitEnter("tickPending"); // Akarin - remove caller - timings.scheduledBlocks.startTimingUnsafe(); // Paper // Akarin - this.q(); - timings.scheduledBlocks.stopTimingUnsafe(); // Paper // Akarin - //this.methodProfiler.exitEnter("tickBlocks"); // Akarin - remove caller - timings.chunkTicks.startTimingUnsafe(); // Paper // Akarin - this.n_(); - timings.chunkTicks.stopTimingUnsafe(); // Paper // Akarin - //this.methodProfiler.exitEnter("chunkMap"); // Akarin - remove caller - timings.doChunkMap.startTimingUnsafe(); // Spigot // Akarin - this.manager.flush(); - timings.doChunkMap.stopTimingUnsafe(); // Spigot // Akarin - //this.methodProfiler.exitEnter("village"); // Akarin - remove caller - timings.doVillages.startTimingUnsafe(); // Spigot // Akarin - this.villages.tick(); - this.siegeManager.a(); - timings.doVillages.stopTimingUnsafe(); // Spigot // Akarin - //this.methodProfiler.exitEnter("portalForcer"); // Akarin - remove caller - timings.doPortalForcer.startTimingUnsafe(); // Spigot // Akarin + gameprofilerfiller.exitEnter("portalForcer"); + timings.doPortalForcer.startTiming(); // Spigot this.portalTravelAgent.a(this.getTime()); - timings.doPortalForcer.stopTimingUnsafe(); // Spigot // Akarin - //this.methodProfiler.exit(); // Akarin - remove caller - timings.doSounds.startTimingUnsafe(); // Spigot // Akarin - this.an(); - timings.doSounds.stopTimingUnsafe(); // Spigot // Akarin - this.P = false; + timings.doPortalForcer.stopTiming(); // Spigot + gameprofilerfiller.exitEnter("raid"); + this.timings.raids.startTiming(); // Paper - timings + this.c.a(); + if (this.mobSpawnerTrader != null) { + this.mobSpawnerTrader.a(); + } + this.timings.raids.stopTiming(); // Paper - timings - timings.doChunkGC.startTimingUnsafe();// Spigot // Akarin - this.getWorld().processChunkGC(); // CraftBukkit - timings.doChunkGC.stopTimingUnsafe(); // Spigot // Akarin + gameprofilerfiller.exitEnter("blockEvents"); + timings.doSounds.startTiming(); // Spigot + this.ae(); + timings.doSounds.stopTiming(); // Spigot + this.ticking = false; + gameprofilerfiller.exitEnter("entities"); + boolean flag3 = true || !this.players.isEmpty() || !this.getForceLoadedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players + + if (flag3) { + this.resetEmptyTime(); + } + + if (flag3 || this.emptyTime++ < 300) { + timings.tickEntities.startTiming(); // Spigot + this.worldProvider.l(); + gameprofilerfiller.enter("global"); + + Entity entity; + + for (i = 0; i < this.globalEntityList.size(); ++i) { + entity = (Entity) this.globalEntityList.get(i); + // CraftBukkit start - Fixed an NPE + if (entity == null) { + continue; + } + // CraftBukkit end + this.a((entity1) -> { + ++entity1.ticksLived; + entity1.tick(); + }, entity); + if (entity.dead) { + this.globalEntityList.remove(i--); + } + } + + gameprofilerfiller.exitEnter("regular"); + this.tickingEntities = true; + ObjectIterator objectiterator = this.entitiesById.int2ObjectEntrySet().iterator(); + + org.spigotmc.ActivationRange.activateEntities(this); // Spigot + timings.entityTick.startTiming(); // Spigot + TimingHistory.entityTicks += this.globalEntityList.size(); // Paper + while (objectiterator.hasNext()) { + Entry entry = (Entry) objectiterator.next(); + Entity entity1 = (Entity) entry.getValue(); + Entity entity2 = entity1.getVehicle(); + + /* CraftBukkit start - We prevent spawning in general, so this butchering is not needed + if (!this.server.getSpawnAnimals() && (entity1 instanceof EntityAnimal || entity1 instanceof EntityWaterAnimal)) { + entity1.die(); + } + + if (!this.server.getSpawnNPCs() && entity1 instanceof NPC) { + entity1.die(); + } + // CraftBukkit end */ + + if (entity2 != null) { + if (!entity2.dead && entity2.w(entity1)) { + continue; + } + + entity1.stopRiding(); + } + + gameprofilerfiller.enter("tick"); + if (!entity1.dead && !(entity1 instanceof EntityComplexPart)) { + this.a(this::entityJoinedWorld, entity1); + ++TimingHistory.entityTicks; // Paper + } + + gameprofilerfiller.exit(); + gameprofilerfiller.enter("remove"); + if (entity1.dead) { + this.removeEntityFromChunk(entity1); + objectiterator.remove(); + this.unregisterEntity(entity1); + } + + gameprofilerfiller.exit(); + } + timings.entityTick.stopTiming(); // Spigot + + this.tickingEntities = false; + + try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings + while ((entity = (Entity) this.entitiesToAdd.poll()) != null) { + this.registerEntity(entity); + } + } // Paper - timings + + gameprofilerfiller.exit(); + timings.tickEntities.stopTiming(); // Spigot + this.tickBlockEntities(); + } + + gameprofilerfiller.exit(); } - public boolean j_() { - return this.P; + public void a(Chunk chunk, int i) { + ChunkCoordIntPair chunkcoordintpair = chunk.getPos(); + boolean flag = this.isRaining(); + int j = chunkcoordintpair.d(); + int k = chunkcoordintpair.e(); + GameProfilerFiller gameprofilerfiller = this.getMethodProfiler(); + + gameprofilerfiller.enter("thunder"); + BlockPosition blockposition; + + if (!this.paperConfig.disableThunder && flag && this.U() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder + blockposition = this.a(this.a(j, 0, k, 15)); + if (this.isRainingAt(blockposition)) { + DifficultyDamageScaler difficultydamagescaler = this.getDamageScaler(blockposition); + boolean flag1 = this.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper + + if (flag1) { + EntityHorseSkeleton entityhorseskeleton = (EntityHorseSkeleton) EntityTypes.SKELETON_HORSE.a((World) this); + + entityhorseskeleton.r(true); + entityhorseskeleton.setAgeRaw(0); + entityhorseskeleton.setPosition((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); + this.addEntity(entityhorseskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit + } + + this.strikeLightning(new EntityLightning(this, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, flag1), org.bukkit.event.weather.LightningStrikeEvent.Cause.WEATHER); // CraftBukkit + } + } + + gameprofilerfiller.exitEnter("iceandsnow"); + if (!this.paperConfig.disableIceAndSnow && this.random.nextInt(16) == 0) { // Paper - Disable ice and snow + blockposition = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, this.a(j, 0, k, 15)); + BlockPosition blockposition1 = blockposition.down(); + BiomeBase biomebase = this.getBiome(blockposition); + + if (biomebase.a((IWorldReader) this, blockposition1)) { + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition1, Blocks.ICE.getBlockData(), null); // CraftBukkit + } + + if (flag && biomebase.b(this, blockposition)) { + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.getBlockData(), null); // CraftBukkit + } + + if (flag && this.getBiome(blockposition1).b() == BiomeBase.Precipitation.RAIN) { + this.getType(blockposition1).getBlock().c((World) this, blockposition1); + } + } + + gameprofilerfiller.exitEnter("tickBlocks"); + timings.chunkTicksBlocks.startTiming(); // Paper + if (i > 0) { + ChunkSection[] achunksection = chunk.getSections(); + int l = achunksection.length; + + for (int i1 = 0; i1 < l; ++i1) { + ChunkSection chunksection = achunksection[i1]; + + if (chunksection != Chunk.a && chunksection.d()) { + int j1 = chunksection.getYPosition(); + + for (int k1 = 0; k1 < i; ++k1) { + BlockPosition blockposition2 = this.a(j, j1, k, 15); + + gameprofilerfiller.enter("randomTick"); + IBlockData iblockdata = chunksection.getType(blockposition2.getX() - j, blockposition2.getY() - j1, blockposition2.getZ() - k); + + if (iblockdata.q()) { + iblockdata.getBlock().randomTick = true; // Paper - fix MC-113809 + iblockdata.b((World) this, blockposition2, this.random); + iblockdata.getBlock().randomTick = false; // Paper - fix MC-113809 + } + + Fluid fluid = iblockdata.p(); + + if (fluid.h()) { + fluid.b(this, blockposition2, this.random); + } + + gameprofilerfiller.exit(); + } + } + } + } + timings.chunkTicksBlocks.stopTiming(); // Paper + gameprofilerfiller.exit(); } - @Nullable public BiomeBase.BiomeMeta getBiomeMetaAt(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { return a(enumcreaturetype, blockposition); } // Akarin - @Nullable - public BiomeBase.BiomeMeta a(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { - List list = this.getChunkProvider().a(enumcreaturetype, blockposition); + protected BlockPosition a(BlockPosition blockposition) { + BlockPosition blockposition1 = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, blockposition); + AxisAlignedBB axisalignedbb = (new AxisAlignedBB(blockposition1, new BlockPosition(blockposition1.getX(), this.getBuildHeight(), blockposition1.getZ()))).g(3.0D); + List list = this.a(EntityLiving.class, axisalignedbb, (java.util.function.Predicate) (entityliving) -> { // CraftBukkit - decompile error + return entityliving != null && entityliving.isAlive() && this.f(entityliving.getChunkCoordinates()); + }); - return list.isEmpty() ? null : (BiomeBase.BiomeMeta) WeightedRandom.a(this.random, list); + if (!list.isEmpty()) { + return ((EntityLiving) list.get(this.random.nextInt(list.size()))).getChunkCoordinates(); + } else { + if (blockposition1.getY() == -1) { + blockposition1 = blockposition1.up(2); + } + + return blockposition1; + } } - public boolean isBiomeMetaValidAt(EnumCreatureType enumcreaturetype, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition blockposition) { return this.a(enumcreaturetype, biomebase_biomemeta, blockposition); } // Akarin - public boolean a(EnumCreatureType enumcreaturetype, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition blockposition) { - List list = this.getChunkProvider().a(enumcreaturetype, blockposition); - - return list != null && !list.isEmpty() ? list.contains(biomebase_biomemeta) : false; + public boolean b() { + return this.ticking; } public void everyoneSleeping() { - this.J = false; + this.C = false; if (!this.players.isEmpty()) { int i = 0; int j = 0; Iterator iterator = this.players.iterator(); while (iterator.hasNext()) { - EntityHuman entityhuman = (EntityHuman) iterator.next(); + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - if (entityhuman.isSpectator()) { + if (entityplayer.isSpectator() || (entityplayer.fauxSleeping && !entityplayer.isSleeping())) { // CraftBukkit ++i; - } else if (entityhuman.isSleeping() || entityhuman.fauxSleeping) { + } else if (entityplayer.isSleeping()) { ++j; } } - this.J = j > 0 && j >= this.players.size() - i; + this.C = j > 0 && j >= this.players.size() - i; } } + @Override public ScoreboardServer getScoreboard() { return this.server.getScoreboard(); } - protected void i() { - this.J = false; - List list = (List) this.players.stream().filter(EntityHuman::isSleeping).collect(Collectors.toList()); - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - EntityHuman entityhuman = (EntityHuman) iterator.next(); - - entityhuman.a(false, false, true); - } - - // Akarin start - /* - if (this.getGameRules().getBoolean("doWeatherCycle")) { - this.b(); - } - */ - // Akarin end - - } - - public void clearWeather() { this.b(); } // Akarin - OBFHLPER - private void b() { + private void clearWeather() { // CraftBukkit start this.worldData.setStorm(false); // If we stop due to everyone sleeping we should reset the weather duration to some other random value. @@ -423,268 +656,14 @@ public class WorldServer extends World implements IAsyncTaskHandler { // CraftBukkit end } - public boolean everyoneDeeplySleeping() { - if (this.J && !this.isClientSide) { - Iterator iterator = this.players.iterator(); - - // CraftBukkit - This allows us to assume that some people are in bed but not really, allowing time to pass in spite of AFKers - boolean foundActualSleepers = false; - - EntityHuman entityhuman; - - do { - if (!iterator.hasNext()) { - return foundActualSleepers; - } - - entityhuman = (EntityHuman) iterator.next(); - - // CraftBukkit start - if (entityhuman.isDeeplySleeping()) { - foundActualSleepers = true; - } - } while (!entityhuman.isSpectator() || entityhuman.isDeeplySleeping() || entityhuman.fauxSleeping); - // CraftBukkit end - - return false; - } else { - return false; - } - } - - public boolean isChunkLoaded(int i, int j, boolean flag) { - return this.a(i, j); - } - - public boolean a(int i, int j) { - return this.getChunkProvider().isLoaded(i, j); - } - - public void randomLightUpdates() { this.l(); } // Akarin - OBFHELPER - protected void l() { - //this.methodProfiler.enter(* // Akarin - remove caller - if (spigotConfig.randomLightUpdates && !this.players.isEmpty()) { // Spigot - int i = ThreadLocalRandom.current().nextInt(this.players.size()); // Akarin - ThreadLocalRandom - EntityHuman entityhuman = (EntityHuman) this.players.get(i); - if (entityhuman == null) return; - int j = MathHelper.floor(entityhuman.locX) + this.random.nextInt(11) - 5; - int k = MathHelper.floor(entityhuman.locY) + this.random.nextInt(11) - 5; - int l = MathHelper.floor(entityhuman.locZ) + this.random.nextInt(11) - 5; - - this.r(new BlockPosition(j, k, l)); - } - - //this.methodProfiler.exit(); // Akarin - remove caller - } - - protected void n_() { - //this.l(); // Akarin - if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { - Iterator iterator = this.manager.b(); - - while (iterator.hasNext()) { - ((Chunk) iterator.next()).d(false); - } - - } else { - int i = this.getGameRules().c("randomTickSpeed"); - boolean flag = this.isRaining(); - boolean flag1 = this.Y(); - - //this.methodProfiler.enter(* // Akarin - remove caller - - for (Iterator iterator1 = this.manager.b(); iterator1.hasNext(); /*this.methodProfiler.exit()*/) { // Akarin - remove caller - //this.methodProfiler.enter(* // Akarin - remove caller - Chunk chunk = (Chunk) iterator1.next(); - int j = chunk.locX * 16; - int k = chunk.locZ * 16; - - //this.methodProfiler.exitEnter("checkNextLight"); // Akarin - remove caller - AkarinAsyncExecutor.scheduleAsyncTask(chunk::x); // Akarin - //this.methodProfiler.exitEnter("tickChunk"); // Akarin - remove caller - chunk.d(false); - if ( !chunk.areNeighborsLoaded( 1 ) ) continue; // Spigot - //this.methodProfiler.exitEnter("thunder"); // Akarin - remove caller - int l; - BlockPosition blockposition; - - if (!this.paperConfig.disableThunder && flag && flag1 && this.random.nextInt(100000) == 0) { // Paper - Disable thunder - this.m = this.m * 3 + 1013904223; - l = this.m >> 2; - blockposition = this.a(new BlockPosition(j + (l & 15), 0, k + (l >> 8 & 15))); - if (this.isRainingAt(blockposition)) { - DifficultyDamageScaler difficultydamagescaler = this.getDamageScaler(blockposition); - boolean flag2 = this.getGameRules().getBoolean("doMobSpawning") && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper - - if (flag2) { - EntityHorseSkeleton entityhorseskeleton = EntityTypes.SKELETON_HORSE.create(this); // Paper - - entityhorseskeleton.s(true); - entityhorseskeleton.setAgeRaw(0); - entityhorseskeleton.setPosition((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); - this.addEntity(entityhorseskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit - } - - this.strikeLightning(new EntityLightning(this, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, flag2), org.bukkit.event.weather.LightningStrikeEvent.Cause.WEATHER); // CraftBukkit - } - } - - //this.methodProfiler.exitEnter("iceandsnow"); // Akarin - remove caller - if (!this.paperConfig.disableIceAndSnow && this.random.nextInt(16) == 0) { // Paper - Disable ice and snow - this.m = this.m * 3 + 1013904223; - l = this.m >> 2; - blockposition = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(j + (l & 15), 0, k + (l >> 8 & 15))); - BlockPosition blockposition1 = blockposition.down(); - BiomeBase biomebase = this.getBiome(blockposition); - - if (biomebase.a((IWorldReader) this, blockposition1)) { - org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition1, Blocks.ICE.getBlockData(), null); // CraftBukkit - } - - if (flag && biomebase.b(this, blockposition)) { - org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.getBlockData(), null); // CraftBukkit - } - - if (flag && this.getBiome(blockposition1).c() == BiomeBase.Precipitation.RAIN) { - this.getType(blockposition1).getBlock().c(this, blockposition1); - } - } - - //this.methodProfiler.exitEnter("tickBlocks"); // Akarin - remove caller - timings.chunkTicksBlocks.startTimingUnsafe(); // Paper - if (i > 0) { - ChunkSection[] achunksection = chunk.getSections(); - int i1 = achunksection.length; - - for (int j1 = 0; j1 < i1; ++j1) { - ChunkSection chunksection = achunksection[j1]; - - if (chunksection != Chunk.a && chunksection.b()) { - for (int k1 = 0; k1 < i; ++k1) { - this.m = this.m * 3 + 1013904223; - int l1 = this.m >> 2; - int i2 = l1 & 15; - int j2 = l1 >> 8 & 15; - int k2 = l1 >> 16 & 15; - IBlockData iblockdata = chunksection.getType(i2, k2, j2); - Fluid fluid = chunksection.b(i2, k2, j2); - - //this.methodProfiler.enter(* // Akarin - remove caller - if (iblockdata.t()) { - iblockdata.b((World) this, new BlockPosition(i2 + j, k2 + chunksection.getYPosition(), j2 + k), this.random); - } - - if (fluid.h()) { - fluid.b(this, new BlockPosition(i2 + j, k2 + chunksection.getYPosition(), j2 + k), this.random); - } - - //this.methodProfiler.exit(); // Akarin - remove caller - } - } - } - } - timings.chunkTicksBlocks.stopTimingUnsafe(); // Paper - } - - //this.methodProfiler.exit(); // Akarin - remove caller - } - } - - protected BlockPosition a(BlockPosition blockposition) { - BlockPosition blockposition1 = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, blockposition); - AxisAlignedBB axisalignedbb = (new AxisAlignedBB(blockposition1, new BlockPosition(blockposition1.getX(), this.getHeight(), blockposition1.getZ()))).g(3.0D); - List list = this.a(EntityLiving.class, axisalignedbb, (java.util.function.Predicate) (entityliving) -> { // CraftBukkit - decompile error - return entityliving != null && entityliving.isAlive() && this.e(entityliving.getChunkCoordinates()); - }); - - if (!list.isEmpty()) { - return ((EntityLiving) list.get(this.random.nextInt(list.size()))).getChunkCoordinates(); - } else { - if (blockposition1.getY() == -1) { - blockposition1 = blockposition1.up(2); - } - - return blockposition1; - } - } - - public void tickEntities() { - if (false && this.players.isEmpty()) { // CraftBukkit - this prevents entity cleanup, other issues on servers with no players - if (this.emptyTime++ >= 300) { - return; - } - } else { - this.p(); - } - - this.worldProvider.l(); - super.tickEntities(); - spigotConfig.currentPrimedTnt = 0; // Spigot - } - - protected void p_() { - super.p_(); - //this.methodProfiler.exitEnter("players"); // Akarin - remove caller - - for (int i = 0; i < this.players.size(); ++i) { - Entity entity = (Entity) this.players.get(i); - Entity entity1 = entity.getVehicle(); - - if (entity1 != null) { - if (!entity1.dead && entity1.w(entity)) { - continue; - } - - entity.stopRiding(); - } - - //this.methodProfiler.enter(* // Akarin - remove caller - if (!entity.dead) { - try { - this.g(entity); - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Ticking player"); - CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Player being ticked"); - - entity.appendEntityCrashDetails(crashreportsystemdetails); - throw new ReportedException(crashreport); - } - } - - //this.methodProfiler.exit(); // Akarin - remove caller - //this.methodProfiler.enter(* // Akarin - remove caller - if (entity.dead) { - int j = entity.chunkX; - int k = entity.chunkZ; - - if (entity.inChunk && this.isChunkLoaded(j, k, true)) { - this.getChunkAt(j, k).b(entity); - } - - this.entityList.remove(entity); - this.c(entity); - } - - //this.methodProfiler.exit(); // Akarin - remove caller - } - - } - - public void p() { + public void resetEmptyTime() { this.emptyTime = 0; } - public void q() { - if (this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) { - this.nextTickListBlock.a(); - this.nextTickListFluid.a(); - } - } - private void a(NextTickListEntry nextticklistentry) { Fluid fluid = this.getFluid(nextticklistentry.a); - if (fluid.c() == nextticklistentry.a()) { + if (fluid.getType() == nextticklistentry.b()) { fluid.a((World) this, nextticklistentry.a); } @@ -693,110 +672,115 @@ public class WorldServer extends World implements IAsyncTaskHandler { private void b(NextTickListEntry nextticklistentry) { IBlockData iblockdata = this.getType(nextticklistentry.a); - if (iblockdata.getBlock() == nextticklistentry.a()) { + if (iblockdata.getBlock() == nextticklistentry.b()) { iblockdata.a((World) this, nextticklistentry.a, this.random); } } - /* CraftBukkit start - We prevent spawning in general, so this butchering is not needed - public void entityJoinedWorld(Entity entity, boolean flag) { - if (!this.getSpawnAnimals() && (entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal)) { - entity.die(); + public void entityJoinedWorld(Entity entity) { + if (entity instanceof EntityHuman || this.getChunkProvider().a(entity)) { + // Spigot start + if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { + entity.ticksLived++; + entity.inactiveTick(); + return; + } + // Spigot end + + entity.tickTimer.startTiming(); // Spigot + entity.H = entity.locX; + entity.I = entity.locY; + entity.J = entity.locZ; + entity.lastYaw = entity.yaw; + entity.lastPitch = entity.pitch; + if (entity.inChunk) { + ++entity.ticksLived; + this.getMethodProfiler().a(() -> { + return IRegistry.ENTITY_TYPE.getKey(entity.getEntityType()).toString(); + }); + entity.tick(); + entity.postTick(); // CraftBukkit + this.getMethodProfiler().exit(); + } + + this.chunkCheck(entity); + if (entity.inChunk) { + Iterator iterator = entity.getPassengers().iterator(); + + while (iterator.hasNext()) { + Entity entity1 = (Entity) iterator.next(); + + this.a(entity, entity1); + } + } + entity.tickTimer.stopTiming(); // Spigot + } - - if (!this.getSpawnNPCs() && entity instanceof NPC) { - entity.die(); - } - - super.entityJoinedWorld(entity, flag); - } - // CraftBukkit end */ - - private boolean getSpawnNPCs() { - return this.server.getSpawnNPCs(); } - private boolean getSpawnAnimals() { - return this.server.getSpawnAnimals(); - } + public void a(Entity entity, Entity entity1) { + if (!entity1.dead && entity1.getVehicle() == entity) { + if (entity1 instanceof EntityHuman || this.getChunkProvider().a(entity1)) { + entity1.H = entity1.locX; + entity1.I = entity1.locY; + entity1.J = entity1.locZ; + entity1.lastYaw = entity1.yaw; + entity1.lastPitch = entity1.pitch; + if (entity1.inChunk) { + ++entity1.ticksLived; + entity1.passengerTick(); + } - protected IChunkProvider r() { - IChunkLoader ichunkloader = this.dataManager.createChunkLoader(this.worldProvider); + this.chunkCheck(entity1); + if (entity1.inChunk) { + Iterator iterator = entity1.getPassengers().iterator(); - // CraftBukkit start - org.bukkit.craftbukkit.generator.InternalChunkGenerator gen; + while (iterator.hasNext()) { + Entity entity2 = (Entity) iterator.next(); - if (this.generator != null) { - gen = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, this.getSeed(), this.generator); - } else if (this.worldProvider instanceof WorldProviderHell) { - gen = new org.bukkit.craftbukkit.generator.NetherChunkGenerator(this, this.getSeed()); - } else if (this.worldProvider instanceof WorldProviderTheEnd) { - gen = new org.bukkit.craftbukkit.generator.SkyLandsChunkGenerator(this, this.getSeed()); + this.a(entity1, entity2); + } + } + + } } else { - gen = new org.bukkit.craftbukkit.generator.NormalChunkGenerator(this, this.getSeed()); + entity1.stopRiding(); } - - return com.destroystokyo.paper.PaperConfig.asyncChunks ? new PaperAsyncChunkProvider(this, ichunkloader, gen, this.server) : new ChunkProviderServer(this, ichunkloader, gen, this.server); // Paper - async chunks - // CraftBukkit end } + public void chunkCheck(Entity entity) { + this.getMethodProfiler().enter("chunkCheck"); + int i = MathHelper.floor(entity.locX / 16.0D); + int j = Math.min(15, Math.max(0, MathHelper.floor(entity.locY / 16.0D))); // Paper - stay consistent with chunk add/remove behavior + int k = MathHelper.floor(entity.locZ / 16.0D); + + if (!entity.inChunk || entity.chunkX != i || entity.chunkY != j || entity.chunkZ != k) { + if (entity.inChunk && this.isChunkLoaded(entity.chunkX, entity.chunkZ)) { + this.getChunkAt(entity.chunkX, entity.chunkZ).a(entity, entity.chunkY); + } + + if (!entity.valid && !entity.bU() && !this.isChunkLoaded(i, k)) { // Paper - always load chunks to register valid entities location + entity.inChunk = false; + } else { + this.getChunkAt(i, k).a(entity); + } + } + + this.getMethodProfiler().exit(); + } + + @Override public boolean a(EntityHuman entityhuman, BlockPosition blockposition) { return !this.server.a(this, blockposition, entityhuman) && this.getWorldBorder().a(blockposition); } public void a(WorldSettings worldsettings) { - if (!this.worldData.v()) { - try { - this.b(worldsettings); - if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { - this.am(); - } - - super.a(worldsettings); - } catch (Throwable throwable) { - CrashReport crashreport = CrashReport.a(throwable, "Exception initializing level"); - - try { - this.a(crashreport); - } catch (Throwable throwable1) { - ; - } - - throw new ReportedException(crashreport); - } - - this.worldData.d(true); - } - - } - - private void am() { - this.worldData.f(false); - this.worldData.c(true); - this.worldData.setStorm(false); - this.worldData.setThundering(false); - this.worldData.g(1000000000); - this.worldData.setDayTime(6000L); - this.worldData.setGameType(EnumGamemode.SPECTATOR); - this.worldData.g(false); - this.worldData.setDifficulty(EnumDifficulty.PEACEFUL); - this.worldData.e(true); - this.getGameRules().set("doDaylightCycle", "false", this.server); - } - - private void b(WorldSettings worldsettings) { if (!this.worldProvider.canRespawn()) { this.worldData.setSpawn(BlockPosition.ZERO.up(this.chunkProvider.getChunkGenerator().getSpawnHeight())); } else if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { this.worldData.setSpawn(BlockPosition.ZERO.up()); } else { - WorldChunkManager worldchunkmanager = this.chunkProvider.getChunkGenerator().getWorldChunkManager(); - List list = worldchunkmanager.a(); - Random random = new Random(this.getSeed()); - BlockPosition blockposition = worldchunkmanager.a(0, 0, 256, list, random); - ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition); - // CraftBukkit start if (this.generator != null) { Random rand = new Random(this.getSeed()); @@ -813,8 +797,16 @@ public class WorldServer extends World implements IAsyncTaskHandler { } // CraftBukkit end + // Paper start - this is useless if craftbukkit returns early + WorldChunkManager worldchunkmanager = this.chunkProvider.getChunkGenerator().getWorldChunkManager(); + List list = worldchunkmanager.a(); + Random random = new Random(this.getSeed()); + BlockPosition blockposition = worldchunkmanager.a(0, 0, 256, list, random); + ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition); + // Paper end + if (blockposition == null) { - WorldServer.a.warn("Unable to find spawn biome"); + WorldServer.LOGGER.warn("Unable to find spawn biome"); } boolean flag = false; @@ -829,7 +821,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { } } - this.worldData.setSpawn(chunkcoordintpair.h().a(8, this.chunkProvider.getChunkGenerator().getSpawnHeight(), 8)); + this.worldData.setSpawn(chunkcoordintpair.l().b(8, this.chunkProvider.getChunkGenerator().getSpawnHeight(), 8)); int i = 0; int j = 0; int k = 0; @@ -858,14 +850,14 @@ public class WorldServer extends World implements IAsyncTaskHandler { } if (worldsettings.c()) { - this.s(); + this.g(); } } } - protected void s() { - WorldGenBonusChest worldgenbonuschest = new WorldGenBonusChest(); + protected void g() { + WorldGenBonusChest worldgenbonuschest = WorldGenerator.BONUS_CHEST; for (int i = 0; i < 10; ++i) { int j = this.worldData.b() + this.random.nextInt(6) - this.random.nextInt(6); @@ -884,98 +876,269 @@ public class WorldServer extends World implements IAsyncTaskHandler { return this.worldProvider.d(); } - public void save(boolean flag, @Nullable IProgressUpdate iprogressupdate) throws ExceptionWorldConflict { + // Paper start - derived from below + public void saveIncrementally(boolean doFull) throws ExceptionWorldConflict { ChunkProviderServer chunkproviderserver = this.getChunkProvider(); - if (chunkproviderserver.d()) { - if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit // Paper - Incremental Auto Saving - Only fire event on full save - timings.worldSave.startTimingUnsafe(); // Paper - if (flag || server.serverAutoSave) { // Paper + if (doFull) { + org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); + } + + try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { + if (doFull) { + this.k_(); + } + + timings.worldSaveChunks.startTiming(); // Paper + if (!this.isSavingDisabled()) chunkproviderserver.saveIncrementally(); + timings.worldSaveChunks.stopTiming(); // Paper + + + // CraftBukkit start - moved from MinecraftServer.saveChunks + // PAIL - rename + if (doFull) { + WorldServer worldserver1 = this; + WorldData worlddata = worldserver1.getWorldData(); + + worldserver1.getWorldBorder().a(worlddata); + worlddata.c(this.server.getBossBattleCustomData().c()); + worldserver1.getDataManager().saveWorldData(worlddata, this.server.getPlayerList().r()); + // CraftBukkit end + } + } + } + // Paper end + + public void save(@Nullable IProgressUpdate iprogressupdate, boolean flag, boolean flag1) throws ExceptionWorldConflict { + ChunkProviderServer chunkproviderserver = this.getChunkProvider(); + + if (!flag1) { + if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit + try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper if (iprogressupdate != null) { iprogressupdate.a(new ChatMessage("menu.savingLevel", new Object[0])); } - this.a(); + this.k_(); if (iprogressupdate != null) { iprogressupdate.c(new ChatMessage("menu.savingChunks", new Object[0])); } + + timings.worldSaveChunks.startTiming(); // Paper + chunkproviderserver.save(flag); + timings.worldSaveChunks.stopTiming(); // Paper } // Paper - - timings.worldSaveChunks.startTimingUnsafe(); // Paper - chunkproviderserver.a(flag); - timings.worldSaveChunks.stopTimingUnsafe(); // Paper - // CraftBukkit - ArrayList -> Collection - /* //Paper start - disable vanilla chunk GC - java.util.Collection list = chunkproviderserver.a(); - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - Chunk chunk = (Chunk) iterator.next(); - - if (chunk != null && !this.manager.a(chunk.locX, chunk.locZ)) { - chunkproviderserver.unload(chunk); - } - }*/ - // Paper end - timings.worldSave.stopTimingUnsafe(); // Paper } + + // CraftBukkit start - moved from MinecraftServer.saveChunks + // PAIL - rename + WorldServer worldserver1 = this; + WorldData worlddata = worldserver1.getWorldData(); + + worldserver1.getWorldBorder().a(worlddata); + worlddata.c(this.server.getBossBattleCustomData().c()); + worldserver1.getDataManager().saveWorldData(worlddata, this.server.getPlayerList().r()); + // CraftBukkit end } - public void flushSave() { - ChunkProviderServer chunkproviderserver = this.getChunkProvider(); - - if (chunkproviderserver.d()) { - chunkproviderserver.c(); - } - } - - protected void a() throws ExceptionWorldConflict { - timings.worldSaveLevel.startTimingUnsafe(); // Paper + protected void k_() throws ExceptionWorldConflict { this.checkSession(); - Iterator iterator = this.server.getWorlds().iterator(); + this.worldProvider.k(); + this.getChunkProvider().getWorldPersistentData().a(); + } - while (iterator.hasNext()) { - WorldServer worldserver = (WorldServer) iterator.next(); + public List a(@Nullable EntityTypes entitytypes, Predicate predicate) { + List list = Lists.newArrayList(); + ChunkProviderServer chunkproviderserver = this.getChunkProvider(); + ObjectIterator objectiterator = this.entitiesById.values().iterator(); - if (worldserver instanceof SecondaryWorldServer) { - ((SecondaryWorldServer) worldserver).t_(); + while (objectiterator.hasNext()) { + Entity entity = (Entity) objectiterator.next(); + + if ((entitytypes == null || entity.getEntityType() == entitytypes) && chunkproviderserver.isLoaded(MathHelper.floor(entity.locX) >> 4, MathHelper.floor(entity.locZ) >> 4) && predicate.test(entity)) { + list.add(entity); } } - this.worldData.a(this.getWorldBorder().getSize()); - this.worldData.d(this.getWorldBorder().getCenterX()); - this.worldData.c(this.getWorldBorder().getCenterZ()); - this.worldData.e(this.getWorldBorder().getDamageBuffer()); - this.worldData.f(this.getWorldBorder().getDamageAmount()); - this.worldData.h(this.getWorldBorder().getWarningDistance()); - this.worldData.i(this.getWorldBorder().getWarningTime()); - this.worldData.b(this.getWorldBorder().j()); - this.worldData.c(this.getWorldBorder().i()); - this.worldData.c(this.server.getBossBattleCustomData().c()); - this.dataManager.saveWorldData(this.worldData, this.server.getPlayerList().t()); - this.h().a(); - timings.worldSaveLevel.stopTimingUnsafe(); // Paper + return list; + } + + public List j() { + List list = Lists.newArrayList(); + ObjectIterator objectiterator = this.entitiesById.values().iterator(); + + while (objectiterator.hasNext()) { + Entity entity = (Entity) objectiterator.next(); + + if (entity instanceof EntityEnderDragon && entity.isAlive()) { + list.add((EntityEnderDragon) entity); + } + } + + return list; + } + + public List a(Predicate predicate) { + List list = Lists.newArrayList(); + Iterator iterator = this.players.iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + if (predicate.test(entityplayer)) { + list.add(entityplayer); + } + } + + return list; + } + + @Nullable + public EntityPlayer l_() { + List list = this.a(EntityLiving::isAlive); + + return list.isEmpty() ? null : (EntityPlayer) list.get(this.random.nextInt(list.size())); + } + + public Object2IntMap l() { + // Paper start + int[] values = this.countMobs(false); + EnumCreatureType[] byId = EnumCreatureType.values(); + Object2IntMap ret = new Object2IntOpenHashMap<>(); + + for (int i = 0, len = values.length; i < len; ++i) { + ret.put(byId[i], values[i]); + } + + return ret; + } + public int[] countMobs(boolean updatePlayerCounts) { + int[] ret = new int[EntityPlayer.ENUMCREATURETYPE_TOTAL_ENUMS]; + // Paper end + ObjectIterator objectiterator = this.entitiesById.values().iterator(); + + while (objectiterator.hasNext()) { + Entity entity = (Entity) objectiterator.next(); + if (entity.shouldBeRemoved) continue; // Paper + if (entity instanceof EntityInsentient) { + EntityInsentient entityinsentient = (EntityInsentient) entity; + + // CraftBukkit - Split out persistent check, don't apply it to special persistent mobs + if (entityinsentient.isTypeNotPersistent(0) && entityinsentient.isPersistent()) { + continue; + } + } + + EnumCreatureType enumcreaturetype = entity.getEntityType().e(); + + if (enumcreaturetype != EnumCreatureType.MISC && this.getChunkProvider().b(entity)) { + // Paper start - Only count natural spawns + if (!this.paperConfig.countAllMobsForSpawning && + !(entity.spawnReason == CreatureSpawnEvent.SpawnReason.NATURAL || + entity.spawnReason == CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) { + continue; + } + // Paper end + // Paper start - rework mob spawning + if (updatePlayerCounts) { + this.getChunkProvider().playerChunkMap.updatePlayerMobTypeMap(entity); + } + ++ret[enumcreaturetype.ordinal()]; + // Paper end + } + } + + return ret; + } + + @Override + public boolean addEntity(Entity entity) { + // CraftBukkit start + return this.addEntity0(entity, CreatureSpawnEvent.SpawnReason.DEFAULT); + } + + @Override + public boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason reason) { + return this.addEntity0(entity, reason); + // CraftBukkit end + } + + public boolean addEntitySerialized(Entity entity) { + // CraftBukkit start + return this.addEntitySerialized(entity, CreatureSpawnEvent.SpawnReason.DEFAULT); + } + + public boolean addEntitySerialized(Entity entity, CreatureSpawnEvent.SpawnReason reason) { + return this.addEntity0(entity, reason); + // CraftBukkit end + } + + public void addEntityTeleport(Entity entity) { + boolean flag = entity.attachedToPlayer; + + entity.attachedToPlayer = true; + this.addEntitySerialized(entity); + entity.attachedToPlayer = flag; + this.chunkCheck(entity); + } + + public void addPlayerCommand(EntityPlayer entityplayer) { + this.addPlayer0(entityplayer); + this.chunkCheck(entityplayer); + } + + public void addPlayerPortal(EntityPlayer entityplayer) { + this.addPlayer0(entityplayer); + this.chunkCheck(entityplayer); + } + + public void addPlayerJoin(EntityPlayer entityplayer) { + this.addPlayer0(entityplayer); + } + + public void addPlayerRespawn(EntityPlayer entityplayer) { + this.addPlayer0(entityplayer); + } + + private void addPlayer0(EntityPlayer entityplayer) { + Entity entity = (Entity) this.entitiesByUUID.get(entityplayer.getUniqueID()); + + if (entity != null) { + WorldServer.LOGGER.warn("Force-added player with duplicate UUID {}", entityplayer.getUniqueID().toString()); + entity.decouple(); + this.removePlayer((EntityPlayer) entity); + } + + this.players.add(entityplayer); + this.everyoneSleeping(); + IChunkAccess ichunkaccess = this.getChunkAt(MathHelper.floor(entityplayer.locX / 16.0D), MathHelper.floor(entityplayer.locZ / 16.0D), ChunkStatus.FULL, true); + + if (ichunkaccess instanceof Chunk) { + ichunkaccess.a((Entity) entityplayer); + } + + this.registerEntity(entityplayer); } // CraftBukkit start - public boolean addEntity(Entity entity, SpawnReason spawnReason) { // Changed signature, added SpawnReason - // World.addEntity(Entity) will call this, and we still want to perform - // existing entity checking when it's called with a SpawnReason - return this.j(entity) ? super.addEntity(entity, spawnReason) : false; - } - // CraftBukkit end + private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { + org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot + if (entity.spawnReason == null) entity.spawnReason = spawnReason; // Paper + // Paper start + if (entity.valid) { + MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable()); - public void a(Stream stream) { - stream.forEach((entity) -> { - if (this.j(entity)) { - this.entityList.add(entity); - this.b(entity); + if (DEBUG_ENTITIES) { + Throwable thr = entity.addedToWorldStack; + if (thr == null) { + MinecraftServer.LOGGER.error("Double add entity has no add stacktrace"); + } else { + MinecraftServer.LOGGER.error("Double add stacktrace: ", thr); + } } - - }); - } - - private boolean j(Entity entity) { + return true; + } + // Paper end if (entity.dead) { // Paper start if (DEBUG_ENTITIES) { @@ -983,135 +1146,370 @@ public class WorldServer extends World implements IAsyncTaskHandler { getAddToWorldStackTrace(entity).printStackTrace(); } // Paper end + // WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getName(entity.getEntityType())); // CraftBukkit + return false; + } else if (this.isUUIDTaken(entity)) { return false; } else { - UUID uuid = entity.getUniqueID(); - - if (this.entitiesByUUID.containsKey(uuid)) { - Entity entity1 = (Entity) this.entitiesByUUID.get(uuid); - - if (this.g.contains(entity1) || entity1.dead) { // Paper - if dupe is dead, overwrite - this.g.remove(entity1); - } else { - if (!(entity instanceof EntityHuman)) { - if (DEBUG_ENTITIES && entity.world.paperConfig.duplicateUUIDMode != com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode.NOTHING) { - WorldServer.a.error("Keeping entity {} that already exists with UUID {}", entity1, uuid.toString()); // CraftBukkit // Paper - WorldServer.a.error("Deleting duplicate entity {}", entity); // Paper - - if (entity1.addedToWorldStack != null) { - entity1.addedToWorldStack.printStackTrace(); - } - getAddToWorldStackTrace(entity).printStackTrace(); - } - return false; - } - - WorldServer.a.warn("Force-added player with duplicate UUID {}", uuid.toString()); - } - - this.removeEntity(entity1); + if (!CraftEventFactory.doEntityAddEventCalling(this, entity, spawnReason)) { + return false; } + // CraftBukkit end + IChunkAccess ichunkaccess = this.getChunkAt(MathHelper.floor(entity.locX / 16.0D), MathHelper.floor(entity.locZ / 16.0D), ChunkStatus.FULL, true); // Paper - always load chunks for entity adds + if (!(ichunkaccess instanceof Chunk)) { + return false; + } else { + ichunkaccess.a(entity); + this.registerEntity(entity); + return true; + } + } + } + + public boolean addEntityChunk(Entity entity) { + if (this.isUUIDTaken(entity)) { + return false; + } else { + this.registerEntity(entity); return true; } } - protected void b(Entity entity) { - super.b(entity); - this.entitiesById.a(entity.getId(), entity); - // Paper start - if (DEBUG_ENTITIES) { - entity.addedToWorldStack = getAddToWorldStackTrace(entity); - } + private boolean isUUIDTaken(Entity entity) { + Entity entity1 = (Entity) this.entitiesByUUID.get(entity.getUniqueID()); - Entity old = this.entitiesByUUID.put(entity.getUniqueID(), entity); - if (old != null && old.getId() != entity.getId() && old.valid && entity.world.paperConfig.duplicateUUIDMode != com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode.NOTHING) { - Logger logger = LogManager.getLogger(); - logger.error("Overwrote an existing entity " + old + " with " + entity); - if (DEBUG_ENTITIES) { - if (old.addedToWorldStack != null) { - old.addedToWorldStack.printStackTrace(); - } else { - logger.error("Oddly, the old entity was not added to the world in the normal way. Plugins?"); + if (entity1 == null) { + return false; + } else { + // Paper start + if (entity1.dead) { + unregisterEntity(entity1); // remove the existing entity + return false; + } + + if (DEBUG_ENTITIES && entity.world.paperConfig.duplicateUUIDMode != PaperWorldConfig.DuplicateUUIDMode.NOTHING) { + WorldServer.LOGGER.error("Keeping entity {} that already exists with UUID {}", EntityTypes.getName(entity1.getEntityType()), entity.getUniqueID().toString()); // CraftBukkit // paper + WorldServer.LOGGER.error("Deleting duplicate entity {}", entity); // CraftBukkit // paper + + if (entity1.addedToWorldStack != null) { + entity1.addedToWorldStack.printStackTrace(); + } + + getAddToWorldStackTrace(entity).printStackTrace(); + } + // Paper end + return true; + } + } + + public void unloadChunk(Chunk chunk) { + // Spigot Start + for (TileEntity tileentity : chunk.getTileEntities().values()) + { + if ( tileentity instanceof IInventory ) + { + for ( org.bukkit.entity.HumanEntity h : Lists.newArrayList((List) ( (IInventory) tileentity ).getViewers() ) ) + { + if ( h instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity ) + { + ( (org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper + } } - entity.addedToWorldStack.printStackTrace(); } } - // Paper end - Entity[] aentity = entity.bi(); + // Spigot End + this.tileEntityListUnload.addAll(chunk.getTileEntities().values()); + List[] aentityslice = chunk.getEntitySlices(); // Spigot + int i = aentityslice.length; - if (aentity != null) { - Entity[] aentity1 = aentity; - int i = aentity.length; + for (int j = 0; j < i; ++j) { + List entityslice = aentityslice[j]; // Spigot + Iterator iterator = entityslice.iterator(); - for (int j = 0; j < i; ++j) { - Entity entity1 = aentity1[j]; + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + // Spigot Start + if ( entity instanceof IInventory ) + { + for ( org.bukkit.entity.HumanEntity h : Lists.newArrayList( (List) ( (IInventory) entity ).getViewers() ) ) + { + if ( h instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity ) + { + ( (org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper + } + } + } + // Spigot End - this.entitiesById.a(entity1.getId(), entity1); + if (!(entity instanceof EntityPlayer)) { + if (this.tickingEntities) { + throw new IllegalStateException("Removing entity while ticking!"); + } + + this.entitiesById.remove(entity.getId()); + this.unregisterEntity(entity); + } } } } - protected void c(Entity entity) { - if (!this.entitiesByUUID.containsKey(entity.getUniqueID()) && !entity.valid) return; // Paper - Already removed, dont fire twice - this looks like it can happen even without our changes - super.c(entity); - this.entitiesById.d(entity.getId()); + public void unregisterEntity(Entity entity) { + org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot + // Spigot start + if ( entity instanceof EntityHuman ) + { + this.getMinecraftServer().worldServer.values().stream().map( WorldServer::getWorldPersistentData ).forEach( (worldData) -> + { + for (Object o : worldData.data.values() ) + { + if ( o instanceof WorldMap ) + { + WorldMap map = (WorldMap) o; + map.humans.remove( (EntityHuman) entity ); + for ( Iterator iter = (Iterator) map.i.iterator(); iter.hasNext(); ) + { + if ( iter.next().trackee == entity ) + { + map.decorations.remove(entity.getDisplayName().getString()); // Paper + iter.remove(); + } + } + } + } + } ); + } + // Spigot end + + if (entity instanceof EntityEnderDragon) { + EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).dT(); + int i = aentitycomplexpart.length; + + for (int j = 0; j < i; ++j) { + EntityComplexPart entitycomplexpart = aentitycomplexpart[j]; + + entitycomplexpart.die(); + } + } + this.entitiesByUUID.remove(entity.getUniqueID()); - Entity[] aentity = entity.bi(); + this.getChunkProvider().removeEntity(entity); + if (entity instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entity; - if (aentity != null) { - Entity[] aentity1 = aentity; - int i = aentity.length; + this.players.remove(entityplayer); + } - for (int j = 0; j < i; ++j) { - Entity entity1 = aentity1[j]; + this.getScoreboard().a(entity); + // CraftBukkit start - SPIGOT-5278 + if (entity instanceof EntityDrowned) { + this.H.remove(((EntityDrowned) entity).b); + this.H.remove(((EntityDrowned) entity).c); + } else + // CraftBukkit end + if (entity instanceof EntityInsentient) { + this.H.remove(((EntityInsentient) entity).getNavigation()); + } + new com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid + entity.valid = false; // CraftBukkit + } - this.entitiesById.d(entity1.getId()); + private void registerEntity(Entity entity) { + org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot + if (this.tickingEntities) { + this.entitiesToAdd.add(entity); + } else { + this.entitiesById.put(entity.getId(), entity); + if (entity instanceof EntityEnderDragon) { + EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).dT(); + int i = aentitycomplexpart.length; + + for (int j = 0; j < i; ++j) { + EntityComplexPart entitycomplexpart = aentitycomplexpart[j]; + + this.entitiesById.put(entitycomplexpart.getId(), entitycomplexpart); + } } + + if (DEBUG_ENTITIES) { + entity.addedToWorldStack = getAddToWorldStackTrace(entity); + } + + Entity old = this.entitiesByUUID.put(entity.getUniqueID(), entity); + if (old != null && old.getId() != entity.getId() && old.valid && entity.world.paperConfig.duplicateUUIDMode != com.destroystokyo.paper.PaperWorldConfig.DuplicateUUIDMode.NOTHING) { // Paper + Logger logger = LogManager.getLogger(); + logger.error("Overwrote an existing entity " + old + " with " + entity); + if (DEBUG_ENTITIES) { + if (old.addedToWorldStack != null) { + old.addedToWorldStack.printStackTrace(); + } else { + logger.error("Oddly, the old entity was not added to the world in the normal way. Plugins?"); + } + entity.addedToWorldStack.printStackTrace(); + } + } + + this.getChunkProvider().addEntity(entity); + // CraftBukkit start - SPIGOT-5278 + if (entity instanceof EntityDrowned) { + this.H.add(((EntityDrowned) entity).b); + this.H.add(((EntityDrowned) entity).c); + } else + // CraftBukkit end + if (entity instanceof EntityInsentient) { + this.H.add(((EntityInsentient) entity).getNavigation()); + } + entity.valid = true; // CraftBukkit + // Paper start - Set origin location when the entity is being added to the world + if (entity.origin == null) { + entity.origin = entity.getBukkitEntity().getLocation(); + } + // Paper end + entity.shouldBeRemoved = false; // Paper - shouldn't be removed after being re-added + new com.destroystokyo.paper.event.entity.EntityAddToWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid } } - // CraftBukkit start - public boolean strikeLightning(Entity entity) { - return this.strikeLightning(entity, LightningStrikeEvent.Cause.UNKNOWN); + public void removeEntity(Entity entity) { + if (this.tickingEntities) { + throw new IllegalStateException("Removing entity while ticking!"); + } else { + this.removeEntityFromChunk(entity); + this.entitiesById.remove(entity.getId()); + this.unregisterEntity(entity); + entity.shouldBeRemoved = true; // Paper + } } - public boolean strikeLightning(Entity entity, LightningStrikeEvent.Cause cause) { - LightningStrikeEvent lightning = new LightningStrikeEvent(this.getWorld(), (org.bukkit.entity.LightningStrike) entity.getBukkitEntity(), cause); + private void removeEntityFromChunk(Entity entity) { + IChunkAccess ichunkaccess = this.getChunkAt(entity.chunkX, entity.chunkZ, ChunkStatus.FULL, false); + + if (ichunkaccess instanceof Chunk) { + ((Chunk) ichunkaccess).b(entity); + } + + } + + public void removePlayer(EntityPlayer entityplayer) { + entityplayer.die(); + this.removeEntity(entityplayer); + this.everyoneSleeping(); + } + + public void strikeLightning(EntityLightning entitylightning) { + // CraftBukkit start + this.strikeLightning(entitylightning, LightningStrikeEvent.Cause.UNKNOWN); + } + + public void strikeLightning(EntityLightning entitylightning, LightningStrikeEvent.Cause cause) { + LightningStrikeEvent lightning = new LightningStrikeEvent(this.getWorld(), (org.bukkit.entity.LightningStrike) entitylightning.getBukkitEntity(), cause); this.getServer().getPluginManager().callEvent(lightning); if (lightning.isCancelled()) { - return false; + return; } // CraftBukkit end - if (super.strikeLightning(entity)) { - this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entity.locX, entity.locY, entity.locZ, this.paperConfig.maxLightningFlashDistance, this, new PacketPlayOutSpawnEntityWeather(entity)); // CraftBukkit - Use dimension, // Paper - use world instead of dimension, limit lightning strike effect distance - return true; - } else { - return false; + this.globalEntityList.add(entitylightning); + this.server.getPlayerList().sendPacketNearby((EntityHuman) null, entitylightning.locX, entitylightning.locY, entitylightning.locZ, paperConfig.maxLightningFlashDistance, this, new PacketPlayOutSpawnEntityWeather(entitylightning)); // Paper - use world instead of dimension, limit lightning strike effect distance + } + + @Override + public void a(int i, BlockPosition blockposition, int j) { + Iterator iterator = this.server.getPlayerList().getPlayers().iterator(); + + // CraftBukkit start + EntityHuman entityhuman = null; + Entity entity = this.getEntity(i); + if (entity instanceof EntityHuman) entityhuman = (EntityHuman) entity; + // CraftBukkit end + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + if (entityplayer != null && entityplayer.world == this && entityplayer.getId() != i) { + double d0 = (double) blockposition.getX() - entityplayer.locX; + double d1 = (double) blockposition.getY() - entityplayer.locY; + double d2 = (double) blockposition.getZ() - entityplayer.locZ; + + // CraftBukkit start + if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { + continue; + } + // CraftBukkit end + + if (d0 * d0 + d1 * d1 + d2 * d2 < 1024.0D) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutBlockBreakAnimation(i, blockposition, j)); + } + } + } + + } + + @Override + public void playSound(@Nullable EntityHuman entityhuman, double d0, double d1, double d2, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) { + this.server.getPlayerList().sendPacketNearby(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.worldProvider.getDimensionManager(), new PacketPlayOutNamedSoundEffect(soundeffect, soundcategory, d0, d1, d2, f, f1)); + } + + @Override + public void playSound(@Nullable EntityHuman entityhuman, Entity entity, SoundEffect soundeffect, SoundCategory soundcategory, float f, float f1) { + this.server.getPlayerList().sendPacketNearby(entityhuman, entity.locX, entity.locY, entity.locZ, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.worldProvider.getDimensionManager(), new PacketPlayOutEntitySound(soundeffect, soundcategory, entity, f, f1)); + } + + @Override + public void b(int i, BlockPosition blockposition, int j) { + this.server.getPlayerList().sendAll(new PacketPlayOutWorldEvent(i, blockposition, j, true)); + } + + @Override + public void a(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { + this.server.getPlayerList().sendPacketNearby(entityhuman, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 64.0D, this.worldProvider.getDimensionManager(), new PacketPlayOutWorldEvent(i, blockposition, j, false)); + } + + @Override + public void notify(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, int i) { + this.getChunkProvider().flagDirty(blockposition); + VoxelShape voxelshape = iblockdata.getCollisionShape(this, blockposition); + VoxelShape voxelshape1 = iblockdata1.getCollisionShape(this, blockposition); + + if (VoxelShapes.c(voxelshape, voxelshape1, OperatorBoolean.NOT_SAME)) { + boolean wasTicking = this.tickingEntities; this.tickingEntities = true; // Paper + Iterator iterator = this.H.iterator(); + + while (iterator.hasNext()) { + NavigationAbstract navigationabstract = (NavigationAbstract) iterator.next(); + + if (!navigationabstract.j()) { + navigationabstract.b(blockposition); + } + } + + this.tickingEntities = wasTicking; // Paper } } + @Override public void broadcastEntityEffect(Entity entity, byte b0) { - this.getTracker().sendPacketToEntity(entity, new PacketPlayOutEntityStatus(entity, b0)); + this.getChunkProvider().broadcastIncludingSelf(entity, new PacketPlayOutEntityStatus(entity, b0)); } + @Override public ChunkProviderServer getChunkProvider() { return (ChunkProviderServer) super.getChunkProvider(); } - public Explosion createExplosion(@Nullable Entity entity, DamageSource damagesource, double d0, double d1, double d2, float f, boolean flag, boolean flag1) { + @Override + public Explosion createExplosion(@Nullable Entity entity, DamageSource damagesource, double d0, double d1, double d2, float f, boolean flag, Explosion.Effect explosion_effect) { // CraftBukkit start - Explosion explosion = super.createExplosion(entity, damagesource, d0, d1, d2, f, flag, flag1); + Explosion explosion = super.createExplosion(entity, damagesource, d0, d1, d2, f, flag, explosion_effect); if (explosion.wasCanceled) { return explosion; } /* Remove - Explosion explosion = new Explosion(this, entity, d0, d1, d2, f, flag, flag1); + Explosion explosion = new Explosion(this, entity, d0, d1, d2, f, flag, explosion_effect); if (damagesource != null) { explosion.a(damagesource); @@ -1121,33 +1519,33 @@ public class WorldServer extends World implements IAsyncTaskHandler { explosion.a(false); */ // CraftBukkit end - TODO: Check if explosions are still properly implemented - if (!flag1) { + if (explosion_effect == Explosion.Effect.NONE) { explosion.clearBlocks(); } Iterator iterator = this.players.iterator(); while (iterator.hasNext()) { - EntityHuman entityhuman = (EntityHuman) iterator.next(); + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); - if (entityhuman.d(d0, d1, d2) < 4096.0D) { - ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutExplosion(d0, d1, d2, f, explosion.getBlocks(), (Vec3D) explosion.c().get(entityhuman))); + if (entityplayer.e(d0, d1, d2) < 4096.0D) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutExplosion(d0, d1, d2, f, explosion.getBlocks(), (Vec3D) explosion.c().get(entityplayer))); } } return explosion; } + @Override public void playBlockAction(BlockPosition blockposition, Block block, int i, int j) { - this.d.add(new BlockActionData(blockposition, block, i, j)); + this.I.add(new BlockActionData(blockposition, block, i, j)); } - private void an() { - while (!this.d.isEmpty()) { - BlockActionData blockactiondata = (BlockActionData) this.d.removeFirst(); + private void ae() { + while (!this.I.isEmpty()) { + BlockActionData blockactiondata = (BlockActionData) this.I.removeFirst(); if (this.a(blockactiondata)) { - // CraftBukkit - this.worldProvider.dimension -> this.dimension, // Paper - dimension -> world this.server.getPlayerList().sendPacketNearby((EntityHuman) null, (double) blockactiondata.a().getX(), (double) blockactiondata.a().getY(), (double) blockactiondata.a().getZ(), 64.0D, this, new PacketPlayOutBlockAction(blockactiondata.a(), blockactiondata.b(), blockactiondata.c(), blockactiondata.d())); } } @@ -1160,79 +1558,28 @@ public class WorldServer extends World implements IAsyncTaskHandler { return iblockdata.getBlock() == blockactiondata.b() ? iblockdata.a(this, blockactiondata.a(), blockactiondata.c(), blockactiondata.d()) : false; } - public void close() { - this.dataManager.a(); - super.close(); - } - - protected void w() { - boolean flag = this.isRaining(); - - super.w(); - /* CraftBukkit start - if (this.o != this.p) { - this.server.getPlayerList().a((Packet) (new PacketPlayOutGameStateChange(7, this.p)), this.worldProvider.getDimensionManager()); - } - - if (this.q != this.r) { - this.server.getPlayerList().a((Packet) (new PacketPlayOutGameStateChange(8, this.r)), this.worldProvider.getDimensionManager()); - } - - if (flag != this.isRaining()) { - if (flag) { - this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(2, 0.0F)); - } else { - this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(1, 0.0F)); - } - - this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(7, this.p)); - this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(8, this.r)); - } - // */ - if (flag != this.isRaining()) { - // Only send weather packets to those affected - for (int i = 0; i < this.players.size(); ++i) { - if (((EntityPlayer) this.players.get(i)).world == this) { - ((EntityPlayer) this.players.get(i)).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); - } - } - } - for (int i = 0; i < this.players.size(); ++i) { - if (((EntityPlayer) this.players.get(i)).world == this) { - ((EntityPlayer) this.players.get(i)).updateWeather(this.o, this.p, this.q, this.r); - } - } - // CraftBukkit end - - } - + @Override public TickListServer getBlockTickList() { return this.nextTickListBlock; } + @Override public TickListServer getFluidTickList() { return this.nextTickListFluid; } @Nonnull + @Override public MinecraftServer getMinecraftServer() { return this.server; } - public EntityTracker getTracker() { - return this.tracker; - } - - public PlayerChunkMap getPlayerChunkMap() { - return this.manager; - } - public PortalTravelAgent getTravelAgent() { return this.portalTravelAgent; } - public DefinedStructureManager D() { - return this.dataManager.h(); + public DefinedStructureManager r() { + return this.dataManager.f(); } public int a(T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6) { @@ -1244,7 +1591,7 @@ public class WorldServer extends World implements IAsyncTaskHandler { // Paper start - Particle API Expansion return sendParticles(players, sender, t0, d0, d1, d2, i, d3, d4, d5, d6, force); } - public int sendParticles(List receivers, EntityPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) { + public int sendParticles(List receivers, EntityPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) { // Paper end PacketPlayOutWorldParticles packetplayoutworldparticles = new PacketPlayOutWorldParticles(t0, force, (float) d0, (float) d1, (float) d2, (float) d3, (float) d4, (float) d5, (float) d6, i); // CraftBukkit end @@ -1273,46 +1620,452 @@ public class WorldServer extends World implements IAsyncTaskHandler { return false; } else { BlockPosition blockposition = entityplayer.getChunkCoordinates(); - double d3 = blockposition.distanceSquared(d0, d1, d2); - if (d3 > 1024.0D && (!flag || d3 > 262144.0D)) { - return false; - } else { + if (blockposition.a((IPosition) (new Vec3D(d0, d1, d2)), flag ? 512.0D : 32.0D)) { entityplayer.playerConnection.sendPacket(packet); return true; + } else { + return false; } } } + @Nullable + @Override + public Entity getEntity(int i) { + return (Entity) this.entitiesById.get(i); + } + @Nullable public Entity getEntity(UUID uuid) { return (Entity) this.entitiesByUUID.get(uuid); } - public ListenableFuture postToMainThread(Runnable runnable) { - return this.server.postToMainThread(runnable); - } - // Akarin start - @Override - public void ensuresMainThread(Runnable runnable) { - this.server.f.offer(ListenableFutureTask.create(runnable, null)); - } - // Akarin end - - public boolean isMainThread() { - return this.server.isMainThread(); - } - @Nullable + @Override public BlockPosition a(String s, BlockPosition blockposition, int i, boolean flag) { - return this.getChunkProvider().a(this, s, blockposition, i, flag); + return this.getChunkProvider().getChunkGenerator().findNearestMapFeature(this, s, blockposition, i, flag); } + @Override public CraftingManager getCraftingManager() { return this.server.getCraftingManager(); } - public TagRegistry F() { + @Override + public TagRegistry t() { return this.server.getTagRegistry(); } + + @Override + public void a(long i) { + super.a(i); + this.worldData.y().a(this.server, i); + } + + @Override + public boolean isSavingDisabled() { + return this.savingDisabled; + } + + public void checkSession() throws ExceptionWorldConflict { + this.dataManager.checkSession(); + } + + public WorldNBTStorage getDataManager() { + return this.dataManager; + } + + public WorldPersistentData getWorldPersistentData() { + return this.getChunkProvider().getWorldPersistentData(); + } + + @Nullable + @Override + public WorldMap a(String s) { + return (WorldMap) this.getMinecraftServer().getWorldServer(DimensionManager.OVERWORLD).getWorldPersistentData().b(() -> { + // CraftBukkit start + // We only get here when the data file exists, but is not a valid map + WorldMap newMap = new WorldMap(s); + MapInitializeEvent event = new MapInitializeEvent(newMap.mapView); + Bukkit.getServer().getPluginManager().callEvent(event); + return newMap; + // CraftBukkit end + }, s); + } + + @Override + public void a(WorldMap worldmap) { + this.getMinecraftServer().getWorldServer(DimensionManager.OVERWORLD).getWorldPersistentData().a((PersistentBase) worldmap); + } + + @Override + public int getWorldMapCount() { + return ((PersistentIdCounts) this.getMinecraftServer().getWorldServer(DimensionManager.OVERWORLD).getWorldPersistentData().a(PersistentIdCounts::new, "idcounts")).a(); + } + + // Paper start - helper function for configurable spawn radius + public void addTicketsForSpawn(int radiusInBlocks, BlockPosition spawn) { + // In order to respect vanilla behavior, which is ensuring everything but the spawn border can tick, we add tickets + // with level 31 for the non-border spawn chunks + ChunkProviderServer chunkproviderserver = this.getChunkProvider(); + int tickRadius = radiusInBlocks - 16; + + // add ticking chunks + for (int x = -tickRadius; x <= tickRadius; x += 16) { + for (int z = -tickRadius; z <= tickRadius; z += 16) { + // radius of 2 will have the current chunk be level 31 + chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, z)), 2, Unit.INSTANCE); + } + } + + // add border chunks + + // add border along x axis (including corner chunks) + for (int x = -radiusInBlocks; x <= radiusInBlocks; x += 16) { + // top + chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, radiusInBlocks)), 1, Unit.INSTANCE); // level 32 + // bottom + chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, -radiusInBlocks)), 1, Unit.INSTANCE); // level 32 + } + + // add border along z axis (excluding corner chunks) + for (int z = -radiusInBlocks + 16; z < radiusInBlocks; z += 16) { + // right + chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 + // left + chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(-radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 + } + } + public void removeTicketsForSpawn(int radiusInBlocks, BlockPosition spawn) { + // In order to respect vanilla behavior, which is ensuring everything but the spawn border can tick, we added tickets + // with level 31 for the non-border spawn chunks + ChunkProviderServer chunkproviderserver = this.getChunkProvider(); + int tickRadius = radiusInBlocks - 16; + + // remove ticking chunks + for (int x = -tickRadius; x <= tickRadius; x += 16) { + for (int z = -tickRadius; z <= tickRadius; z += 16) { + // radius of 2 will have the current chunk be level 31 + chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, z)), 2, Unit.INSTANCE); + } + } + + // remove border chunks + + // remove border along x axis (including corner chunks) + for (int x = -radiusInBlocks; x <= radiusInBlocks; x += 16) { + // top + chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, radiusInBlocks)), 1, Unit.INSTANCE); // level 32 + // bottom + chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(x, 0, -radiusInBlocks)), 1, Unit.INSTANCE); // level 32 + } + + // remove border along z axis (excluding corner chunks) + for (int z = -radiusInBlocks + 16; z < radiusInBlocks; z += 16) { + // right + chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 + // left + chunkproviderserver.removeTicket(TicketType.START, new ChunkCoordIntPair(spawn.add(-radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 + } + } + // Paper end + + @Override + public void a_(BlockPosition blockposition) { + // Paper - configurable spawn radius + BlockPosition prevSpawn = this.getSpawn(); + + super.a_(blockposition); + if (this.keepSpawnInMemory) { + // if this keepSpawnInMemory is false a plugin has already removed our tickets, do not re-add + this.removeTicketsForSpawn(this.paperConfig.keepLoadedRange, prevSpawn); + this.addTicketsForSpawn(this.paperConfig.keepLoadedRange, blockposition); + } + // Paper end + } + + public LongSet getForceLoadedChunks() { + ForcedChunk forcedchunk = (ForcedChunk) this.getWorldPersistentData().b(ForcedChunk::new, "chunks"); + + return (LongSet) (forcedchunk != null ? LongSets.unmodifiable(forcedchunk.a()) : LongSets.EMPTY_SET); + } + + public boolean setForceLoaded(int i, int j, boolean flag) { + ForcedChunk forcedchunk = (ForcedChunk) this.getWorldPersistentData().a(ForcedChunk::new, "chunks"); + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + long k = chunkcoordintpair.pair(); + boolean flag1; + + if (flag) { + flag1 = forcedchunk.a().add(k); + if (flag1) { + this.getChunkAt(i, j); + } + } else { + flag1 = forcedchunk.a().remove(k); + } + + forcedchunk.a(flag1); + if (flag1) { + this.getChunkProvider().a(chunkcoordintpair, flag); + } + + return flag1; + } + + @Override + public List getPlayers() { + return this.players; + } + + @Override + public void a(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) { + Optional optional = VillagePlaceType.b(iblockdata); + Optional optional1 = VillagePlaceType.b(iblockdata1); + + if (!Objects.equals(optional, optional1)) { + BlockPosition blockposition1 = blockposition.immutableCopy(); + + optional.ifPresent((villageplacetype) -> { + this.getMinecraftServer().execute(() -> { + this.B().a(blockposition1); + PacketDebug.b(this, blockposition1); + }); + }); + optional1.ifPresent((villageplacetype) -> { + this.getMinecraftServer().execute(() -> { + this.B().a(blockposition1, villageplacetype); + PacketDebug.a(this, blockposition1); + }); + }); + } + } + + public VillagePlace B() { + return this.getChunkProvider().j(); + } + + public boolean b_(BlockPosition blockposition) { + return this.a(blockposition, 1); + } + + public boolean a(SectionPosition sectionposition) { + return this.b_(sectionposition.t()); + } + + public boolean a(BlockPosition blockposition, int i) { + return i > 6 ? false : this.b(SectionPosition.a(blockposition)) <= i; + } + + public int b(SectionPosition sectionposition) { + return this.B().a(sectionposition); + } + + public PersistentRaid C() { + return this.c; + } + + @Nullable + public Raid c_(BlockPosition blockposition) { + return this.c.a(blockposition, 9216); + } + + public boolean d_(BlockPosition blockposition) { + return this.c_(blockposition) != null; + } + + public void a(ReputationEvent reputationevent, Entity entity, ReputationHandler reputationhandler) { + reputationhandler.a(reputationevent, entity); + } + + public void a(java.nio.file.Path java_nio_file_path) throws IOException { + PlayerChunkMap playerchunkmap = this.getChunkProvider().playerChunkMap; + BufferedWriter bufferedwriter = Files.newBufferedWriter(java_nio_file_path.resolve("stats.txt")); + Throwable throwable = null; + + try { + bufferedwriter.write(String.format("spawning_chunks: %d\n", playerchunkmap.e().b())); + ObjectIterator objectiterator = this.l().object2IntEntrySet().iterator(); + + while (objectiterator.hasNext()) { + it.unimi.dsi.fastutil.objects.Object2IntMap.Entry it_unimi_dsi_fastutil_objects_object2intmap_entry = (it.unimi.dsi.fastutil.objects.Object2IntMap.Entry) objectiterator.next(); + + bufferedwriter.write(String.format("spawn_count.%s: %d\n", ((EnumCreatureType) it_unimi_dsi_fastutil_objects_object2intmap_entry.getKey()).a(), it_unimi_dsi_fastutil_objects_object2intmap_entry.getIntValue())); + } + + bufferedwriter.write(String.format("entities: %d\n", this.entitiesById.size())); + bufferedwriter.write(String.format("block_entities: %d\n", this.tileEntityListTick.size())); // Paper - remove unused list + bufferedwriter.write(String.format("block_ticks: %d\n", this.getBlockTickList().a())); + bufferedwriter.write(String.format("fluid_ticks: %d\n", this.getFluidTickList().a())); + bufferedwriter.write("distance_manager: " + playerchunkmap.e().c() + "\n"); + bufferedwriter.write(String.format("pending_tasks: %d\n", this.getChunkProvider().f())); + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (bufferedwriter != null) { + if (throwable != null) { + try { + bufferedwriter.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + bufferedwriter.close(); + } + } + + } + + CrashReport crashreport = new CrashReport("Level dump", new Exception("dummy")); + + this.a(crashreport); + BufferedWriter bufferedwriter1 = Files.newBufferedWriter(java_nio_file_path.resolve("example_crash.txt")); + Throwable throwable3 = null; + + try { + bufferedwriter1.write(crashreport.e()); + } catch (Throwable throwable4) { + throwable3 = throwable4; + throw throwable4; + } finally { + if (bufferedwriter1 != null) { + if (throwable3 != null) { + try { + bufferedwriter1.close(); + } catch (Throwable throwable5) { + throwable3.addSuppressed(throwable5); + } + } else { + bufferedwriter1.close(); + } + } + + } + + java.nio.file.Path java_nio_file_path1 = java_nio_file_path.resolve("chunks.csv"); + BufferedWriter bufferedwriter2 = Files.newBufferedWriter(java_nio_file_path1); + Throwable throwable6 = null; + + try { + playerchunkmap.a((Writer) bufferedwriter2); + } catch (Throwable throwable7) { + throwable6 = throwable7; + throw throwable7; + } finally { + if (bufferedwriter2 != null) { + if (throwable6 != null) { + try { + bufferedwriter2.close(); + } catch (Throwable throwable8) { + throwable6.addSuppressed(throwable8); + } + } else { + bufferedwriter2.close(); + } + } + + } + + java.nio.file.Path java_nio_file_path2 = java_nio_file_path.resolve("entities.csv"); + BufferedWriter bufferedwriter3 = Files.newBufferedWriter(java_nio_file_path2); + Throwable throwable9 = null; + + try { + a((Writer) bufferedwriter3, (Iterable) this.entitiesById.values()); + } catch (Throwable throwable10) { + throwable9 = throwable10; + throw throwable10; + } finally { + if (bufferedwriter3 != null) { + if (throwable9 != null) { + try { + bufferedwriter3.close(); + } catch (Throwable throwable11) { + throwable9.addSuppressed(throwable11); + } + } else { + bufferedwriter3.close(); + } + } + + } + + java.nio.file.Path java_nio_file_path3 = java_nio_file_path.resolve("global_entities.csv"); + BufferedWriter bufferedwriter4 = Files.newBufferedWriter(java_nio_file_path3); + Throwable throwable12 = null; + + try { + a((Writer) bufferedwriter4, (Iterable) this.globalEntityList); + } catch (Throwable throwable13) { + throwable12 = throwable13; + throw throwable13; + } finally { + if (bufferedwriter4 != null) { + if (throwable12 != null) { + try { + bufferedwriter4.close(); + } catch (Throwable throwable14) { + throwable12.addSuppressed(throwable14); + } + } else { + bufferedwriter4.close(); + } + } + + } + + java.nio.file.Path java_nio_file_path4 = java_nio_file_path.resolve("block_entities.csv"); + BufferedWriter bufferedwriter5 = Files.newBufferedWriter(java_nio_file_path4); + Throwable throwable15 = null; + + try { + this.a((Writer) bufferedwriter5); + } catch (Throwable throwable16) { + throwable15 = throwable16; + throw throwable16; + } finally { + if (bufferedwriter5 != null) { + if (throwable15 != null) { + try { + bufferedwriter5.close(); + } catch (Throwable throwable17) { + throwable15.addSuppressed(throwable17); + } + } else { + bufferedwriter5.close(); + } + } + + } + + } + + private static void a(Writer writer, Iterable iterable) throws IOException { + CSVWriter csvwriter = CSVWriter.a().a("x").a("y").a("z").a("uuid").a("type").a("alive").a("display_name").a("custom_name").a(writer); + Iterator iterator = iterable.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + IChatBaseComponent ichatbasecomponent = entity.getCustomName(); + IChatBaseComponent ichatbasecomponent1 = entity.getScoreboardDisplayName(); + + csvwriter.a(entity.locX, entity.locY, entity.locZ, entity.getUniqueID(), IRegistry.ENTITY_TYPE.getKey(entity.getEntityType()), entity.isAlive(), ichatbasecomponent1.getString(), ichatbasecomponent != null ? ichatbasecomponent.getString() : null); + } + + } + + private void a(Writer writer) throws IOException { + CSVWriter csvwriter = CSVWriter.a().a("x").a("y").a("z").a("type").a(writer); + Iterator iterator = this.tileEntityListTick.iterator(); // Paper - remove unused list + + while (iterator.hasNext()) { + TileEntity tileentity = (TileEntity) iterator.next(); + BlockPosition blockposition = tileentity.getPosition(); + + csvwriter.a(blockposition.getX(), blockposition.getY(), blockposition.getZ(), IRegistry.BLOCK_ENTITY_TYPE.getKey(tileentity.q())); + } + + } } diff --git a/src/main/java/net/minecraft/server/WorldUpgrader.java b/src/main/java/net/minecraft/server/WorldUpgrader.java new file mode 100644 index 000000000..af2af1e62 --- /dev/null +++ b/src/main/java/net/minecraft/server/WorldUpgrader.java @@ -0,0 +1,276 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.UnmodifiableIterator; +import com.google.common.collect.ImmutableMap.Builder; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import it.unimi.dsi.fastutil.objects.Object2FloatMap; +import it.unimi.dsi.fastutil.objects.Object2FloatMaps; +import it.unimi.dsi.fastutil.objects.Object2FloatOpenCustomHashMap; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.concurrent.ThreadFactory; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class WorldUpgrader { + + private static final Logger LOGGER = LogManager.getLogger(); + private static final ThreadFactory b = (new ThreadFactoryBuilder()).setDaemon(true).build(); + private final String c; + private final boolean d; + private final WorldNBTStorage e; + private final Thread f; + private final File g; + private volatile boolean h = true; + private volatile boolean i; + private volatile float j; + private volatile int k; + private volatile int l; + private volatile int m; + private final Object2FloatMap n = Object2FloatMaps.synchronize(new Object2FloatOpenCustomHashMap(SystemUtils.i())); + private volatile IChatBaseComponent o = new ChatMessage("optimizeWorld.stage.counting", new Object[0]); + private static final Pattern p = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$"); + private final WorldPersistentData q; + + public WorldUpgrader(String s, Convertable convertable, WorldData worlddata, boolean flag) { + this.c = worlddata.getName(); + this.d = flag; + this.e = convertable.a(s, (MinecraftServer) null); + this.e.saveWorldData(worlddata); + this.q = new WorldPersistentData(new File(DimensionManager.OVERWORLD.a(this.e.getDirectory()), "data"), this.e.getDataFixer()); + this.g = this.e.getDirectory(); + this.f = WorldUpgrader.b.newThread(this::i); + this.f.setUncaughtExceptionHandler((thread, throwable) -> { + WorldUpgrader.LOGGER.error("Error upgrading world", throwable); + this.o = new ChatMessage("optimizeWorld.stage.failed", new Object[0]); + }); + this.f.start(); + } + + public void a() { + this.h = false; + + try { + this.f.join(); + } catch (InterruptedException interruptedexception) { + ; + } + + } + + private void i() { + File file = this.e.getDirectory(); + + this.k = 0; + Builder> builder = ImmutableMap.builder(); + + List list; + + for (Iterator iterator = DimensionManager.a().iterator(); iterator.hasNext(); this.k += list.size()) { + DimensionManager dimensionmanager = (DimensionManager) iterator.next(); + + list = this.b(dimensionmanager); + builder.put(dimensionmanager, list.listIterator()); + } + + if (this.k == 0) { + this.i = true; + } else { + float f = (float) this.k; + ImmutableMap> immutablemap = builder.build(); + Builder builder1 = ImmutableMap.builder(); + Iterator iterator1 = DimensionManager.a().iterator(); + + while (iterator1.hasNext()) { + DimensionManager dimensionmanager1 = (DimensionManager) iterator1.next(); + File file1 = dimensionmanager1.a(file); + + builder1.put(dimensionmanager1, new IChunkLoader(new File(file1, "region"), this.e.getDataFixer())); + } + + ImmutableMap immutablemap1 = builder1.build(); + long i = SystemUtils.getMonotonicMillis(); + + this.o = new ChatMessage("optimizeWorld.stage.upgrading", new Object[0]); + + while (this.h) { + boolean flag = false; + float f1 = 0.0F; + + float f2; + + for (Iterator iterator2 = DimensionManager.a().iterator(); iterator2.hasNext(); f1 += f2) { + DimensionManager dimensionmanager2 = (DimensionManager) iterator2.next(); + ListIterator listiterator = (ListIterator) immutablemap.get(dimensionmanager2); + IChunkLoader ichunkloader = (IChunkLoader) immutablemap1.get(dimensionmanager2); + + if (listiterator.hasNext()) { + ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) listiterator.next(); + boolean flag1 = false; + + try { + NBTTagCompound nbttagcompound = ichunkloader.read(chunkcoordintpair); + + if (nbttagcompound != null) { + int j = IChunkLoader.a(nbttagcompound); + NBTTagCompound nbttagcompound1 = ichunkloader.getChunkData(dimensionmanager2, () -> { + return this.q; + }, nbttagcompound, chunkcoordintpair, null); // CraftBukkit + boolean flag2 = j < SharedConstants.a().getWorldVersion(); + + if (this.d) { + NBTTagCompound nbttagcompound2 = nbttagcompound1.getCompound("Level"); + + flag2 = flag2 || nbttagcompound2.hasKey("Heightmaps"); + nbttagcompound2.remove("Heightmaps"); + flag2 = flag2 || nbttagcompound2.hasKey("isLightOn"); + nbttagcompound2.remove("isLightOn"); + } + + if (flag2) { + ichunkloader.write(chunkcoordintpair, nbttagcompound1); + flag1 = true; + } + } + } catch (ReportedException reportedexception) { + Throwable throwable = reportedexception.getCause(); + + if (!(throwable instanceof IOException)) { + throw reportedexception; + } + + WorldUpgrader.LOGGER.error("Error upgrading chunk {}", chunkcoordintpair, throwable); + } catch (IOException ioexception) { + WorldUpgrader.LOGGER.error("Error upgrading chunk {}", chunkcoordintpair, ioexception); + } + + if (flag1) { + ++this.l; + } else { + ++this.m; + } + + flag = true; + } + + f2 = (float) listiterator.nextIndex() / f; + this.n.put(dimensionmanager2, f2); + } + + this.j = f1; + if (!flag) { + this.h = false; + } + } + + this.o = new ChatMessage("optimizeWorld.stage.finished", new Object[0]); + UnmodifiableIterator unmodifiableiterator = immutablemap1.values().iterator(); + + while (unmodifiableiterator.hasNext()) { + IChunkLoader ichunkloader1 = (IChunkLoader) unmodifiableiterator.next(); + + try { + ichunkloader1.close(); + } catch (IOException ioexception1) { + WorldUpgrader.LOGGER.error("Error upgrading chunk", ioexception1); + } + } + + this.q.a(); + i = SystemUtils.getMonotonicMillis() - i; + WorldUpgrader.LOGGER.info("World optimizaton finished after {} ms", i); + this.i = true; + } + } + + private List b(DimensionManager dimensionmanager) { + File file = dimensionmanager.a(this.g); + File file1 = new File(file, "region"); + File[] afile = file1.listFiles((file2, s) -> { + return s.endsWith(".mca"); + }); + + if (afile == null) { + return ImmutableList.of(); + } else { + List list = Lists.newArrayList(); + File[] afile1 = afile; + int i = afile.length; + + for (int j = 0; j < i; ++j) { + File file2 = afile1[j]; + Matcher matcher = WorldUpgrader.p.matcher(file2.getName()); + + if (matcher.matches()) { + int k = Integer.parseInt(matcher.group(1)) << 5; + int l = Integer.parseInt(matcher.group(2)) << 5; + + try { + RegionFile regionfile = new RegionFile(file2); + Throwable throwable = null; + + try { + for (int i1 = 0; i1 < 32; ++i1) { + for (int j1 = 0; j1 < 32; ++j1) { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i1 + k, j1 + l); + + if (regionfile.b(chunkcoordintpair)) { + list.add(chunkcoordintpair); + } + } + } + } catch (Throwable throwable1) { + throwable = throwable1; + throw throwable1; + } finally { + if (regionfile != null) { + if (throwable != null) { + try { + regionfile.close(); + } catch (Throwable throwable2) { + throwable.addSuppressed(throwable2); + } + } else { + regionfile.close(); + } + } + + } + } catch (Throwable throwable3) { + ; + } + } + } + + return list; + } + } + + public boolean b() { + return this.i; + } + + public int d() { + return this.k; + } + + public int e() { + return this.l; + } + + public int f() { + return this.m; + } + + public IChatBaseComponent g() { + return this.o; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java index 280fe935c..373bea4b6 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -3,35 +3,52 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; import java.lang.ref.WeakReference; import java.util.Arrays; - -import java.util.Random; -import net.minecraft.server.*; - +import java.util.Collection; +import net.minecraft.server.BiomeBase; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.Blocks; +import net.minecraft.server.ChunkSection; +import net.minecraft.server.DataPaletteBlock; +import net.minecraft.server.EnumSkyBlock; +import net.minecraft.server.GameProfileSerializer; +import net.minecraft.server.HeightMap; +import net.minecraft.server.IBlockData; +import net.minecraft.server.LightEngine; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NibbleArray; +import net.minecraft.server.SectionPosition; +import net.minecraft.server.SeededRandom; +import net.minecraft.server.WorldChunkManager; +import net.minecraft.server.WorldServer; import org.bukkit.Chunk; +import org.bukkit.ChunkSnapshot; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockState; +import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.entity.Entity; -import org.bukkit.ChunkSnapshot; +import org.bukkit.plugin.Plugin; public class CraftChunk implements Chunk { private WeakReference weakChunk; private final WorldServer worldServer; private final int x; private final int z; - private static final byte[] emptyData = new byte[2048]; - private static final DataPaletteBlock emptyBlockIDs = new ChunkSection(0, false).getBlocks(); - private static final byte[] emptySkyLight = new byte[2048]; + private static final DataPaletteBlock emptyBlockIDs = new ChunkSection(0).getBlocks(); + private static final byte[] emptyLight = new byte[2048]; public CraftChunk(net.minecraft.server.Chunk chunk) { this.weakChunk = new WeakReference(chunk); worldServer = (WorldServer) getHandle().world; - x = getHandle().locX; - z = getHandle().locZ; + x = getHandle().getPos().x; + z = getHandle().getPos().z; } + @Override public World getWorld() { return worldServer.getWorld(); } @@ -56,10 +73,12 @@ public class CraftChunk implements Chunk { weakChunk.clear(); } + @Override public int getX() { return x; } + @Override public int getZ() { return z; } @@ -69,13 +88,18 @@ public class CraftChunk implements Chunk { return "CraftChunk{" + "x=" + getX() + "z=" + getZ() + '}'; } + @Override public Block getBlock(int x, int y, int z) { validateChunkCoordinates(x, y, z); return new CraftBlock(worldServer, new BlockPosition((this.x << 4) | x, y, (this.z << 4) | z)); } + @Override public Entity[] getEntities() { + if (!isLoaded()) { + getWorld().getChunkAt(x, z); // Transient load for this tick + } int count = 0, index = 0; net.minecraft.server.Chunk chunk = getHandle(); @@ -86,24 +110,30 @@ public class CraftChunk implements Chunk { Entity[] entities = new Entity[count]; for (int i = 0; i < 16; i++) { - - for (Object obj : chunk.entitySlices[i].toArray()) { - if (!(obj instanceof net.minecraft.server.Entity)) { + // Paper start - speed up (was with chunk.entitySlices[i].toArray() and cast checks which costs a lot of performance if called often) + for (net.minecraft.server.Entity entity : chunk.entitySlices[i]) { + if (entity == null) { continue; } - - entities[index++] = ((net.minecraft.server.Entity) obj).getBukkitEntity(); + entities[index++] = entity.getBukkitEntity(); } + // Paper end } return entities; } - // Paper start + @Override public BlockState[] getTileEntities() { + // Paper start return getTileEntities(true); } + + @Override public BlockState[] getTileEntities(boolean useSnapshot) { + if (!isLoaded()) { + getWorld().getChunkAt(x, z); // Transient load for this tick + } // Paper end int index = 0; net.minecraft.server.Chunk chunk = getHandle(); @@ -116,24 +146,28 @@ public class CraftChunk implements Chunk { } BlockPosition position = (BlockPosition) obj; - entities[index++] = worldServer.getWorld().getBlockAt(position).getState(useSnapshot); // Paper // Akarin + entities[index++] = worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(useSnapshot); // Paper } return entities; } + @Override public boolean isLoaded() { return getWorld().isChunkLoaded(this); } + @Override public boolean load() { return getWorld().loadChunk(getX(), getZ(), true); } + @Override public boolean load(boolean generate) { return getWorld().loadChunk(getX(), getZ(), generate); } + @Override public boolean unload() { return getWorld().unloadChunk(getX(), getZ()); } @@ -144,14 +178,11 @@ public class CraftChunk implements Chunk { return SeededRandom.a(getX(), getZ(), getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; } + @Override public boolean unload(boolean save) { return getWorld().unloadChunk(getX(), getZ(), save); } - public boolean unload(boolean save, boolean safe) { - return getWorld().unloadChunk(getX(), getZ(), save, safe); - } - @Override public boolean isForceLoaded() { return getWorld().isChunkForceLoaded(getX(), getZ()); @@ -162,10 +193,53 @@ public class CraftChunk implements Chunk { getWorld().setChunkForceLoaded(getX(), getZ(), forced); } + @Override + public boolean addPluginChunkTicket(Plugin plugin) { + return getWorld().addPluginChunkTicket(getX(), getZ(), plugin); + } + + @Override + public boolean removePluginChunkTicket(Plugin plugin) { + return getWorld().removePluginChunkTicket(getX(), getZ(), plugin); + } + + @Override + public Collection getPluginChunkTickets() { + return getWorld().getPluginChunkTickets(getX(), getZ()); + } + + @Override + public long getInhabitedTime() { + return getHandle().q(); + } + + @Override + public void setInhabitedTime(long ticks) { + Preconditions.checkArgument(ticks >= 0, "ticks cannot be negative"); + + getHandle().b(ticks); + } + + @Override + public boolean contains(BlockData block) { + Preconditions.checkArgument(block != null, "Block cannot be null"); + + IBlockData nms = ((CraftBlockData) block).getState(); + for (ChunkSection section : getHandle().getSections()) { + if (section != null && section.getBlocks().a(nms)) { + return true; + } + } + + return false; + } + + @Override public ChunkSnapshot getChunkSnapshot() { return getChunkSnapshot(true, false, false); } + @Override public ChunkSnapshot getChunkSnapshot(boolean includeMaxBlockY, boolean includeBiome, boolean includeBiomeTempRain) { net.minecraft.server.Chunk chunk = getHandle(); @@ -178,34 +252,41 @@ public class CraftChunk implements Chunk { for (int i = 0; i < cs.length; i++) { if (cs[i] == null) { // Section is empty? sectionBlockIDs[i] = emptyBlockIDs; - sectionSkyLights[i] = emptySkyLight; - sectionEmitLights[i] = emptyData; + sectionSkyLights[i] = emptyLight; + sectionEmitLights[i] = emptyLight; sectionEmpty[i] = true; } else { // Not empty NBTTagCompound data = new NBTTagCompound(); - cs[i].getBlocks().b(data, "Spigot", "Magic"); + cs[i].getBlocks().a(data, "Palette", "BlockStates"); DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData()); // TODO: snapshot whole ChunkSection - blockids.a(data, "Spigot", "Magic"); + blockids.a(data.getList("Palette", CraftMagicNumbers.NBT.TAG_COMPOUND), data.getLongArray("BlockStates")); sectionBlockIDs[i] = blockids; - if (cs[i].getSkyLightArray() == null) { - sectionSkyLights[i] = emptySkyLight; + LightEngine lightengine = chunk.world.getChunkProvider().getLightEngine(); + NibbleArray skyLightArray = lightengine.a(EnumSkyBlock.SKY).a(SectionPosition.a(x, i, z)); + if (skyLightArray == null) { + sectionSkyLights[i] = emptyLight; } else { sectionSkyLights[i] = new byte[2048]; - System.arraycopy(cs[i].getSkyLightArray().asBytes(), 0, sectionSkyLights[i], 0, 2048); + System.arraycopy(skyLightArray.asBytes(), 0, sectionSkyLights[i], 0, 2048); + } + NibbleArray emitLightArray = lightengine.a(EnumSkyBlock.BLOCK).a(SectionPosition.a(x, i, z)); + if (emitLightArray == null) { + sectionEmitLights[i] = emptyLight; + } else { + sectionEmitLights[i] = new byte[2048]; + System.arraycopy(emitLightArray.asBytes(), 0, sectionEmitLights[i], 0, 2048); } - sectionEmitLights[i] = new byte[2048]; - System.arraycopy(cs[i].getEmittedLightArray().asBytes(), 0, sectionEmitLights[i], 0, 2048); } } HeightMap hmap = null; if (includeMaxBlockY) { - hmap = new HeightMap(null, HeightMap.Type.LIGHT_BLOCKING); - hmap.a(chunk.heightMap.get(HeightMap.Type.LIGHT_BLOCKING).b()); + hmap = new HeightMap(null, HeightMap.Type.MOTION_BLOCKING); + hmap.a(chunk.heightMap.get(HeightMap.Type.MOTION_BLOCKING).a()); } BiomeBase[] biome = null; @@ -268,16 +349,16 @@ public class CraftChunk implements Chunk { for (int i = 0; i < hSection; i++) { blockIDs[i] = emptyBlockIDs; - skyLight[i] = emptySkyLight; - emitLight[i] = emptyData; + skyLight[i] = emptyLight; + emitLight[i] = emptyLight; empty[i] = true; } - return new CraftChunkSnapshot(x, z, world.getName(), world.getFullTime(), blockIDs, skyLight, emitLight, empty, new HeightMap(null, HeightMap.Type.LIGHT_BLOCKING), biome, biomeTemp); + return new CraftChunkSnapshot(x, z, world.getName(), world.getFullTime(), blockIDs, skyLight, emitLight, empty, new HeightMap(null, HeightMap.Type.MOTION_BLOCKING), biome, biomeTemp); } private static float[] getTemperatures(WorldChunkManager chunkmanager, int chunkX, int chunkZ) { - BiomeBase[] biomes = chunkmanager.getBiomes(chunkX, chunkZ, 16, 16); + BiomeBase[] biomes = chunkmanager.getBiomeBlock(chunkX, chunkZ, 16, 16); float[] temps = new float[biomes.length]; for (int i = 0; i < biomes.length; i++) { @@ -300,6 +381,6 @@ public class CraftChunk implements Chunk { } static { - Arrays.fill(emptySkyLight, (byte) 0xFF); + Arrays.fill(emptyLight, (byte) 0xFF); } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java index f3be8c202..8cf0502af 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java @@ -1,6 +1,10 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; +import net.minecraft.server.BiomeBase; +import net.minecraft.server.DataPaletteBlock; +import net.minecraft.server.HeightMap; +import net.minecraft.server.IBlockData; import org.bukkit.ChunkSnapshot; import org.bukkit.Material; import org.bukkit.block.Biome; @@ -9,11 +13,6 @@ import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.util.CraftMagicNumbers; -import net.minecraft.server.BiomeBase; -import net.minecraft.server.DataPaletteBlock; -import net.minecraft.server.HeightMap; -import net.minecraft.server.IBlockData; - /** * Represents a static, thread-safe snapshot of chunk of blocks * Purpose is to allow clean, efficient copy of a chunk data to be made, and then handed off for processing in another thread (e.g. map rendering) @@ -44,18 +43,35 @@ public class CraftChunkSnapshot implements ChunkSnapshot { this.biomeTemp = biomeTemp; } + @Override public int getX() { return x; } + @Override public int getZ() { return z; } + @Override public String getWorldName() { return worldname; } + @Override + public boolean contains(BlockData block) { + Preconditions.checkArgument(block != null, "Block cannot be null"); + + IBlockData nms = ((CraftBlockData) block).getState(); + for (DataPaletteBlock palette : blockids) { + if (palette.a(nms)) { + return true; + } + } + + return false; + } + @Override public Material getBlockType(int x, int y, int z) { CraftChunk.validateChunkCoordinates(x, y, z); @@ -77,6 +93,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot { return CraftMagicNumbers.toLegacyData(blockids[y >> 4].a(x, y & 0xF, z)); } + @Override public final int getBlockSkyLight(int x, int y, int z) { CraftChunk.validateChunkCoordinates(x, y, z); @@ -84,6 +101,7 @@ public class CraftChunkSnapshot implements ChunkSnapshot { return (skylight[y >> 4][off] >> ((x & 1) << 2)) & 0xF; } + @Override public final int getBlockEmittedLight(int x, int y, int z) { CraftChunk.validateChunkCoordinates(x, y, z); @@ -91,28 +109,36 @@ public class CraftChunkSnapshot implements ChunkSnapshot { return (emitlight[y >> 4][off] >> ((x & 1) << 2)) & 0xF; } + @Override public final int getHighestBlockYAt(int x, int z) { + Preconditions.checkState(hmap != null, "ChunkSnapshot created without height map. Please call getSnapshot with includeMaxblocky=true"); CraftChunk.validateChunkCoordinates(x, 0, z); return hmap.a(x, z); } + @Override public final Biome getBiome(int x, int z) { + Preconditions.checkState(biome != null, "ChunkSnapshot created without biome. Please call getSnapshot with includeBiome=true"); CraftChunk.validateChunkCoordinates(x, 0, z); return CraftBlock.biomeBaseToBiome(biome[z << 4 | x]); } + @Override public final double getRawBiomeTemperature(int x, int z) { + Preconditions.checkState(biomeTemp != null, "ChunkSnapshot created without biome temperatures. Please call getSnapshot with includeBiomeTempRain=true"); CraftChunk.validateChunkCoordinates(x, 0, z); return biomeTemp[z << 4 | x]; } + @Override public final long getCaptureFullTime() { return captureFulltime; } + @Override public final boolean isSectionEmpty(int sy) { return empty[sy]; } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java b/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java index 921a57f5a..7511e3813 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java @@ -3,19 +3,20 @@ package org.bukkit.craftbukkit; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Arrays; +import java.util.Collection; import java.util.Map; -import java.util.concurrent.Callable; import net.minecraft.server.CrashReportCallable; - +import net.minecraft.server.MinecraftServer; import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.World; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; -import net.minecraft.server.MinecraftServer; -import org.bukkit.craftbukkit.util.CraftMagicNumbers; - public class CraftCrashReport implements CrashReportCallable { + @Override public Object call() throws Exception { StringWriter value = new StringWriter(); try { @@ -33,6 +34,15 @@ public class CraftCrashReport implements CrashReportCallable { value.append(' ').append(entry.getKey().getState().name()).append(' ').append(entry.getKey().getName()).append(": ").append(Arrays.toString(entry.getValue())).append(','); } value.append("}\n ").append(Bukkit.getScheduler().toString()); + value.append("\n Force Loaded Chunks: {"); + for (World world : Bukkit.getWorlds()) { + value.append(' ').append(world.getName()).append(": {"); + for (Map.Entry> entry : world.getPluginChunkTickets().entrySet()) { + value.append(' ').append(entry.getKey().getDescription().getFullName()).append(": ").append(Integer.toString(entry.getValue().size())).append(','); + } + value.append("},"); + } + value.append("}"); } catch (Throwable t) { value.append("\n Failed to handle CraftCrashReport:\n"); PrintWriter writer = new PrintWriter(value); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftEffect.java b/src/main/java/org/bukkit/craftbukkit/CraftEffect.java index c6edd7a50..8345587b5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftEffect.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftEffect.java @@ -20,7 +20,7 @@ public class CraftEffect { datavalue = ((Potion) data).toDamageValue() & 0x3F; break; case RECORD_PLAY: - Validate.isTrue(((Material) data).isRecord(), "Invalid record type!"); + Validate.isTrue(data == Material.AIR || ((Material) data).isRecord(), "Invalid record type!"); datavalue = Item.getId(CraftMagicNumbers.getItem((Material) data)); break; case SMOKE: diff --git a/src/main/java/org/bukkit/craftbukkit/CraftFluidCollisionMode.java b/src/main/java/org/bukkit/craftbukkit/CraftFluidCollisionMode.java index faf2fd4ec..5a51d6abd 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftFluidCollisionMode.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftFluidCollisionMode.java @@ -1,7 +1,7 @@ package org.bukkit.craftbukkit; +import net.minecraft.server.RayTrace.FluidCollisionOption; import org.bukkit.FluidCollisionMode; -import net.minecraft.server.FluidCollisionOption; public class CraftFluidCollisionMode { @@ -12,11 +12,11 @@ public class CraftFluidCollisionMode { switch (fluidCollisionMode) { case ALWAYS: - return FluidCollisionOption.ALWAYS; + return FluidCollisionOption.ANY; case SOURCE_ONLY: return FluidCollisionOption.SOURCE_ONLY; case NEVER: - return FluidCollisionOption.NEVER; + return FluidCollisionOption.NONE; default: return null; } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java b/src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java index 7a8ea3bd0..372404cd1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java @@ -1,12 +1,10 @@ package org.bukkit.craftbukkit; -import net.minecraft.server.IpBanEntry; -import net.minecraft.server.IpBanList; -import net.minecraft.server.MinecraftServer; - import java.io.IOException; import java.util.Date; import java.util.logging.Level; +import net.minecraft.server.IpBanEntry; +import net.minecraft.server.IpBanList; import org.bukkit.Bukkit; public final class CraftIpBanEntry implements org.bukkit.BanEntry { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java b/src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java index 80832f78a..101a32555 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java @@ -1,18 +1,15 @@ package org.bukkit.craftbukkit; +import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Date; import java.util.Set; - +import java.util.logging.Level; import net.minecraft.server.IpBanEntry; import net.minecraft.server.IpBanList; -import net.minecraft.server.MinecraftServer; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; - -import com.google.common.collect.ImmutableSet; -import java.util.logging.Level; import org.bukkit.Bukkit; public class CraftIpBanList implements org.bukkit.BanList { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java b/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java index d76fe60fb..0064d9327 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java @@ -9,6 +9,8 @@ import net.minecraft.server.DamageSource; import net.minecraft.server.Entity; import net.minecraft.server.EntityHuman; import net.minecraft.server.IInventory; +import net.minecraft.server.LootContextParameterSets; +import net.minecraft.server.LootContextParameters; import net.minecraft.server.LootTable; import net.minecraft.server.LootTableInfo; import net.minecraft.server.WorldServer; @@ -39,7 +41,7 @@ public class CraftLootTable implements org.bukkit.loot.LootTable { @Override public Collection populateLoot(Random random, LootContext context) { LootTableInfo nmsContext = convertContext(context); - List nmsItems = handle.populateLoot(random, nmsContext); + List nmsItems = handle.populateLoot(nmsContext); Collection bukkit = new ArrayList<>(nmsItems.size()); for (net.minecraft.server.ItemStack item : nmsItems) { @@ -59,7 +61,7 @@ public class CraftLootTable implements org.bukkit.loot.LootTable { IInventory handle = craftInventory.getInventory(); // TODO: When events are added, call event here w/ custom reason? - getHandle().fillInventory(handle, random, nmsContext); + getHandle().fillInventory(handle, nmsContext); } @Override @@ -72,23 +74,25 @@ public class CraftLootTable implements org.bukkit.loot.LootTable { WorldServer handle = ((CraftWorld) loc.getWorld()).getHandle(); LootTableInfo.Builder builder = new LootTableInfo.Builder(handle); - builder.luck(context.getLuck()); + if (getHandle() != LootTable.a) { // PAIL - empty + // builder.luck(context.getLuck()); - if (context.getLootedEntity() != null) { - Entity nmsLootedEntity = ((CraftEntity) context.getLootedEntity()).getHandle(); - builder.entity(nmsLootedEntity); - builder.damageSource(DamageSource.GENERIC); - builder.position(new BlockPosition(nmsLootedEntity)); + if (context.getLootedEntity() != null) { + Entity nmsLootedEntity = ((CraftEntity) context.getLootedEntity()).getHandle(); + builder.set(LootContextParameters.THIS_ENTITY, nmsLootedEntity); + builder.set(LootContextParameters.DAMAGE_SOURCE, DamageSource.GENERIC); + builder.set(LootContextParameters.POSITION, new BlockPosition(nmsLootedEntity)); + } + + if (context.getKiller() != null) { + EntityHuman nmsKiller = ((CraftHumanEntity) context.getKiller()).getHandle(); + builder.set(LootContextParameters.KILLER_ENTITY, nmsKiller); + // If there is a player killer, damage source should reflect that in case loot tables use that information + builder.set(LootContextParameters.DAMAGE_SOURCE, DamageSource.playerAttack(nmsKiller)); + } } - if (context.getKiller() != null) { - EntityHuman nmsKiller = ((CraftHumanEntity) context.getKiller()).getHandle(); - builder.killer(nmsKiller); - // If there is a player killer, damage source should reflect that in case loot tables use that information - builder.damageSource(DamageSource.playerAttack(nmsKiller)); - } - - return builder.build(); + return builder.build(getHandle().getLootContextParameterSet()); } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java index e1973c5d6..3824180ee 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -6,12 +6,10 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; - import net.minecraft.server.DimensionManager; import net.minecraft.server.NBTTagCompound; import net.minecraft.server.WhiteListEntry; import net.minecraft.server.WorldNBTStorage; - import org.bukkit.BanList; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -40,10 +38,12 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa return profile; } + @Override public boolean isOnline() { return getPlayer() != null; } + @Override public String getName() { Player player = getPlayer(); if (player != null) { @@ -66,6 +66,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa return null; } + @Override public UUID getUniqueId() { return profile.getId(); } @@ -74,10 +75,12 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa return server; } + @Override public boolean isOp() { return server.getHandle().isOp(profile); } + @Override public void setOp(boolean value) { if (value == isOp()) { return; @@ -90,6 +93,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } } + @Override public boolean isBanned() { if (getName() == null) { return false; @@ -110,10 +114,12 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } } + @Override public boolean isWhitelisted() { return server.getHandle().getWhitelist().isWhitelisted(profile); } + @Override public void setWhitelisted(boolean value) { if (value) { server.getHandle().getWhitelist().add(new WhiteListEntry(profile)); @@ -122,6 +128,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } } + @Override public Map serialize() { Map result = new LinkedHashMap(); @@ -144,6 +151,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa return getClass().getSimpleName() + "[UUID=" + profile.getId() + "]"; } + @Override public Player getPlayer() { return server.getPlayer(getUniqueId()); } @@ -205,6 +213,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa return new File(getStorageLazy().getPlayerDir(), getUniqueId() + ".dat"); } + @Override public long getFirstPlayed() { Player player = getPlayer(); if (player != null) return player.getFirstPlayed(); @@ -223,6 +232,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } } + @Override public long getLastPlayed() { Player player = getPlayer(); if (player != null) return player.getLastPlayed(); @@ -241,6 +251,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } } + @Override public boolean hasPlayedBefore() { return getData() != null; } @@ -300,6 +311,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } // Paper end + @Override public Location getBedSpawnLocation() { NBTTagCompound data = getData(); if (data == null) return null; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftParticle.java b/src/main/java/org/bukkit/craftbukkit/CraftParticle.java index f4c52bf65..99377033b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftParticle.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftParticle.java @@ -76,6 +76,14 @@ public enum CraftParticle { BUBBLE_COLUMN_UP("bubble_column_up"), NAUTILUS("nautilus"), DOLPHIN("dolphin"), + SNEEZE("sneeze"), + CAMPFIRE_COSY_SMOKE("campfire_cosy_smoke"), + CAMPFIRE_SIGNAL_SMOKE("campfire_signal_smoke"), + COMPOSTER("composter"), + FLASH("flash"), + FALLING_LAVA("falling_lava"), + LANDING_LAVA("landing_lava"), + FALLING_WATER("falling_water"), // ----- Legacy Separator ----- LEGACY_BLOCK_CRACK("block"), LEGACY_BLOCK_DUST("block"), @@ -143,10 +151,10 @@ public enum CraftParticle { } public static Particle toBukkit(net.minecraft.server.ParticleParam nms) { - return toBukkit(nms.b()); + return toBukkit(nms.getParticle()); } public static Particle toBukkit(net.minecraft.server.Particle nms) { - return particles.inverse().get(nms.d()); + return particles.inverse().get(IRegistry.PARTICLE_TYPE.getKey(nms)); } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftProfileBanEntry.java b/src/main/java/org/bukkit/craftbukkit/CraftProfileBanEntry.java index 3c6f9229f..bbe91bca1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftProfileBanEntry.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftProfileBanEntry.java @@ -1,13 +1,11 @@ package org.bukkit.craftbukkit; import com.mojang.authlib.GameProfile; -import net.minecraft.server.GameProfileBanEntry; -import net.minecraft.server.GameProfileBanList; -import net.minecraft.server.MinecraftServer; - import java.io.IOException; import java.util.Date; import java.util.logging.Level; +import net.minecraft.server.GameProfileBanEntry; +import net.minecraft.server.GameProfileBanList; import org.bukkit.Bukkit; public final class CraftProfileBanEntry implements org.bukkit.BanEntry { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftProfileBanList.java b/src/main/java/org/bukkit/craftbukkit/CraftProfileBanList.java index 356413980..3938d920b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftProfileBanList.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftProfileBanList.java @@ -1,22 +1,18 @@ package org.bukkit.craftbukkit; +import com.google.common.collect.ImmutableSet; +import com.mojang.authlib.GameProfile; import java.io.IOException; import java.util.Date; import java.util.Set; - +import java.util.UUID; +import java.util.logging.Level; import net.minecraft.server.GameProfileBanEntry; import net.minecraft.server.GameProfileBanList; import net.minecraft.server.JsonListEntry; import net.minecraft.server.MinecraftServer; - import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; - -import com.google.common.collect.ImmutableSet; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.ProfileLookupCallback; - -import java.util.logging.Level; import org.bukkit.Bukkit; public class CraftProfileBanList implements org.bukkit.BanList { @@ -30,7 +26,7 @@ public class CraftProfileBanList implements org.bukkit.BanList { public org.bukkit.BanEntry getBanEntry(String target) { Validate.notNull(target, "Target cannot be null"); - GameProfile profile = MinecraftServer.getServer().getModernUserCache().acquire(target); + GameProfile profile = getProfile(target); if (profile == null) { return null; } @@ -47,29 +43,30 @@ public class CraftProfileBanList implements org.bukkit.BanList { public org.bukkit.BanEntry addBan(String target, String reason, Date expires, String source) { Validate.notNull(target, "Ban target cannot be null"); - // Akarin start - MinecraftServer.getServer().getModernUserCache().acquire(target, profile -> { - GameProfileBanEntry entry = new GameProfileBanEntry(profile, new Date(), - StringUtils.isBlank(source) ? null : source, expires, - StringUtils.isBlank(reason) ? null : reason); + GameProfile profile = getProfile(target); + if (profile == null) { + return null; + } - list.add(entry); + GameProfileBanEntry entry = new GameProfileBanEntry(profile, new Date(), + StringUtils.isBlank(source) ? null : source, expires, + StringUtils.isBlank(reason) ? null : reason); - try { - list.save(); - } catch (IOException ex) { - Bukkit.getLogger().log(Level.SEVERE, "Failed to save banned-players.json, {0}", ex.getMessage()); - } - }); + list.add(entry); - return null; - // Akarin end + try { + list.save(); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Failed to save banned-players.json, {0}", ex.getMessage()); + } + + return new CraftProfileBanEntry(profile, entry, list); } @Override public Set getBanEntries() { ImmutableSet.Builder builder = ImmutableSet.builder(); - + for (JsonListEntry entry : list.getValues()) { GameProfile profile = (GameProfile) entry.getKey(); builder.add(new CraftProfileBanEntry(profile, (GameProfileBanEntry) entry, list)); @@ -82,7 +79,7 @@ public class CraftProfileBanList implements org.bukkit.BanList { public boolean isBanned(String target) { Validate.notNull(target, "Target cannot be null"); - GameProfile profile = MinecraftServer.getServer().getModernUserCache().acquire(target);// Akarin + GameProfile profile = getProfile(target); if (profile == null) { return false; } @@ -94,9 +91,19 @@ public class CraftProfileBanList implements org.bukkit.BanList { public void pardon(String target) { Validate.notNull(target, "Target cannot be null"); - // Akarin start - MinecraftServer.getServer().getModernUserCache().acquire(target, profile -> list.remove(profile)); - //list.remove(profile); - // Akarin end + GameProfile profile = getProfile(target); + list.remove(profile); + } + + private GameProfile getProfile(String target) { + UUID uuid = null; + + try { + uuid = UUID.fromString(target); + } catch (IllegalArgumentException ex) { + // + } + + return (uuid != null) ? MinecraftServer.getServer().getUserCache().a(uuid) : MinecraftServer.getServer().getUserCache().getProfile(target); } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRaid.java b/src/main/java/org/bukkit/craftbukkit/CraftRaid.java new file mode 100644 index 000000000..d17cdcb1d --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/CraftRaid.java @@ -0,0 +1,101 @@ +package org.bukkit.craftbukkit; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.EntityRaider; +import net.minecraft.server.World; +import org.bukkit.Location; +import org.bukkit.Raid; +import org.bukkit.entity.Raider; + +public final class CraftRaid implements Raid { + + private final net.minecraft.server.Raid handle; + + public CraftRaid(net.minecraft.server.Raid handle) { + this.handle = handle; + } + + @Override + public boolean isStarted() { + return handle.j(); // PAIL rename isStarted + } + + @Override + public long getActiveTicks() { + return handle.i; + } + + @Override + public int getBadOmenLevel() { + return handle.o; + } + + @Override + public void setBadOmenLevel(int badOmenLevel) { + int max = handle.l(); // PAIL rename getMaxBadOmenLevel + Preconditions.checkArgument(0 <= badOmenLevel && badOmenLevel <= max, "Bad Omen level must be between 0 and %s", max); + handle.o = badOmenLevel; + } + + @Override + public Location getLocation() { + BlockPosition pos = handle.t(); // PAIL rename getCenterLocation + World world = handle.i(); // PAIL rename getWorld + return new Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()); + } + + @Override + public RaidStatus getStatus() { + if (handle.d()) { // PAIL rename isStopped + return RaidStatus.STOPPED; + } else if (handle.e()) { // PAIL rename isVictory + return RaidStatus.VICTORY; + } else if (handle.f()) { // PAIL rename isLoss + return RaidStatus.LOSS; + } else { + return RaidStatus.ONGOING; + } + } + + @Override + public int getSpawnedGroups() { + return handle.k(); // PAIL rename countSpawnedGroups + } + + @Override + public int getTotalGroups() { + return handle.v + (handle.o > 1 ? 1 : 0); + } + + @Override + public int getTotalWaves() { + return handle.v; + } + + @Override + public float getTotalHealth() { + return handle.q(); // PAIL rename sumMobHealth + } + + @Override + public Set getHeroes() { + return Collections.unmodifiableSet(handle.h); + } + + @Override + public List getRaiders() { + return handle.getRaiders().stream().map(new Function() { + @Override + public Raider apply(EntityRaider entityRaider) { + return (Raider) entityRaider.getBukkitEntity(); + } + }).collect(ImmutableList.toImmutableList()); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 5ccf55e4a..105d31906 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1,14 +1,33 @@ package org.bukkit.craftbukkit; +import com.google.common.base.Charsets; +import com.google.common.base.Function; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.google.common.collect.MapMaker; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.mojang.authlib.GameProfile; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.tree.CommandNode; +import com.mojang.brigadier.tree.LiteralCommandNode; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufOutputStream; +import io.netty.buffer.Unpooled; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; +import java.util.Base64; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; @@ -21,25 +40,60 @@ import java.util.UUID; import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Pattern; - import javax.imageio.ImageIO; - -import net.minecraft.server.*; - +import net.minecraft.server.Advancement; +import net.minecraft.server.ArgumentEntity; +import net.minecraft.server.Block; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.BossBattleCustom; +import net.minecraft.server.CommandDispatcher; +import net.minecraft.server.CommandListenerWrapper; +import net.minecraft.server.DedicatedPlayerList; +import net.minecraft.server.DedicatedServer; +import net.minecraft.server.DedicatedServerProperties; +import net.minecraft.server.DedicatedServerSettings; +import net.minecraft.server.DimensionManager; +import net.minecraft.server.Enchantments; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.EnumDifficulty; +import net.minecraft.server.EnumGamemode; +import net.minecraft.server.Item; +import net.minecraft.server.ItemWorldMap; +import net.minecraft.server.Items; +import net.minecraft.server.JsonListEntry; +import net.minecraft.server.LootTableRegistry; +import net.minecraft.server.MapIcon; +import net.minecraft.server.MinecraftKey; +import net.minecraft.server.MobEffects; +import net.minecraft.server.PlayerList; +import net.minecraft.server.ServerCommand; +import net.minecraft.server.TagsServer; +import net.minecraft.server.TicketType; +import net.minecraft.server.Vec3D; +import net.minecraft.server.WorldData; +import net.minecraft.server.WorldMap; +import net.minecraft.server.WorldNBTStorage; +import net.minecraft.server.WorldServer; +import net.minecraft.server.WorldSettings; +import net.minecraft.server.WorldType; +import org.apache.commons.lang.Validate; +import org.apache.commons.lang3.StringUtils; import org.bukkit.BanList; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; +import org.bukkit.Keyed; import org.bukkit.Location; +import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; import org.bukkit.Server; +import org.bukkit.StructureType; import org.bukkit.UnsafeValues; import org.bukkit.Warning.WarningState; import org.bukkit.World; -import org.bukkit.StructureType; import org.bukkit.World.Environment; import org.bukkit.WorldCreator; +import org.bukkit.block.data.BlockData; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarFlag; import org.bukkit.boss.BarStyle; @@ -55,20 +109,28 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.conversations.Conversable; +import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.boss.CraftBossBar; import org.bukkit.craftbukkit.boss.CraftKeyedBossbar; +import org.bukkit.craftbukkit.command.BukkitCommandWrapper; +import org.bukkit.craftbukkit.command.CraftCommandMap; +import org.bukkit.craftbukkit.command.VanillaCommandWrapper; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.generator.CraftChunkData; import org.bukkit.craftbukkit.help.SimpleHelpMap; +import org.bukkit.craftbukkit.inventory.CraftBlastingRecipe; +import org.bukkit.craftbukkit.inventory.CraftCampfireRecipe; import org.bukkit.craftbukkit.inventory.CraftFurnaceRecipe; -import org.bukkit.craftbukkit.inventory.CraftInventoryCustom; -import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.inventory.CraftItemFactory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.inventory.CraftMerchantCustom; import org.bukkit.craftbukkit.inventory.CraftRecipe; import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; +import org.bukkit.craftbukkit.inventory.CraftSmokingRecipe; +import org.bukkit.craftbukkit.inventory.CraftStonecuttingRecipe; import org.bukkit.craftbukkit.inventory.RecipeIterator; +import org.bukkit.craftbukkit.inventory.util.CraftInventoryCreator; import org.bukkit.craftbukkit.map.CraftMapView; import org.bukkit.craftbukkit.metadata.EntityMetadataStore; import org.bukkit.craftbukkit.metadata.PlayerMetadataStore; @@ -76,8 +138,12 @@ import org.bukkit.craftbukkit.metadata.WorldMetadataStore; import org.bukkit.craftbukkit.potion.CraftPotionBrewer; import org.bukkit.craftbukkit.scheduler.CraftScheduler; import org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager; +import org.bukkit.craftbukkit.tag.CraftBlockTag; +import org.bukkit.craftbukkit.tag.CraftItemTag; +import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.craftbukkit.util.CraftIconCache; import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.craftbukkit.util.DatFileFilter; import org.bukkit.craftbukkit.util.Versioning; import org.bukkit.craftbukkit.util.permissions.CraftDefaultPermissions; @@ -87,19 +153,25 @@ import org.bukkit.event.command.UnknownCommandEvent; // Paper import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.PlayerChatTabCompleteEvent; import org.bukkit.event.server.BroadcastMessageEvent; +import org.bukkit.event.server.ServerLoadEvent; +import org.bukkit.event.server.TabCompleteEvent; import org.bukkit.event.world.WorldInitEvent; import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.generator.ChunkGenerator; import org.bukkit.help.HelpMap; +import org.bukkit.inventory.BlastingRecipe; +import org.bukkit.inventory.CampfireRecipe; import org.bukkit.inventory.FurnaceRecipe; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.Merchant; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Merchant; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapelessRecipe; +import org.bukkit.inventory.SmokingRecipe; +import org.bukkit.inventory.StonecuttingRecipe; import org.bukkit.loot.LootTable; import org.bukkit.map.MapView; import org.bukkit.permissions.Permissible; @@ -112,65 +184,23 @@ import org.bukkit.plugin.SimplePluginManager; import org.bukkit.plugin.SimpleServicesManager; import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.plugin.messaging.Messenger; +import org.bukkit.plugin.messaging.StandardMessenger; import org.bukkit.potion.Potion; import org.bukkit.potion.PotionEffectType; -import org.bukkit.plugin.messaging.StandardMessenger; import org.bukkit.scheduler.BukkitWorker; import org.bukkit.util.StringUtil; import org.bukkit.util.permissions.DefaultPermissions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.SafeConstructor; import org.yaml.snakeyaml.error.MarkedYAMLException; -import org.apache.commons.lang.Validate; -import com.google.common.base.Charsets; -import com.google.common.base.Function; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; -import com.google.common.collect.MapMaker; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.tree.CommandNode; -import com.mojang.brigadier.tree.LiteralCommandNode; - -import co.aikar.timings.ThreadAssertion; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufOutputStream; -import io.netty.buffer.Unpooled; -import it.unimi.dsi.fastutil.longs.LongIterator; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.HashMap; -import org.bukkit.Keyed; -import org.apache.commons.lang.StringUtils; -import org.bukkit.NamespacedKey; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.block.data.CraftBlockData; -import org.bukkit.craftbukkit.command.BukkitCommandWrapper; -import org.bukkit.craftbukkit.command.CraftCommandMap; -import org.bukkit.craftbukkit.command.VanillaCommandWrapper; -import org.bukkit.craftbukkit.inventory.util.CraftInventoryCreator; -import org.bukkit.craftbukkit.tag.CraftBlockTag; -import org.bukkit.craftbukkit.tag.CraftItemTag; -import org.bukkit.craftbukkit.util.CraftChatMessage; -import org.bukkit.craftbukkit.util.CraftNamespacedKey; -import org.bukkit.event.server.ServerLoadEvent; -import org.bukkit.event.server.TabCompleteEvent; -import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.BaseComponent; // Spigot import javax.annotation.Nullable; // Paper import javax.annotation.Nonnull; // Paper - public final class CraftServer implements Server { - private final String serverName = org.apache.commons.lang3.StringUtils.isBlank(io.akarin.server.core.AkarinGlobalConfig.serverBrandName) ? "Akarin" : io.akarin.server.core.AkarinGlobalConfig.serverBrandName; // Paper // Akarin - configurable brand name + private final String serverName = "Paper"; // Paper private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); @@ -180,13 +210,13 @@ public final class CraftServer implements Server { private final SimpleHelpMap helpMap = new SimpleHelpMap(this); private final StandardMessenger messenger = new StandardMessenger(); private final SimplePluginManager pluginManager = new SimplePluginManager(this, commandMap); - protected final MinecraftServer console; + protected final DedicatedServer console; protected final DedicatedPlayerList playerList; private final Map worlds = new LinkedHashMap(); private YamlConfiguration configuration; private YamlConfiguration commandsConfiguration; private final Yaml yaml = new Yaml(new SafeConstructor()); - private final com.github.benmanes.caffeine.cache.Cache offlinePlayers = com.github.benmanes.caffeine.cache.Caffeine.newBuilder().weakValues().build(); // Akarin - caffeine + private final Map offlinePlayers = new MapMaker().weakValues().makeMap(); private final EntityMetadataStore entityMetadata = new EntityMetadataStore(); private final PlayerMetadataStore playerMetadata = new PlayerMetadataStore(); private final WorldMetadataStore worldMetadata = new WorldMetadataStore(); @@ -194,11 +224,9 @@ public final class CraftServer implements Server { private int animalSpawn = -1; private int waterAnimalSpawn = -1; private int ambientSpawn = -1; - public int chunkGCPeriod = -1; - public int chunkGCLoadThresh = 0; private File container; private WarningState warningState = WarningState.DEFAULT; - private final BooleanWrapper online = new BooleanWrapper(); + public String minimumAPI; public CraftScoreboardManager scoreboardManager; public boolean playerCommandState; private boolean printSaveWarning; @@ -209,16 +237,12 @@ public final class CraftServer implements Server { public int reloadCount; public static Exception excessiveVelEx; // Paper - Velocity warnings - private final class BooleanWrapper { - private boolean value = true; - } - static { ConfigurationSerialization.registerClass(CraftOfflinePlayer.class); CraftItemFactory.instance(); } - public CraftServer(MinecraftServer console, PlayerList playerList) { + public CraftServer(DedicatedServer console, PlayerList playerList) { this.console = console; this.playerList = (DedicatedPlayerList) playerList; this.playerView = Collections.unmodifiableList(Lists.transform(playerList.players, new Function() { @@ -228,7 +252,6 @@ public final class CraftServer implements Server { } })); this.serverVersion = CraftServer.class.getPackage().getImplementationVersion(); - online.value = console.getPropertyManager().getBoolean("online-mode", true); Bukkit.setServer(this); @@ -290,8 +313,8 @@ public final class CraftServer implements Server { ambientSpawn = configuration.getInt("spawn-limits.ambient"); console.autosavePeriod = configuration.getInt("ticks-per.autosave"); warningState = WarningState.value(configuration.getString("settings.deprecated-verbose")); - chunkGCPeriod = configuration.getInt("chunk-gc.period-in-ticks"); - chunkGCLoadThresh = configuration.getInt("chunk-gc.load-threshold"); + TicketType.PLUGIN.loadPeriod = configuration.getInt("chunk-gc.period-in-ticks"); + minimumAPI = configuration.getString("settings.minimum-api"); loadIcon(); } @@ -556,37 +579,27 @@ public final class CraftServer implements Server { // so if that changes this will need to as well @Override public int getPort() { - return this.getConfigInt("server-port", 25565); + return this.getServer().getPort(); } @Override public int getViewDistance() { - return this.getConfigInt("view-distance", 10); + return this.getProperties().viewDistance; } @Override public String getIp() { - return this.getConfigString("server-ip", ""); - } - - @Override - public String getServerName() { - return this.getConfigString("server-name", "Unknown Server"); - } - - @Override - public String getServerId() { - return this.getConfigString("server-id", "unnamed"); + return this.getServer().getServerIp(); } @Override public String getWorldType() { - return this.getConfigString("level-type", "DEFAULT"); + return this.getProperties().levelType.name(); } @Override public boolean getGenerateStructures() { - return this.getConfigBoolean("generate-structures", true); + return this.getServer().getGenerateStructures(); } @Override @@ -596,7 +609,7 @@ public final class CraftServer implements Server { @Override public boolean getAllowNether() { - return this.getConfigBoolean("allow-nether", true); + return this.getServer().getAllowNether(); } public boolean getWarnOnOverload() { @@ -609,22 +622,13 @@ public final class CraftServer implements Server { @Override public boolean hasWhitelist() { - return this.getConfigBoolean("white-list", false); + return this.getProperties().whiteList.get(); } // NOTE: Temporary calls through to server.properies until its replaced - private String getConfigString(String variable, String defaultValue) { - return this.console.getPropertyManager().getString(variable, defaultValue); + private DedicatedServerProperties getProperties() { + return this.console.getDedicatedServerProperties(); } - - private int getConfigInt(String variable, int defaultValue) { - return this.console.getPropertyManager().getInt(variable, defaultValue); - } - - private boolean getConfigBoolean(String variable, boolean defaultValue) { - return this.console.getPropertyManager().getBoolean(variable, defaultValue); - } - // End Temporary calls @Override @@ -640,7 +644,7 @@ public final class CraftServer implements Server { @Override public long getConnectionThrottle() { // Spigot Start - Automatically set connection throttle for bungee configurations - if (org.spigotmc.SpigotConfig.bungee) { + if (org.spigotmc.SpigotConfig.bungee || com.destroystokyo.paper.PaperConfig.velocitySupport) { // Paper - Velocity support return -1; } else { return this.configuration.getInt("settings.connection-throttle"); @@ -707,10 +711,10 @@ public final class CraftServer implements Server { public boolean dispatchCommand(CommandSender sender, String commandLine) { Validate.notNull(sender, "Sender cannot be null"); Validate.notNull(commandLine, "CommandLine cannot be null"); - //org.spigotmc.AsyncCatcher.catchOp( "command dispatch" ); // Spigot // Akarin + org.spigotmc.AsyncCatcher.catchOp("command dispatch"); // Spigot // Paper Start - if (!org.spigotmc.AsyncCatcher.shuttingDown && !ThreadAssertion.is() && !Bukkit.isPrimaryThread()) { // Akarin + if (!org.spigotmc.AsyncCatcher.shuttingDown && !Bukkit.isPrimaryThread()) { final CommandSender fSender = sender; final String fCommandLine = commandLine; Bukkit.getLogger().log(Level.SEVERE, "Command Dispatched Async: " + commandLine); @@ -757,28 +761,23 @@ public final class CraftServer implements Server { reloadCount++; configuration = YamlConfiguration.loadConfiguration(getConfigFile()); commandsConfiguration = YamlConfiguration.loadConfiguration(getCommandsConfigFile()); - PropertyManager config = new PropertyManager(console.options); - ((DedicatedServer) console).propertyManager = config; + console.propertyManager = new DedicatedServerSettings(console.options); + DedicatedServerProperties config = console.propertyManager.getProperties(); - boolean animals = config.getBoolean("spawn-animals", console.getSpawnAnimals()); - boolean monsters = config.getBoolean("spawn-monsters", console.getWorldServer(DimensionManager.OVERWORLD).getDifficulty() != EnumDifficulty.PEACEFUL); - EnumDifficulty difficulty = EnumDifficulty.getById(config.getInt("difficulty", console.getWorldServer(DimensionManager.OVERWORLD).getDifficulty().ordinal())); - - online.value = config.getBoolean("online-mode", console.getOnlineMode()); - console.setSpawnAnimals(config.getBoolean("spawn-animals", console.getSpawnAnimals())); - console.setPVP(config.getBoolean("pvp", console.getPVP())); - console.setAllowFlight(config.getBoolean("allow-flight", console.getAllowFlight())); - console.setMotd(config.getString("motd", console.getMotd())); + console.setSpawnAnimals(config.spawnAnimals); + console.setPVP(config.pvp); + console.setAllowFlight(config.allowFlight); + console.setMotd(config.motd); monsterSpawn = configuration.getInt("spawn-limits.monsters"); animalSpawn = configuration.getInt("spawn-limits.animals"); waterAnimalSpawn = configuration.getInt("spawn-limits.water-animals"); ambientSpawn = configuration.getInt("spawn-limits.ambient"); warningState = WarningState.value(configuration.getString("settings.deprecated-verbose")); + TicketType.PLUGIN.loadPeriod = configuration.getInt("chunk-gc.period-in-ticks"); + minimumAPI = configuration.getString("settings.minimum-api"); printSaveWarning = false; console.autosavePeriod = configuration.getInt("ticks-per.autosave"); - chunkGCPeriod = configuration.getInt("chunk-gc.period-in-ticks"); - chunkGCLoadThresh = configuration.getInt("chunk-gc.load-threshold"); loadIcon(); try { @@ -795,8 +794,8 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings")); // Paper for (WorldServer world : console.getWorlds()) { - world.worldData.setDifficulty(difficulty); - world.setSpawnFlags(monsters, animals); + world.worldData.setDifficulty(config.difficulty); + world.setSpawnFlags(config.spawnMonsters, config.spawnAnimals); if (this.getTicksPerAnimalSpawns() < 0) { world.ticksPerAnimalSpawns = 400; } else { @@ -949,6 +948,7 @@ public final class CraftServer implements Server { @Override public World createWorld(WorldCreator creator) { + Preconditions.checkState(!console.worldServer.isEmpty(), "Cannot create additional worlds on STARTUP"); Validate.notNull(creator, "Creator may not be null"); String name = creator.name(); @@ -976,7 +976,7 @@ public final class CraftServer implements Server { boolean used = false; do { for (WorldServer server : console.getWorlds()) { - used = server.dimension.getDimensionID() + 1 == dimension; // Paper - getDimensionID returns the dimension - 1, so we have to add 1 + used = server.getWorldProvider().getDimensionManager().getDimensionID() + 1 == dimension; // Paper - getDimensionID returns the dimension - 1, so we have to add 1 if (used) { dimension++; break; @@ -985,10 +985,10 @@ public final class CraftServer implements Server { } while(used); boolean hardcore = false; - IDataManager sdm = new ServerNBTManager(getWorldContainer(), name, getServer(), getHandle().getServer().dataConverterManager); - PersistentCollection persistentcollection = new PersistentCollection(sdm); + WorldNBTStorage sdm = new WorldNBTStorage(getWorldContainer(), name, getServer(), getHandle().getServer().dataConverterManager); WorldData worlddata = sdm.getWorldData(); - WorldSettings worldSettings = null; + WorldSettings worldSettings; + // See MinecraftServer.a(String, String, long, WorldType, JsonElement) if (worlddata == null) { worldSettings = new WorldSettings(com.destroystokyo.paper.PaperConfig.seedOverride.getOrDefault(name, creator.seed()), EnumGamemode.getById(getDefaultGameMode().getValue()), generateStructures, hardcore, type); // Paper JsonElement parsedSettings = new JsonParser().parse(creator.generatorSettings()); @@ -996,72 +996,28 @@ public final class CraftServer implements Server { worldSettings.setGeneratorSettings(parsedSettings.getAsJsonObject()); } worlddata = new WorldData(worldSettings, name); + } else { + worlddata.setName(name); + worldSettings = new WorldSettings(worlddata); } - worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) - DimensionManager internalDimension = new DimensionManager(dimension, name, name, () -> DimensionManager.a(creator.environment().getId()).e()); - WorldServer internal = (WorldServer) new WorldServer(console, sdm, persistentcollection, worlddata, internalDimension, console.methodProfiler, creator.environment(), generator).i_(); + DimensionManager actualDimension = DimensionManager.a(creator.environment().getId()); + DimensionManager internalDimension = DimensionManager.register(name.toLowerCase(java.util.Locale.ENGLISH), new DimensionManager(dimension, actualDimension.getSuffix(), actualDimension.folder, (w, manager) -> actualDimension.providerFactory.apply(w, manager), actualDimension.hasSkyLight(), actualDimension)); + WorldServer internal = (WorldServer) new WorldServer(console, console.executorService, sdm, worlddata, internalDimension, console.getMethodProfiler(), getServer().worldLoadListenerFactory.create(11), creator.environment(), generator); if (!(worlds.containsKey(name.toLowerCase(java.util.Locale.ENGLISH)))) { return null; } - if (worldSettings != null) { - internal.a(worldSettings); - } + console.initWorld(internal, worlddata, worldSettings); - internal.tracker = new EntityTracker(internal); - internal.addIWorldAccess(new WorldManager(console, internal)); internal.worldData.setDifficulty(EnumDifficulty.EASY); internal.setSpawnFlags(true, true); - console.worldServer.put(internal.dimension, internal); + console.worldServer.put(internal.getWorldProvider().getDimensionManager(), internal); pluginManager.callEvent(new WorldInitEvent(internal.getWorld())); - System.out.println("Preparing start region for level " + (console.worldServer.size() - 1) + " (Seed: " + internal.getSeed() + ")"); - if (internal.getWorld().getKeepSpawnInMemory()) { - short short1 = internal.paperConfig.keepLoadedRange; // Paper - long i = System.currentTimeMillis(); - // Paper start - for (ChunkCoordIntPair coords : internal.getChunkProvider().getSpiralOutChunks(internal.getSpawn(), short1 >> 4)) {{ - int j = coords.x; - int k = coords.z; - // Paper end - - long l = System.currentTimeMillis(); - - if (l < i) { - i = l; - } - - if (l > i + 1000L) { - int i1 = (short1 * 2 + 1) * (short1 * 2 + 1); - int j1 = (j + short1) * (short1 * 2 + 1) + k + 1; - - System.out.println("Preparing spawn area for " + name + ", " + (j1 * 100 / i1) + "%"); - i = l; - } - - BlockPosition chunkcoordinates = internal.getSpawn(); - internal.getChunkProvider().getChunkAt(chunkcoordinates.getX() + j >> 4, chunkcoordinates.getZ() + k >> 4, true, true, c -> {}); // Paper - } - } - } - - DimensionManager dimensionmanager = internalDimension.e().getDimensionManager(); - ForcedChunk forcedchunk = (ForcedChunk) persistentcollection.get(dimensionmanager, ForcedChunk::new, "chunks"); - - if (forcedchunk != null) { - LongIterator longiterator = forcedchunk.a().iterator(); - - while (longiterator.hasNext()) { - System.out.println("Loading forced chunks for dimension " + dimension + ", " + forcedchunk.a().size() * 100 / 625 + "%"); - long k = longiterator.nextLong(); - ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(k); - - internal.getChunkProvider().getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, true, true); - } - } + getServer().loadSpawn(internal.getChunkProvider().playerChunkMap.worldLoadListener, internal); pluginManager.callEvent(new WorldLoadEvent(internal.getWorld())); return internal.getWorld(); @@ -1080,15 +1036,15 @@ public final class CraftServer implements Server { WorldServer handle = ((CraftWorld) world).getHandle(); - if (!(console.worldServer.containsKey(handle.dimension))) { + if (!(console.worldServer.containsKey(handle.getWorldProvider().getDimensionManager()))) { return false; } - if (handle.dimension == DimensionManager.OVERWORLD) { + if (handle.getWorldProvider().getDimensionManager() == DimensionManager.OVERWORLD) { return false; } - if (handle.players.size() > 0) { + if (handle.getPlayers().size() > 0) { return false; } @@ -1099,45 +1055,22 @@ public final class CraftServer implements Server { return false; } - if (save) { - try { - handle.save(true, null); - handle.close(); - } catch (ExceptionWorldConflict ex) { - getLogger().log(Level.SEVERE, null, ex); + try { + if (save) { + handle.save(null, true, true); } + + handle.getChunkProvider().close(save); + } catch (Exception ex) { + getLogger().log(Level.SEVERE, null, ex); } worlds.remove(world.getName().toLowerCase(java.util.Locale.ENGLISH)); - console.worldServer.remove(handle.dimension); - - File parentFolder = world.getWorldFolder().getAbsoluteFile(); - - // Synchronized because access to RegionFileCache.cache is guarded by this lock. - synchronized (RegionFileCache.class) { - Iterator> i = RegionFileCache.cache.entrySet().iterator(); - while(i.hasNext()) { - Map.Entry entry = i.next(); - File child = entry.getKey().getAbsoluteFile(); - while (child != null) { - if (child.equals(parentFolder)) { - i.remove(); - try { - entry.getValue().close(); - } catch (IOException ex) { - getLogger().log(Level.SEVERE, null, ex); - } - break; - } - child = child.getParentFile(); - } - } - } - + console.worldServer.remove(handle.getWorldProvider().getDimensionManager()); return true; } - public MinecraftServer getServer() { + public DedicatedServer getServer() { return console; } @@ -1209,6 +1142,14 @@ public final class CraftServer implements Server { toAdd = CraftShapelessRecipe.fromBukkitRecipe((ShapelessRecipe) recipe); } else if (recipe instanceof FurnaceRecipe) { toAdd = CraftFurnaceRecipe.fromBukkitRecipe((FurnaceRecipe) recipe); + } else if (recipe instanceof BlastingRecipe) { + toAdd = CraftBlastingRecipe.fromBukkitRecipe((BlastingRecipe) recipe); + } else if (recipe instanceof CampfireRecipe) { + toAdd = CraftCampfireRecipe.fromBukkitRecipe((CampfireRecipe) recipe); + } else if (recipe instanceof SmokingRecipe) { + toAdd = CraftSmokingRecipe.fromBukkitRecipe((SmokingRecipe) recipe); + } else if (recipe instanceof StonecuttingRecipe) { + toAdd = CraftStonecuttingRecipe.fromBukkitRecipe((StonecuttingRecipe) recipe); } else { return false; } @@ -1243,12 +1184,12 @@ public final class CraftServer implements Server { @Override public void clearRecipes() { - console.getCraftingManager().recipes.clear(); + console.getCraftingManager().clearRecipes(); } @Override public void resetRecipes() { - console.getCraftingManager().a(console.getResourceManager()); + console.reload(); // Not ideal but hard to reload a subset of a resource pack } @Override @@ -1289,7 +1230,7 @@ public final class CraftServer implements Server { @Override public int getSpawnRadius() { - return ((DedicatedServer) console).propertyManager.getInt("spawn-protection", 16); + return this.getServer().getSpawnProtection(); } @Override @@ -1300,7 +1241,7 @@ public final class CraftServer implements Server { @Override public boolean getOnlineMode() { - return online.value; + return console.getOnlineMode(); } @Override @@ -1352,8 +1293,7 @@ public final class CraftServer implements Server { @Override @Deprecated public CraftMapView getMap(int id) { - PersistentCollection collection = console.getWorldServer(DimensionManager.OVERWORLD).worldMaps; - WorldMap worldmap = (WorldMap) collection.get(DimensionManager.OVERWORLD, WorldMap::new, "map_" + id); + WorldMap worldmap = console.getWorldServer(DimensionManager.OVERWORLD).a("map_" + id); if (worldmap == null) { return null; } @@ -1395,7 +1335,7 @@ public final class CraftServer implements Server { @Override public void shutdown() { - console.safeShutdown(); + console.safeShutdown(false); } @Override @@ -1407,7 +1347,7 @@ public final class CraftServer implements Server { } } - BroadcastMessageEvent broadcastMessageEvent = new BroadcastMessageEvent(message, recipients); + BroadcastMessageEvent broadcastMessageEvent = new BroadcastMessageEvent(!Bukkit.isPrimaryThread(), message, recipients); getPluginManager().callEvent(broadcastMessageEvent); if (broadcastMessageEvent.isCancelled()) { @@ -1432,9 +1372,9 @@ public final class CraftServer implements Server { } GameProfile profile; // Only fetch an online UUID in online mode - if (MinecraftServer.getServer().getOnlineMode() + if (net.minecraft.server.MinecraftServer.getServer().getOnlineMode() || (org.spigotmc.SpigotConfig.bungee && com.destroystokyo.paper.PaperConfig.bungeeOnlineMode)) { - profile = console.getModernUserCache().acquire( name ); // Akarin + profile = console.getUserCache().getProfile( name ); } else { // Make an OfflinePlayer using an offline mode UUID since the name has no profile profile = new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name); @@ -1454,10 +1394,10 @@ public final class CraftServer implements Server { // Spigot Start GameProfile profile = null; // Only fetch an online UUID in online mode - if ( MinecraftServer.getServer().getOnlineMode() - || com.destroystokyo.paper.PaperConfig.isProxyOnlineMode()) // Paper - Handle via setting + if ( getOnlineMode() + || com.destroystokyo.paper.PaperConfig.isProxyOnlineMode() ) // Paper - Handle via setting { - profile = console.getModernUserCache().acquire( name ); // Akarin + profile = console.getUserCache().getProfile( name ); } // Spigot end if (profile == null) { @@ -1468,7 +1408,7 @@ public final class CraftServer implements Server { result = getOfflinePlayer(profile); } } else { - offlinePlayers.invalidate(result.getUniqueId()); // Akarin - caffeine + offlinePlayers.remove(result.getUniqueId()); } return result; @@ -1480,13 +1420,13 @@ public final class CraftServer implements Server { OfflinePlayer result = getPlayer(id); if (result == null) { - result = offlinePlayers.getIfPresent(id); + result = offlinePlayers.get(id); if (result == null) { result = new CraftOfflinePlayer(this, new GameProfile(id, null)); offlinePlayers.put(id, result); } } else { - offlinePlayers.invalidate(id); // Akarin - caffeine + offlinePlayers.remove(id); } return result; @@ -1524,7 +1464,7 @@ public final class CraftServer implements Server { for (JsonListEntry entry : playerList.getProfileBans().getValues()) { result.add(getOfflinePlayer((GameProfile) entry.getKey())); - } + } return result; } @@ -1545,7 +1485,7 @@ public final class CraftServer implements Server { @Override public void setWhitelist(boolean value) { playerList.setHasWhitelist(value); - console.getPropertyManager().setProperty("white-list", value); + console.setHasWhitelist(value); } @Override @@ -1677,13 +1617,13 @@ public final class CraftServer implements Server { @Override public Inventory createInventory(InventoryHolder owner, int size) throws IllegalArgumentException { - Validate.isTrue(size % 9 == 0, "Chests must have a size that is a multiple of 9!"); + Validate.isTrue(9 <= size && size <= 54 && size % 9 == 0, "Size for custom inventory must be a multiple of 9 between 9 and 54 slots (got " + size + ")"); return CraftInventoryCreator.INSTANCE.createInventory(owner, size); } @Override public Inventory createInventory(InventoryHolder owner, int size, String title) throws IllegalArgumentException { - Validate.isTrue(size % 9 == 0, "Chests must have a size that is a multiple of 9!"); + Validate.isTrue(9 <= size && size <= 54 && size % 9 == 0, "Size for custom inventory must be a multiple of 9 between 9 and 54 slots (got " + size + ")"); return CraftInventoryCreator.INSTANCE.createInventory(owner, size, title); } @@ -1724,7 +1664,7 @@ public final class CraftServer implements Server { @Override public boolean isPrimaryThread() { - return ThreadAssertion.is() || Thread.currentThread().equals(console.primaryThread); + return Thread.currentThread().equals(console.serverThread); // Paper - Fix issues with detecting main thread properly } @Override @@ -1750,7 +1690,7 @@ public final class CraftServer implements Server { offers = tabCompleteChat(player, message); } - TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers, message.startsWith("/") || forceCommand, pos != null ? MCUtil.toLocation(((CraftWorld) player.getWorld()).getHandle(), new BlockPosition(pos)) : null); // Paper + TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers, message.startsWith("/") || forceCommand, pos != null ? net.minecraft.server.MCUtil.toLocation(((CraftWorld) player.getWorld()).getHandle(), new BlockPosition(pos)) : null); // Paper getPluginManager().callEvent(tabEvent); return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions(); @@ -1758,7 +1698,7 @@ public final class CraftServer implements Server { public List tabCompleteCommand(Player player, String message, WorldServer world, Vec3D pos) { // Spigot Start - if ( (org.spigotmc.SpigotConfig.tabComplete < 0 || message.length() <= org.spigotmc.SpigotConfig.tabComplete) && !message.contains( " " ) ) + if ( (org.spigotmc.SpigotConfig.tabComplete < 0 || message.length() <= org.spigotmc.SpigotConfig.tabComplete) && !message.contains( " " ) ) { return ImmutableList.of(); } @@ -1951,7 +1891,7 @@ public final class CraftServer implements Server { @Override public Iterator advancementIterator() { - return Iterators.unmodifiableIterator(Iterators.transform(console.getAdvancementData().b().iterator(), new Function() { // PAIL: rename + return Iterators.unmodifiableIterator(Iterators.transform(console.getAdvancementData().a().iterator(), new Function() { // PAIL: rename @Override public org.bukkit.advancement.Advancement apply(Advancement advancement) { return advancement.bukkit; @@ -2000,11 +1940,11 @@ public final class CraftServer implements Server { case org.bukkit.Tag.REGISTRY_BLOCKS: Preconditions.checkArgument(clazz == org.bukkit.Material.class, "Block namespace must have material type"); - return (org.bukkit.Tag) new CraftBlockTag(console.getTagRegistry().a(), key); + return (org.bukkit.Tag) new CraftBlockTag(console.getTagRegistry().getBlockTags(), key); case org.bukkit.Tag.REGISTRY_ITEMS: Preconditions.checkArgument(clazz == org.bukkit.Material.class, "Item namespace must have material type"); - return (org.bukkit.Tag) new CraftItemTag(console.getTagRegistry().b(), key); + return (org.bukkit.Tag) new CraftItemTag(console.getTagRegistry().getItemTags(), key); default: throw new IllegalArgumentException(); } @@ -2017,18 +1957,19 @@ public final class CraftServer implements Server { case org.bukkit.Tag.REGISTRY_BLOCKS: Preconditions.checkArgument(clazz == org.bukkit.Material.class, "Block namespace must have material type"); - TagsServer blockTags = console.getTagRegistry().a(); // PAIL: getBlockTags - return blockTags.c().keySet().stream().map(key -> (org.bukkit.Tag) new CraftBlockTag(blockTags, key)).collect(ImmutableList.toImmutableList()); + TagsServer blockTags = console.getTagRegistry().getBlockTags(); + return blockTags.b().keySet().stream().map(key -> (org.bukkit.Tag) new CraftBlockTag(blockTags, key)).collect(ImmutableList.toImmutableList()); case org.bukkit.Tag.REGISTRY_ITEMS: Preconditions.checkArgument(clazz == org.bukkit.Material.class, "Item namespace must have material type"); - TagsServer itemTags = console.getTagRegistry().b(); // PAIL: getItemTags - return itemTags.c().keySet().stream().map(key -> (org.bukkit.Tag) new CraftItemTag(itemTags, key)).collect(ImmutableList.toImmutableList()); + TagsServer itemTags = console.getTagRegistry().getItemTags(); + return itemTags.b().keySet().stream().map(key -> (org.bukkit.Tag) new CraftItemTag(itemTags, key)).collect(ImmutableList.toImmutableList()); default: throw new IllegalArgumentException(); } } + @Override public LootTable getLootTable(NamespacedKey key) { Validate.notNull(key, "NamespacedKey cannot be null"); @@ -2041,12 +1982,12 @@ public final class CraftServer implements Server { Preconditions.checkArgument(selector != null, "Selector cannot be null"); Preconditions.checkArgument(sender != null, "Sender cannot be null"); - ArgumentEntity arg = ArgumentEntity.b(); + ArgumentEntity arg = ArgumentEntity.multipleEntities(); List nms; try { StringReader reader = new StringReader(selector); - nms = arg.parse(reader, true).b(VanillaCommandWrapper.getListener(sender)); + nms = arg.parse(reader, true).getEntities(VanillaCommandWrapper.getListener(sender)); Preconditions.checkArgument(!reader.canRead(), "Spurious trailing data in selector: " + selector); } catch (CommandSyntaxException ex) { throw new IllegalArgumentException("Could not parse selector: " + selector, ex); @@ -2065,9 +2006,9 @@ public final class CraftServer implements Server { @Override public double[] getTPS() { return new double[] { - MinecraftServer.getServer().tps1.getAverage(), - MinecraftServer.getServer().tps5.getAverage(), - MinecraftServer.getServer().tps15.getAverage() + net.minecraft.server.MinecraftServer.getServer().tps1.getAverage(), + net.minecraft.server.MinecraftServer.getServer().tps5.getAverage(), + net.minecraft.server.MinecraftServer.getServer().tps15.getAverage() }; } // Paper end @@ -2127,22 +2068,31 @@ public final class CraftServer implements Server { // Paper start @SuppressWarnings({"rawtypes", "unchecked"}) - public static boolean dumpHeap(File file) { + public static java.nio.file.Path dumpHeap(java.nio.file.Path dir, String name) { try { - if (file.getParentFile() != null) { - file.getParentFile().mkdirs(); + java.nio.file.Files.createDirectories(dir); + + javax.management.MBeanServer server = java.lang.management.ManagementFactory.getPlatformMBeanServer(); + java.nio.file.Path file; + + try { + Class clazz = Class.forName("openj9.lang.management.OpenJ9DiagnosticsMXBean"); + Object openj9Mbean = java.lang.management.ManagementFactory.newPlatformMXBeanProxy(server, "openj9.lang.management:type=OpenJ9Diagnostics", clazz); + java.lang.reflect.Method m = clazz.getMethod("triggerDumpToFile", String.class, String.class); + file = dir.resolve(name + ".phd"); + m.invoke(openj9Mbean, "heap", file.toString()); + } catch (ClassNotFoundException e) { + Class clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean"); + Object hotspotMBean = java.lang.management.ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", clazz); + java.lang.reflect.Method m = clazz.getMethod("dumpHeap", String.class, boolean.class); + file = dir.resolve(name + ".hprof"); + m.invoke(hotspotMBean, file.toString(), true); } - Class clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean"); - javax.management.MBeanServer server = java.lang.management.ManagementFactory.getPlatformMBeanServer(); - Object hotspotMBean = java.lang.management.ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", clazz); - java.lang.reflect.Method m = clazz.getMethod("dumpHeap", String.class, boolean.class); - m.invoke(hotspotMBean, file.getPath(), true); - return true; + return file; } catch (Throwable t) { - Bukkit.getLogger().severe("Could not write heap to " + file); - t.printStackTrace(); - return false; + Bukkit.getLogger().log(Level.SEVERE, "Could not write heap", t); + return null; } } @@ -2188,18 +2138,22 @@ public final class CraftServer implements Server { return com.destroystokyo.paper.PaperConfig.suggestPlayersWhenNullTabCompletions; } + @Override public String getPermissionMessage() { return com.destroystokyo.paper.PaperConfig.noPermissionMessage; } + @Override public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nonnull UUID uuid) { return createProfile(uuid, null); } + @Override public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nonnull String name) { return createProfile(null, name); } + @Override public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name) { Player player = uuid != null ? Bukkit.getPlayer(uuid) : (name != null ? Bukkit.getPlayerExact(name) : null); if (player != null) { @@ -2207,5 +2161,10 @@ public final class CraftServer implements Server { } return new com.destroystokyo.paper.profile.CraftPlayerProfile(uuid, name); } + + @Override + public int getCurrentTick() { + return net.minecraft.server.MinecraftServer.currentTick; + } // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftSound.java b/src/main/java/org/bukkit/craftbukkit/CraftSound.java index ee8219e3b..9f317ff2e 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftSound.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftSound.java @@ -4,7 +4,6 @@ import com.google.common.base.Preconditions; import net.minecraft.server.IRegistry; import net.minecraft.server.MinecraftKey; import net.minecraft.server.SoundEffect; - import org.apache.commons.lang.Validate; import org.bukkit.Sound; @@ -25,22 +24,40 @@ public enum CraftSound { BLOCK_ANVIL_PLACE("block.anvil.place"), BLOCK_ANVIL_STEP("block.anvil.step"), BLOCK_ANVIL_USE("block.anvil.use"), + BLOCK_BAMBOO_BREAK("block.bamboo.break"), + BLOCK_BAMBOO_FALL("block.bamboo.fall"), + BLOCK_BAMBOO_HIT("block.bamboo.hit"), + BLOCK_BAMBOO_PLACE("block.bamboo.place"), + BLOCK_BAMBOO_SAPLING_BREAK("block.bamboo_sapling.break"), + BLOCK_BAMBOO_SAPLING_HIT("block.bamboo_sapling.hit"), + BLOCK_BAMBOO_SAPLING_PLACE("block.bamboo_sapling.place"), + BLOCK_BAMBOO_STEP("block.bamboo.step"), + BLOCK_BARREL_CLOSE("block.barrel.close"), + BLOCK_BARREL_OPEN("block.barrel.open"), BLOCK_BEACON_ACTIVATE("block.beacon.activate"), BLOCK_BEACON_AMBIENT("block.beacon.ambient"), BLOCK_BEACON_DEACTIVATE("block.beacon.deactivate"), BLOCK_BEACON_POWER_SELECT("block.beacon.power_select"), + BLOCK_BELL_RESONATE("block.bell.resonate"), + BLOCK_BELL_USE("block.bell.use"), + BLOCK_BLASTFURNACE_FIRE_CRACKLE("block.blastfurnace.fire_crackle"), BLOCK_BREWING_STAND_BREW("block.brewing_stand.brew"), BLOCK_BUBBLE_COLUMN_BUBBLE_POP("block.bubble_column.bubble_pop"), BLOCK_BUBBLE_COLUMN_UPWARDS_AMBIENT("block.bubble_column.upwards_ambient"), BLOCK_BUBBLE_COLUMN_UPWARDS_INSIDE("block.bubble_column.upwards_inside"), BLOCK_BUBBLE_COLUMN_WHIRLPOOL_AMBIENT("block.bubble_column.whirlpool_ambient"), BLOCK_BUBBLE_COLUMN_WHIRLPOOL_INSIDE("block.bubble_column.whirlpool_inside"), + BLOCK_CAMPFIRE_CRACKLE("block.campfire.crackle"), BLOCK_CHEST_CLOSE("block.chest.close"), BLOCK_CHEST_LOCKED("block.chest.locked"), BLOCK_CHEST_OPEN("block.chest.open"), BLOCK_CHORUS_FLOWER_DEATH("block.chorus_flower.death"), BLOCK_CHORUS_FLOWER_GROW("block.chorus_flower.grow"), BLOCK_COMPARATOR_CLICK("block.comparator.click"), + BLOCK_COMPOSTER_EMPTY("block.composter.empty"), + BLOCK_COMPOSTER_FILL("block.composter.fill"), + BLOCK_COMPOSTER_FILL_SUCCESS("block.composter.fill_success"), + BLOCK_COMPOSTER_READY("block.composter.ready"), BLOCK_CONDUIT_ACTIVATE("block.conduit.activate"), BLOCK_CONDUIT_AMBIENT("block.conduit.ambient"), BLOCK_CONDUIT_AMBIENT_SHORT("block.conduit.ambient.short"), @@ -51,6 +68,7 @@ public enum CraftSound { BLOCK_CORAL_BLOCK_HIT("block.coral_block.hit"), BLOCK_CORAL_BLOCK_PLACE("block.coral_block.place"), BLOCK_CORAL_BLOCK_STEP("block.coral_block.step"), + BLOCK_CROP_BREAK("block.crop.break"), BLOCK_DISPENSER_DISPENSE("block.dispenser.dispense"), BLOCK_DISPENSER_FAIL("block.dispenser.fail"), BLOCK_DISPENSER_LAUNCH("block.dispenser.launch"), @@ -80,6 +98,7 @@ public enum CraftSound { BLOCK_GRAVEL_HIT("block.gravel.hit"), BLOCK_GRAVEL_PLACE("block.gravel.place"), BLOCK_GRAVEL_STEP("block.gravel.step"), + BLOCK_GRINDSTONE_USE("block.grindstone.use"), BLOCK_IRON_DOOR_CLOSE("block.iron_door.close"), BLOCK_IRON_DOOR_OPEN("block.iron_door.open"), BLOCK_IRON_TRAPDOOR_CLOSE("block.iron_trapdoor.close"), @@ -89,6 +108,11 @@ public enum CraftSound { BLOCK_LADDER_HIT("block.ladder.hit"), BLOCK_LADDER_PLACE("block.ladder.place"), BLOCK_LADDER_STEP("block.ladder.step"), + BLOCK_LANTERN_BREAK("block.lantern.break"), + BLOCK_LANTERN_FALL("block.lantern.fall"), + BLOCK_LANTERN_HIT("block.lantern.hit"), + BLOCK_LANTERN_PLACE("block.lantern.place"), + BLOCK_LANTERN_STEP("block.lantern.step"), BLOCK_LAVA_AMBIENT("block.lava.ambient"), BLOCK_LAVA_EXTINGUISH("block.lava.extinguish"), BLOCK_LAVA_POP("block.lava.pop"), @@ -101,14 +125,20 @@ public enum CraftSound { BLOCK_METAL_PRESSURE_PLATE_CLICK_OFF("block.metal_pressure_plate.click_off"), BLOCK_METAL_PRESSURE_PLATE_CLICK_ON("block.metal_pressure_plate.click_on"), BLOCK_METAL_STEP("block.metal.step"), + BLOCK_NETHER_WART_BREAK("block.nether_wart.break"), + BLOCK_NOTE_BLOCK_BANJO("block.note_block.banjo"), BLOCK_NOTE_BLOCK_BASEDRUM("block.note_block.basedrum"), BLOCK_NOTE_BLOCK_BASS("block.note_block.bass"), BLOCK_NOTE_BLOCK_BELL("block.note_block.bell"), + BLOCK_NOTE_BLOCK_BIT("block.note_block.bit"), BLOCK_NOTE_BLOCK_CHIME("block.note_block.chime"), + BLOCK_NOTE_BLOCK_COW_BELL("block.note_block.cow_bell"), + BLOCK_NOTE_BLOCK_DIDGERIDOO("block.note_block.didgeridoo"), BLOCK_NOTE_BLOCK_FLUTE("block.note_block.flute"), BLOCK_NOTE_BLOCK_GUITAR("block.note_block.guitar"), BLOCK_NOTE_BLOCK_HARP("block.note_block.harp"), BLOCK_NOTE_BLOCK_HAT("block.note_block.hat"), + BLOCK_NOTE_BLOCK_IRON_XYLOPHONE("block.note_block.iron_xylophone"), BLOCK_NOTE_BLOCK_PLING("block.note_block.pling"), BLOCK_NOTE_BLOCK_SNARE("block.note_block.snare"), BLOCK_NOTE_BLOCK_XYLOPHONE("block.note_block.xylophone"), @@ -124,6 +154,11 @@ public enum CraftSound { BLOCK_SAND_HIT("block.sand.hit"), BLOCK_SAND_PLACE("block.sand.place"), BLOCK_SAND_STEP("block.sand.step"), + BLOCK_SCAFFOLDING_BREAK("block.scaffolding.break"), + BLOCK_SCAFFOLDING_FALL("block.scaffolding.fall"), + BLOCK_SCAFFOLDING_HIT("block.scaffolding.hit"), + BLOCK_SCAFFOLDING_PLACE("block.scaffolding.place"), + BLOCK_SCAFFOLDING_STEP("block.scaffolding.step"), BLOCK_SHULKER_BOX_CLOSE("block.shulker_box.close"), BLOCK_SHULKER_BOX_OPEN("block.shulker_box.open"), BLOCK_SLIME_BLOCK_BREAK("block.slime_block.break"), @@ -131,6 +166,7 @@ public enum CraftSound { BLOCK_SLIME_BLOCK_HIT("block.slime_block.hit"), BLOCK_SLIME_BLOCK_PLACE("block.slime_block.place"), BLOCK_SLIME_BLOCK_STEP("block.slime_block.step"), + BLOCK_SMOKER_SMOKE("block.smoker.smoke"), BLOCK_SNOW_BREAK("block.snow.break"), BLOCK_SNOW_FALL("block.snow.fall"), BLOCK_SNOW_HIT("block.snow.hit"), @@ -145,6 +181,8 @@ public enum CraftSound { BLOCK_STONE_PRESSURE_PLATE_CLICK_OFF("block.stone_pressure_plate.click_off"), BLOCK_STONE_PRESSURE_PLATE_CLICK_ON("block.stone_pressure_plate.click_on"), BLOCK_STONE_STEP("block.stone.step"), + BLOCK_SWEET_BERRY_BUSH_BREAK("block.sweet_berry_bush.break"), + BLOCK_SWEET_BERRY_BUSH_PLACE("block.sweet_berry_bush.place"), BLOCK_TRIPWIRE_ATTACH("block.tripwire.attach"), BLOCK_TRIPWIRE_CLICK_OFF("block.tripwire.click_off"), BLOCK_TRIPWIRE_CLICK_ON("block.tripwire.click_on"), @@ -194,11 +232,14 @@ public enum CraftSound { ENTITY_BOAT_PADDLE_LAND("entity.boat.paddle_land"), ENTITY_BOAT_PADDLE_WATER("entity.boat.paddle_water"), ENTITY_CAT_AMBIENT("entity.cat.ambient"), + ENTITY_CAT_BEG_FOR_FOOD("entity.cat.beg_for_food"), ENTITY_CAT_DEATH("entity.cat.death"), + ENTITY_CAT_EAT("entity.cat.eat"), ENTITY_CAT_HISS("entity.cat.hiss"), ENTITY_CAT_HURT("entity.cat.hurt"), ENTITY_CAT_PURR("entity.cat.purr"), ENTITY_CAT_PURREOW("entity.cat.purreow"), + ENTITY_CAT_STRAY_AMBIENT("entity.cat.stray_ambient"), ENTITY_CHICKEN_AMBIENT("entity.chicken.ambient"), ENTITY_CHICKEN_DEATH("entity.chicken.death"), ENTITY_CHICKEN_EGG("entity.chicken.egg"), @@ -271,6 +312,7 @@ public enum CraftSound { ENTITY_ENDER_PEARL_THROW("entity.ender_pearl.throw"), ENTITY_EVOKER_AMBIENT("entity.evoker.ambient"), ENTITY_EVOKER_CAST_SPELL("entity.evoker.cast_spell"), + ENTITY_EVOKER_CELEBRATE("entity.evoker.celebrate"), ENTITY_EVOKER_DEATH("entity.evoker.death"), ENTITY_EVOKER_FANGS_ATTACK("entity.evoker_fangs.attack"), ENTITY_EVOKER_HURT("entity.evoker.hurt"), @@ -291,6 +333,16 @@ public enum CraftSound { ENTITY_FISHING_BOBBER_SPLASH("entity.fishing_bobber.splash"), ENTITY_FISHING_BOBBER_THROW("entity.fishing_bobber.throw"), ENTITY_FISH_SWIM("entity.fish.swim"), + ENTITY_FOX_AGGRO("entity.fox.aggro"), + ENTITY_FOX_AMBIENT("entity.fox.ambient"), + ENTITY_FOX_BITE("entity.fox.bite"), + ENTITY_FOX_DEATH("entity.fox.death"), + ENTITY_FOX_EAT("entity.fox.eat"), + ENTITY_FOX_HURT("entity.fox.hurt"), + ENTITY_FOX_SCREECH("entity.fox.screech"), + ENTITY_FOX_SLEEP("entity.fox.sleep"), + ENTITY_FOX_SNIFF("entity.fox.sniff"), + ENTITY_FOX_SPIT("entity.fox.spit"), ENTITY_GENERIC_BIG_FALL("entity.generic.big_fall"), ENTITY_GENERIC_BURN("entity.generic.burn"), ENTITY_GENERIC_DEATH("entity.generic.death"), @@ -381,13 +433,31 @@ public enum CraftSound { ENTITY_MAGMA_CUBE_SQUISH_SMALL("entity.magma_cube.squish_small"), ENTITY_MINECART_INSIDE("entity.minecart.inside"), ENTITY_MINECART_RIDING("entity.minecart.riding"), + ENTITY_MOOSHROOM_CONVERT("entity.mooshroom.convert"), + ENTITY_MOOSHROOM_EAT("entity.mooshroom.eat"), + ENTITY_MOOSHROOM_MILK("entity.mooshroom.milk"), ENTITY_MOOSHROOM_SHEAR("entity.mooshroom.shear"), + ENTITY_MOOSHROOM_SUSPICIOUS_MILK("entity.mooshroom.suspicious_milk"), ENTITY_MULE_AMBIENT("entity.mule.ambient"), ENTITY_MULE_CHEST("entity.mule.chest"), ENTITY_MULE_DEATH("entity.mule.death"), ENTITY_MULE_HURT("entity.mule.hurt"), + ENTITY_OCELOT_AMBIENT("entity.ocelot.ambient"), + ENTITY_OCELOT_DEATH("entity.ocelot.death"), + ENTITY_OCELOT_HURT("entity.ocelot.hurt"), ENTITY_PAINTING_BREAK("entity.painting.break"), ENTITY_PAINTING_PLACE("entity.painting.place"), + ENTITY_PANDA_AGGRESSIVE_AMBIENT("entity.panda.aggressive_ambient"), + ENTITY_PANDA_AMBIENT("entity.panda.ambient"), + ENTITY_PANDA_BITE("entity.panda.bite"), + ENTITY_PANDA_CANT_BREED("entity.panda.cant_breed"), + ENTITY_PANDA_DEATH("entity.panda.death"), + ENTITY_PANDA_EAT("entity.panda.eat"), + ENTITY_PANDA_HURT("entity.panda.hurt"), + ENTITY_PANDA_PRE_SNEEZE("entity.panda.pre_sneeze"), + ENTITY_PANDA_SNEEZE("entity.panda.sneeze"), + ENTITY_PANDA_STEP("entity.panda.step"), + ENTITY_PANDA_WORRIED_AMBIENT("entity.panda.worried_ambient"), ENTITY_PARROT_AMBIENT("entity.parrot.ambient"), ENTITY_PARROT_DEATH("entity.parrot.death"), ENTITY_PARROT_EAT("entity.parrot.eat"), @@ -402,11 +472,15 @@ public enum CraftSound { ENTITY_PARROT_IMITATE_ENDER_DRAGON("entity.parrot.imitate.ender_dragon"), ENTITY_PARROT_IMITATE_EVOKER("entity.parrot.imitate.evoker"), ENTITY_PARROT_IMITATE_GHAST("entity.parrot.imitate.ghast"), + ENTITY_PARROT_IMITATE_GUARDIAN("entity.parrot.imitate.guardian"), ENTITY_PARROT_IMITATE_HUSK("entity.parrot.imitate.husk"), ENTITY_PARROT_IMITATE_ILLUSIONER("entity.parrot.imitate.illusioner"), ENTITY_PARROT_IMITATE_MAGMA_CUBE("entity.parrot.imitate.magma_cube"), + ENTITY_PARROT_IMITATE_PANDA("entity.parrot.imitate.panda"), ENTITY_PARROT_IMITATE_PHANTOM("entity.parrot.imitate.phantom"), + ENTITY_PARROT_IMITATE_PILLAGER("entity.parrot.imitate.pillager"), ENTITY_PARROT_IMITATE_POLAR_BEAR("entity.parrot.imitate.polar_bear"), + ENTITY_PARROT_IMITATE_RAVAGER("entity.parrot.imitate.ravager"), ENTITY_PARROT_IMITATE_SHULKER("entity.parrot.imitate.shulker"), ENTITY_PARROT_IMITATE_SILVERFISH("entity.parrot.imitate.silverfish"), ENTITY_PARROT_IMITATE_SKELETON("entity.parrot.imitate.skeleton"), @@ -434,6 +508,10 @@ public enum CraftSound { ENTITY_PIG_HURT("entity.pig.hurt"), ENTITY_PIG_SADDLE("entity.pig.saddle"), ENTITY_PIG_STEP("entity.pig.step"), + ENTITY_PILLAGER_AMBIENT("entity.pillager.ambient"), + ENTITY_PILLAGER_CELEBRATE("entity.pillager.celebrate"), + ENTITY_PILLAGER_DEATH("entity.pillager.death"), + ENTITY_PILLAGER_HURT("entity.pillager.hurt"), ENTITY_PLAYER_ATTACK_CRIT("entity.player.attack.crit"), ENTITY_PLAYER_ATTACK_KNOCKBACK("entity.player.attack.knockback"), ENTITY_PLAYER_ATTACK_NODAMAGE("entity.player.attack.nodamage"), @@ -447,6 +525,7 @@ public enum CraftSound { ENTITY_PLAYER_HURT("entity.player.hurt"), ENTITY_PLAYER_HURT_DROWN("entity.player.hurt_drown"), ENTITY_PLAYER_HURT_ON_FIRE("entity.player.hurt_on_fire"), + ENTITY_PLAYER_HURT_SWEET_BERRY_BUSH("entity.player.hurt_sweet_berry_bush"), ENTITY_PLAYER_LEVELUP("entity.player.levelup"), ENTITY_PLAYER_SMALL_FALL("entity.player.small_fall"), ENTITY_PLAYER_SPLASH("entity.player.splash"), @@ -470,6 +549,14 @@ public enum CraftSound { ENTITY_RABBIT_DEATH("entity.rabbit.death"), ENTITY_RABBIT_HURT("entity.rabbit.hurt"), ENTITY_RABBIT_JUMP("entity.rabbit.jump"), + ENTITY_RAVAGER_AMBIENT("entity.ravager.ambient"), + ENTITY_RAVAGER_ATTACK("entity.ravager.attack"), + ENTITY_RAVAGER_CELEBRATE("entity.ravager.celebrate"), + ENTITY_RAVAGER_DEATH("entity.ravager.death"), + ENTITY_RAVAGER_HURT("entity.ravager.hurt"), + ENTITY_RAVAGER_ROAR("entity.ravager.roar"), + ENTITY_RAVAGER_STEP("entity.ravager.step"), + ENTITY_RAVAGER_STUNNED("entity.ravager.stunned"), ENTITY_SALMON_AMBIENT("entity.salmon.ambient"), ENTITY_SALMON_DEATH("entity.salmon.death"), ENTITY_SALMON_FLOP("entity.salmon.flop"), @@ -556,15 +643,41 @@ public enum CraftSound { ENTITY_VEX_DEATH("entity.vex.death"), ENTITY_VEX_HURT("entity.vex.hurt"), ENTITY_VILLAGER_AMBIENT("entity.villager.ambient"), + ENTITY_VILLAGER_CELEBRATE("entity.villager.celebrate"), ENTITY_VILLAGER_DEATH("entity.villager.death"), ENTITY_VILLAGER_HURT("entity.villager.hurt"), ENTITY_VILLAGER_NO("entity.villager.no"), ENTITY_VILLAGER_TRADE("entity.villager.trade"), + ENTITY_VILLAGER_WORK_ARMORER("entity.villager.work_armorer"), + ENTITY_VILLAGER_WORK_BUTCHER("entity.villager.work_butcher"), + ENTITY_VILLAGER_WORK_CARTOGRAPHER("entity.villager.work_cartographer"), + ENTITY_VILLAGER_WORK_CLERIC("entity.villager.work_cleric"), + ENTITY_VILLAGER_WORK_FARMER("entity.villager.work_farmer"), + ENTITY_VILLAGER_WORK_FISHERMAN("entity.villager.work_fisherman"), + ENTITY_VILLAGER_WORK_FLETCHER("entity.villager.work_fletcher"), + ENTITY_VILLAGER_WORK_LEATHERWORKER("entity.villager.work_leatherworker"), + ENTITY_VILLAGER_WORK_LIBRARIAN("entity.villager.work_librarian"), + ENTITY_VILLAGER_WORK_MASON("entity.villager.work_mason"), + ENTITY_VILLAGER_WORK_SHEPHERD("entity.villager.work_shepherd"), + ENTITY_VILLAGER_WORK_TOOLSMITH("entity.villager.work_toolsmith"), + ENTITY_VILLAGER_WORK_WEAPONSMITH("entity.villager.work_weaponsmith"), ENTITY_VILLAGER_YES("entity.villager.yes"), ENTITY_VINDICATOR_AMBIENT("entity.vindicator.ambient"), + ENTITY_VINDICATOR_CELEBRATE("entity.vindicator.celebrate"), ENTITY_VINDICATOR_DEATH("entity.vindicator.death"), ENTITY_VINDICATOR_HURT("entity.vindicator.hurt"), + ENTITY_WANDERING_TRADER_AMBIENT("entity.wandering_trader.ambient"), + ENTITY_WANDERING_TRADER_DEATH("entity.wandering_trader.death"), + ENTITY_WANDERING_TRADER_DISAPPEARED("entity.wandering_trader.disappeared"), + ENTITY_WANDERING_TRADER_DRINK_MILK("entity.wandering_trader.drink_milk"), + ENTITY_WANDERING_TRADER_DRINK_POTION("entity.wandering_trader.drink_potion"), + ENTITY_WANDERING_TRADER_HURT("entity.wandering_trader.hurt"), + ENTITY_WANDERING_TRADER_NO("entity.wandering_trader.no"), + ENTITY_WANDERING_TRADER_REAPPEARED("entity.wandering_trader.reappeared"), + ENTITY_WANDERING_TRADER_TRADE("entity.wandering_trader.trade"), + ENTITY_WANDERING_TRADER_YES("entity.wandering_trader.yes"), ENTITY_WITCH_AMBIENT("entity.witch.ambient"), + ENTITY_WITCH_CELEBRATE("entity.witch.celebrate"), ENTITY_WITCH_DEATH("entity.witch.death"), ENTITY_WITCH_DRINK("entity.witch.drink"), ENTITY_WITCH_HURT("entity.witch.hurt"), @@ -611,6 +724,7 @@ public enum CraftSound { ENTITY_ZOMBIE_VILLAGER_DEATH("entity.zombie_villager.death"), ENTITY_ZOMBIE_VILLAGER_HURT("entity.zombie_villager.hurt"), ENTITY_ZOMBIE_VILLAGER_STEP("entity.zombie_villager.step"), + EVENT_RAID_HORN("event.raid.horn"), ITEM_ARMOR_EQUIP_CHAIN("item.armor.equip_chain"), ITEM_ARMOR_EQUIP_DIAMOND("item.armor.equip_diamond"), ITEM_ARMOR_EQUIP_ELYTRA("item.armor.equip_elytra"), @@ -620,6 +734,8 @@ public enum CraftSound { ITEM_ARMOR_EQUIP_LEATHER("item.armor.equip_leather"), ITEM_ARMOR_EQUIP_TURTLE("item.armor.equip_turtle"), ITEM_AXE_STRIP("item.axe.strip"), + ITEM_BOOK_PAGE_TURN("item.book.page_turn"), + ITEM_BOOK_PUT("item.book.put"), ITEM_BOTTLE_EMPTY("item.bottle.empty"), ITEM_BOTTLE_FILL("item.bottle.fill"), ITEM_BOTTLE_FILL_DRAGONBREATH("item.bottle.fill_dragonbreath"), @@ -630,13 +746,24 @@ public enum CraftSound { ITEM_BUCKET_FILL_FISH("item.bucket.fill_fish"), ITEM_BUCKET_FILL_LAVA("item.bucket.fill_lava"), ITEM_CHORUS_FRUIT_TELEPORT("item.chorus_fruit.teleport"), + ITEM_CROP_PLANT("item.crop.plant"), + ITEM_CROSSBOW_HIT("item.crossbow.hit"), + ITEM_CROSSBOW_LOADING_END("item.crossbow.loading_end"), + ITEM_CROSSBOW_LOADING_MIDDLE("item.crossbow.loading_middle"), + ITEM_CROSSBOW_LOADING_START("item.crossbow.loading_start"), + ITEM_CROSSBOW_QUICK_CHARGE_1("item.crossbow.quick_charge_1"), + ITEM_CROSSBOW_QUICK_CHARGE_2("item.crossbow.quick_charge_2"), + ITEM_CROSSBOW_QUICK_CHARGE_3("item.crossbow.quick_charge_3"), + ITEM_CROSSBOW_SHOOT("item.crossbow.shoot"), ITEM_ELYTRA_FLYING("item.elytra.flying"), ITEM_FIRECHARGE_USE("item.firecharge.use"), ITEM_FLINTANDSTEEL_USE("item.flintandsteel.use"), ITEM_HOE_TILL("item.hoe.till"), + ITEM_NETHER_WART_PLANT("item.nether_wart.plant"), ITEM_SHIELD_BLOCK("item.shield.block"), ITEM_SHIELD_BREAK("item.shield.break"), ITEM_SHOVEL_FLATTEN("item.shovel.flatten"), + ITEM_SWEET_BERRIES_PICK_FROM_BUSH("item.sweet_berries.pick_from_bush"), ITEM_TOTEM_USE("item.totem.use"), ITEM_TRIDENT_HIT("item.trident.hit"), ITEM_TRIDENT_HIT_GROUND("item.trident.hit_ground"), @@ -667,6 +794,11 @@ public enum CraftSound { MUSIC_NETHER("music.nether"), MUSIC_UNDER_WATER("music.under_water"), UI_BUTTON_CLICK("ui.button.click"), + UI_CARTOGRAPHY_TABLE_TAKE_RESULT("ui.cartography_table.take_result"), + UI_LOOM_SELECT_PATTERN("ui.loom.select_pattern"), + UI_LOOM_TAKE_RESULT("ui.loom.take_result"), + UI_STONECUTTER_SELECT_RECIPE("ui.stonecutter.select_recipe"), + UI_STONECUTTER_TAKE_RESULT("ui.stonecutter.take_result"), UI_TOAST_CHALLENGE_COMPLETE("ui.toast.challenge_complete"), UI_TOAST_IN("ui.toast.in"), UI_TOAST_OUT("ui.toast.out"), diff --git a/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java b/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java index 31252df5b..4536b70dc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java @@ -1,11 +1,5 @@ package org.bukkit.craftbukkit; -import net.minecraft.server.StatisticList; - -import org.bukkit.Statistic; -import org.bukkit.Material; -import org.bukkit.entity.EntityType; - import com.google.common.base.Preconditions; import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableBiMap; @@ -14,7 +8,11 @@ import net.minecraft.server.EntityTypes; import net.minecraft.server.IRegistry; import net.minecraft.server.Item; import net.minecraft.server.MinecraftKey; +import net.minecraft.server.StatisticList; +import org.bukkit.Material; +import org.bukkit.Statistic; import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.EntityType; public enum CraftStatistic { DAMAGE_DEALT(StatisticList.DAMAGE_DEALT), @@ -82,7 +80,18 @@ public enum CraftStatistic { DAMAGE_BLOCKED_BY_SHIELD(StatisticList.DAMAGE_BLOCKED_BY_SHIELD), DAMAGE_ABSORBED(StatisticList.DAMAGE_ABSORBED), DAMAGE_RESISTED(StatisticList.DAMAGE_RESISTED), - CLEAN_SHULKER_BOX(StatisticList.CLEAN_SHULKER_BOX); + CLEAN_SHULKER_BOX(StatisticList.CLEAN_SHULKER_BOX), + OPEN_BARREL(StatisticList.OPEN_BARREL), + INTERACT_WITH_BLAST_FURNACE(StatisticList.INTERACT_WITH_BLAST_FURNACE), + INTERACT_WITH_SMOKER(StatisticList.INTERACT_WITH_SMOKER), + INTERACT_WITH_LECTERN(StatisticList.INTERACT_WITH_LECTERN), + INTERACT_WITH_CAMPFIRE(StatisticList.INTERACT_WITH_CAMPFIRE), + INTERACT_WITH_CARTOGRAPHY_TABLE(StatisticList.INTERACT_WITH_CARTOGRAPHY_TABLE), + INTERACT_WITH_LOOM(StatisticList.INTERACT_WITH_LOOM), + INTERACT_WITH_STONECUTTER(StatisticList.INTERACT_WITH_STONECUTTER), + BELL_RING(StatisticList.BELL_RING), + RAID_TRIGGER(StatisticList.RAID_TRIGGER), + RAID_WIN(StatisticList.RAID_WIN); private final MinecraftKey minecraftKey; private final org.bukkit.Statistic bukkit; private static final BiMap statistics; @@ -104,8 +113,8 @@ public enum CraftStatistic { } public static org.bukkit.Statistic getBukkitStatistic(net.minecraft.server.Statistic statistic) { - IRegistry statRegistry = statistic.a().a(); - MinecraftKey nmsKey = IRegistry.STATS.getKey(statistic.a()); + IRegistry statRegistry = statistic.getWrapper().getRegistry(); + MinecraftKey nmsKey = IRegistry.STATS.getKey(statistic.getWrapper()); if (statRegistry == IRegistry.CUSTOM_STAT) { nmsKey = (MinecraftKey) statistic.b(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java b/src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java deleted file mode 100644 index e1eb3aa0f..000000000 --- a/src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.bukkit.craftbukkit; - -import net.minecraft.server.BlockPosition; -import net.minecraft.server.DimensionManager; -import net.minecraft.server.PortalTravelAgent; -import net.minecraft.server.WorldServer; - -import org.bukkit.Location; -import org.bukkit.TravelAgent; - -public class CraftTravelAgent extends PortalTravelAgent implements TravelAgent { - - public static TravelAgent DEFAULT = null; - - private int searchRadius = world.paperConfig.portalSearchRadius; // Paper - Configurable search radius - private int creationRadius = 16; - private boolean canCreatePortal = true; - - public CraftTravelAgent(WorldServer worldserver) { - super(worldserver); - if (DEFAULT == null && worldserver.dimension == DimensionManager.OVERWORLD) { - DEFAULT = this; - } - } - - @Override - public Location findOrCreate(Location target) { - WorldServer worldServer = ((CraftWorld) target.getWorld()).getHandle(); - - Location found = this.findPortal(target); - if (found == null) { - if (this.getCanCreatePortal() && this.createPortal(target)) { - found = this.findPortal(target); - } else { - found = target; // fallback to original if unable to find or create - } - } - - return found; - } - - @Override - public Location findPortal(Location location) { - PortalTravelAgent pta = ((CraftWorld) location.getWorld()).getHandle().getTravelAgent(); - BlockPosition found = pta.findPortal(location.getX(), location.getY(), location.getZ(), this.getSearchRadius()); - return found != null ? new Location(location.getWorld(), found.getX(), found.getY(), found.getZ(), location.getYaw(), location.getPitch()) : null; - } - - @Override - public boolean createPortal(Location location) { - PortalTravelAgent pta = ((CraftWorld) location.getWorld()).getHandle().getTravelAgent(); - return pta.createPortal(location.getX(), location.getY(), location.getZ(), this.getCreationRadius()); - } - - @Override - public TravelAgent setSearchRadius(int radius) { - this.searchRadius = radius; - return this; - } - - @Override - public int getSearchRadius() { - return this.searchRadius; - } - - @Override - public TravelAgent setCreationRadius(int radius) { - this.creationRadius = radius < 2 ? 0 : radius; - return this; - } - - @Override - public int getCreationRadius() { - return this.creationRadius; - } - - @Override - public boolean getCanCreatePortal() { - return this.canCreatePortal; - } - - @Override - public void setCanCreatePortal(boolean create) { - this.canCreatePortal = create; - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index bc45338ec..f33d9c8b4 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1,25 +1,97 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.util.concurrent.Futures; -import it.unimi.dsi.fastutil.longs.LongSet; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; - -import javax.annotation.Nullable; - -import net.minecraft.server.*; - +import java.util.stream.Collectors; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.objects.ObjectSortedSet; +import net.minecraft.server.AxisAlignedBB; +import net.minecraft.server.BiomeBase; +import net.minecraft.server.BlockChorusFlower; +import net.minecraft.server.BlockDiodeAbstract; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.Blocks; +import net.minecraft.server.ChunkCoordIntPair; +import net.minecraft.server.ChunkMapDistance; +import net.minecraft.server.ChunkStatus; +import net.minecraft.server.EntityAreaEffectCloud; +import net.minecraft.server.EntityArmorStand; +import net.minecraft.server.EntityArrow; +import net.minecraft.server.EntityBoat; +import net.minecraft.server.EntityEgg; +import net.minecraft.server.EntityEnderSignal; +import net.minecraft.server.EntityEvokerFangs; +import net.minecraft.server.EntityExperienceOrb; +import net.minecraft.server.EntityFallingBlock; +import net.minecraft.server.EntityFireball; +import net.minecraft.server.EntityFireworks; +import net.minecraft.server.EntityHanging; +import net.minecraft.server.EntityHuman; +import net.minecraft.server.EntityInsentient; +import net.minecraft.server.EntityItem; +import net.minecraft.server.EntityItemFrame; +import net.minecraft.server.EntityLeash; +import net.minecraft.server.EntityLightning; +import net.minecraft.server.EntityMinecartChest; +import net.minecraft.server.EntityMinecartCommandBlock; +import net.minecraft.server.EntityMinecartFurnace; +import net.minecraft.server.EntityMinecartHopper; +import net.minecraft.server.EntityMinecartMobSpawner; +import net.minecraft.server.EntityMinecartRideable; +import net.minecraft.server.EntityMinecartTNT; +import net.minecraft.server.EntityPainting; +import net.minecraft.server.EntityPotion; +import net.minecraft.server.EntitySnowball; +import net.minecraft.server.EntityTNTPrimed; +import net.minecraft.server.EntityTippedArrow; +import net.minecraft.server.EntityTypes; +import net.minecraft.server.EntityZombie; +import net.minecraft.server.EnumDifficulty; +import net.minecraft.server.EnumDirection; +import net.minecraft.server.EnumMobSpawn; +import net.minecraft.server.ExceptionWorldConflict; +import net.minecraft.server.Explosion; +import net.minecraft.server.GameRules; +import net.minecraft.server.GroupDataEntity; +import net.minecraft.server.HeightMap; +import net.minecraft.server.IBlockData; +import net.minecraft.server.IChunkAccess; +import net.minecraft.server.MinecraftKey; +import net.minecraft.server.MovingObjectPosition; +import net.minecraft.server.PacketPlayOutCustomSoundEffect; +import net.minecraft.server.PacketPlayOutUpdateTime; +import net.minecraft.server.PacketPlayOutWorldEvent; +import net.minecraft.server.PersistentRaid; +import net.minecraft.server.PlayerChunk; +import net.minecraft.server.ProtoChunkExtension; +import net.minecraft.server.RayTrace; +import net.minecraft.server.SoundCategory; +import net.minecraft.server.Ticket; +import net.minecraft.server.TicketType; +import net.minecraft.server.Unit; +import net.minecraft.server.Vec3D; +import net.minecraft.server.WorldGenFeatureEmptyConfiguration; +import net.minecraft.server.WorldGenHugeMushroomConfiguration; +import net.minecraft.server.WorldGenerator; +import net.minecraft.server.WorldServer; import org.apache.commons.lang.Validate; import org.bukkit.BlockChangeDelegate; import org.bukkit.Bukkit; @@ -34,6 +106,7 @@ import org.bukkit.Particle; import org.bukkit.Sound; import org.bukkit.StructureType; import org.bukkit.TreeType; +import org.bukkit.Raid; import org.bukkit.World; import org.bukkit.WorldBorder; import org.bukkit.block.Biome; @@ -44,14 +117,127 @@ import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.block.data.CraftBlockData; -import org.bukkit.craftbukkit.entity.*; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftItem; +import org.bukkit.craftbukkit.entity.CraftLightningStrike; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.metadata.BlockMetadataStore; import org.bukkit.craftbukkit.potion.CraftPotionUtil; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftRayTraceResult; -import org.bukkit.entity.*; +import org.bukkit.entity.AbstractArrow; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.AbstractVillager; +import org.bukkit.entity.Ambient; +import org.bukkit.entity.AreaEffectCloud; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Bat; +import org.bukkit.entity.Blaze; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Cat; +import org.bukkit.entity.CaveSpider; +import org.bukkit.entity.ChestedHorse; +import org.bukkit.entity.Chicken; +import org.bukkit.entity.Cod; +import org.bukkit.entity.ComplexLivingEntity; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Donkey; +import org.bukkit.entity.DragonFireball; +import org.bukkit.entity.Drowned; +import org.bukkit.entity.Egg; +import org.bukkit.entity.ElderGuardian; +import org.bukkit.entity.EnderCrystal; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.EnderPearl; +import org.bukkit.entity.EnderSignal; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.Endermite; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Evoker; +import org.bukkit.entity.EvokerFangs; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Fireball; +import org.bukkit.entity.Firework; +import org.bukkit.entity.Fish; +import org.bukkit.entity.Fox; +import org.bukkit.entity.Ghast; +import org.bukkit.entity.Giant; +import org.bukkit.entity.Golem; +import org.bukkit.entity.Guardian; +import org.bukkit.entity.Hanging; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Husk; +import org.bukkit.entity.Illager; +import org.bukkit.entity.Illusioner; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.LeashHitch; +import org.bukkit.entity.LightningStrike; +import org.bukkit.entity.LingeringPotion; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Llama; +import org.bukkit.entity.LlamaSpit; +import org.bukkit.entity.MagmaCube; +import org.bukkit.entity.Minecart; +import org.bukkit.entity.Mule; +import org.bukkit.entity.MushroomCow; +import org.bukkit.entity.Ocelot; +import org.bukkit.entity.Painting; +import org.bukkit.entity.Panda; +import org.bukkit.entity.Parrot; +import org.bukkit.entity.Phantom; +import org.bukkit.entity.Pig; +import org.bukkit.entity.PigZombie; +import org.bukkit.entity.Pillager; +import org.bukkit.entity.Player; +import org.bukkit.entity.PolarBear; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.PufferFish; +import org.bukkit.entity.Rabbit; +import org.bukkit.entity.Ravager; +import org.bukkit.entity.Salmon; +import org.bukkit.entity.Sheep; +import org.bukkit.entity.Shulker; +import org.bukkit.entity.ShulkerBullet; +import org.bukkit.entity.Silverfish; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.SkeletonHorse; +import org.bukkit.entity.Slime; +import org.bukkit.entity.SmallFireball; +import org.bukkit.entity.Snowball; +import org.bukkit.entity.Snowman; +import org.bukkit.entity.SpectralArrow; +import org.bukkit.entity.Spellcaster; +import org.bukkit.entity.Spider; +import org.bukkit.entity.Squid; +import org.bukkit.entity.Stray; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.entity.Tameable; +import org.bukkit.entity.ThrownExpBottle; +import org.bukkit.entity.ThrownPotion; +import org.bukkit.entity.TippedArrow; +import org.bukkit.entity.TraderLlama; +import org.bukkit.entity.Trident; +import org.bukkit.entity.TropicalFish; +import org.bukkit.entity.Turtle; +import org.bukkit.entity.Vex; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Vindicator; +import org.bukkit.entity.WanderingTrader; +import org.bukkit.entity.Witch; +import org.bukkit.entity.Wither; +import org.bukkit.entity.WitherSkeleton; +import org.bukkit.entity.WitherSkull; +import org.bukkit.entity.Wolf; +import org.bukkit.entity.Zombie; +import org.bukkit.entity.ZombieHorse; +import org.bukkit.entity.ZombieVillager; import org.bukkit.entity.minecart.CommandMinecart; import org.bukkit.entity.minecart.ExplosiveMinecart; import org.bukkit.entity.minecart.HopperMinecart; @@ -73,7 +259,6 @@ import org.bukkit.util.BoundingBox; import org.bukkit.util.Consumer; import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; public class CraftWorld implements World { public static final int CUSTOM_DIMENSION_OFFSET = 10; @@ -89,17 +274,26 @@ public class CraftWorld implements World { private int animalSpawn = -1; private int waterAnimalSpawn = -1; private int ambientSpawn = -1; - private int chunkLoadCount = 0; - private int chunkGCTickCount; // Paper start - Provide fast information methods public int getEntityCount() { - return world.entityList.size(); + int ret = 0; + for (net.minecraft.server.Entity entity : world.entitiesById.values()) { + if (entity.isChunkLoaded()) { + ++ret; + } + } + return ret; } public int getTileEntityCount() { // We don't use the full world tile entity list, so we must iterate chunks + Long2ObjectLinkedOpenHashMap chunks = world.getChunkProvider().playerChunkMap.visibleChunks; int size = 0; - for (net.minecraft.server.Chunk chunk : ((ChunkProviderServer) world.getChunkProvider()).chunks.values()) { + for (net.minecraft.server.PlayerChunk playerchunk : chunks.values()) { + net.minecraft.server.Chunk chunk = playerchunk.getChunk(); + if (chunk == null) { + continue; + } size += chunk.tileEntities.size(); } return size; @@ -108,7 +302,15 @@ public class CraftWorld implements World { return world.tileEntityListTick.size(); } public int getChunkCount() { - return world.getChunkProvider().chunks.size(); + int ret = 0; + + for (PlayerChunk chunkHolder : world.getChunkProvider().playerChunkMap.visibleChunks.values()) { + if (chunkHolder.getChunk() != null) { + ++ret; + } + } + + return ret; } public int getPlayerCount() { return world.players.size(); @@ -122,29 +324,46 @@ public class CraftWorld implements World { this.generator = gen; environment = env; - - if (server.chunkGCPeriod > 0) { - chunkGCTickCount = rand.nextInt(server.chunkGCPeriod); - } } - // Akarin start - public Block getBlockAt(BlockPosition blockPosition) { - return CraftBlock.at(world, blockPosition); - } - // Akarin end + @Override public Block getBlockAt(int x, int y, int z) { return CraftBlock.at(world, new BlockPosition(x, y, z)); } + @Override public int getHighestBlockYAt(int x, int z) { if (!isChunkLoaded(x >> 4, z >> 4)) { - loadChunk(x >> 4, z >> 4); + getChunkAt(x >> 4, z >> 4); // Transient load for this tick } - return world.getHighestBlockYAt(HeightMap.Type.LIGHT_BLOCKING, new BlockPosition(x, 0, z)).getY(); + return world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, new BlockPosition(x, 0, z)).getY(); } + // Paper start - Implement heightmap api + @Override + public int getHighestBlockYAt(final int x, final int z, final com.destroystokyo.paper.HeightmapType heightmap) throws UnsupportedOperationException { + this.getChunkAt(x >> 4, z >> 4); // heightmap will ret 0 on unloaded areas + + switch (heightmap) { + case LIGHT_BLOCKING: + throw new UnsupportedOperationException(); // TODO + //return this.world.getHighestBlockY(HeightMap.Type.LIGHT_BLOCKING, x, z); + case ANY: + return this.world.getHighestBlockY(HeightMap.Type.WORLD_SURFACE, x, z); + case SOLID: + return this.world.getHighestBlockY(HeightMap.Type.OCEAN_FLOOR, x, z); + case SOLID_OR_LIQUID: + return this.world.getHighestBlockY(HeightMap.Type.MOTION_BLOCKING, x, z); + case SOLID_OR_LIQUID_NO_LEAVES: + return this.world.getHighestBlockY(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, x, z); + default: + throw new UnsupportedOperationException(); + } + } + // Paper end + + @Override public Location getSpawnLocation() { BlockPosition spawn = world.getSpawn(); return new Location(this, spawn.getX(), spawn.getY(), spawn.getZ()); @@ -157,6 +376,7 @@ public class CraftWorld implements World { return equals(location.getWorld()) ? setSpawnLocation(location.getBlockX(), location.getBlockY(), location.getBlockZ()) : false; } + @Override public boolean setSpawnLocation(int x, int y, int z) { try { Location previousLocation = getSpawnLocation(); @@ -172,107 +392,105 @@ public class CraftWorld implements World { } } - // Paper start - Async chunk load API @Override - public java.util.concurrent.CompletableFuture getChunkAtAsync(final int x, final int z, final boolean gen) { - final ChunkProviderServer cps = this.world.getChunkProvider(); - java.util.concurrent.CompletableFuture future = new java.util.concurrent.CompletableFuture<>(); - cps.getChunkAt(x, z, true, gen, chunk -> future.complete(chunk != null ? chunk.bukkitChunk : null)); - return future; - } - // Paper end - public Chunk getChunkAt(int x, int z) { - return this.world.getChunkProvider().getChunkAt(x, z, true, true).bukkitChunk; + return this.world.getChunkProvider().getChunkAt(x, z, true).bukkitChunk; } + @Override public Chunk getChunkAt(Block block) { return getChunkAt(block.getX() >> 4, block.getZ() >> 4); } + @Override public boolean isChunkLoaded(int x, int z) { - return world.getChunkProvider().isLoaded(x, z); + return world.getChunkProvider().getChunkAtIfLoadedImmediately(x, z) != null; // Paper } @Override public boolean isChunkGenerated(int x, int z) { - return isChunkLoaded(x, z) || ((ChunkRegionLoader) world.getChunkProvider().chunkLoader).chunkExists(x, z); - } - - public Chunk[] getLoadedChunks() { - Object[] chunks = world.getChunkProvider().chunks.values().toArray(); - org.bukkit.Chunk[] craftChunks = new CraftChunk[chunks.length]; - - for (int i = 0; i < chunks.length; i++) { - net.minecraft.server.Chunk chunk = (net.minecraft.server.Chunk) chunks[i]; - craftChunks[i] = chunk.bukkitChunk; + // Paper start - Fix this method + if (!Bukkit.isPrimaryThread()) { + return CompletableFuture.supplyAsync(() -> { + return CraftWorld.this.isChunkGenerated(x, z); + }, world.getChunkProvider().serverThreadQueue).join(); + } + IChunkAccess chunk = world.getChunkProvider().getChunkAtImmediately(x, z); + if (chunk == null) { + chunk = world.getChunkProvider().playerChunkMap.getUnloadingChunk(x, z); + } + if (chunk != null) { + return chunk instanceof ProtoChunkExtension || chunk instanceof net.minecraft.server.Chunk; + } + try { + return world.getChunkProvider().playerChunkMap.getChunkStatusOnDisk(new ChunkCoordIntPair(x, z)) == ChunkStatus.FULL; + // Paper end + } catch (IOException ex) { + throw new RuntimeException(ex); } - - return craftChunks; } + @Override + public Chunk[] getLoadedChunks() { + Long2ObjectLinkedOpenHashMap chunks = world.getChunkProvider().playerChunkMap.visibleChunks; + return chunks.values().stream().map(PlayerChunk::getFullChunk).filter(Objects::nonNull).map(net.minecraft.server.Chunk::getBukkitChunk).toArray(Chunk[]::new); + } + + @Override public void loadChunk(int x, int z) { loadChunk(x, z, true); } + @Override public boolean unloadChunk(Chunk chunk) { return unloadChunk(chunk.getX(), chunk.getZ()); } + @Override public boolean unloadChunk(int x, int z) { return unloadChunk(x, z, true); } + @Override public boolean unloadChunk(int x, int z, boolean save) { - return unloadChunk(x, z, save, false); + return unloadChunk0(x, z, save); } + @Override public boolean unloadChunkRequest(int x, int z) { - return unloadChunkRequest(x, z, true); - } - - public boolean unloadChunkRequest(int x, int z, boolean safe) { - //org.spigotmc.AsyncCatcher.catchOp( "chunk unload"); // Spigot // Akarin - if (safe && isChunkInUse(x, z)) { - return false; - } - - net.minecraft.server.Chunk chunk = world.getChunkIfLoaded(x, z); // Paper - optimize ifLaoded + org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot + net.minecraft.server.IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, false); if (chunk != null) { - world.getChunkProvider().unload(chunk); + world.getChunkProvider().removeTicket(TicketType.PLUGIN, chunk.getPos(), 1, Unit.INSTANCE); } return true; } - public boolean unloadChunk(int x, int z, boolean save, boolean safe) { - //org.spigotmc.AsyncCatcher.catchOp( "chunk unload" ); // Spigot // Akarin - if (isChunkInUse(x, z)) { - return false; - } - - return unloadChunk0(x, z, save); - } - private boolean unloadChunk0(int x, int z, boolean save) { - Boolean result = MCUtil.ensureMain("Unload Chunk", () -> { // Paper - Ensure never async - net.minecraft.server.Chunk chunk = world.getChunkIfLoaded(x, z); // Paper - optimize ifLoaded + org.spigotmc.AsyncCatcher.catchOp("chunk unload"); // Spigot + net.minecraft.server.Chunk chunk = (net.minecraft.server.Chunk) world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, false); if (chunk == null) { return true; } - // If chunk had previously been queued to save, must do save to avoid loss of that data - return world.getChunkProvider().unloadChunk(chunk, chunk.mustSave || save); - }); return result != null ? result : false; // Paper - Ensure never async + chunk.mustNotSave = !save; + unloadChunkRequest(x, z); + + world.getChunkProvider().purgeUnload(); + return !isChunkLoaded(x, z); } + @Override public boolean regenerateChunk(int x, int z) { - //org.spigotmc.AsyncCatcher.catchOp( "chunk regenerate" ); // Spigot // Akarin + org.spigotmc.AsyncCatcher.catchOp("chunk regenerate"); // Spigot + throw new UnsupportedOperationException("Not supported in this Minecraft version! Unless you can fix it, this is not a bug :)"); + /* if (!unloadChunk0(x, z, false)) { return false; } - final long chunkKey = ChunkCoordIntPair.a(x, z); + final long chunkKey = ChunkCoordIntPair.pair(x, z); world.getChunkProvider().unloadQueue.remove(chunkKey); net.minecraft.server.Chunk chunk = world.getChunkProvider().generateChunk(x, z); @@ -286,8 +504,10 @@ public class CraftWorld implements World { } return chunk != null; + */ } + @Override public boolean refreshChunk(int x, int z) { if (!isChunkLoaded(x, z)) { return false; @@ -308,28 +528,150 @@ public class CraftWorld implements World { return true; } + @Override public boolean isChunkInUse(int x, int z) { - return world.getPlayerChunkMap().isChunkInUse(x, z) || world.isForceLoaded(x, z); + return isChunkLoaded(x, z); } + @Override public boolean loadChunk(int x, int z, boolean generate) { - //org.spigotmc.AsyncCatcher.catchOp( "chunk load"); // Spigot // Akarin - chunkLoadCount++; - return world.getChunkProvider().getChunkAt(x, z, true, generate || isChunkGenerated(x, z)) != null; // Paper + org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot + // Paper start - Optimize this method + ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(x, z); + + if (!generate) { + + IChunkAccess immediate = world.getChunkProvider().getChunkAtImmediately(x, z); + if (immediate == null) { + immediate = world.getChunkProvider().playerChunkMap.getUnloadingChunk(x, z); + } + if (immediate != null) { + if (!(immediate instanceof ProtoChunkExtension) && !(immediate instanceof net.minecraft.server.Chunk)) { + return false; // not full status + } + world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE); + world.getChunkAt(x, z); // make sure we're at ticket level 32 or lower + return true; + } + + ChunkStatus status = world.getChunkProvider().playerChunkMap.getStatusOnDiskNoLoad(x, z); // Paper - async io - move to own method + + // Paper start - async io + if (status == ChunkStatus.EMPTY) { + // does not exist on disk + return false; + } + + if (status == null) { // at this stage we don't know what it is on disk + IChunkAccess chunk = world.getChunkProvider().getChunkAt(x, z, ChunkStatus.EMPTY, true); + if (!(chunk instanceof ProtoChunkExtension) && !(chunk instanceof net.minecraft.server.Chunk)) { + return false; + } + } else if (status != ChunkStatus.FULL) { + return false; // not full status on disk + } + // Paper end + + // fall through to load + // we do this so we do not re-read the chunk data on disk + } + + world.getChunkProvider().addTicket(TicketType.PLUGIN, chunkPos, 1, Unit.INSTANCE); + world.getChunkProvider().getChunkAt(x, z, ChunkStatus.FULL, true); + return true; + // Paper end } + @Override public boolean isChunkLoaded(Chunk chunk) { return isChunkLoaded(chunk.getX(), chunk.getZ()); } + @Override public void loadChunk(Chunk chunk) { loadChunk(chunk.getX(), chunk.getZ()); ((CraftChunk) getChunkAt(chunk.getX(), chunk.getZ())).getHandle().bukkitChunk = chunk; } + @Override + public boolean addPluginChunkTicket(int x, int z, Plugin plugin) { + Preconditions.checkArgument(plugin != null, "null plugin"); + Preconditions.checkArgument(plugin.isEnabled(), "plugin is not enabled"); + + ChunkMapDistance chunkDistanceManager = this.world.getChunkProvider().playerChunkMap.chunkDistanceManager; + + if (chunkDistanceManager.addTicketAtLevel(TicketType.PLUGIN_TICKET, new ChunkCoordIntPair(x, z), 31, plugin)) { // keep in-line with force loading, add at level 31 + this.getChunkAt(x, z); // ensure loaded + return true; + } + + return false; + } + + @Override + public boolean removePluginChunkTicket(int x, int z, Plugin plugin) { + Preconditions.checkNotNull(plugin, "null plugin"); + + ChunkMapDistance chunkDistanceManager = this.world.getChunkProvider().playerChunkMap.chunkDistanceManager; + return chunkDistanceManager.removeTicketAtLevel(TicketType.PLUGIN_TICKET, new ChunkCoordIntPair(x, z), 31, plugin); // keep in-line with force loading, remove at level 31 + } + + @Override + public void removePluginChunkTickets(Plugin plugin) { + Preconditions.checkNotNull(plugin, "null plugin"); + + ChunkMapDistance chunkDistanceManager = this.world.getChunkProvider().playerChunkMap.chunkDistanceManager; + chunkDistanceManager.removeAllTicketsFor(TicketType.PLUGIN_TICKET, 31, plugin); // keep in-line with force loading, remove at level 31 + } + + @Override + public Collection getPluginChunkTickets(int x, int z) { + ChunkMapDistance chunkDistanceManager = this.world.getChunkProvider().playerChunkMap.chunkDistanceManager; + ObjectSortedSet> tickets = chunkDistanceManager.tickets.get(ChunkCoordIntPair.pair(x, z)); + + if (tickets == null) { + return Collections.emptyList(); + } + + ImmutableList.Builder ret = ImmutableList.builder(); + for (Ticket ticket : tickets) { + if (ticket.getTicketType() == TicketType.PLUGIN_TICKET) { + ret.add((Plugin) ticket.identifier); + } + } + + return ret.build(); + } + + @Override + public Map> getPluginChunkTickets() { + Map> ret = new HashMap<>(); + ChunkMapDistance chunkDistanceManager = this.world.getChunkProvider().playerChunkMap.chunkDistanceManager; + + for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.tickets.long2ObjectEntrySet()) { + long chunkKey = chunkTickets.getLongKey(); + ObjectSortedSet> tickets = chunkTickets.getValue(); + + Chunk chunk = null; + for (Ticket ticket : tickets) { + if (ticket.getTicketType() != TicketType.PLUGIN_TICKET) { + continue; + } + + if (chunk == null) { + chunk = this.getChunkAt(ChunkCoordIntPair.getX(chunkKey), ChunkCoordIntPair.getZ(chunkKey)); + } + + ret.computeIfAbsent((Plugin) ticket.identifier, (key) -> ImmutableList.builder()).add(chunk); + } + } + + return ret.entrySet().stream().collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, (entry) -> entry.getValue().build())); + } + @Override public boolean isChunkForceLoaded(int x, int z) { - return getHandle().isForceLoaded(x, z); + return getHandle().getForceLoadedChunks().contains(ChunkCoordIntPair.pair(x, z)); } @Override @@ -341,17 +683,18 @@ public class CraftWorld implements World { public Collection getForceLoadedChunks() { Set chunks = new HashSet<>(); - for (long coord : getHandle().ag()) { // PAIL - chunks.add(getChunkAt(ChunkCoordIntPair.a(coord), ChunkCoordIntPair.b(coord))); + for (long coord : getHandle().getForceLoadedChunks()) { + chunks.add(getChunkAt(ChunkCoordIntPair.getX(coord), ChunkCoordIntPair.getZ(coord))); } - return com.koloboke.collect.set.hash.HashObjSets.newImmutableSet(chunks); // Akarin - koloboke + return Collections.unmodifiableCollection(chunks); } public WorldServer getHandle() { return world; } + @Override public org.bukkit.entity.Item dropItem(Location loc, ItemStack item) { Validate.notNull(item, "Cannot drop a Null item."); EntityItem entity = new EntityItem(world, loc.getX(), loc.getY(), loc.getZ(), CraftItemStack.asNMSCopy(item)); @@ -362,6 +705,7 @@ public class CraftWorld implements World { return new CraftItem(world.getServer(), entity); } + @Override public org.bukkit.entity.Item dropItemNaturally(Location loc, ItemStack item) { double xs = (world.random.nextFloat() * 0.5F) + 0.25D; double ys = (world.random.nextFloat() * 0.5F) + 0.25D; @@ -373,25 +717,27 @@ public class CraftWorld implements World { return dropItem(loc, item); } + @Override public Arrow spawnArrow(Location loc, Vector velocity, float speed, float spread) { return spawnArrow(loc, velocity, speed, spread, Arrow.class); } - public T spawnArrow(Location loc, Vector velocity, float speed, float spread, Class clazz) { + @Override + public T spawnArrow(Location loc, Vector velocity, float speed, float spread, Class clazz) { Validate.notNull(loc, "Can not spawn arrow with a null location"); Validate.notNull(velocity, "Can not spawn arrow with a null velocity"); Validate.notNull(clazz, "Can not spawn an arrow with no class"); EntityArrow arrow; if (TippedArrow.class.isAssignableFrom(clazz)) { - arrow = new EntityTippedArrow(world); + arrow = EntityTypes.ARROW.a(world); ((EntityTippedArrow) arrow).setType(CraftPotionUtil.fromBukkit(new PotionData(PotionType.WATER, false, false))); } else if (SpectralArrow.class.isAssignableFrom(clazz)) { - arrow = new EntitySpectralArrow(world); + arrow = EntityTypes.SPECTRAL_ARROW.a(world); } else if (Trident.class.isAssignableFrom(clazz)){ - arrow = new EntityThrownTrident(world); + arrow = EntityTypes.TRIDENT.a(world); } else { - arrow = new EntityTippedArrow(world); + arrow = EntityTypes.ARROW.a(world); } arrow.setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); @@ -400,84 +746,92 @@ public class CraftWorld implements World { return (T) arrow.getBukkitEntity(); } + @Override public Entity spawnEntity(Location loc, EntityType entityType) { return spawn(loc, entityType.getEntityClass()); } + @Override public LightningStrike strikeLightning(Location loc) { EntityLightning lightning = new EntityLightning(world, loc.getX(), loc.getY(), loc.getZ(), false); world.strikeLightning(lightning); return new CraftLightningStrike(server, lightning); } + @Override public LightningStrike strikeLightningEffect(Location loc) { EntityLightning lightning = new EntityLightning(world, loc.getX(), loc.getY(), loc.getZ(), true); world.strikeLightning(lightning); return new CraftLightningStrike(server, lightning); } + @Override public boolean generateTree(Location loc, TreeType type) { BlockPosition pos = new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); net.minecraft.server.WorldGenerator gen; + net.minecraft.server.WorldGenFeatureConfiguration conf = new WorldGenFeatureEmptyConfiguration(); switch (type) { - case BIG_TREE: - gen = new WorldGenBigTree(true); + case BIG_TREE: + gen = WorldGenerator.FANCY_TREE; break; case BIRCH: - gen = new WorldGenForest(true, false); + gen = WorldGenerator.BIRCH_TREE; break; case REDWOOD: - gen = new WorldGenTaiga2(true); + gen = WorldGenerator.SPRUCE_TREE; break; case TALL_REDWOOD: - gen = new WorldGenTaiga1(); + gen = WorldGenerator.PINE_TREE; break; case JUNGLE: - gen = new WorldGenJungleTree(true, 10, 20, Blocks.JUNGLE_LOG.getBlockData(), Blocks.JUNGLE_LEAVES.getBlockData()); + gen = WorldGenerator.MEGA_JUNGLE_TREE; break; case SMALL_JUNGLE: - gen = new WorldGenTrees(true, 4 + rand.nextInt(7), Blocks.JUNGLE_LOG.getBlockData(), Blocks.JUNGLE_LEAVES.getBlockData(), false); + gen = WorldGenerator.JUNGLE_TREE; break; case COCOA_TREE: - gen = new WorldGenJungleTree(true, 10, 20, Blocks.JUNGLE_LOG.getBlockData(), Blocks.JUNGLE_LEAVES.getBlockData()); + gen = WorldGenerator.MEGA_JUNGLE_TREE; break; case JUNGLE_BUSH: - gen = new WorldGenGroundBush(Blocks.JUNGLE_LOG.getBlockData(), Blocks.OAK_LEAVES.getBlockData()); + gen = WorldGenerator.JUNGLE_GROUND_BUSH; break; case RED_MUSHROOM: - gen = new WorldGenHugeMushroomRed(); + gen = WorldGenerator.HUGE_RED_MUSHROOM; + conf = new WorldGenHugeMushroomConfiguration(true); break; case BROWN_MUSHROOM: - gen = new WorldGenHugeMushroomBrown(); + gen = WorldGenerator.HUGE_BROWN_MUSHROOM; + conf = new WorldGenHugeMushroomConfiguration(true); break; case SWAMP: - gen = new WorldGenSwampTree(); + gen = WorldGenerator.SWAMP_TREE; break; case ACACIA: - gen = new WorldGenAcaciaTree(true); + gen = WorldGenerator.SAVANNA_TREE; break; case DARK_OAK: - gen = new WorldGenForestTree(true); + gen = WorldGenerator.DARK_OAK_TREE; break; case MEGA_REDWOOD: - gen = new WorldGenMegaTree(false, rand.nextBoolean()); + gen = WorldGenerator.MEGA_PINE_TREE; break; case TALL_BIRCH: - gen = new WorldGenForest(true, true); + gen = WorldGenerator.SUPER_BIRCH_TREE; break; case CHORUS_PLANT: ((BlockChorusFlower) Blocks.CHORUS_FLOWER).a(world, pos, rand, 8); return true; case TREE: default: - gen = new WorldGenTrees(true); + gen = WorldGenerator.NORMAL_TREE; break; } - return gen.generate(world, world.worldProvider.getChunkGenerator(), rand, pos, new WorldGenFeatureEmptyConfiguration()); + return gen.generate(world, world.worldProvider.getChunkGenerator(), rand, pos, conf); } + @Override public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { world.captureTreeGeneration = true; world.captureBlockStates = true; @@ -501,6 +855,7 @@ public class CraftWorld implements World { } } + @Override public String getName() { return world.worldData.getName(); } @@ -510,6 +865,7 @@ public class CraftWorld implements World { return world.worldData.getSeed(); } + @Override public UUID getUID() { return world.getDataManager().getUUID(); } @@ -519,22 +875,26 @@ public class CraftWorld implements World { return "CraftWorld{name=" + getName() + '}'; } + @Override public long getTime() { long time = getFullTime() % 24000; if (time < 0) time += 24000; return time; } + @Override public void setTime(long time) { long margin = (time - getFullTime()) % 24000; if (margin < 0) margin += 24000; setFullTime(getFullTime() + margin); } + @Override public long getFullTime() { return world.getDayTime(); } + @Override public void setFullTime(long time) { world.setDayTime(time); @@ -543,94 +903,111 @@ public class CraftWorld implements World { CraftPlayer cp = (CraftPlayer) p; if (cp.getHandle().playerConnection == null) continue; - cp.getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateTime(cp.getHandle().world.getTime(), cp.getHandle().getPlayerTime(), cp.getHandle().world.getGameRules().getBoolean("doDaylightCycle"))); + cp.getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateTime(cp.getHandle().world.getTime(), cp.getHandle().getPlayerTime(), cp.getHandle().world.getGameRules().getBoolean(GameRules.DO_DAYLIGHT_CYCLE))); } } // Paper start + @Override public boolean isDayTime() { return getHandle().isDayTime(); } // Paper end + @Override public boolean createExplosion(double x, double y, double z, float power) { return createExplosion(x, y, z, power, false, true); } + @Override public boolean createExplosion(double x, double y, double z, float power, boolean setFire) { return createExplosion(x, y, z, power, setFire, true); } + @Override public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks) { - return !world.createExplosion(null, x, y, z, power, setFire, breakBlocks).wasCanceled; + return createExplosion(x, y, z, power, setFire, breakBlocks, null); + } + + @Override + public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) { + return !world.createExplosion(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, breakBlocks ? Explosion.Effect.BREAK : Explosion.Effect.NONE).wasCanceled; } // Paper start public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks) { - return !world.createExplosion(source != null ? ((CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks).wasCanceled; + return !world.createExplosion(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? Explosion.Effect.BREAK : Explosion.Effect.NONE).wasCanceled; } // Paper end + @Override public boolean createExplosion(Location loc, float power) { return createExplosion(loc, power, false); } + @Override public boolean createExplosion(Location loc, float power, boolean setFire) { - return createExplosion(loc.getX(), loc.getY(), loc.getZ(), power, setFire); + return createExplosion(loc, power, setFire, true); } + @Override + public boolean createExplosion(Location loc, float power, boolean setFire, boolean breakBlocks) { + return createExplosion(loc, power, setFire, breakBlocks, null); + } + + @Override + public boolean createExplosion(Location loc, float power, boolean setFire, boolean breakBlocks, Entity source) { + Preconditions.checkArgument(loc != null, "Location is null"); + Preconditions.checkArgument(this.equals(loc.getWorld()), "Location not in world"); + + return createExplosion(loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks, source); + } + + @Override public Environment getEnvironment() { return environment; } - public void setEnvironment(Environment env) { - if (environment != env) { - environment = env; - switch (env) { - case NORMAL: - world.worldProvider = new WorldProviderNormal(); - break; - case NETHER: - world.worldProvider = new WorldProviderHell(); - break; - case THE_END: - world.worldProvider = new WorldProviderTheEnd(); - break; - } - } - } - + @Override public Block getBlockAt(Location location) { return getBlockAt(location.getBlockX(), location.getBlockY(), location.getBlockZ()); } + @Override public int getHighestBlockYAt(Location location) { return getHighestBlockYAt(location.getBlockX(), location.getBlockZ()); } + @Override public Chunk getChunkAt(Location location) { return getChunkAt(location.getBlockX() >> 4, location.getBlockZ() >> 4); } + @Override public ChunkGenerator getGenerator() { return generator; } + @Override public List getPopulators() { return populators; } + @Override public Block getHighestBlockAt(int x, int z) { return getBlockAt(x, getHighestBlockYAt(x, z), z); } + @Override public Block getHighestBlockAt(Location location) { return getHighestBlockAt(location.getBlockX(), location.getBlockZ()); } + @Override public Biome getBiome(int x, int z) { return CraftBlock.biomeBaseToBiome(this.world.getBiome(new BlockPosition(x, 0, z))); } + @Override public void setBiome(int x, int z, Biome bio) { BiomeBase bb = CraftBlock.biomeToBiomeBase(bio); if (this.world.isLoaded(new BlockPosition(x, 0, z))) { @@ -645,25 +1022,28 @@ public class CraftWorld implements World { } } + @Override public double getTemperature(int x, int z) { return this.world.getBiome(new BlockPosition(x, 0, z)).getTemperature(); } + @Override public double getHumidity(int x, int z) { return this.world.getBiome(new BlockPosition(x, 0, z)).getHumidity(); } + @Override public List getEntities() { List list = new ArrayList(); - for (Object o : world.entityList) { + for (Object o : world.entitiesById.values()) { if (o instanceof net.minecraft.server.Entity) { net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o; if (mcEnt.shouldBeRemoved) continue; // Paper Entity bukkitEntity = mcEnt.getBukkitEntity(); // Assuming that bukkitEntity isn't null - if (bukkitEntity != null) { + if (bukkitEntity != null && bukkitEntity.isValid()) { list.add(bukkitEntity); } } @@ -672,17 +1052,18 @@ public class CraftWorld implements World { return list; } + @Override public List getLivingEntities() { List list = new ArrayList(); - for (Object o : world.entityList) { + for (Object o : world.entitiesById.values()) { if (o instanceof net.minecraft.server.Entity) { net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o; if (mcEnt.shouldBeRemoved) continue; // Paper Entity bukkitEntity = mcEnt.getBukkitEntity(); // Assuming that bukkitEntity isn't null - if (bukkitEntity != null && bukkitEntity instanceof LivingEntity) { + if (bukkitEntity != null && bukkitEntity instanceof LivingEntity && bukkitEntity.isValid()) { list.add((LivingEntity) bukkitEntity); } } @@ -691,17 +1072,19 @@ public class CraftWorld implements World { return list; } + @Override @SuppressWarnings("unchecked") @Deprecated public Collection getEntitiesByClass(Class... classes) { return (Collection)getEntitiesByClasses(classes); } + @Override @SuppressWarnings("unchecked") public Collection getEntitiesByClass(Class clazz) { Collection list = new ArrayList(); - for (Object entity: world.entityList) { + for (Object entity: world.entitiesById.values()) { if (entity instanceof net.minecraft.server.Entity) { if (((net.minecraft.server.Entity) entity).shouldBeRemoved) continue; // Paper Entity bukkitEntity = ((net.minecraft.server.Entity) entity).getBukkitEntity(); @@ -712,7 +1095,7 @@ public class CraftWorld implements World { Class bukkitClass = bukkitEntity.getClass(); - if (clazz.isAssignableFrom(bukkitClass)) { + if (clazz.isAssignableFrom(bukkitClass) && bukkitEntity.isValid()) { list.add((T) bukkitEntity); } } @@ -721,10 +1104,11 @@ public class CraftWorld implements World { return list; } + @Override public Collection getEntitiesByClasses(Class... classes) { Collection list = new ArrayList(); - for (Object entity: world.entityList) { + for (Object entity: world.entitiesById.values()) { if (entity instanceof net.minecraft.server.Entity) { if (((net.minecraft.server.Entity) entity).shouldBeRemoved) continue; // Paper Entity bukkitEntity = ((net.minecraft.server.Entity) entity).getBukkitEntity(); @@ -737,7 +1121,9 @@ public class CraftWorld implements World { for (Class clazz : classes) { if (clazz.isAssignableFrom(bukkitClass)) { - list.add(bukkitEntity); + if (bukkitEntity.isValid()) { + list.add(bukkitEntity); + } break; } } @@ -768,6 +1154,7 @@ public class CraftWorld implements World { @Override public Collection getNearbyEntities(BoundingBox boundingBox, Predicate filter) { + org.spigotmc.AsyncCatcher.catchOp("getNearbyEntities"); // Spigot Validate.notNull(boundingBox, "Bounding box is null!"); AxisAlignedBB bb = new AxisAlignedBB(boundingBox.getMinX(), boundingBox.getMinY(), boundingBox.getMinZ(), boundingBox.getMaxX(), boundingBox.getMaxY(), boundingBox.getMaxZ()); @@ -870,7 +1257,7 @@ public class CraftWorld implements World { Vector dir = direction.clone().normalize().multiply(maxDistance); Vec3D startPos = new Vec3D(start.getX(), start.getY(), start.getZ()); Vec3D endPos = new Vec3D(start.getX() + dir.getX(), start.getY() + dir.getY(), start.getZ() + dir.getZ()); - MovingObjectPosition nmsHitResult = this.getHandle().rayTrace(startPos, endPos, CraftFluidCollisionMode.toNMS(fluidCollisionMode), ignorePassableBlocks, false); + MovingObjectPosition nmsHitResult = this.getHandle().rayTrace(new RayTrace(startPos, endPos, ignorePassableBlocks ? RayTrace.BlockCollisionOption.COLLIDER : RayTrace.BlockCollisionOption.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), null)); return CraftRayTraceResult.fromNMS(this, nmsHitResult); } @@ -905,10 +1292,11 @@ public class CraftWorld implements World { return blockHit; } + @Override public List getPlayers() { - List list = new ArrayList(world.players.size()); + List list = new ArrayList(world.getPlayers().size()); - for (EntityHuman human : world.players) { + for (EntityHuman human : world.getPlayers()) { HumanEntity bukkitEntity = human.getBukkitEntity(); if ((bukkitEntity != null) && (bukkitEntity instanceof Player)) { @@ -920,6 +1308,7 @@ public class CraftWorld implements World { } // Paper start - getEntity by UUID API + @Override public Entity getEntity(UUID uuid) { Validate.notNull(uuid, "UUID cannot be null"); net.minecraft.server.Entity entity = world.getEntity(uuid); @@ -927,18 +1316,15 @@ public class CraftWorld implements World { } // Paper end + @Override public void save() { - // Spigot start - save(true); - } - public void save(boolean forceSave) { - // Spigot end + org.spigotmc.AsyncCatcher.catchOp("world save"); // Spigot this.server.checkSaveState(); try { boolean oldSave = world.savingDisabled; world.savingDisabled = false; - world.save(forceSave, null); // Spigot + world.save(null, false, false); world.savingDisabled = oldSave; } catch (ExceptionWorldConflict ex) { @@ -946,18 +1332,22 @@ public class CraftWorld implements World { } } + @Override public boolean isAutoSave() { return !world.savingDisabled; } + @Override public void setAutoSave(boolean value) { world.savingDisabled = !value; } + @Override public void setDifficulty(Difficulty difficulty) { this.getHandle().worldData.setDifficulty(EnumDifficulty.getById(difficulty.getValue())); } + @Override public Difficulty getDifficulty() { return Difficulty.getByValue(this.getHandle().getDifficulty().ordinal()); } @@ -966,48 +1356,59 @@ public class CraftWorld implements World { return blockMetadata; } + @Override public boolean hasStorm() { return world.worldData.hasStorm(); } + @Override public void setStorm(boolean hasStorm) { world.worldData.setStorm(hasStorm); setWeatherDuration(0); // Reset weather duration (legacy behaviour) } + @Override public int getWeatherDuration() { return world.worldData.getWeatherDuration(); } + @Override public void setWeatherDuration(int duration) { world.worldData.setWeatherDuration(duration); } + @Override public boolean isThundering() { return world.worldData.isThundering(); } + @Override public void setThundering(boolean thundering) { world.worldData.setThundering(thundering); setThunderDuration(0); // Reset weather duration (legacy behaviour) } + @Override public int getThunderDuration() { return world.worldData.getThunderDuration(); } + @Override public void setThunderDuration(int duration) { world.worldData.setThunderDuration(duration); } + @Override public long getSeed() { return world.worldData.getSeed(); } + @Override public boolean getPVP() { return world.pvpMode; } + @Override public void setPVP(boolean pvp) { world.pvpMode = pvp; } @@ -1016,14 +1417,17 @@ public class CraftWorld implements World { playEffect(player.getLocation(), effect, data, 0); } + @Override public void playEffect(Location location, Effect effect, int data) { playEffect(location, effect, data, 64); } + @Override public void playEffect(Location loc, Effect effect, T data) { playEffect(loc, effect, data, 64); } + @Override public void playEffect(Location loc, Effect effect, T data, int radius) { if (data != null) { Validate.isTrue(effect.getData() != null && effect.getData().isAssignableFrom(data.getClass()), "Wrong kind of data for this effect!"); @@ -1035,6 +1439,7 @@ public class CraftWorld implements World { playEffect(loc, effect, datavalue, radius); } + @Override public void playEffect(Location location, Effect effect, int data, int radius) { Validate.notNull(location, "Location cannot be null"); Validate.notNull(effect, "Effect cannot be null"); @@ -1055,6 +1460,7 @@ public class CraftWorld implements World { } } + @Override public T spawn(Location location, Class clazz) throws IllegalArgumentException { return spawn(location, clazz, null, SpawnReason.CUSTOM); } @@ -1070,6 +1476,7 @@ public class CraftWorld implements World { return spawnFallingBlock(location, data.getItemType(), data.getData()); } + @Override public FallingBlock spawnFallingBlock(Location location, org.bukkit.Material material, byte data) throws IllegalArgumentException { Validate.notNull(location, "Location cannot be null"); Validate.notNull(material, "Material cannot be null"); @@ -1123,48 +1530,50 @@ public class CraftWorld implements World { entity = new EntitySnowball(world, x, y, z); } else if (Egg.class.isAssignableFrom(clazz)) { entity = new EntityEgg(world, x, y, z); - } else if (Arrow.class.isAssignableFrom(clazz)) { + } else if (AbstractArrow.class.isAssignableFrom(clazz)) { if (TippedArrow.class.isAssignableFrom(clazz)) { - entity = new EntityTippedArrow(world); + entity = EntityTypes.ARROW.a(world); ((EntityTippedArrow) entity).setType(CraftPotionUtil.fromBukkit(new PotionData(PotionType.WATER, false, false))); } else if (SpectralArrow.class.isAssignableFrom(clazz)) { - entity = new EntitySpectralArrow(world); + entity = EntityTypes.SPECTRAL_ARROW.a(world); } else if (Trident.class.isAssignableFrom(clazz)) { - entity = new EntityThrownTrident(world); + entity = EntityTypes.TRIDENT.a(world); } else { - entity = new EntityTippedArrow(world); + entity = EntityTypes.ARROW.a(world); } entity.setPositionRotation(x, y, z, 0, 0); } else if (ThrownExpBottle.class.isAssignableFrom(clazz)) { - entity = new EntityThrownExpBottle(world); + entity = EntityTypes.EXPERIENCE_BOTTLE.a(world); entity.setPositionRotation(x, y, z, 0, 0); } else if (EnderPearl.class.isAssignableFrom(clazz)) { - entity = new EntityEnderPearl(world); + entity = EntityTypes.ENDER_PEARL.a(world); entity.setPositionRotation(x, y, z, 0, 0); } else if (ThrownPotion.class.isAssignableFrom(clazz)) { if (LingeringPotion.class.isAssignableFrom(clazz)) { - entity = new EntityPotion(world, x, y, z, CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.LINGERING_POTION, 1))); + entity = new EntityPotion(world, x, y, z); + ((EntityPotion) entity).setItem(CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.LINGERING_POTION, 1))); } else { - entity = new EntityPotion(world, x, y, z, CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.SPLASH_POTION, 1))); + entity = new EntityPotion(world, x, y, z); + ((EntityPotion) entity).setItem(CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.SPLASH_POTION, 1))); } } else if (Fireball.class.isAssignableFrom(clazz)) { if (SmallFireball.class.isAssignableFrom(clazz)) { - entity = new EntitySmallFireball(world); + entity = EntityTypes.SMALL_FIREBALL.a(world); } else if (WitherSkull.class.isAssignableFrom(clazz)) { - entity = new EntityWitherSkull(world); + entity = EntityTypes.WITHER_SKULL.a(world); } else if (DragonFireball.class.isAssignableFrom(clazz)) { - entity = new EntityDragonFireball(world); + entity = EntityTypes.DRAGON_FIREBALL.a(world); } else { - entity = new EntityLargeFireball(world); + entity = EntityTypes.FIREBALL.a(world); } entity.setPositionRotation(x, y, z, yaw, pitch); Vector direction = location.getDirection().multiply(10); ((EntityFireball) entity).setDirection(direction.getX(), direction.getY(), direction.getZ()); } else if (ShulkerBullet.class.isAssignableFrom(clazz)) { - entity = new EntityShulkerBullet(world); + entity = EntityTypes.SHULKER_BULLET.a(world); entity.setPositionRotation(x, y, z, yaw, pitch); } else if (LlamaSpit.class.isAssignableFrom(clazz)) { - entity = new EntityLlamaSpit(world); + entity = EntityTypes.LLAMA_SPIT.a(world); entity.setPositionRotation(x, y, z, yaw, pitch); } } else if (Minecart.class.isAssignableFrom(clazz)) { @@ -1186,157 +1595,175 @@ public class CraftWorld implements World { } else if (EnderSignal.class.isAssignableFrom(clazz)) { entity = new EntityEnderSignal(world, x, y, z); } else if (EnderCrystal.class.isAssignableFrom(clazz)) { - entity = new EntityEnderCrystal(world); + entity = EntityTypes.END_CRYSTAL.a(world); entity.setPositionRotation(x, y, z, 0, 0); } else if (LivingEntity.class.isAssignableFrom(clazz)) { if (Chicken.class.isAssignableFrom(clazz)) { - entity = EntityTypes.CHICKEN.create(world); // Paper + entity = EntityTypes.CHICKEN.a(world); } else if (Cow.class.isAssignableFrom(clazz)) { if (MushroomCow.class.isAssignableFrom(clazz)) { - entity = EntityTypes.MOOSHROOM.create(world); // Paper + entity = EntityTypes.MOOSHROOM.a(world); } else { - entity = EntityTypes.COW.create(world); // Paper + entity = EntityTypes.COW.a(world); } } else if (Golem.class.isAssignableFrom(clazz)) { if (Snowman.class.isAssignableFrom(clazz)) { - entity = EntityTypes.SNOW_GOLEM.create(world); // Paper + entity = EntityTypes.SNOW_GOLEM.a(world); } else if (IronGolem.class.isAssignableFrom(clazz)) { - entity = EntityTypes.IRON_GOLEM.create(world); // Paper + entity = EntityTypes.IRON_GOLEM.a(world); } else if (Shulker.class.isAssignableFrom(clazz)) { - entity = EntityTypes.SHULKER.create(world); // Paper + entity = EntityTypes.SHULKER.a(world); } } else if (Creeper.class.isAssignableFrom(clazz)) { - entity = EntityTypes.CREEPER.create(world); // Paper + entity = EntityTypes.CREEPER.a(world); } else if (Ghast.class.isAssignableFrom(clazz)) { - entity = EntityTypes.GHAST.create(world); // Paper + entity = EntityTypes.GHAST.a(world); } else if (Pig.class.isAssignableFrom(clazz)) { - entity = EntityTypes.PIG.create(world); // Paper + entity = EntityTypes.PIG.a(world); } else if (Player.class.isAssignableFrom(clazz)) { // need a net server handler for this one } else if (Sheep.class.isAssignableFrom(clazz)) { - entity = EntityTypes.SHEEP.create(world); // Paper + entity = EntityTypes.SHEEP.a(world); } else if (AbstractHorse.class.isAssignableFrom(clazz)) { if (ChestedHorse.class.isAssignableFrom(clazz)) { if (Donkey.class.isAssignableFrom(clazz)) { - entity = EntityTypes.DONKEY.create(world); // Paper + entity = EntityTypes.DONKEY.a(world); } else if (Mule.class.isAssignableFrom(clazz)) { - entity = EntityTypes.MULE.create(world); // Paper + entity = EntityTypes.MULE.a(world); } else if (Llama.class.isAssignableFrom(clazz)) { - entity = EntityTypes.LLAMA.create(world); // Paper + if (TraderLlama.class.isAssignableFrom(clazz)) { + entity = EntityTypes.TRADER_LLAMA.a(world); + } else { + entity = EntityTypes.LLAMA.a(world); + } } } else if (SkeletonHorse.class.isAssignableFrom(clazz)) { - entity = EntityTypes.SKELETON_HORSE.create(world); // Paper + entity = EntityTypes.SKELETON_HORSE.a(world); } else if (ZombieHorse.class.isAssignableFrom(clazz)) { - entity = EntityTypes.ZOMBIE_HORSE.create(world); // Paper + entity = EntityTypes.ZOMBIE_HORSE.a(world); } else { - entity = EntityTypes.HORSE.create(world); // Paper + entity = EntityTypes.HORSE.a(world); } } else if (Skeleton.class.isAssignableFrom(clazz)) { if (Stray.class.isAssignableFrom(clazz)){ - entity = EntityTypes.STRAY.create(world); // Paper + entity = EntityTypes.STRAY.a(world); } else if (WitherSkeleton.class.isAssignableFrom(clazz)) { - entity = EntityTypes.WITHER_SKELETON.create(world); // Paper + entity = EntityTypes.WITHER_SKELETON.a(world); } else { - entity = EntityTypes.SKELETON.create(world); // Paper + entity = EntityTypes.SKELETON.a(world); } } else if (Slime.class.isAssignableFrom(clazz)) { if (MagmaCube.class.isAssignableFrom(clazz)) { - entity = EntityTypes.MAGMA_CUBE.create(world); // Paper + entity = EntityTypes.MAGMA_CUBE.a(world); } else { - entity = EntityTypes.SLIME.create(world); // Paper + entity = EntityTypes.SLIME.a(world); } } else if (Spider.class.isAssignableFrom(clazz)) { if (CaveSpider.class.isAssignableFrom(clazz)) { - entity = EntityTypes.CAVE_SPIDER.create(world); // Paper + entity = EntityTypes.CAVE_SPIDER.a(world); } else { - entity = EntityTypes.SPIDER.create(world); // Paper + entity = EntityTypes.SPIDER.a(world); } } else if (Squid.class.isAssignableFrom(clazz)) { - entity = EntityTypes.SQUID.create(world); // Paper + entity = EntityTypes.SQUID.a(world); } else if (Tameable.class.isAssignableFrom(clazz)) { if (Wolf.class.isAssignableFrom(clazz)) { - entity = EntityTypes.WOLF.create(world); // Paper - } else if (Ocelot.class.isAssignableFrom(clazz)) { - entity = EntityTypes.OCELOT.create(world); // Paper + entity = EntityTypes.WOLF.a(world); } else if (Parrot.class.isAssignableFrom(clazz)) { - entity = EntityTypes.PARROT.create(world); // Paper + entity = EntityTypes.PARROT.a(world); + } else if (Cat.class.isAssignableFrom(clazz)) { + entity = EntityTypes.CAT.a(world); } } else if (PigZombie.class.isAssignableFrom(clazz)) { - entity = EntityTypes.ZOMBIE_PIGMAN.create(world); // Paper + entity = EntityTypes.ZOMBIE_PIGMAN.a(world); } else if (Zombie.class.isAssignableFrom(clazz)) { if (Husk.class.isAssignableFrom(clazz)) { - entity = EntityTypes.HUSK.create(world); // Paper + entity = EntityTypes.HUSK.a(world); } else if (ZombieVillager.class.isAssignableFrom(clazz)) { - entity = EntityTypes.ZOMBIE_VILLAGER.create(world); // Paper + entity = EntityTypes.ZOMBIE_VILLAGER.a(world); } else if (Drowned.class.isAssignableFrom(clazz)) { - entity = EntityTypes.DROWNED.create(world); // Paper + entity = EntityTypes.DROWNED.a(world); } else { - entity = EntityTypes.ZOMBIE.create(world); // Paper + entity = new EntityZombie(world); } } else if (Giant.class.isAssignableFrom(clazz)) { - entity = EntityTypes.GIANT.create(world); // Paper + entity = EntityTypes.GIANT.a(world); } else if (Silverfish.class.isAssignableFrom(clazz)) { - entity = EntityTypes.SILVERFISH.create(world); // Paper + entity = EntityTypes.SILVERFISH.a(world); } else if (Enderman.class.isAssignableFrom(clazz)) { - entity = EntityTypes.ENDERMAN.create(world); // Paper + entity = EntityTypes.ENDERMAN.a(world); } else if (Blaze.class.isAssignableFrom(clazz)) { - entity = EntityTypes.BLAZE.create(world); // Paper - } else if (Villager.class.isAssignableFrom(clazz)) { - entity = EntityTypes.VILLAGER.create(world); // Paper + entity = EntityTypes.BLAZE.a(world); + } else if (AbstractVillager.class.isAssignableFrom(clazz)) { + if (Villager.class.isAssignableFrom(clazz)) { + entity = EntityTypes.VILLAGER.a(world); + } else if (WanderingTrader.class.isAssignableFrom(clazz)) { + entity = EntityTypes.WANDERING_TRADER.a(world); + } } else if (Witch.class.isAssignableFrom(clazz)) { - entity = EntityTypes.WITCH.create(world); // Paper + entity = EntityTypes.WITCH.a(world); } else if (Wither.class.isAssignableFrom(clazz)) { - entity = EntityTypes.WITHER.create(world); // Paper + entity = EntityTypes.WITHER.a(world); } else if (ComplexLivingEntity.class.isAssignableFrom(clazz)) { if (EnderDragon.class.isAssignableFrom(clazz)) { - entity = EntityTypes.ENDER_DRAGON.create(world); // Paper + entity = EntityTypes.ENDER_DRAGON.a(world); } } else if (Ambient.class.isAssignableFrom(clazz)) { if (Bat.class.isAssignableFrom(clazz)) { - entity = EntityTypes.BAT.create(world); // Paper + entity = EntityTypes.BAT.a(world); } } else if (Rabbit.class.isAssignableFrom(clazz)) { - entity = EntityTypes.RABBIT.create(world); // Paper + entity = EntityTypes.RABBIT.a(world); } else if (Endermite.class.isAssignableFrom(clazz)) { - entity = EntityTypes.ENDERMITE.create(world); // Paper + entity = EntityTypes.ENDERMITE.a(world); } else if (Guardian.class.isAssignableFrom(clazz)) { if (ElderGuardian.class.isAssignableFrom(clazz)){ - entity = EntityTypes.ELDER_GUARDIAN.create(world); // Paper + entity = EntityTypes.ELDER_GUARDIAN.a(world); } else { - entity = EntityTypes.GUARDIAN.create(world); // Paper + entity = EntityTypes.GUARDIAN.a(world); } } else if (ArmorStand.class.isAssignableFrom(clazz)) { - entity = EntityTypes.ARMOR_STAND.create(world); // Paper + entity = new EntityArmorStand(world, x, y, z); } else if (PolarBear.class.isAssignableFrom(clazz)) { - entity = EntityTypes.POLAR_BEAR.create(world); // Paper + entity = EntityTypes.POLAR_BEAR.a(world); } else if (Vex.class.isAssignableFrom(clazz)) { - entity = EntityTypes.VEX.create(world); // Paper + entity = EntityTypes.VEX.a(world); } else if (Illager.class.isAssignableFrom(clazz)) { if (Spellcaster.class.isAssignableFrom(clazz)) { if (Evoker.class.isAssignableFrom(clazz)) { - entity = EntityTypes.EVOKER.create(world); // Paper + entity = EntityTypes.EVOKER.a(world); } else if (Illusioner.class.isAssignableFrom(clazz)) { - entity = EntityTypes.ILLUSIONER.create(world); // Paper + entity = EntityTypes.ILLUSIONER.a(world); } } else if (Vindicator.class.isAssignableFrom(clazz)) { - entity = EntityTypes.VINDICATOR.create(world); // Paper + entity = EntityTypes.VINDICATOR.a(world); + } else if (Pillager.class.isAssignableFrom(clazz)) { + entity = EntityTypes.PILLAGER.a(world); } } else if (Turtle.class.isAssignableFrom(clazz)) { - entity = EntityTypes.TURTLE.create(world); // Paper + entity = EntityTypes.TURTLE.a(world); } else if (Phantom.class.isAssignableFrom(clazz)) { - entity = EntityTypes.PHANTOM.create(world); // Paper + entity = EntityTypes.PHANTOM.a(world); } else if (Fish.class.isAssignableFrom(clazz)) { if (Cod.class.isAssignableFrom(clazz)) { - entity = EntityTypes.COD.create(world); // Paper + entity = EntityTypes.COD.a(world); } else if (PufferFish.class.isAssignableFrom(clazz)) { - entity = EntityTypes.PUFFERFISH.create(world); // Paper + entity = EntityTypes.PUFFERFISH.a(world); } else if (Salmon.class.isAssignableFrom(clazz)) { - entity = EntityTypes.SALMON.create(world); // Paper + entity = EntityTypes.SALMON.a(world); } else if (TropicalFish.class.isAssignableFrom(clazz)) { - entity = EntityTypes.TROPICAL_FISH.create(world); // Paper + entity = EntityTypes.TROPICAL_FISH.a(world); } } else if (Dolphin.class.isAssignableFrom(clazz)) { - entity = EntityTypes.DOLPHIN.create(world); // Paper + entity = EntityTypes.DOLPHIN.a(world); + } else if (Ocelot.class.isAssignableFrom(clazz)) { + entity = EntityTypes.OCELOT.a(world); + } else if (Ravager.class.isAssignableFrom(clazz)) { + entity = EntityTypes.RAVAGER.a(world); + } else if (Panda.class.isAssignableFrom(clazz)) { + entity = EntityTypes.PANDA.a(world); + } else if (Fox.class.isAssignableFrom(clazz)) { + entity = EntityTypes.FOX.a(world); } if (entity != null) { @@ -1357,13 +1784,20 @@ public class CraftWorld implements World { height = 9; } - BlockFace[] faces = new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH, BlockFace.UP, BlockFace.DOWN}; - final BlockPosition pos = new BlockPosition((int) x, (int) y, (int) z); + // Paper start - In addition to d65a2576e40e58c8e446b330febe6799d13a604f do not check UP/DOWN for non item frames + // BlockFace[] faces = new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH, BlockFace.UP, BlockFace.DOWN}; + BlockFace[] faces = (ItemFrame.class.isAssignableFrom(clazz)) + ? new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH, BlockFace.UP, BlockFace.DOWN} + : new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH}; + // Paper end + final BlockPosition pos = new BlockPosition(x, y, z); for (BlockFace dir : faces) { IBlockData nmsBlock = world.getType(pos.shift(CraftBlock.blockFaceToNotch(dir))); if (nmsBlock.getMaterial().isBuildable() || BlockDiodeAbstract.isDiode(nmsBlock)) { boolean taken = false; - AxisAlignedBB bb = EntityHanging.calculateBoundingBox(null, pos, CraftBlock.blockFaceToNotch(dir).opposite(), width, height); + AxisAlignedBB bb = (ItemFrame.class.isAssignableFrom(clazz)) + ? EntityItemFrame.calculateBoundingBox(null, pos, CraftBlock.blockFaceToNotch(dir).opposite(), width, height) + : EntityHanging.calculateBoundingBox(null, pos, CraftBlock.blockFaceToNotch(dir).opposite(), width, height); List list = (List) world.getEntities(null, bb); for (Iterator it = list.iterator(); !taken && it.hasNext();) { net.minecraft.server.Entity e = it.next(); @@ -1380,7 +1814,7 @@ public class CraftWorld implements World { } if (LeashHitch.class.isAssignableFrom(clazz)) { - entity = new EntityLeash(world, new BlockPosition((int) x, (int) y, (int) z)); + entity = new EntityLeash(world, new BlockPosition(x, y, z)); entity.attachedToPlayer = true; } else { // No valid face found @@ -1388,9 +1822,9 @@ public class CraftWorld implements World { EnumDirection dir = CraftBlock.blockFaceToNotch(face).opposite(); if (Painting.class.isAssignableFrom(clazz)) { - entity = new EntityPainting(world, new BlockPosition((int) x, (int) y, (int) z), dir); + entity = new EntityPainting(world, new BlockPosition(x, y, z), dir); } else if (ItemFrame.class.isAssignableFrom(clazz)) { - entity = new EntityItemFrame(world, new BlockPosition((int) x, (int) y, (int) z), dir); + entity = new EntityItemFrame(world, new BlockPosition(x, y, z), dir); } } @@ -1401,12 +1835,8 @@ public class CraftWorld implements World { entity = new EntityTNTPrimed(world, x, y, z, null); } else if (ExperienceOrb.class.isAssignableFrom(clazz)) { entity = new EntityExperienceOrb(world, x, y, z, 0, org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM, null, null); // Paper - } else if (Weather.class.isAssignableFrom(clazz)) { - // not sure what this can do - if (LightningStrike.class.isAssignableFrom(clazz)) { - entity = new EntityLightning(world, x, y, z, false); - // what is this, I don't even - } + } else if (LightningStrike.class.isAssignableFrom(clazz)) { + entity = new EntityLightning(world, x, y, z, false); } else if (Firework.class.isAssignableFrom(clazz)) { entity = new EntityFireworks(world, x, y, z, net.minecraft.server.ItemStack.a); } else if (AreaEffectCloud.class.isAssignableFrom(clazz)) { @@ -1417,9 +1847,9 @@ public class CraftWorld implements World { if (entity != null) { // Spigot start - if (entity instanceof EntityOcelot) + if (entity instanceof net.minecraft.server.EntityOcelot) { - ( (EntityOcelot) entity ).spawnBonus = false; + ( (net.minecraft.server.EntityOcelot) entity ).spawnBonus = false; } // Spigot end return entity; @@ -1438,7 +1868,7 @@ public class CraftWorld implements World { Preconditions.checkArgument(entity != null, "Cannot spawn null entity"); if (entity instanceof EntityInsentient) { - ((EntityInsentient) entity).prepare(getHandle().getDamageScaler(new BlockPosition(entity)), (GroupDataEntity) null, null); + ((EntityInsentient) entity).prepare(getHandle(), getHandle().getDamageScaler(new BlockPosition(entity)), EnumMobSpawn.COMMAND, (GroupDataEntity) null, null); } if (function != null) { @@ -1455,56 +1885,58 @@ public class CraftWorld implements World { return addEntity(entity, reason, function); } + @Override public ChunkSnapshot getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTempRain) { return CraftChunk.getEmptyChunkSnapshot(x, z, this, includeBiome, includeBiomeTempRain); } + @Override public void setSpawnFlags(boolean allowMonsters, boolean allowAnimals) { world.setSpawnFlags(allowMonsters, allowAnimals); } + @Override public boolean getAllowAnimals() { - return world.allowAnimals; + return world.getChunkProvider().allowAnimals; } + @Override public boolean getAllowMonsters() { - return world.allowMonsters; + return world.getChunkProvider().allowMonsters; } + @Override public int getMaxHeight() { - return world.getHeight(); + return world.getBuildHeight(); } + @Override public int getSeaLevel() { return world.getSeaLevel(); } + @Override public boolean getKeepSpawnInMemory() { return world.keepSpawnInMemory; } + @Override public void setKeepSpawnInMemory(boolean keepLoaded) { + // Paper start - Configurable spawn radius + if (keepLoaded == world.keepSpawnInMemory) { + // do nothing, nothing has changed + return; + } world.keepSpawnInMemory = keepLoaded; // Grab the worlds spawn chunk - BlockPosition chunkcoordinates = this.world.getSpawn(); - int chunkCoordX = chunkcoordinates.getX() >> 4; - int chunkCoordZ = chunkcoordinates.getZ() >> 4; - // Cycle through the 25x25 Chunks around it to load/unload the chunks. - int radius = world.paperConfig.keepLoadedRange / 16; // Paper - // Paper start - for (ChunkCoordIntPair coords : world.getChunkProvider().getSpiralOutChunks(world.getSpawn(), radius)) {{ - int x = coords.x; - int z = coords.z; - // Paper end - if (keepLoaded) { - getChunkAtAsync(chunkCoordX + x, chunkCoordZ + z, chunk -> {}); // Paper - Async Chunks - } else { - if (isChunkLoaded(chunkCoordX + x, chunkCoordZ + z)) { - unloadChunk(chunkCoordX + x, chunkCoordZ + z); - } - } - } + BlockPosition prevSpawn = this.world.getSpawn(); + if (keepLoaded) { + world.addTicketsForSpawn(world.paperConfig.keepLoadedRange, prevSpawn); + } else { + // TODO: doesn't work well if spawn changed.... // paper - resolved + world.removeTicketsForSpawn(world.paperConfig.keepLoadedRange, prevSpawn); } + // Paper end } @Override @@ -1526,10 +1958,12 @@ public class CraftWorld implements World { return this.getUID() == other.getUID(); } + @Override public File getWorldFolder() { - return ((WorldNBTStorage) world.getDataManager()).getDirectory(); + return world.getDataManager().getDirectory(); } + @Override public void sendPluginMessage(Plugin source, String channel, byte[] message) { StandardMessenger.validatePluginMessage(server.getMessenger(), source, channel, message); @@ -1538,6 +1972,7 @@ public class CraftWorld implements World { } } + @Override public Set getListeningPluginChannels() { Set result = new HashSet(); @@ -1548,46 +1983,57 @@ public class CraftWorld implements World { return result; } + @Override public org.bukkit.WorldType getWorldType() { return org.bukkit.WorldType.getByName(world.getWorldData().getType().name()); } + @Override public boolean canGenerateStructures() { return world.getWorldData().shouldGenerateMapFeatures(); } + @Override public long getTicksPerAnimalSpawns() { return world.ticksPerAnimalSpawns; } + @Override public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns) { world.ticksPerAnimalSpawns = ticksPerAnimalSpawns; } + @Override public long getTicksPerMonsterSpawns() { return world.ticksPerMonsterSpawns; } + @Override public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns) { world.ticksPerMonsterSpawns = ticksPerMonsterSpawns; } + @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { server.getWorldMetadata().setMetadata(this, metadataKey, newMetadataValue); } + @Override public List getMetadata(String metadataKey) { return server.getWorldMetadata().getMetadata(this, metadataKey); } + @Override public boolean hasMetadata(String metadataKey) { return server.getWorldMetadata().hasMetadata(this, metadataKey); } + @Override public void removeMetadata(String metadataKey, Plugin owningPlugin) { server.getWorldMetadata().removeMetadata(this, metadataKey, owningPlugin); } + @Override public int getMonsterSpawnLimit() { if (monsterSpawn < 0) { return server.getMonsterSpawnLimit(); @@ -1596,10 +2042,12 @@ public class CraftWorld implements World { return monsterSpawn; } + @Override public void setMonsterSpawnLimit(int limit) { monsterSpawn = limit; } + @Override public int getAnimalSpawnLimit() { if (animalSpawn < 0) { return server.getAnimalSpawnLimit(); @@ -1608,10 +2056,12 @@ public class CraftWorld implements World { return animalSpawn; } + @Override public void setAnimalSpawnLimit(int limit) { animalSpawn = limit; } + @Override public int getWaterAnimalSpawnLimit() { if (waterAnimalSpawn < 0) { return server.getWaterAnimalSpawnLimit(); @@ -1620,10 +2070,12 @@ public class CraftWorld implements World { return waterAnimalSpawn; } + @Override public void setWaterAnimalSpawnLimit(int limit) { waterAnimalSpawn = limit; } + @Override public int getAmbientSpawnLimit() { if (ambientSpawn < 0) { return server.getAmbientSpawnLimit(); @@ -1632,14 +2084,17 @@ public class CraftWorld implements World { return ambientSpawn; } + @Override public void setAmbientSpawnLimit(int limit) { ambientSpawn = limit; } + @Override public void playSound(Location loc, Sound sound, float volume, float pitch) { playSound(loc, sound, org.bukkit.SoundCategory.MASTER, volume, pitch); } + @Override public void playSound(Location loc, String sound, float volume, float pitch) { playSound(loc, sound, org.bukkit.SoundCategory.MASTER, volume, pitch); } @@ -1652,7 +2107,7 @@ public class CraftWorld implements World { double y = loc.getY(); double z = loc.getZ(); - getHandle().a(null, x, y, z, CraftSound.getSoundEffect(CraftSound.getSound(sound)), SoundCategory.valueOf(category.name()), volume, pitch); // PAIL: rename + getHandle().playSound(null, x, y, z, CraftSound.getSoundEffect(CraftSound.getSound(sound)), SoundCategory.valueOf(category.name()), volume, pitch); } @Override @@ -1667,45 +2122,85 @@ public class CraftWorld implements World { world.getMinecraftServer().getPlayerList().sendPacketNearby(null, x, y, z, volume > 1.0F ? 16.0F * volume : 16.0D, this.world, packet); // Paper - this.world.dimension -> this.world } + private static Map> gamerules; + public static synchronized Map> getGameRulesNMS() { + if (gamerules != null) { + return gamerules; + } + + Map> gamerules = new HashMap<>(); + GameRules.a(new GameRules.GameRuleVisitor() { + @Override + public > void a(GameRules.GameRuleKey gamerules_gamerulekey, GameRules.GameRuleDefinition gamerules_gameruledefinition) { + gamerules.put(gamerules_gamerulekey.a(), gamerules_gamerulekey); + } + }); + + return CraftWorld.gamerules = gamerules; + } + + private static Map> gameruleDefinitions; + public static synchronized Map> getGameRuleDefinitions() { + if (gameruleDefinitions != null) { + return gameruleDefinitions; + } + + Map> gameruleDefinitions = new HashMap<>(); + GameRules.a(new GameRules.GameRuleVisitor() { + @Override + public > void a(GameRules.GameRuleKey gamerules_gamerulekey, GameRules.GameRuleDefinition gamerules_gameruledefinition) { + gameruleDefinitions.put(gamerules_gamerulekey.a(), gamerules_gameruledefinition); + } + }); + + return CraftWorld.gameruleDefinitions = gameruleDefinitions; + } + + @Override public String getGameRuleValue(String rule) { // In method contract for some reason if (rule == null) { return null; } - GameRules.GameRuleValue value = getHandle().getGameRules().get(rule); - return value != null ? value.a() : ""; + GameRules.GameRuleValue value = getHandle().getGameRules().get(getGameRulesNMS().get(rule)); + return value != null ? value.toString() : ""; } + @Override public boolean setGameRuleValue(String rule, String value) { // No null values allowed if (rule == null || value == null) return false; if (!isGameRule(rule)) return false; - getHandle().getGameRules().set(rule, value, getHandle().getMinecraftServer()); + GameRules.GameRuleValue handle = getHandle().getGameRules().get(getGameRulesNMS().get(rule)); + handle.setValue(value); + handle.onChange(getHandle().getMinecraftServer()); return true; } + @Override public String[] getGameRules() { - return GameRules.getGameRules().keySet().toArray(new String[GameRules.getGameRules().size()]); + return getGameRulesNMS().keySet().toArray(new String[getGameRulesNMS().size()]); } + @Override public boolean isGameRule(String rule) { Validate.isTrue(rule != null && !rule.isEmpty(), "Rule cannot be null nor empty"); - return GameRules.getGameRules().containsKey(rule); + return getGameRulesNMS().containsKey(rule); } @Override public T getGameRuleValue(GameRule rule) { Validate.notNull(rule, "GameRule cannot be null"); - return convert(rule, getHandle().getGameRules().get(rule.getName())); + return convert(rule, getHandle().getGameRules().get(getGameRulesNMS().get(rule.getName()))); } @Override public T getGameRuleDefault(GameRule rule) { Validate.notNull(rule, "GameRule cannot be null"); - return convert(rule, GameRules.getGameRules().get(rule.getName()).a()); + return convert(rule, getGameRuleDefinitions().get(rule.getName()).getValue()); } @Override @@ -1715,22 +2210,23 @@ public class CraftWorld implements World { if (!isGameRule(rule.getName())) return false; - getHandle().getGameRules().set(rule.getName(), newValue.toString(), getHandle().getMinecraftServer()); + GameRules.GameRuleValue handle = getHandle().getGameRules().get(getGameRulesNMS().get(rule.getName())); + handle.setValue(newValue.toString()); + handle.onChange(getHandle().getMinecraftServer()); return true; } - private T convert(GameRule rule, GameRules.GameRuleValue value) { + private T convert(GameRule rule, GameRules.GameRuleValue value) { if (value == null) { return null; } - switch (value.getType()) { - case BOOLEAN_VALUE: - return rule.getType().cast(value.b()); - case NUMERICAL_VALUE: - return rule.getType().cast(value.c()); - default: - throw new IllegalArgumentException("Invalid GameRule type (" + value.getType() + ") for GameRule " + rule.getName()); + if (value instanceof GameRules.GameRuleBoolean) { + return rule.getType().cast(((GameRules.GameRuleBoolean) value).a()); + } else if (value instanceof GameRules.GameRuleInt) { + return rule.getType().cast(value.getIntValue()); + } else { + throw new IllegalArgumentException("Invalid GameRule type (" + value + ") for GameRule " + rule.getName()); } } @@ -1838,33 +2334,48 @@ public class CraftWorld implements World { return (nearest == null) ? null : new Location(this, nearest.getX(), nearest.getY(), nearest.getZ()); } - public void processChunkGC() { - chunkGCTickCount++; + @Override + public Raid locateNearestRaid(Location location, int radius) { + Validate.notNull(location, "Location cannot be null"); + Validate.isTrue(radius >= 0, "Radius cannot be negative"); - if (chunkLoadCount >= server.chunkGCLoadThresh && server.chunkGCLoadThresh > 0) { - chunkLoadCount = 0; - } else if (chunkGCTickCount >= server.chunkGCPeriod && server.chunkGCPeriod > 0) { - chunkGCTickCount = 0; - } else { - return; - } - - ChunkProviderServer cps = world.getChunkProvider(); - for (net.minecraft.server.Chunk chunk : cps.chunks.values()) { - // If in use, skip it - if (isChunkInUse(chunk.locX, chunk.locZ) || chunk.scheduledForUnload != null) { // Paper - delayed chunk unloads - continue; - } - - // Already unloading? - if (cps.unloadQueue.contains(ChunkCoordIntPair.a(chunk.locX, chunk.locZ))) { - continue; - } - - // Add unload request - cps.unload(chunk); - } + PersistentRaid persistentRaid = world.C(); // PAIL rename getPersistentRaid + net.minecraft.server.Raid raid = persistentRaid.a(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), radius * radius); // PAIL rename getNearbyRaid + return (raid == null) ? null : new CraftRaid(raid); } + + @Override + public List getRaids() { + PersistentRaid persistentRaid = world.C(); // PAIL rename getPersistentRaid + return persistentRaid.a.values().stream().map(CraftRaid::new).collect(Collectors.toList()); + } + + // Paper start + @Override + public CompletableFuture getChunkAtAsync(int x, int z, boolean gen) { + if (Bukkit.isPrimaryThread()) { + net.minecraft.server.Chunk immediate = this.world.getChunkProvider().getChunkAtIfLoadedImmediately(x, z); + if (immediate != null) { + return CompletableFuture.completedFuture(immediate.bukkitChunk); + } + } + + CompletableFuture ret = new CompletableFuture<>(); + this.world.getChunkProvider().getChunkAtAsynchronously(x, z, gen, (net.minecraft.server.Chunk chunk) -> { + ret.complete(chunk == null ? null : chunk.bukkitChunk); + }); + + return ret; + } + // Paper end + + // Spigot start + @Override + public int getViewDistance() { + return world.spigotConfig.viewDistance; + } + // Spigot end + // Spigot start private final Spigot spigot = new Spigot() { @@ -1891,51 +2402,4 @@ public class CraftWorld implements World { return spigot; } // Spigot end - - // Akarin start - @Nullable - @Override - public io.akarin.server.api.structure.Village getNearestVillage(@NotNull Location location, double xRadius, double yRadius, double zRadius) { - List villages = this.world.getPersistentVillage().getVillages(); - - double nearestRange = -1; - Village nearestVillage = null; - - for (Village village : villages) { - BlockPosition center = village.getCenter(); - double xRange = Math.abs(center.getX() - location.getX()); - double yRange = Math.abs(center.getY() - location.getY()); - double zRange = Math.abs(center.getZ() - location.getZ()); - - if (xRange <= xRadius && yRange <= yRadius && zRange <+ zRadius) { - double range = Math.sqrt(xRange * xRange + yRange * yRange + zRange * zRange); - - if (nearestVillage == null || range < nearestRange) { - nearestVillage = village; - nearestRange = range; - } - } - } - - return nearestVillage == null ? null : nearestVillage.village; - } - - @Override - public List getVillagesInRange(@NotNull Location location, double xRadius, double yRadius, double zRadius) { - List villages = this.world.getPersistentVillage().getVillages(); - List villagesInRange = Lists.newArrayList(); - - for (Village village : villages) { - BlockPosition center = village.getCenter(); - double xRange = Math.abs(center.getX() - location.getX()); - double yRange = Math.abs(center.getY() - location.getY()); - double zRange = Math.abs(center.getZ() - location.getZ()); - - if (xRange <= xRadius && yRange <= yRadius && zRange <+ zRadius) - villagesInRange.add(village.village); - } - - return villagesInRange; - } - // Akarin end } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorldBorder.java b/src/main/java/org/bukkit/craftbukkit/CraftWorldBorder.java index 403c854c4..044d46ac8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorldBorder.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorldBorder.java @@ -45,14 +45,14 @@ public class CraftWorldBorder implements WorldBorder { if (time > 0L) { this.handle.transitionSizeBetween(this.handle.getSize(), newSize, time * 1000L); } else { - this.handle.setSize(newSize); + this.handle.setSize(newSize); } } @Override public Location getCenter() { - double x = this.handle.getCenterX(); - double z = this.handle.getCenterZ(); + double x = this.handle.getCenterX(); + double z = this.handle.getCenterZ(); return new Location(this.world, x, 0, z); } @@ -63,7 +63,7 @@ public class CraftWorldBorder implements WorldBorder { x = Math.min(3.0E7D, Math.max(-3.0E7D, x)); z = Math.min(3.0E7D, Math.max(-3.0E7D, z)); - this.handle.setCenter(x, z); + this.handle.setCenter(x, z); } @Override @@ -108,7 +108,7 @@ public class CraftWorldBorder implements WorldBorder { @Override public void setWarningDistance(int distance) { - this.handle.setWarningDistance(distance); + this.handle.setWarningDistance(distance); } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java index 408622c7b..008fb8444 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -7,7 +7,6 @@ import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.List; -import java.util.TimeZone; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -21,7 +20,6 @@ public class Main { public static boolean useConsole = true; public static void main(String[] args) { - io.akarin.server.core.AkarinGlobalConfig.init(new File("akarin.yml")); // Akarin // Todo: Installation script OptionParser parser = new OptionParser() { { @@ -113,6 +111,7 @@ public class Main { .describedAs("Yml file"); acceptsAll(asList("forceUpgrade"), "Whether to force a world upgrade"); + acceptsAll(asList("eraseCache"), "Whether to force cache erase during world upgrade"); acceptsAll(asList("nojline"), "Disables jline and emulates the vanilla console"); @@ -173,8 +172,8 @@ public class Main { } float javaVersion = Float.parseFloat(System.getProperty("java.class.version")); - if (javaVersion > 56.0) { - System.err.println("Unsupported Java detected (" + javaVersion + "). Only up to Java 12 is supported."); + if (javaVersion > 57.0) { + System.err.println("Unsupported Java detected (" + javaVersion + "). Only up to Java 13 is supported."); return; } @@ -220,7 +219,7 @@ public class Main { if (buildDate.before(deadline.getTime())) { // Paper start - This is some stupid bullshit System.err.println("*** Warning, you've not updated in a while! ***"); - System.err.println("*** Please visit our website for the latest information: https://akarin.io/ ***"); // Paper // Akarin + System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads ***"); // Paper //System.err.println("*** Server will start in 20 seconds ***"); //Thread.sleep(TimeUnit.SECONDS.toMillis(20)); // Paper End @@ -239,7 +238,7 @@ public class Main { System.out.println("Unable to read system info"); } // Paper end - + System.setProperty( "library.jansi.version", "Paper" ); // Paper - set meaningless jansi version to prevent git builds from crashing on Windows System.out.println("Loading libraries, please wait..."); MinecraftServer.main(options); } catch (Throwable t) { diff --git a/src/main/java/org/bukkit/craftbukkit/TrigMath.java b/src/main/java/org/bukkit/craftbukkit/TrigMath.java deleted file mode 100644 index 6d613c53c..000000000 --- a/src/main/java/org/bukkit/craftbukkit/TrigMath.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.bukkit.craftbukkit; - -/** - * Credits for this class goes to user aioobe on stackoverflow.com - * Source: http://stackoverflow.com/questions/4454630/j2me-calculate-the-the-distance-between-2-latitude-and-longitude - */ -public class TrigMath { - - static final double sq2p1 = 2.414213562373095048802e0; - static final double sq2m1 = .414213562373095048802e0; - static final double p4 = .161536412982230228262e2; - static final double p3 = .26842548195503973794141e3; - static final double p2 = .11530293515404850115428136e4; - static final double p1 = .178040631643319697105464587e4; - static final double p0 = .89678597403663861959987488e3; - static final double q4 = .5895697050844462222791e2; - static final double q3 = .536265374031215315104235e3; - static final double q2 = .16667838148816337184521798e4; - static final double q1 = .207933497444540981287275926e4; - static final double q0 = .89678597403663861962481162e3; - static final double PIO2 = 1.5707963267948966135E0; - - private static double mxatan(double arg) { - double argsq = arg * arg, value; - - value = ((((p4 * argsq + p3) * argsq + p2) * argsq + p1) * argsq + p0); - value = value / (((((argsq + q4) * argsq + q3) * argsq + q2) * argsq + q1) * argsq + q0); - return value * arg; - } - - private static double msatan(double arg) { - return arg < sq2m1 ? mxatan(arg) - : arg > sq2p1 ? PIO2 - mxatan(1 / arg) - : PIO2 / 2 + mxatan((arg - 1) / (arg + 1)); - } - - public static double atan(double arg) { - return arg > 0 ? msatan(arg) : -msatan(-arg); - } - - public static double atan2(double arg1, double arg2) { - if (arg1 + arg2 == arg1) - return arg1 >= 0 ? PIO2 : -PIO2; - arg1 = atan(arg1 / arg2); - return arg2 < 0 ? arg1 <= 0 ? arg1 + Math.PI : arg1 - Math.PI : arg1; - } -} \ No newline at end of file diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java index 061471835..a5aadf285 100644 --- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java +++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancement.java @@ -25,6 +25,6 @@ public class CraftAdvancement implements org.bukkit.advancement.Advancement { @Override public Collection getCriteria() { - return com.koloboke.collect.set.hash.HashObjSets.newImmutableSet(handle.getCriteria().keySet()); // Akarin - koloboke + return Collections.unmodifiableCollection(handle.getCriteria().keySet()); } } diff --git a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementProgress.java b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementProgress.java index a52131e6e..60fc5aff8 100644 --- a/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementProgress.java +++ b/src/main/java/org/bukkit/craftbukkit/advancement/CraftAdvancementProgress.java @@ -49,11 +49,11 @@ public class CraftAdvancementProgress implements AdvancementProgress { @Override public Collection getRemainingCriteria() { - return com.koloboke.collect.set.hash.HashObjSets.newImmutableSet(Lists.newArrayList(handle.getRemainingCriteria())); // Akarin - koloboke + return Collections.unmodifiableCollection(Lists.newArrayList(handle.getRemainingCriteria())); } @Override public Collection getAwardedCriteria() { - return com.koloboke.collect.set.hash.HashObjSets.newImmutableSet(Lists.newArrayList(handle.getAwardedCriteria())); // Akarin - koloboke + return Collections.unmodifiableCollection(Lists.newArrayList(handle.getAwardedCriteria())); } } diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java index 07b457e8a..f9da97c07 100644 --- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java +++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java @@ -25,7 +25,7 @@ public class CraftAttributeInstance implements AttributeInstance { @Override public double getBaseValue() { - return handle.b(); + return handle.getBaseValue(); } @Override @@ -36,7 +36,7 @@ public class CraftAttributeInstance implements AttributeInstance { @Override public Collection getModifiers() { List result = new ArrayList(); - for (net.minecraft.server.AttributeModifier nms : handle.c()) { + for (net.minecraft.server.AttributeModifier nms : handle.getModifiers()) { result.add(convert(nms)); } @@ -46,13 +46,13 @@ public class CraftAttributeInstance implements AttributeInstance { @Override public void addModifier(AttributeModifier modifier) { Preconditions.checkArgument(modifier != null, "modifier"); - handle.b(convert(modifier)); + handle.addModifier(convert(modifier)); } @Override public void removeModifier(AttributeModifier modifier) { Preconditions.checkArgument(modifier != null, "modifier"); - handle.c(convert(modifier)); + handle.removeModifier(convert(modifier)); } @Override @@ -66,10 +66,10 @@ public class CraftAttributeInstance implements AttributeInstance { } public static net.minecraft.server.AttributeModifier convert(AttributeModifier bukkit) { - return new net.minecraft.server.AttributeModifier(bukkit.getUniqueId(), bukkit.getName(), bukkit.getAmount(), bukkit.getOperation().ordinal()); + return new net.minecraft.server.AttributeModifier(bukkit.getUniqueId(), bukkit.getName(), bukkit.getAmount(), net.minecraft.server.AttributeModifier.Operation.values()[bukkit.getOperation().ordinal()]); } public static AttributeModifier convert(net.minecraft.server.AttributeModifier nms) { - return new AttributeModifier(nms.a(), nms.b(), nms.d(), AttributeModifier.Operation.values()[nms.c()]); + return new AttributeModifier(nms.getUniqueId(), nms.getName(), nms.getAmount(), AttributeModifier.Operation.values()[nms.getOperation().ordinal()]); } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java index 1939a881e..754205636 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java @@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.block; import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.List; +import net.minecraft.server.BlockBannerAbstract; import net.minecraft.server.EnumColor; import net.minecraft.server.NBTTagCompound; import net.minecraft.server.NBTTagList; @@ -31,9 +32,7 @@ public class CraftBanner extends CraftBlockEntityState impleme public void load(TileEntityBanner banner) { super.load(banner); - if (banner.color != null) { - base = DyeColor.getByWoolData((byte) banner.color.getColorIndex()); - } + base = DyeColor.getByWoolData((byte) ((BlockBannerAbstract) this.data.getBlock()).getColor().getColorIndex()); patterns = new ArrayList(); if (banner.patterns != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java new file mode 100644 index 000000000..cb5ac0f09 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java @@ -0,0 +1,33 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityBarrel; +import org.bukkit.Material; +import org.bukkit.block.Barrel; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.inventory.Inventory; + +public class CraftBarrel extends CraftLootable implements Barrel { + + public CraftBarrel(Block block) { + super(block, TileEntityBarrel.class); + } + + public CraftBarrel(Material material, TileEntityBarrel te) { + super(material, te); + } + + @Override + public Inventory getSnapshotInventory() { + return new CraftInventory(this.getSnapshot()); + } + + @Override + public Inventory getInventory() { + if (!this.isPlaced()) { + return this.getSnapshotInventory(); + } + + return new CraftInventory(this.getTileEntity()); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java index 5b908d3bf..21ebceafb 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java @@ -2,6 +2,7 @@ package org.bukkit.craftbukkit.block; import java.util.ArrayList; import java.util.Collection; +import net.minecraft.server.ChestLock; import net.minecraft.server.EntityHuman; import net.minecraft.server.MobEffectList; import net.minecraft.server.TileEntity; @@ -9,14 +10,12 @@ import net.minecraft.server.TileEntityBeacon; import org.bukkit.Material; import org.bukkit.block.Beacon; import org.bukkit.block.Block; -import org.bukkit.craftbukkit.inventory.CraftInventoryBeacon; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.entity.LivingEntity; -import org.bukkit.inventory.BeaconInventory; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -public class CraftBeacon extends CraftContainer implements Beacon { +public class CraftBeacon extends CraftBlockEntityState implements Beacon { public CraftBeacon(final Block block) { super(block, TileEntityBeacon.class); @@ -26,20 +25,6 @@ public class CraftBeacon extends CraftContainer implements Bea super(material, te); } - @Override - public BeaconInventory getSnapshotInventory() { - return new CraftInventoryBeacon(this.getSnapshot()); - } - - @Override - public BeaconInventory getInventory() { - if (!this.isPlaced()) { - return this.getSnapshotInventory(); - } - - return new CraftInventoryBeacon(this.getTileEntity()); - } - @Override public Collection getEntitiesInRange() { TileEntity tileEntity = this.getTileEntityFromWorld(); @@ -88,11 +73,26 @@ public class CraftBeacon extends CraftContainer implements Bea @Override public String getCustomName() { TileEntityBeacon beacon = this.getSnapshot(); - return beacon.hasCustomName() ? CraftChatMessage.fromComponent(beacon.getCustomName()) : null; + return beacon.customName != null ? CraftChatMessage.fromComponent(beacon.customName) : null; } @Override public void setCustomName(String name) { this.getSnapshot().setCustomName(CraftChatMessage.fromStringOrNull(name)); } + + @Override + public boolean isLocked() { + return !this.getSnapshot().chestLock.key.isEmpty(); + } + + @Override + public String getLock() { + return this.getSnapshot().chestLock.key; + } + + @Override + public void setLock(String key) { + this.getSnapshot().chestLock = (key == null) ? ChestLock.a : new ChestLock(key); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBell.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBell.java new file mode 100644 index 000000000..bf5d0c3a1 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBell.java @@ -0,0 +1,16 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityBell; +import org.bukkit.Material; +import org.bukkit.block.Block; + +public class CraftBell extends CraftBlockEntityState { + + public CraftBell(Block block) { + super(block, TileEntityBell.class); + } + + public CraftBell(Material material, TileEntityBell te) { + super(material, te); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlastFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlastFurnace.java new file mode 100644 index 000000000..6a6a89848 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlastFurnace.java @@ -0,0 +1,17 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityBlastFurnace; +import org.bukkit.Material; +import org.bukkit.block.BlastFurnace; +import org.bukkit.block.Block; + +public class CraftBlastFurnace extends CraftFurnace implements BlastFurnace { + + public CraftBlastFurnace(Block block) { + super(block, TileEntityBlastFurnace.class); + } + + public CraftBlastFurnace(Material material, TileEntityBlastFurnace te) { + super(material, te); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java index 7ae4b7952..fc65cef63 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -1,13 +1,27 @@ package org.bukkit.craftbukkit.block; import com.google.common.base.Preconditions; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; - -import net.minecraft.server.*; - +import java.util.stream.Collectors; +import net.minecraft.server.AxisAlignedBB; +import net.minecraft.server.BiomeBase; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.BlockRedstoneWire; +import net.minecraft.server.BlockTileEntity; +import net.minecraft.server.Blocks; +import net.minecraft.server.EnumDirection; +import net.minecraft.server.EnumSkyBlock; +import net.minecraft.server.GeneratorAccess; +import net.minecraft.server.IBlockData; +import net.minecraft.server.IRegistry; +import net.minecraft.server.MinecraftKey; +import net.minecraft.server.MovingObjectPosition; +import net.minecraft.server.RayTrace; +import net.minecraft.server.TileEntity; +import net.minecraft.server.Vec3D; +import net.minecraft.server.VoxelShape; +import net.minecraft.server.WorldServer; import org.apache.commons.lang.Validate; import org.bukkit.Chunk; import org.bukkit.FluidCollisionMode; @@ -40,7 +54,7 @@ public class CraftBlock implements Block { public CraftBlock(GeneratorAccess world, BlockPosition position) { this.world = world; - this.position = position.h(); + this.position = position.immutableCopy(); } public static CraftBlock at(GeneratorAccess world, BlockPosition position) { @@ -59,6 +73,7 @@ public class CraftBlock implements Block { return position; } + @Override public World getWorld() { return world.getMinecraftWorld().getWorld(); } @@ -67,10 +82,12 @@ public class CraftBlock implements Block { return (CraftWorld) getWorld(); } + @Override public Location getLocation() { return new Location(getWorld(), position.getX(), position.getY(), position.getZ()); } + @Override public Location getLocation(Location loc) { if (loc != null) { loc.setWorld(getWorld()); @@ -88,18 +105,22 @@ public class CraftBlock implements Block { return new BlockVector(getX(), getY(), getZ()); } + @Override public int getX() { return position.getX(); } + @Override public int getY() { return position.getY(); } + @Override public int getZ() { return position.getZ(); } + @Override public Chunk getChunk() { return getWorld().getChunkAt(this); } @@ -124,6 +145,7 @@ public class CraftBlock implements Block { return world.getType(position); } + @Override public byte getData() { IBlockData blockData = world.getType(position); return CraftMagicNumbers.toLegacyData(blockData); @@ -134,6 +156,7 @@ public class CraftBlock implements Block { return CraftBlockData.fromData(getData0()); } + @Override public void setType(final Material type) { setType(type, true); } @@ -158,7 +181,12 @@ public class CraftBlock implements Block { public boolean setTypeAndData(final IBlockData blockData, final boolean applyPhysics) { // SPIGOT-611: need to do this to prevent glitchiness. Easier to handle this here (like /setblock) than to fix weirdness in tile entity cleanup if (!blockData.isAir() && blockData.getBlock() instanceof BlockTileEntity && blockData.getBlock() != getNMSBlock()) { - world.setTypeAndData(position, Blocks.AIR.getBlockData(), 0); + // SPIGOT-4612: faster - just clear tile + if (world instanceof net.minecraft.server.World) { + ((net.minecraft.server.World) world).removeTileEntity(position); + } else { + world.setTypeAndData(position, Blocks.AIR.getBlockData(), 0); + } } if (applyPhysics) { @@ -178,18 +206,22 @@ public class CraftBlock implements Block { } } + @Override public Material getType() { return CraftMagicNumbers.getMaterial(world.getType(position).getBlock()); } + @Override public byte getLightLevel() { return (byte) world.getMinecraftWorld().getLightLevel(position); } + @Override public byte getLightFromSky() { return (byte) world.getBrightness(EnumSkyBlock.SKY, position); } + @Override public byte getLightFromBlocks() { return (byte) world.getBrightness(EnumSkyBlock.BLOCK, position); } @@ -203,18 +235,22 @@ public class CraftBlock implements Block { return getRelative(face, distance); } + @Override public Block getRelative(final int modX, final int modY, final int modZ) { return getWorld().getBlockAt(getX() + modX, getY() + modY, getZ() + modZ); } + @Override public Block getRelative(BlockFace face) { return getRelative(face, 1); } + @Override public Block getRelative(BlockFace face, int distance) { return getRelative(face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance); } + @Override public BlockFace getFace(final Block block) { BlockFace[] values = BlockFace.values(); @@ -274,6 +310,7 @@ public class CraftBlock implements Block { } } + @Override public BlockState getState() { // Paper start - allow disabling the use of snapshots return getState(true); @@ -292,14 +329,24 @@ public class CraftBlock implements Block { Material material = getType(); switch (material) { - case SIGN: - case WALL_SIGN: + case ACACIA_SIGN: + case ACACIA_WALL_SIGN: + case BIRCH_SIGN: + case BIRCH_WALL_SIGN: + case DARK_OAK_SIGN: + case DARK_OAK_WALL_SIGN: + case JUNGLE_SIGN: + case JUNGLE_WALL_SIGN: + case OAK_SIGN: + case OAK_WALL_SIGN: + case SPRUCE_SIGN: + case SPRUCE_WALL_SIGN: return new CraftSign(this); case CHEST: case TRAPPED_CHEST: return new CraftChest(this); case FURNACE: - return new CraftFurnace(this); + return new CraftFurnaceFurnace(this); case DISPENSER: return new CraftDispenser(this); case DROPPER: @@ -413,6 +460,20 @@ public class CraftBlock implements Block { return new CraftBed(this); case CONDUIT: return new CraftConduit(this); + case BARREL: + return new CraftBarrel(this); + case BELL: + return new CraftBell(this); + case BLAST_FURNACE: + return new CraftBlastFurnace(this); + case CAMPFIRE: + return new CraftCampfire(this); + case JIGSAW: + return new CraftJigsaw(this); + case LECTERN: + return new CraftLectern(this); + case SMOKER: + return new CraftSmoker(this); default: TileEntity tileEntity = world.getTileEntity(position); if (tileEntity != null) { @@ -425,10 +486,12 @@ public class CraftBlock implements Block { } } + @Override public Biome getBiome() { return getWorld().getBiome(getX(), getZ()); } + @Override public void setBiome(Biome bio) { getWorld().setBiome(getX(), getZ(), bio); } @@ -449,18 +512,22 @@ public class CraftBlock implements Block { return IRegistry.BIOME.get(new MinecraftKey(bio.name().toLowerCase(java.util.Locale.ENGLISH))); } + @Override public double getTemperature() { return world.getBiome(position).getAdjustedTemperature(position); } + @Override public double getHumidity() { return getWorld().getHumidity(getX(), getZ()); } + @Override public boolean isBlockPowered() { return world.getMinecraftWorld().getBlockPower(position) > 0; } + @Override public boolean isBlockIndirectlyPowered() { return world.getMinecraftWorld().isBlockIndirectlyPowered(position); } @@ -479,10 +546,12 @@ public class CraftBlock implements Block { return this.position.hashCode() ^ this.getWorld().hashCode(); } + @Override public boolean isBlockFacePowered(BlockFace face) { return world.getMinecraftWorld().isBlockFacePowered(position, blockFaceToNotch(face)); } + @Override public boolean isBlockFaceIndirectlyPowered(BlockFace face) { int power = world.getMinecraftWorld().getBlockFacePower(position, blockFaceToNotch(face)); @@ -494,6 +563,7 @@ public class CraftBlock implements Block { return power > 0; } + @Override public int getBlockPower(BlockFace face) { int power = 0; BlockRedstoneWire wire = (BlockRedstoneWire) Blocks.REDSTONE_WIRE; @@ -510,110 +580,72 @@ public class CraftBlock implements Block { return power > 0 ? power : (face == BlockFace.SELF ? isBlockIndirectlyPowered() : isBlockFaceIndirectlyPowered(face)) ? 15 : 0; } + @Override public int getBlockPower() { return getBlockPower(BlockFace.SELF); } + @Override public boolean isEmpty() { return getNMS().isAir(); } + @Override public boolean isLiquid() { - return (getType() == Material.WATER) || (getType() == Material.LAVA); + return getNMS().getMaterial().isLiquid(); } + @Override public PistonMoveReaction getPistonMoveReaction() { return PistonMoveReaction.getById(getNMS().getPushReaction().ordinal()); } - private boolean itemCausesDrops(ItemStack item) { - net.minecraft.server.Block block = this.getNMSBlock(); - net.minecraft.server.Item itemType = CraftMagicNumbers.getItem(item.getType()); - return block != null && (block.getBlockData().getMaterial().isAlwaysDestroyable() || (itemType != null && itemType.canDestroySpecialBlock(block.getBlockData()))); + @Override + public boolean breakNaturally() { + return breakNaturally(new ItemStack(Material.AIR)); } - public boolean breakNaturally() { + @Override + public boolean breakNaturally(ItemStack item) { // Order matters here, need to drop before setting to air so skulls can get their data net.minecraft.server.Block block = this.getNMSBlock(); boolean result = false; if (block != null && block != Blocks.AIR) { - block.dropNaturally(getNMS(), world.getMinecraftWorld(), position, 1.0F, 0); + net.minecraft.server.Block.dropItems(getNMS(), world.getMinecraftWorld(), position, world.getTileEntity(position), null, CraftItemStack.asNMSCopy(item)); result = true; } - setType(Material.AIR); - return result; - } - - public boolean breakNaturally(ItemStack item) { - if (itemCausesDrops(item)) { - return breakNaturally(); - } else { - return setTypeAndData(Blocks.AIR.getBlockData(), true); - } + return setTypeAndData(Blocks.AIR.getBlockData(), true) && result; } + @Override public Collection getDrops() { - List drops = new ArrayList(); - - net.minecraft.server.Block block = this.getNMSBlock(); - if (block != Blocks.AIR) { - IBlockData data = getData0(); - // based on nms.Block.dropNaturally - int count = block.getDropCount(data, 0, world.getMinecraftWorld(), position, world.getMinecraftWorld().random); - for (int i = 0; i < count; ++i) { - Item item = block.getDropType(data, world.getMinecraftWorld(), position, 0).getItem(); - if (item != Items.AIR) { - // Skulls are special, their data is based on the tile entity - if (block instanceof BlockSkullAbstract) { - net.minecraft.server.ItemStack nmsStack = block.a((IBlockAccess) world, position, data); - TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(position); - - if ((block == Blocks.PLAYER_HEAD || block == Blocks.PLAYER_WALL_HEAD) && tileentityskull.getGameProfile() != null) { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - - GameProfileSerializer.serialize(nbttagcompound, tileentityskull.getGameProfile()); - nmsStack.getOrCreateTag().set("SkullOwner", nbttagcompound); - } - - drops.add(CraftItemStack.asBukkitCopy(nmsStack)); - // We don't want to drop cocoa blocks, we want to drop cocoa beans. - } else if (Blocks.COCOA == block) { - int age = (Integer) data.get(BlockCocoa.AGE); - int dropAmount = (age >= 2 ? 3 : 1); - for (int j = 0; j < dropAmount; ++j) { - drops.add(new ItemStack(Material.COCOA_BEANS, 1)); - } - } else { - drops.add(new ItemStack(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(item), 1)); - } - } - } - } - return drops; + return getDrops(new ItemStack(Material.AIR)); } + @Override public Collection getDrops(ItemStack item) { - if (itemCausesDrops(item)) { - return getDrops(); - } else { - return Collections.emptyList(); - } + return net.minecraft.server.Block.getDrops(getNMS(), (WorldServer) world.getMinecraftWorld(), position, world.getTileEntity(position), null, CraftItemStack.asNMSCopy(item)) + .stream().map(CraftItemStack::asBukkitCopy).collect(Collectors.toList()); } + @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { getCraftWorld().getBlockMetadata().setMetadata(this, metadataKey, newMetadataValue); } + @Override public List getMetadata(String metadataKey) { return getCraftWorld().getBlockMetadata().getMetadata(this, metadataKey); } + @Override public boolean hasMetadata(String metadataKey) { return getCraftWorld().getBlockMetadata().hasMetadata(this, metadataKey); } + @Override public void removeMetadata(String metadataKey, Plugin owningPlugin) { getCraftWorld().getBlockMetadata().removeMetadata(this, metadataKey, owningPlugin); } @@ -642,25 +674,7 @@ public class CraftBlock implements Block { Vec3D startPos = new Vec3D(start.getX(), start.getY(), start.getZ()); Vec3D endPos = new Vec3D(start.getX() + dir.getX(), start.getY() + dir.getY(), start.getZ() + dir.getZ()); - // Similar to to nms.World#rayTrace: - IBlockData blockData = world.getType(position); - Fluid fluid = world.getFluid(position); - boolean collidableBlock = blockData.getBlock().isCollidable(blockData); - boolean collideWithFluid = CraftFluidCollisionMode.toNMS(fluidCollisionMode).predicate.test(fluid); - - if (!collidableBlock && !collideWithFluid) { - return null; - } - - MovingObjectPosition nmsHitResult = null; - if (collidableBlock) { - nmsHitResult = net.minecraft.server.Block.rayTrace(blockData, world.getMinecraftWorld(), position, startPos, endPos); - } - - if (nmsHitResult == null && collideWithFluid) { - nmsHitResult = VoxelShapes.create(0.0D, 0.0D, 0.0D, 1.0D, (double) fluid.getHeight(), 1.0D).rayTrace(startPos, endPos, position); - } - + MovingObjectPosition nmsHitResult = world.rayTraceBlock(new RayTrace(startPos, endPos, RayTrace.BlockCollisionOption.OUTLINE, CraftFluidCollisionMode.toNMS(fluidCollisionMode), null), position); return CraftRayTraceResult.fromNMS(this.getWorld(), nmsHitResult); } @@ -675,4 +689,11 @@ public class CraftBlock implements Block { AxisAlignedBB aabb = shape.getBoundingBox(); return new BoundingBox(getX() + aabb.minX, getY() + aabb.minY, getZ() + aabb.minZ, getX() + aabb.maxX, getY() + aabb.maxY, getZ() + aabb.maxZ); } + + // Paper start + @Override + public com.destroystokyo.paper.block.BlockSoundGroup getSoundGroup() { + return new com.destroystokyo.paper.block.CraftBlockSoundGroup(getNMSBlock().getBlockData().getStepSound()); + } + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java index 082a1b6e2..3e22d558e 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java @@ -1,14 +1,16 @@ package org.bukkit.craftbukkit.block; +import com.google.common.base.Preconditions; import net.minecraft.server.BlockPosition; import net.minecraft.server.NBTTagCompound; import net.minecraft.server.TileEntity; -import net.minecraft.server.World; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.TileState; import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.persistence.PersistentDataContainer; -public class CraftBlockEntityState extends CraftBlockState { +public class CraftBlockEntityState extends CraftBlockState implements TileState { private final Class tileEntityClass; private final T tileEntity; @@ -17,24 +19,35 @@ public class CraftBlockEntityState extends CraftBlockState public CraftBlockEntityState(Block block, Class tileEntityClass) { super(block); + try {// Paper - show location on failure + this.tileEntityClass = tileEntityClass; // get tile entity from block: CraftWorld world = (CraftWorld) this.getWorld(); this.tileEntity = tileEntityClass.cast(world.getHandle().getTileEntity(this.getPosition())); + Preconditions.checkState(this.tileEntity != null, "Tile is null, asynchronous access? " + block); // Paper start this.snapshotDisabled = DISABLE_SNAPSHOT; if (DISABLE_SNAPSHOT) { this.snapshot = this.tileEntity; } else { - this.snapshot = this.createSnapshot(this.tileEntity, world.getHandle()); + this.snapshot = this.createSnapshot(this.tileEntity); } // copy tile entity data: if(this.snapshot != null) { this.load(this.snapshot); } // Paper end + // Paper start - show location on failure + } catch (Throwable thr) { + if (thr instanceof ThreadDeath) { + throw (ThreadDeath)thr; + } + throw new RuntimeException("Failed to read BlockState at: world: " + block.getWorld().getName() + " location: (" + block.getX() + ", " + block.getY() + ", " + block.getZ() + ")", thr); + } + // Paper end } public final boolean snapshotDisabled; // Paper @@ -50,7 +63,7 @@ public class CraftBlockEntityState extends CraftBlockState if (DISABLE_SNAPSHOT) { this.snapshot = this.tileEntity; } else { - this.snapshot = this.createSnapshot(this.tileEntity, null); + this.snapshot = this.createSnapshot(this.tileEntity); } // copy tile entity data: if(this.snapshot != null) { @@ -59,13 +72,13 @@ public class CraftBlockEntityState extends CraftBlockState // Paper end } - private T createSnapshot(T tileEntity, World world) { + private T createSnapshot(T tileEntity) { if (tileEntity == null) { return null; } NBTTagCompound nbtTagCompound = tileEntity.save(new NBTTagCompound()); - T snapshot = (T) TileEntity.create(nbtTagCompound, world); + T snapshot = (T) TileEntity.create(nbtTagCompound); return snapshot; } @@ -138,4 +151,9 @@ public class CraftBlockEntityState extends CraftBlockState return result; } + + @Override + public PersistentDataContainer getPersistentDataContainer() { + return this.getSnapshot().persistentDataContainer; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java index ab955bd74..0cb5582b1 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java @@ -1,12 +1,15 @@ package org.bukkit.craftbukkit.block; import com.google.common.base.Preconditions; +import java.util.List; import net.minecraft.server.BlockPosition; -import org.bukkit.Location; -import org.bukkit.block.Block; +import net.minecraft.server.GeneratorAccess; +import net.minecraft.server.IBlockData; import org.bukkit.Chunk; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.CraftChunk; @@ -18,10 +21,6 @@ import org.bukkit.material.MaterialData; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; -import java.util.List; -import net.minecraft.server.GeneratorAccess; -import net.minecraft.server.IBlockData; - public class CraftBlockState implements BlockState { private final CraftWorld world; private final CraftChunk chunk; @@ -54,26 +53,31 @@ public class CraftBlockState implements BlockState { } public static CraftBlockState getBlockState(net.minecraft.server.World world, net.minecraft.server.BlockPosition pos, int flag) { - return new CraftBlockState(world.getWorld().getBlockAt(pos), flag); // Akarin + return new CraftBlockState(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()), flag); } + @Override public World getWorld() { requirePlaced(); return world; } + @Override public int getX() { return position.getX(); } + @Override public int getY() { return position.getY(); } + @Override public int getZ() { return position.getZ(); } + @Override public Chunk getChunk() { requirePlaced(); return chunk; @@ -102,6 +106,7 @@ public class CraftBlockState implements BlockState { this.data = ((CraftBlockData) data).getState(); } + @Override public void setData(final MaterialData data) { Material mat = CraftMagicNumbers.getMaterial(this.data).getItemType(); @@ -117,10 +122,12 @@ public class CraftBlockState implements BlockState { } } + @Override public MaterialData getData() { return CraftMagicNumbers.getMaterial(data); } + @Override public void setType(final Material type) { Preconditions.checkArgument(type != null, "Material cannot be null"); Preconditions.checkArgument(type.isBlock(), "Material must be a block!"); @@ -130,6 +137,7 @@ public class CraftBlockState implements BlockState { } } + @Override public Material getType() { return CraftMagicNumbers.getMaterial(data.getBlock()); } @@ -142,23 +150,28 @@ public class CraftBlockState implements BlockState { return flag; } + @Override public byte getLightLevel() { return getBlock().getLightLevel(); } + @Override public CraftBlock getBlock() { requirePlaced(); return CraftBlock.at(world.getHandle(), position); } + @Override public boolean update() { return update(false); } + @Override public boolean update(boolean force) { return update(force, true); } + @Override public boolean update(boolean force, boolean applyPhysics) { if (!isPlaced()) { return true; @@ -188,14 +201,17 @@ public class CraftBlockState implements BlockState { return true; } + @Override public byte getRawData() { return CraftMagicNumbers.toLegacyData(data); } + @Override public Location getLocation() { return new Location(world, getX(), getY(), getZ()); } + @Override public Location getLocation(Location loc) { if (loc != null) { loc.setWorld(world); @@ -209,6 +225,7 @@ public class CraftBlockState implements BlockState { return loc; } + @Override public void setRawData(byte data) { this.data = CraftMagicNumbers.getBlock(getType(), data); } @@ -243,21 +260,25 @@ public class CraftBlockState implements BlockState { return hash; } + @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { requirePlaced(); chunk.getCraftWorld().getBlockMetadata().setMetadata(getBlock(), metadataKey, newMetadataValue); } + @Override public List getMetadata(String metadataKey) { requirePlaced(); return chunk.getCraftWorld().getBlockMetadata().getMetadata(getBlock(), metadataKey); } + @Override public boolean hasMetadata(String metadataKey) { requirePlaced(); return chunk.getCraftWorld().getBlockMetadata().hasMetadata(getBlock(), metadataKey); } + @Override public void removeMetadata(String metadataKey, Plugin owningPlugin) { requirePlaced(); chunk.getCraftWorld().getBlockMetadata().removeMetadata(getBlock(), metadataKey, owningPlugin); @@ -273,4 +294,4 @@ public class CraftBlockState implements BlockState { throw new IllegalStateException("The blockState must be placed to call this method"); } } -} \ No newline at end of file +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java index dafaa6fb3..37b6ad55c 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java @@ -5,7 +5,6 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BrewingStand; import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer; -import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.inventory.BrewerInventory; public class CraftBrewingStand extends CraftContainer implements BrewingStand { @@ -34,41 +33,21 @@ public class CraftBrewingStand extends CraftContainer im @Override public int getBrewingTime() { - return this.getSnapshot().getProperty(0); + return this.getSnapshot().brewTime; } @Override public void setBrewingTime(int brewTime) { - this.getSnapshot().setProperty(0, brewTime); + this.getSnapshot().brewTime = brewTime; } @Override public int getFuelLevel() { - return this.getSnapshot().getProperty(1); + return this.getSnapshot().fuelLevel; } @Override public void setFuelLevel(int level) { - this.getSnapshot().setProperty(1, level); - } - - @Override - public String getCustomName() { - TileEntityBrewingStand brewingStand = this.getSnapshot(); - return brewingStand.hasCustomName() ? CraftChatMessage.fromComponent(brewingStand.getCustomName()) : null; - } - - @Override - public void setCustomName(String name) { - this.getSnapshot().setCustomName(CraftChatMessage.fromStringOrNull(name)); - } - - @Override - public void applyTo(TileEntityBrewingStand brewingStand) { - super.applyTo(brewingStand); - - if (!this.getSnapshot().hasCustomName()) { - brewingStand.setCustomName(null); - } + this.getSnapshot().fuelLevel = level; } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCampfire.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCampfire.java new file mode 100644 index 000000000..95d10dd9f --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCampfire.java @@ -0,0 +1,55 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityCampfire; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Campfire; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +public class CraftCampfire extends CraftBlockEntityState implements Campfire { + + public CraftCampfire(Block block) { + super(block, TileEntityCampfire.class); + } + + public CraftCampfire(Material material, TileEntityCampfire te) { + super(material, te); + } + + @Override + public int getSize() { + return getSnapshot().getItems().size(); + } + + @Override + public ItemStack getItem(int index) { + net.minecraft.server.ItemStack item = getSnapshot().getItems().get(index); + return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item); + } + + @Override + public void setItem(int index, ItemStack item) { + getSnapshot().getItems().set(index, CraftItemStack.asNMSCopy(item)); + } + + @Override + public int getCookTime(int index) { + return getSnapshot().cookingTimes[index]; + } + + @Override + public void setCookTime(int index, int cookTime) { + getSnapshot().cookingTimes[index] = cookTime; + } + + @Override + public int getCookTimeTotal(int index) { + return getSnapshot().cookingTotalTimes[index]; + } + + @Override + public void setCookTimeTotal(int index, int cookTimeTotal) { + getSnapshot().cookingTotalTimes[index] = cookTimeTotal; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java index 14b5be75f..019fa7118 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java @@ -3,9 +3,7 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.BlockChest; import net.minecraft.server.Blocks; import net.minecraft.server.ITileInventory; -import net.minecraft.server.InventoryLargeChest; import net.minecraft.server.TileEntityChest; - import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Chest; @@ -50,10 +48,10 @@ public class CraftChest extends CraftLootable implements Chest, CraftWorld world = (CraftWorld) this.getWorld(); BlockChest blockChest = (BlockChest) (this.getType() == Material.CHEST ? Blocks.CHEST : Blocks.TRAPPED_CHEST); - ITileInventory nms = blockChest.getInventory(data, world.getHandle(), this.getPosition(), true); + ITileInventory nms = blockChest.getInventory(data, world.getHandle(), this.getPosition()); - if (nms instanceof InventoryLargeChest) { - inventory = new CraftInventoryDoubleChest((InventoryLargeChest) nms); + if (nms instanceof BlockChest.DoubleInventory) { + inventory = new CraftInventoryDoubleChest((BlockChest.DoubleInventory) nms); } return inventory; } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java index 06a1d4473..36ba813e5 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftContainer.java @@ -5,6 +5,7 @@ import net.minecraft.server.TileEntityContainer; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Container; +import org.bukkit.craftbukkit.util.CraftChatMessage; public abstract class CraftContainer extends CraftBlockEntityState implements Container { @@ -18,16 +19,36 @@ public abstract class CraftContainer extends Craf @Override public boolean isLocked() { - return this.getSnapshot().isLocked(); + return !this.getSnapshot().chestLock.key.isEmpty(); } @Override public String getLock() { - return this.getSnapshot().getLock().getKey(); + return this.getSnapshot().chestLock.key; } @Override public void setLock(String key) { - this.getSnapshot().setLock(key == null ? ChestLock.a : new ChestLock(key)); + this.getSnapshot().chestLock = (key == null) ? ChestLock.a : new ChestLock(key); + } + + @Override + public String getCustomName() { + T container = this.getSnapshot(); + return container.customName != null ? CraftChatMessage.fromComponent(container.getCustomName()) : null; + } + + @Override + public void setCustomName(String name) { + this.getSnapshot().setCustomName(CraftChatMessage.fromStringOrNull(name)); + } + + @Override + public void applyTo(T container) { + super.applyTo(container); + + if (this.getSnapshot().customName == null) { + container.setCustomName(null); + } } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java index aa63b854d..e78e3804b 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java @@ -5,7 +5,6 @@ import net.minecraft.server.EntityTypes; import net.minecraft.server.MinecraftKey; import net.minecraft.server.TileEntityMobSpawner; import org.bukkit.Material; - import org.bukkit.block.Block; import org.bukkit.block.CreatureSpawner; import org.bukkit.entity.EntityType; @@ -32,7 +31,7 @@ public class CraftCreatureSpawner extends CraftBlockEntityState implements Furnace { +public class CraftFurnace extends CraftContainer implements Furnace { - public CraftFurnace(final Block block) { - super(block, TileEntityFurnace.class); + public CraftFurnace(Block block, Class tileEntityClass) { + super(block, tileEntityClass); } - public CraftFurnace(final Material material, final TileEntityFurnace te) { + public CraftFurnace(final Material material, final T te) { super(material, te); } @@ -35,54 +34,34 @@ public class CraftFurnace extends CraftContainer implements F @Override public short getBurnTime() { - return (short) this.getSnapshot().getProperty(0); + return (short) this.getSnapshot().burnTime; } @Override public void setBurnTime(short burnTime) { - this.getSnapshot().setProperty(0, burnTime); + this.getSnapshot().burnTime = burnTime; // SPIGOT-844: Allow lighting and relighting using this API this.data = this.data.set(BlockFurnace.LIT, burnTime > 0); } @Override public short getCookTime() { - return (short) this.getSnapshot().getProperty(2); + return (short) this.getSnapshot().cookTime; } @Override public void setCookTime(short cookTime) { - this.getSnapshot().setProperty(2, cookTime); + this.getSnapshot().cookTime = cookTime; } @Override public int getCookTimeTotal() { - return this.getSnapshot().getProperty(3); + return this.getSnapshot().cookTimeTotal; } @Override public void setCookTimeTotal(int cookTimeTotal) { - this.getSnapshot().setProperty(3, cookTimeTotal); - } - - @Override - public String getCustomName() { - TileEntityFurnace furnace = this.getSnapshot(); - return furnace.hasCustomName() ? CraftChatMessage.fromComponent(furnace.getCustomName()) : null; - } - - @Override - public void setCustomName(String name) { - this.getSnapshot().setCustomName(CraftChatMessage.fromStringOrNull(name)); - } - - @Override - public void applyTo(TileEntityFurnace furnace) { - super.applyTo(furnace); - - if (!this.getSnapshot().hasCustomName()) { - furnace.setCustomName(null); - } + this.getSnapshot().cookTimeTotal = cookTimeTotal; } // Paper start - cook speed multiplier API diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnaceFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnaceFurnace.java new file mode 100644 index 000000000..fd8b91c1b --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnaceFurnace.java @@ -0,0 +1,16 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityFurnaceFurnace; +import org.bukkit.Material; +import org.bukkit.block.Block; + +public class CraftFurnaceFurnace extends CraftFurnace { + + public CraftFurnaceFurnace(Block block) { + super(block, TileEntityFurnaceFurnace.class); + } + + public CraftFurnaceFurnace(Material material, TileEntityFurnaceFurnace te) { + super(material, te); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftJigsaw.java b/src/main/java/org/bukkit/craftbukkit/block/CraftJigsaw.java new file mode 100644 index 000000000..bbce44c48 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftJigsaw.java @@ -0,0 +1,17 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityJigsaw; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Jigsaw; + +public class CraftJigsaw extends CraftBlockEntityState implements Jigsaw { + + public CraftJigsaw(Block block) { + super(block, TileEntityJigsaw.class); + } + + public CraftJigsaw(Material material, TileEntityJigsaw te) { + super(material, te); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftLectern.java b/src/main/java/org/bukkit/craftbukkit/block/CraftLectern.java new file mode 100644 index 000000000..bb57b750b --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftLectern.java @@ -0,0 +1,43 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityLectern; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Lectern; +import org.bukkit.craftbukkit.inventory.CraftInventoryLectern; +import org.bukkit.inventory.Inventory; + +public class CraftLectern extends CraftBlockEntityState implements Lectern { + + public CraftLectern(Block block) { + super(block, TileEntityLectern.class); + } + + public CraftLectern(Material material, TileEntityLectern te) { + super(material, te); + } + + @Override + public int getPage() { + return getSnapshot().getPage(); + } + + @Override + public void setPage(int page) { + getSnapshot().setPage(page); + } + + @Override + public Inventory getSnapshotInventory() { + return new CraftInventoryLectern(this.getSnapshot().inventory); + } + + @Override + public Inventory getInventory() { + if (!this.isPlaced()) { + return this.getSnapshotInventory(); + } + + return new CraftInventoryLectern(this.getTileEntity().inventory); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java index daf183fb1..678aa09d4 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java @@ -7,7 +7,6 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Nameable; import org.bukkit.block.Block; -import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.loot.LootTable; import org.bukkit.loot.Lootable; @@ -22,36 +21,22 @@ public abstract class CraftLootable extends CraftC super(material, tileEntity); } - @Override - public String getCustomName() { - T lootable = this.getSnapshot(); - return lootable.hasCustomName() ? CraftChatMessage.fromComponent(lootable.getCustomName()) : null; - } - - @Override - public void setCustomName(String name) { - this.getSnapshot().setCustomName(CraftChatMessage.fromStringOrNull(name)); - } - @Override public void applyTo(T lootable) { super.applyTo(lootable); - if (!this.getSnapshot().hasCustomName()) { - lootable.setCustomName(null); - } - if (this.getSnapshot().getLootTable() == null) { + if (this.getSnapshot().lootTable == null) { lootable.setLootTable((MinecraftKey) null, 0L); } } @Override public LootTable getLootTable() { - if (getSnapshot().getLootTable() == null) { + if (getSnapshot().lootTable == null) { return null; } - MinecraftKey key = getSnapshot().getLootTable(); + MinecraftKey key = getSnapshot().lootTable; return Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(key)); } @@ -62,7 +47,7 @@ public abstract class CraftLootable extends CraftC @Override public long getSeed() { - return getSnapshotNBT().getLong("LootTableSeed"); // returns OL if an error occurred + return getSnapshot().lootTableSeed; } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java index 3a8f64360..af15656cc 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java @@ -1,8 +1,10 @@ package org.bukkit.craftbukkit.block; import net.minecraft.server.ChatComponentText; +import net.minecraft.server.EnumColor; import net.minecraft.server.IChatBaseComponent; import net.minecraft.server.TileEntitySign; +import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.Sign; @@ -57,6 +59,16 @@ public class CraftSign extends CraftBlockEntityState implements this.editable = editable; } + @Override + public DyeColor getColor() { + return DyeColor.getByWoolData((byte) getSnapshot().getColor().getColorIndex()); + } + + @Override + public void setColor(DyeColor color) { + getSnapshot().setColor(EnumColor.fromColorIndex(color.getWoolData())); + } + @Override public void applyTo(TileEntitySign sign) { super.applyTo(sign); diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java index 8b5491431..2dd2f476f 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java @@ -4,15 +4,11 @@ import com.destroystokyo.paper.profile.CraftPlayerProfile; import com.destroystokyo.paper.profile.PlayerProfile; import com.google.common.base.Preconditions; import com.mojang.authlib.GameProfile; -import com.mojang.authlib.ProfileLookupCallback; - import net.minecraft.server.MinecraftServer; import net.minecraft.server.TileEntitySkull; - import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; - import org.bukkit.SkullType; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -40,7 +36,7 @@ public class CraftSkull extends CraftBlockEntityState implement public void load(TileEntitySkull skull) { super.load(skull); - profile = skull.getGameProfile(); + profile = skull.gameProfile; } static int getSkullType(SkullType type) { @@ -77,9 +73,12 @@ public class CraftSkull extends CraftBlockEntityState implement return false; } - // Akarin start - MinecraftServer.getServer().getModernUserCache().acquire(name, gameProfile -> profile = gameProfile); - // Akarin end + GameProfile profile = MinecraftServer.getServer().getUserCache().getProfile(name); + if (profile == null) { + return false; + } + + this.profile = profile; return true; } diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSmoker.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSmoker.java new file mode 100644 index 000000000..40bfcad46 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSmoker.java @@ -0,0 +1,17 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntitySmoker; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Smoker; + +public class CraftSmoker extends CraftFurnace implements Smoker { + + public CraftSmoker(Block block) { + super(block, TileEntitySmoker.class); + } + + public CraftSmoker(Material material, TileEntitySmoker te) { + super(material, te); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java index 4bb43e360..839e645b6 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java @@ -1,6 +1,5 @@ package org.bukkit.craftbukkit.block.data; -import java.util.stream.Collectors; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.collect.BiMap; @@ -11,6 +10,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import net.minecraft.server.ArgumentBlock; import net.minecraft.server.Block; import net.minecraft.server.BlockDataAbstract; @@ -22,6 +22,7 @@ import net.minecraft.server.IBlockData; import net.minecraft.server.IBlockState; import net.minecraft.server.INamable; import net.minecraft.server.IRegistry; +import net.minecraft.server.NBTTagCompound; import org.bukkit.Material; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; @@ -75,7 +76,7 @@ public class CraftBlockData implements BlockData { protected > Set getValues(BlockStateEnum nms, Class bukkit) { ImmutableSet.Builder values = ImmutableSet.builder(); - for (Enum e : nms.d()) { + for (Enum e : nms.getValues()) { values.add(toBukkit(e, bukkit)); } @@ -275,6 +276,18 @@ public class CraftBlockData implements BlockData { return stateString.toString(); } + public NBTTagCompound toStates() { + NBTTagCompound compound = new NBTTagCompound(); + + for (Map.Entry, Comparable> entry : state.getStateMap().entrySet()) { + IBlockState iblockstate = (IBlockState) entry.getKey(); + + compound.setString(iblockstate.a(), iblockstate.a(entry.getValue())); + } + + return compound; + } + @Override public boolean equals(Object obj) { return obj instanceof CraftBlockData && state.equals(((CraftBlockData) obj).state); @@ -331,7 +344,7 @@ public class CraftBlockData implements BlockData { private static IBlockState getState(Class block, String name, boolean optional) { IBlockState state = null; - for (Block instance : (Iterable) IRegistry.BLOCK) { // Eclipse fail + for (Block instance : IRegistry.BLOCK) { if (instance.getClass() == block) { if (state == null) { state = instance.getStates().a(name); @@ -374,14 +387,19 @@ public class CraftBlockData implements BlockData { static { // register(net.minecraft.server.BlockAnvil.class, org.bukkit.craftbukkit.block.impl.CraftAnvil::new); + register(net.minecraft.server.BlockBamboo.class, org.bukkit.craftbukkit.block.impl.CraftBamboo::new); register(net.minecraft.server.BlockBanner.class, org.bukkit.craftbukkit.block.impl.CraftBanner::new); register(net.minecraft.server.BlockBannerWall.class, org.bukkit.craftbukkit.block.impl.CraftBannerWall::new); + register(net.minecraft.server.BlockBarrel.class, org.bukkit.craftbukkit.block.impl.CraftBarrel::new); register(net.minecraft.server.BlockBed.class, org.bukkit.craftbukkit.block.impl.CraftBed::new); register(net.minecraft.server.BlockBeetroot.class, org.bukkit.craftbukkit.block.impl.CraftBeetroot::new); + register(net.minecraft.server.BlockBell.class, org.bukkit.craftbukkit.block.impl.CraftBell::new); + register(net.minecraft.server.BlockBlastFurnace.class, org.bukkit.craftbukkit.block.impl.CraftBlastFurnace::new); register(net.minecraft.server.BlockBrewingStand.class, org.bukkit.craftbukkit.block.impl.CraftBrewingStand::new); register(net.minecraft.server.BlockBubbleColumn.class, org.bukkit.craftbukkit.block.impl.CraftBubbleColumn::new); register(net.minecraft.server.BlockCactus.class, org.bukkit.craftbukkit.block.impl.CraftCactus::new); register(net.minecraft.server.BlockCake.class, org.bukkit.craftbukkit.block.impl.CraftCake::new); + register(net.minecraft.server.BlockCampfire.class, org.bukkit.craftbukkit.block.impl.CraftCampfire::new); register(net.minecraft.server.BlockCarrots.class, org.bukkit.craftbukkit.block.impl.CraftCarrots::new); register(net.minecraft.server.BlockCauldron.class, org.bukkit.craftbukkit.block.impl.CraftCauldron::new); register(net.minecraft.server.BlockChest.class, org.bukkit.craftbukkit.block.impl.CraftChest::new); @@ -391,6 +409,7 @@ public class CraftBlockData implements BlockData { register(net.minecraft.server.BlockCobbleWall.class, org.bukkit.craftbukkit.block.impl.CraftCobbleWall::new); register(net.minecraft.server.BlockCocoa.class, org.bukkit.craftbukkit.block.impl.CraftCocoa::new); register(net.minecraft.server.BlockCommand.class, org.bukkit.craftbukkit.block.impl.CraftCommand::new); + register(net.minecraft.server.BlockComposter.class, org.bukkit.craftbukkit.block.impl.CraftComposter::new); register(net.minecraft.server.BlockConduit.class, org.bukkit.craftbukkit.block.impl.CraftConduit::new); register(net.minecraft.server.BlockCoralDead.class, org.bukkit.craftbukkit.block.impl.CraftCoralDead::new); register(net.minecraft.server.BlockCoralFan.class, org.bukkit.craftbukkit.block.impl.CraftCoralFan::new); @@ -412,21 +431,25 @@ public class CraftBlockData implements BlockData { register(net.minecraft.server.BlockFire.class, org.bukkit.craftbukkit.block.impl.CraftFire::new); register(net.minecraft.server.BlockFloorSign.class, org.bukkit.craftbukkit.block.impl.CraftFloorSign::new); register(net.minecraft.server.BlockFluids.class, org.bukkit.craftbukkit.block.impl.CraftFluids::new); - register(net.minecraft.server.BlockFurnace.class, org.bukkit.craftbukkit.block.impl.CraftFurnace::new); - register(net.minecraft.server.BlockGlassPane.class, org.bukkit.craftbukkit.block.impl.CraftGlassPane::new); + register(net.minecraft.server.BlockFurnaceFurace.class, org.bukkit.craftbukkit.block.impl.CraftFurnaceFurace::new); register(net.minecraft.server.BlockGlazedTerracotta.class, org.bukkit.craftbukkit.block.impl.CraftGlazedTerracotta::new); register(net.minecraft.server.BlockGrass.class, org.bukkit.craftbukkit.block.impl.CraftGrass::new); + register(net.minecraft.server.BlockGrindstone.class, org.bukkit.craftbukkit.block.impl.CraftGrindstone::new); register(net.minecraft.server.BlockHay.class, org.bukkit.craftbukkit.block.impl.CraftHay::new); register(net.minecraft.server.BlockHopper.class, org.bukkit.craftbukkit.block.impl.CraftHopper::new); register(net.minecraft.server.BlockHugeMushroom.class, org.bukkit.craftbukkit.block.impl.CraftHugeMushroom::new); register(net.minecraft.server.BlockIceFrost.class, org.bukkit.craftbukkit.block.impl.CraftIceFrost::new); register(net.minecraft.server.BlockIronBars.class, org.bukkit.craftbukkit.block.impl.CraftIronBars::new); + register(net.minecraft.server.BlockJigsaw.class, org.bukkit.craftbukkit.block.impl.CraftJigsaw::new); register(net.minecraft.server.BlockJukeBox.class, org.bukkit.craftbukkit.block.impl.CraftJukeBox::new); register(net.minecraft.server.BlockKelp.class, org.bukkit.craftbukkit.block.impl.CraftKelp::new); register(net.minecraft.server.BlockLadder.class, org.bukkit.craftbukkit.block.impl.CraftLadder::new); + register(net.minecraft.server.BlockLantern.class, org.bukkit.craftbukkit.block.impl.CraftLantern::new); register(net.minecraft.server.BlockLeaves.class, org.bukkit.craftbukkit.block.impl.CraftLeaves::new); + register(net.minecraft.server.BlockLectern.class, org.bukkit.craftbukkit.block.impl.CraftLectern::new); register(net.minecraft.server.BlockLever.class, org.bukkit.craftbukkit.block.impl.CraftLever::new); register(net.minecraft.server.BlockLogAbstract.class, org.bukkit.craftbukkit.block.impl.CraftLogAbstract::new); + register(net.minecraft.server.BlockLoom.class, org.bukkit.craftbukkit.block.impl.CraftLoom::new); register(net.minecraft.server.BlockMinecartDetector.class, org.bukkit.craftbukkit.block.impl.CraftMinecartDetector::new); register(net.minecraft.server.BlockMinecartTrack.class, org.bukkit.craftbukkit.block.impl.CraftMinecartTrack::new); register(net.minecraft.server.BlockMycel.class, org.bukkit.craftbukkit.block.impl.CraftMycel::new); @@ -452,12 +475,14 @@ public class CraftBlockData implements BlockData { register(net.minecraft.server.BlockRepeater.class, org.bukkit.craftbukkit.block.impl.CraftRepeater::new); register(net.minecraft.server.BlockRotatable.class, org.bukkit.craftbukkit.block.impl.CraftRotatable::new); register(net.minecraft.server.BlockSapling.class, org.bukkit.craftbukkit.block.impl.CraftSapling::new); + register(net.minecraft.server.BlockScaffolding.class, org.bukkit.craftbukkit.block.impl.CraftScaffolding::new); register(net.minecraft.server.BlockSeaPickle.class, org.bukkit.craftbukkit.block.impl.CraftSeaPickle::new); register(net.minecraft.server.BlockShulkerBox.class, org.bukkit.craftbukkit.block.impl.CraftShulkerBox::new); register(net.minecraft.server.BlockSkull.class, org.bukkit.craftbukkit.block.impl.CraftSkull::new); register(net.minecraft.server.BlockSkullPlayer.class, org.bukkit.craftbukkit.block.impl.CraftSkullPlayer::new); register(net.minecraft.server.BlockSkullPlayerWall.class, org.bukkit.craftbukkit.block.impl.CraftSkullPlayerWall::new); register(net.minecraft.server.BlockSkullWall.class, org.bukkit.craftbukkit.block.impl.CraftSkullWall::new); + register(net.minecraft.server.BlockSmoker.class, org.bukkit.craftbukkit.block.impl.CraftSmoker::new); register(net.minecraft.server.BlockSnow.class, org.bukkit.craftbukkit.block.impl.CraftSnow::new); register(net.minecraft.server.BlockSoil.class, org.bukkit.craftbukkit.block.impl.CraftSoil::new); register(net.minecraft.server.BlockStainedGlassPane.class, org.bukkit.craftbukkit.block.impl.CraftStainedGlassPane::new); @@ -466,10 +491,12 @@ public class CraftBlockData implements BlockData { register(net.minecraft.server.BlockStemAttached.class, org.bukkit.craftbukkit.block.impl.CraftStemAttached::new); register(net.minecraft.server.BlockStepAbstract.class, org.bukkit.craftbukkit.block.impl.CraftStepAbstract::new); register(net.minecraft.server.BlockStoneButton.class, org.bukkit.craftbukkit.block.impl.CraftStoneButton::new); + register(net.minecraft.server.BlockStonecutter.class, org.bukkit.craftbukkit.block.impl.CraftStonecutter::new); register(net.minecraft.server.BlockStructure.class, org.bukkit.craftbukkit.block.impl.CraftStructure::new); + register(net.minecraft.server.BlockSweetBerryBush.class, org.bukkit.craftbukkit.block.impl.CraftSweetBerryBush::new); register(net.minecraft.server.BlockTNT.class, org.bukkit.craftbukkit.block.impl.CraftTNT::new); + register(net.minecraft.server.BlockTallPlant.class, org.bukkit.craftbukkit.block.impl.CraftTallPlant::new); register(net.minecraft.server.BlockTallPlantFlower.class, org.bukkit.craftbukkit.block.impl.CraftTallPlantFlower::new); - register(net.minecraft.server.BlockTallPlantShearable.class, org.bukkit.craftbukkit.block.impl.CraftTallPlantShearable::new); register(net.minecraft.server.BlockTallSeaGrass.class, org.bukkit.craftbukkit.block.impl.CraftTallSeaGrass::new); register(net.minecraft.server.BlockTorchWall.class, org.bukkit.craftbukkit.block.impl.CraftTorchWall::new); register(net.minecraft.server.BlockTrapdoor.class, org.bukkit.craftbukkit.block.impl.CraftTrapdoor::new); diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftWaterlogged.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftWaterlogged.java index 011c9aea8..4e1a672fc 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftWaterlogged.java +++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftWaterlogged.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.block.data; import org.bukkit.block.data.Waterlogged; -import org.bukkit.craftbukkit.block.data.CraftBlockData; public abstract class CraftWaterlogged extends CraftBlockData implements Waterlogged { diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftBamboo.java b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftBamboo.java new file mode 100644 index 000000000..65485a9ed --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftBamboo.java @@ -0,0 +1,19 @@ +package org.bukkit.craftbukkit.block.data.type; + +import org.bukkit.block.data.type.Bamboo; +import org.bukkit.craftbukkit.block.data.CraftBlockData; + +public abstract class CraftBamboo extends CraftBlockData implements Bamboo { + + private static final net.minecraft.server.BlockStateEnum LEAVES = getEnum("leaves"); + + @Override + public Leaves getLeaves() { + return get(LEAVES, Leaves.class); + } + + @Override + public void setLeaves(Leaves leaves) { + set(LEAVES, leaves); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftBell.java b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftBell.java new file mode 100644 index 000000000..a94dd1cee --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftBell.java @@ -0,0 +1,19 @@ +package org.bukkit.craftbukkit.block.data.type; + +import org.bukkit.block.data.type.Bell; +import org.bukkit.craftbukkit.block.data.CraftBlockData; + +public abstract class CraftBell extends CraftBlockData implements Bell { + + private static final net.minecraft.server.BlockStateEnum ATTACHMENT = getEnum("attachment"); + + @Override + public Attachment getAttachment() { + return get(ATTACHMENT, Attachment.class); + } + + @Override + public void setAttachment(Attachment leaves) { + set(ATTACHMENT, leaves); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftCampfire.java b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftCampfire.java new file mode 100644 index 000000000..99250172b --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftCampfire.java @@ -0,0 +1,19 @@ +package org.bukkit.craftbukkit.block.data.type; + +import org.bukkit.block.data.type.Campfire; +import org.bukkit.craftbukkit.block.data.CraftBlockData; + +public abstract class CraftCampfire extends CraftBlockData implements Campfire { + + private static final net.minecraft.server.BlockStateBoolean SIGNAL_FIRE = getBoolean("signal_fire"); + + @Override + public boolean isSignalFire() { + return get(SIGNAL_FIRE); + } + + @Override + public void setSignalFire(boolean signalFire) { + set(SIGNAL_FIRE, signalFire); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftJukebox.java b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftJukebox.java index 32eab86d7..c1fe52e1b 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftJukebox.java +++ b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftJukebox.java @@ -1,7 +1,7 @@ package org.bukkit.craftbukkit.block.data.type; -import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.block.data.type.Jukebox; +import org.bukkit.craftbukkit.block.data.CraftBlockData; public abstract class CraftJukebox extends CraftBlockData implements Jukebox { diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLantern.java b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLantern.java new file mode 100644 index 000000000..01bdf9d80 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLantern.java @@ -0,0 +1,19 @@ +package org.bukkit.craftbukkit.block.data.type; + +import org.bukkit.block.data.type.Lantern; +import org.bukkit.craftbukkit.block.data.CraftBlockData; + +public abstract class CraftLantern extends CraftBlockData implements Lantern { + + private static final net.minecraft.server.BlockStateBoolean HANGING = getBoolean("hanging"); + + @Override + public boolean isHanging() { + return get(HANGING); + } + + @Override + public void setHanging(boolean hanging) { + set(HANGING, hanging); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLectern.java b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLectern.java new file mode 100644 index 000000000..1ecdf4718 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLectern.java @@ -0,0 +1,14 @@ +package org.bukkit.craftbukkit.block.data.type; + +import org.bukkit.block.data.type.Lectern; +import org.bukkit.craftbukkit.block.data.CraftBlockData; + +public abstract class CraftLectern extends CraftBlockData implements Lectern { + + private static final net.minecraft.server.BlockStateBoolean HAS_BOOK = getBoolean("has_book"); + + @Override + public boolean hasBook() { + return get(HAS_BOOK); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftScaffolding.java b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftScaffolding.java new file mode 100644 index 000000000..fe896908c --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftScaffolding.java @@ -0,0 +1,35 @@ +package org.bukkit.craftbukkit.block.data.type; + +import org.bukkit.block.data.type.Scaffolding; +import org.bukkit.craftbukkit.block.data.CraftBlockData; + +public abstract class CraftScaffolding extends CraftBlockData implements Scaffolding { + + private static final net.minecraft.server.BlockStateBoolean BOTTOM = getBoolean("bottom"); + private static final net.minecraft.server.BlockStateInteger DISTANCE = getInteger("distance"); + + @Override + public boolean isBottom() { + return get(BOTTOM); + } + + @Override + public void setBottom(boolean bottom) { + set(BOTTOM, bottom); + } + + @Override + public int getDistance() { + return get(DISTANCE); + } + + @Override + public void setDistance(int distance) { + set(DISTANCE, distance); + } + + @Override + public int getMaximumDistance() { + return getMax(DISTANCE); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBamboo.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBamboo.java new file mode 100644 index 000000000..3c650d4f8 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBamboo.java @@ -0,0 +1,67 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftBamboo extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Bamboo, org.bukkit.block.data.Ageable, org.bukkit.block.data.type.Sapling { + + public CraftBamboo() { + super(); + } + + public CraftBamboo(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.type.CraftBamboo + + private static final net.minecraft.server.BlockStateEnum LEAVES = getEnum(net.minecraft.server.BlockBamboo.class, "leaves"); + + @Override + public Leaves getLeaves() { + return get(LEAVES, Leaves.class); + } + + @Override + public void setLeaves(Leaves leaves) { + set(LEAVES, leaves); + } + + // org.bukkit.craftbukkit.block.data.CraftAgeable + + private static final net.minecraft.server.BlockStateInteger AGE = getInteger(net.minecraft.server.BlockBamboo.class, "age"); + + @Override + public int getAge() { + return get(AGE); + } + + @Override + public void setAge(int age) { + set(AGE, age); + } + + @Override + public int getMaximumAge() { + return getMax(AGE); + } + + // org.bukkit.craftbukkit.block.data.type.CraftSapling + + private static final net.minecraft.server.BlockStateInteger STAGE = getInteger(net.minecraft.server.BlockBamboo.class, "stage"); + + @Override + public int getStage() { + return get(STAGE); + } + + @Override + public void setStage(int stage) { + set(STAGE, stage); + } + + @Override + public int getMaximumStage() { + return getMax(STAGE); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBarrel.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBarrel.java new file mode 100644 index 000000000..81919c941 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBarrel.java @@ -0,0 +1,34 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftBarrel extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.Directional { + + public CraftBarrel() { + super(); + } + + public CraftBarrel(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.CraftDirectional + + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockBarrel.class, "facing"); + + @Override + public org.bukkit.block.BlockFace getFacing() { + return get(FACING, org.bukkit.block.BlockFace.class); + } + + @Override + public void setFacing(org.bukkit.block.BlockFace facing) { + set(FACING, facing); + } + + @Override + public java.util.Set getFaces() { + return getValues(FACING, org.bukkit.block.BlockFace.class); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBell.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBell.java new file mode 100644 index 000000000..526af161b --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBell.java @@ -0,0 +1,48 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftBell extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Bell, org.bukkit.block.data.Directional { + + public CraftBell() { + super(); + } + + public CraftBell(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.type.CraftBell + + private static final net.minecraft.server.BlockStateEnum ATTACHMENT = getEnum(net.minecraft.server.BlockBell.class, "attachment"); + + @Override + public Attachment getAttachment() { + return get(ATTACHMENT, Attachment.class); + } + + @Override + public void setAttachment(Attachment leaves) { + set(ATTACHMENT, leaves); + } + + // org.bukkit.craftbukkit.block.data.CraftDirectional + + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockBell.class, "facing"); + + @Override + public org.bukkit.block.BlockFace getFacing() { + return get(FACING, org.bukkit.block.BlockFace.class); + } + + @Override + public void setFacing(org.bukkit.block.BlockFace facing) { + set(FACING, facing); + } + + @Override + public java.util.Set getFaces() { + return getValues(FACING, org.bukkit.block.BlockFace.class); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBlastFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBlastFurnace.java new file mode 100644 index 000000000..8e223604f --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftBlastFurnace.java @@ -0,0 +1,48 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftBlastFurnace extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Furnace, org.bukkit.block.data.Directional, org.bukkit.block.data.Lightable { + + public CraftBlastFurnace() { + super(); + } + + public CraftBlastFurnace(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.CraftDirectional + + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockBlastFurnace.class, "facing"); + + @Override + public org.bukkit.block.BlockFace getFacing() { + return get(FACING, org.bukkit.block.BlockFace.class); + } + + @Override + public void setFacing(org.bukkit.block.BlockFace facing) { + set(FACING, facing); + } + + @Override + public java.util.Set getFaces() { + return getValues(FACING, org.bukkit.block.BlockFace.class); + } + + // org.bukkit.craftbukkit.block.data.CraftLightable + + private static final net.minecraft.server.BlockStateBoolean LIT = getBoolean(net.minecraft.server.BlockBlastFurnace.class, "lit"); + + @Override + public boolean isLit() { + return get(LIT); + } + + @Override + public void setLit(boolean lit) { + set(LIT, lit); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCampfire.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCampfire.java new file mode 100644 index 000000000..a9fcc7ab9 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCampfire.java @@ -0,0 +1,57 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftCampfire extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Campfire, org.bukkit.block.data.Lightable, org.bukkit.block.data.Waterlogged { + + public CraftCampfire() { + super(); + } + + public CraftCampfire(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.type.CraftCampfire + + private static final net.minecraft.server.BlockStateBoolean SIGNAL_FIRE = getBoolean(net.minecraft.server.BlockCampfire.class, "signal_fire"); + + @Override + public boolean isSignalFire() { + return get(SIGNAL_FIRE); + } + + @Override + public void setSignalFire(boolean signalFire) { + set(SIGNAL_FIRE, signalFire); + } + + // org.bukkit.craftbukkit.block.data.CraftLightable + + private static final net.minecraft.server.BlockStateBoolean LIT = getBoolean(net.minecraft.server.BlockCampfire.class, "lit"); + + @Override + public boolean isLit() { + return get(LIT); + } + + @Override + public void setLit(boolean lit) { + set(LIT, lit); + } + + // org.bukkit.craftbukkit.block.data.CraftWaterlogged + + private static final net.minecraft.server.BlockStateBoolean WATERLOGGED = getBoolean(net.minecraft.server.BlockCampfire.class, "waterlogged"); + + @Override + public boolean isWaterlogged() { + return get(WATERLOGGED); + } + + @Override + public void setWaterlogged(boolean waterlogged) { + set(WATERLOGGED, waterlogged); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java new file mode 100644 index 000000000..536628624 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java @@ -0,0 +1,34 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftComposter extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.Levelled { + + public CraftComposter() { + super(); + } + + public CraftComposter(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.CraftLevelled + + private static final net.minecraft.server.BlockStateInteger LEVEL = getInteger(net.minecraft.server.BlockComposter.class, "level"); + + @Override + public int getLevel() { + return get(LEVEL); + } + + @Override + public void setLevel(int level) { + set(LEVEL, level); + } + + @Override + public int getMaximumLevel() { + return getMax(LEVEL); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFurnaceFurace.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFurnaceFurace.java new file mode 100644 index 000000000..49d4b885e --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFurnaceFurace.java @@ -0,0 +1,48 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftFurnaceFurace extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Furnace, org.bukkit.block.data.Directional, org.bukkit.block.data.Lightable { + + public CraftFurnaceFurace() { + super(); + } + + public CraftFurnaceFurace(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.CraftDirectional + + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockFurnaceFurace.class, "facing"); + + @Override + public org.bukkit.block.BlockFace getFacing() { + return get(FACING, org.bukkit.block.BlockFace.class); + } + + @Override + public void setFacing(org.bukkit.block.BlockFace facing) { + set(FACING, facing); + } + + @Override + public java.util.Set getFaces() { + return getValues(FACING, org.bukkit.block.BlockFace.class); + } + + // org.bukkit.craftbukkit.block.data.CraftLightable + + private static final net.minecraft.server.BlockStateBoolean LIT = getBoolean(net.minecraft.server.BlockFurnaceFurace.class, "lit"); + + @Override + public boolean isLit() { + return get(LIT); + } + + @Override + public void setLit(boolean lit) { + set(LIT, lit); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftGlassPane.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftGlassPane.java deleted file mode 100644 index 4c8bfcb73..000000000 --- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftGlassPane.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Automatically generated file, changes will be lost. - */ -package org.bukkit.craftbukkit.block.impl; - -public final class CraftGlassPane extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.GlassPane, org.bukkit.block.data.MultipleFacing, org.bukkit.block.data.Waterlogged { - - public CraftGlassPane() { - super(); - } - - public CraftGlassPane(net.minecraft.server.IBlockData state) { - super(state); - } - - // org.bukkit.craftbukkit.block.data.CraftMultipleFacing - - private static final net.minecraft.server.BlockStateBoolean[] FACES = new net.minecraft.server.BlockStateBoolean[]{ - getBoolean(net.minecraft.server.BlockGlassPane.class, "north", true), getBoolean(net.minecraft.server.BlockGlassPane.class, "east", true), getBoolean(net.minecraft.server.BlockGlassPane.class, "south", true), getBoolean(net.minecraft.server.BlockGlassPane.class, "west", true), getBoolean(net.minecraft.server.BlockGlassPane.class, "up", true), getBoolean(net.minecraft.server.BlockGlassPane.class, "down", true) - }; - - @Override - public boolean hasFace(org.bukkit.block.BlockFace face) { - return get(FACES[face.ordinal()]); - } - - @Override - public void setFace(org.bukkit.block.BlockFace face, boolean has) { - set(FACES[face.ordinal()], has); - } - - @Override - public java.util.Set getFaces() { - com.google.common.collect.ImmutableSet.Builder faces = com.google.common.collect.ImmutableSet.builder(); - - for (int i = 0; i < FACES.length; i++) { - if (FACES[i] != null && get(FACES[i])) { - faces.add(org.bukkit.block.BlockFace.values()[i]); - } - } - - return faces.build(); - } - - @Override - public java.util.Set getAllowedFaces() { - com.google.common.collect.ImmutableSet.Builder faces = com.google.common.collect.ImmutableSet.builder(); - - for (int i = 0; i < FACES.length; i++) { - if (FACES[i] != null) { - faces.add(org.bukkit.block.BlockFace.values()[i]); - } - } - - return faces.build(); - } - - // org.bukkit.craftbukkit.block.data.CraftWaterlogged - - private static final net.minecraft.server.BlockStateBoolean WATERLOGGED = getBoolean(net.minecraft.server.BlockGlassPane.class, "waterlogged"); - - @Override - public boolean isWaterlogged() { - return get(WATERLOGGED); - } - - @Override - public void setWaterlogged(boolean waterlogged) { - set(WATERLOGGED, waterlogged); - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftGrindstone.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftGrindstone.java new file mode 100644 index 000000000..f4c08558e --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftGrindstone.java @@ -0,0 +1,34 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftGrindstone extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.Directional { + + public CraftGrindstone() { + super(); + } + + public CraftGrindstone(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.CraftDirectional + + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockGrindstone.class, "facing"); + + @Override + public org.bukkit.block.BlockFace getFacing() { + return get(FACING, org.bukkit.block.BlockFace.class); + } + + @Override + public void setFacing(org.bukkit.block.BlockFace facing) { + set(FACING, facing); + } + + @Override + public java.util.Set getFaces() { + return getValues(FACING, org.bukkit.block.BlockFace.class); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftJigsaw.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftJigsaw.java new file mode 100644 index 000000000..10f0094b7 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftJigsaw.java @@ -0,0 +1,34 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftJigsaw extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.Directional { + + public CraftJigsaw() { + super(); + } + + public CraftJigsaw(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.CraftDirectional + + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockJigsaw.class, "facing"); + + @Override + public org.bukkit.block.BlockFace getFacing() { + return get(FACING, org.bukkit.block.BlockFace.class); + } + + @Override + public void setFacing(org.bukkit.block.BlockFace facing) { + set(FACING, facing); + } + + @Override + public java.util.Set getFaces() { + return getValues(FACING, org.bukkit.block.BlockFace.class); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLantern.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLantern.java new file mode 100644 index 000000000..8e279de3e --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLantern.java @@ -0,0 +1,29 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftLantern extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Lantern { + + public CraftLantern() { + super(); + } + + public CraftLantern(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.type.CraftLantern + + private static final net.minecraft.server.BlockStateBoolean HANGING = getBoolean(net.minecraft.server.BlockLantern.class, "hanging"); + + @Override + public boolean isHanging() { + return get(HANGING); + } + + @Override + public void setHanging(boolean hanging) { + set(HANGING, hanging); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLectern.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLectern.java new file mode 100644 index 000000000..f7fa832ed --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLectern.java @@ -0,0 +1,57 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftLectern extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Lectern, org.bukkit.block.data.Directional, org.bukkit.block.data.Powerable { + + public CraftLectern() { + super(); + } + + public CraftLectern(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.type.CraftLectern + + private static final net.minecraft.server.BlockStateBoolean HAS_BOOK = getBoolean(net.minecraft.server.BlockLectern.class, "has_book"); + + @Override + public boolean hasBook() { + return get(HAS_BOOK); + } + + // org.bukkit.craftbukkit.block.data.CraftDirectional + + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockLectern.class, "facing"); + + @Override + public org.bukkit.block.BlockFace getFacing() { + return get(FACING, org.bukkit.block.BlockFace.class); + } + + @Override + public void setFacing(org.bukkit.block.BlockFace facing) { + set(FACING, facing); + } + + @Override + public java.util.Set getFaces() { + return getValues(FACING, org.bukkit.block.BlockFace.class); + } + + // org.bukkit.craftbukkit.block.data.CraftPowerable + + private static final net.minecraft.server.BlockStateBoolean POWERED = getBoolean(net.minecraft.server.BlockLectern.class, "powered"); + + @Override + public boolean isPowered() { + return get(POWERED); + } + + @Override + public void setPowered(boolean powered) { + set(POWERED, powered); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLoom.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLoom.java new file mode 100644 index 000000000..e0e56dc95 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLoom.java @@ -0,0 +1,34 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftLoom extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.Directional { + + public CraftLoom() { + super(); + } + + public CraftLoom(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.CraftDirectional + + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockLoom.class, "facing"); + + @Override + public org.bukkit.block.BlockFace getFacing() { + return get(FACING, org.bukkit.block.BlockFace.class); + } + + @Override + public void setFacing(org.bukkit.block.BlockFace facing) { + set(FACING, facing); + } + + @Override + public java.util.Set getFaces() { + return getValues(FACING, org.bukkit.block.BlockFace.class); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftScaffolding.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftScaffolding.java new file mode 100644 index 000000000..857e4d1fc --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftScaffolding.java @@ -0,0 +1,59 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftScaffolding extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Scaffolding, org.bukkit.block.data.Waterlogged { + + public CraftScaffolding() { + super(); + } + + public CraftScaffolding(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.type.CraftScaffolding + + private static final net.minecraft.server.BlockStateBoolean BOTTOM = getBoolean(net.minecraft.server.BlockScaffolding.class, "bottom"); + private static final net.minecraft.server.BlockStateInteger DISTANCE = getInteger(net.minecraft.server.BlockScaffolding.class, "distance"); + + @Override + public boolean isBottom() { + return get(BOTTOM); + } + + @Override + public void setBottom(boolean bottom) { + set(BOTTOM, bottom); + } + + @Override + public int getDistance() { + return get(DISTANCE); + } + + @Override + public void setDistance(int distance) { + set(DISTANCE, distance); + } + + @Override + public int getMaximumDistance() { + return getMax(DISTANCE); + } + + // org.bukkit.craftbukkit.block.data.CraftWaterlogged + + private static final net.minecraft.server.BlockStateBoolean WATERLOGGED = getBoolean(net.minecraft.server.BlockScaffolding.class, "waterlogged"); + + @Override + public boolean isWaterlogged() { + return get(WATERLOGGED); + } + + @Override + public void setWaterlogged(boolean waterlogged) { + set(WATERLOGGED, waterlogged); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftSmoker.java similarity index 69% rename from src/main/java/org/bukkit/craftbukkit/block/impl/CraftFurnace.java rename to src/main/java/org/bukkit/craftbukkit/block/impl/CraftSmoker.java index 1ca1a9c79..c14aed35c 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftSmoker.java @@ -3,19 +3,19 @@ */ package org.bukkit.craftbukkit.block.impl; -public final class CraftFurnace extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Furnace, org.bukkit.block.data.Directional, org.bukkit.block.data.Lightable { +public final class CraftSmoker extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.type.Furnace, org.bukkit.block.data.Directional, org.bukkit.block.data.Lightable { - public CraftFurnace() { + public CraftSmoker() { super(); } - public CraftFurnace(net.minecraft.server.IBlockData state) { + public CraftSmoker(net.minecraft.server.IBlockData state) { super(state); } // org.bukkit.craftbukkit.block.data.CraftDirectional - private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockFurnace.class, "facing"); + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockSmoker.class, "facing"); @Override public org.bukkit.block.BlockFace getFacing() { @@ -34,7 +34,7 @@ public final class CraftFurnace extends org.bukkit.craftbukkit.block.data.CraftB // org.bukkit.craftbukkit.block.data.CraftLightable - private static final net.minecraft.server.BlockStateBoolean LIT = getBoolean(net.minecraft.server.BlockFurnace.class, "lit"); + private static final net.minecraft.server.BlockStateBoolean LIT = getBoolean(net.minecraft.server.BlockSmoker.class, "lit"); @Override public boolean isLit() { diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftStonecutter.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftStonecutter.java new file mode 100644 index 000000000..7a2789eb7 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftStonecutter.java @@ -0,0 +1,34 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftStonecutter extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.Directional { + + public CraftStonecutter() { + super(); + } + + public CraftStonecutter(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.CraftDirectional + + private static final net.minecraft.server.BlockStateEnum FACING = getEnum(net.minecraft.server.BlockStonecutter.class, "facing"); + + @Override + public org.bukkit.block.BlockFace getFacing() { + return get(FACING, org.bukkit.block.BlockFace.class); + } + + @Override + public void setFacing(org.bukkit.block.BlockFace facing) { + set(FACING, facing); + } + + @Override + public java.util.Set getFaces() { + return getValues(FACING, org.bukkit.block.BlockFace.class); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftSweetBerryBush.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftSweetBerryBush.java new file mode 100644 index 000000000..2733a067e --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftSweetBerryBush.java @@ -0,0 +1,34 @@ +/** + * Automatically generated file, changes will be lost. + */ +package org.bukkit.craftbukkit.block.impl; + +public final class CraftSweetBerryBush extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.Ageable { + + public CraftSweetBerryBush() { + super(); + } + + public CraftSweetBerryBush(net.minecraft.server.IBlockData state) { + super(state); + } + + // org.bukkit.craftbukkit.block.data.CraftAgeable + + private static final net.minecraft.server.BlockStateInteger AGE = getInteger(net.minecraft.server.BlockSweetBerryBush.class, "age"); + + @Override + public int getAge() { + return get(AGE); + } + + @Override + public void setAge(int age) { + set(AGE, age); + } + + @Override + public int getMaximumAge() { + return getMax(AGE); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftTallPlantShearable.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftTallPlant.java similarity index 57% rename from src/main/java/org/bukkit/craftbukkit/block/impl/CraftTallPlantShearable.java rename to src/main/java/org/bukkit/craftbukkit/block/impl/CraftTallPlant.java index c98414b3b..0ed0ad0cf 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftTallPlantShearable.java +++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftTallPlant.java @@ -3,19 +3,19 @@ */ package org.bukkit.craftbukkit.block.impl; -public final class CraftTallPlantShearable extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.Bisected { +public final class CraftTallPlant extends org.bukkit.craftbukkit.block.data.CraftBlockData implements org.bukkit.block.data.Bisected { - public CraftTallPlantShearable() { + public CraftTallPlant() { super(); } - public CraftTallPlantShearable(net.minecraft.server.IBlockData state) { + public CraftTallPlant(net.minecraft.server.IBlockData state) { super(state); } // org.bukkit.craftbukkit.block.data.CraftBisected - private static final net.minecraft.server.BlockStateEnum HALF = getEnum(net.minecraft.server.BlockTallPlantShearable.class, "half"); + private static final net.minecraft.server.BlockStateEnum HALF = getEnum(net.minecraft.server.BlockTallPlant.class, "half"); @Override public Half getHalf() { diff --git a/src/main/java/org/bukkit/craftbukkit/boss/CraftBossBar.java b/src/main/java/org/bukkit/craftbukkit/boss/CraftBossBar.java index e9f92eccd..d1033d73d 100644 --- a/src/main/java/org/bukkit/craftbukkit/boss/CraftBossBar.java +++ b/src/main/java/org/bukkit/craftbukkit/boss/CraftBossBar.java @@ -2,6 +2,11 @@ package org.bukkit.craftbukkit.boss; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; import net.minecraft.server.BossBattle; import net.minecraft.server.BossBattleServer; import net.minecraft.server.EntityPlayer; @@ -14,12 +19,6 @@ import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.entity.Player; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Supplier; - public class CraftBossBar implements BossBar { private final BossBattleServer handle; diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java deleted file mode 100644 index 33d5fc7d5..000000000 --- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.bukkit.craftbukkit.chunkio; - -import net.minecraft.server.Chunk; -import net.minecraft.server.ChunkProviderServer; -import net.minecraft.server.ChunkRegionLoader; -import net.minecraft.server.MCUtil; // Paper -import net.minecraft.server.World; -import org.bukkit.craftbukkit.util.AsynchronousExecutor; - -public class ChunkIOExecutor { - static final int BASE_THREADS = 1; - static final int PLAYERS_PER_THREAD = 50; - - private static final AsynchronousExecutor instance = new AsynchronousExecutor(new ChunkIOProvider(), BASE_THREADS); - - public static Chunk syncChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z) { - return MCUtil.ensureMain("Async Chunk Load", () -> instance.getSkipQueue(new QueuedChunk(x, z, loader, world, provider))); // Paper - } - - public static void queueChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z, Runnable runnable) { - instance.add(new QueuedChunk(x, z, loader, world, provider), runnable); - } - - // Abuses the fact that hashCode and equals for QueuedChunk only use world and coords - public static void dropQueuedChunkLoad(World world, int x, int z, Runnable runnable) { - instance.drop(new QueuedChunk(x, z, null, world, null), runnable); - } - - public static void adjustPoolSize(int players) { - int size = Math.max(BASE_THREADS, (int) Math.ceil(players / PLAYERS_PER_THREAD)); - instance.setActiveThreads(size); - } - - public static void tick() { - instance.finishActive(); - } - - // Paper start - public static boolean hasQueuedChunkLoad(World world, int x, int z) { - return instance.hasTask(new QueuedChunk(x, z, null, world, null)); - } - // Paper end -} diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java deleted file mode 100644 index cd98d6ecd..000000000 --- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.bukkit.craftbukkit.chunkio; - -import java.io.IOException; - -import co.aikar.timings.Timing; -import net.minecraft.server.Chunk; -import net.minecraft.server.ChunkCoordIntPair; -import net.minecraft.server.ChunkRegionLoader; -import net.minecraft.server.NBTTagCompound; - -import org.bukkit.Server; -import org.bukkit.craftbukkit.util.AsynchronousExecutor; - -import java.util.concurrent.atomic.AtomicInteger; - -class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider { - private final AtomicInteger threadNumber = new AtomicInteger(1); - - // async stuff - public Chunk callStage1(QueuedChunk queuedChunk) throws RuntimeException { - try (Timing ignored = queuedChunk.provider.world.timings.chunkIOStage1.startTimingIfSync()) { // Paper - ChunkRegionLoader loader = queuedChunk.loader; - Object[] data = loader.loadChunk(queuedChunk.world, queuedChunk.x, queuedChunk.z, (chunk) -> {}); - - if (data != null) { - queuedChunk.compound = (NBTTagCompound) data[1]; - return (Chunk) data[0]; - } - - return null; - } catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - // sync stuff - public void callStage2(QueuedChunk queuedChunk, Chunk chunk) throws RuntimeException { - if (chunk == null || queuedChunk.provider.chunks.containsKey(ChunkCoordIntPair.a(queuedChunk.x, queuedChunk.z))) { // Paper - also call original if it was already loaded - // If the chunk loading failed just do it synchronously (may generate) - queuedChunk.provider.getChunkAt(queuedChunk.x, queuedChunk.z, true, true); // Paper - actually call original if it was already loaded - return; - } - try (Timing ignored = queuedChunk.provider.world.timings.chunkIOStage2.startTimingIfSync(true)) { // Paper // Akarin - - queuedChunk.loader.loadEntities(queuedChunk.compound.getCompound("Level"), chunk); - chunk.setLastSaved(queuedChunk.provider.world.getTime()); - queuedChunk.provider.chunks.put(ChunkCoordIntPair.a(queuedChunk.x, queuedChunk.z), chunk); - chunk.addEntities(); - } // Paper - } - - public void callStage3(QueuedChunk queuedChunk, Chunk chunk, Runnable runnable) throws RuntimeException { - runnable.run(); - } - - public Thread newThread(Runnable runnable) { - Thread thread = new Thread(runnable, "Chunk I/O Executor Thread-" + threadNumber.getAndIncrement()); - thread.setDaemon(true); - return thread; - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java b/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java deleted file mode 100644 index 842d424f6..000000000 --- a/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.bukkit.craftbukkit.chunkio; - -import net.minecraft.server.ChunkProviderServer; -import net.minecraft.server.ChunkRegionLoader; -import net.minecraft.server.NBTTagCompound; -import net.minecraft.server.World; - -class QueuedChunk { - final int x; - final int z; - final ChunkRegionLoader loader; - final World world; - final ChunkProviderServer provider; - NBTTagCompound compound; - - public QueuedChunk(int x, int z, ChunkRegionLoader loader, World world, ChunkProviderServer provider) { - this.x = x; - this.z = z; - this.loader = loader; - this.world = world; - this.provider = provider; - } - - @Override - public int hashCode() { - return (x * 31 + z * 29) ^ world.hashCode(); - } - - @Override - public boolean equals(Object object) { - if (object instanceof QueuedChunk) { - QueuedChunk other = (QueuedChunk) object; - return x == other.x && z == other.z && world == other.world; - } - - return false; - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java index 95d13c146..a51202ed5 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java +++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java @@ -4,7 +4,6 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.logging.Level; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.util.Waitable; @@ -25,6 +24,7 @@ public class ConsoleCommandCompleter implements Completer { } // Paper start - Change method signature for JLine update + @Override public void complete(LineReader reader, ParsedLine line, List candidates) { final CraftServer server = this.server.server; final String buffer = line.line(); diff --git a/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java index 701a57e02..5beb2ad62 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java +++ b/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java @@ -3,7 +3,6 @@ package org.bukkit.craftbukkit.command; import net.minecraft.server.CommandListenerWrapper; import net.minecraft.server.IChatBaseComponent; import net.minecraft.server.TileEntity; - import org.bukkit.block.Block; import org.bukkit.command.BlockCommandSender; import org.bukkit.craftbukkit.block.CraftBlock; @@ -22,30 +21,36 @@ public class CraftBlockCommandSender extends ServerCommandSender implements Bloc this.tile = tile; } + @Override public Block getBlock() { return CraftBlock.at(tile.getWorld(), tile.getPosition()); } + @Override public void sendMessage(String message) { for (IChatBaseComponent component : CraftChatMessage.fromString(message)) { block.base.sendMessage(component); } } + @Override public void sendMessage(String[] messages) { for (String message : messages) { sendMessage(message); } } + @Override public String getName() { return block.getName(); } + @Override public boolean isOp() { return true; } + @Override public void setOp(boolean value) { throw new UnsupportedOperationException("Cannot change operator status of a block"); } diff --git a/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java index 9abcf92db..bfd21a072 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java +++ b/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java @@ -18,48 +18,59 @@ public class CraftConsoleCommandSender extends ServerCommandSender implements Co super(); } + @Override public void sendMessage(String message) { sendRawMessage(message); } + @Override public void sendRawMessage(String message) { System.out.println(ChatColor.stripColor(message)); } + @Override public void sendMessage(String[] messages) { for (String message : messages) { sendMessage(message); } } + @Override public String getName() { return "CONSOLE"; } + @Override public boolean isOp() { return true; } + @Override public void setOp(boolean value) { throw new UnsupportedOperationException("Cannot change operator status of server console"); } + @Override public boolean beginConversation(Conversation conversation) { return conversationTracker.beginConversation(conversation); } + @Override public void abandonConversation(Conversation conversation) { conversationTracker.abandonConversation(conversation, new ConversationAbandonedEvent(conversation, new ManuallyAbandonedConversationCanceller())); } + @Override public void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) { conversationTracker.abandonConversation(conversation, details); } + @Override public void acceptConversationInput(String input) { conversationTracker.acceptConversationInput(input); } + @Override public boolean isConversing() { return conversationTracker.isConversing(); } diff --git a/src/main/java/org/bukkit/craftbukkit/command/ProxiedNativeCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/ProxiedNativeCommandSender.java index 7609e861c..ce2c5c38c 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/ProxiedNativeCommandSender.java +++ b/src/main/java/org/bukkit/craftbukkit/command/ProxiedNativeCommandSender.java @@ -3,7 +3,6 @@ package org.bukkit.craftbukkit.command; import java.util.Set; import net.minecraft.server.CommandListenerWrapper; - import org.bukkit.Server; import org.bukkit.command.CommandSender; import org.bukkit.command.ProxiedCommandSender; diff --git a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java index 5c3421dd3..9776746a0 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java +++ b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.command; +import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.command.CommandSender; @@ -9,8 +10,6 @@ import org.bukkit.permissions.PermissionAttachment; import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; -import java.util.Set; - public abstract class ServerCommandSender implements CommandSender { private static PermissibleBase blockPermInst; private final PermissibleBase perm; @@ -26,46 +25,57 @@ public abstract class ServerCommandSender implements CommandSender { } } + @Override public boolean isPermissionSet(String name) { return perm.isPermissionSet(name); } + @Override public boolean isPermissionSet(Permission perm) { return this.perm.isPermissionSet(perm); } + @Override public boolean hasPermission(String name) { return perm.hasPermission(name); } + @Override public boolean hasPermission(Permission perm) { return this.perm.hasPermission(perm); } + @Override public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { return perm.addAttachment(plugin, name, value); } + @Override public PermissionAttachment addAttachment(Plugin plugin) { return perm.addAttachment(plugin); } + @Override public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { return perm.addAttachment(plugin, name, value, ticks); } + @Override public PermissionAttachment addAttachment(Plugin plugin, int ticks) { return perm.addAttachment(plugin, ticks); } + @Override public void removeAttachment(PermissionAttachment attachment) { perm.removeAttachment(attachment); } + @Override public void recalculatePermissions() { perm.recalculatePermissions(); } + @Override public Set getEffectivePermissions() { return perm.getEffectivePermissions(); } @@ -74,6 +84,7 @@ public abstract class ServerCommandSender implements CommandSender { return false; } + @Override public Server getServer() { return Bukkit.getServer(); } diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java index 59d82cf64..a3ae4a9ff 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java +++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java @@ -74,7 +74,7 @@ public final class VanillaCommandWrapper extends BukkitCommand { return ((EntityMinecartCommandBlock) ((CraftMinecartCommand) sender).getHandle()).getCommandBlock().getWrapper(); } if (sender instanceof RemoteConsoleCommandSender) { - return ((DedicatedServer) MinecraftServer.getServer()).remoteControlCommandListener.f(); + return ((DedicatedServer) MinecraftServer.getServer()).remoteControlCommandListener.getWrapper(); } if (sender instanceof ConsoleCommandSender) { return ((CraftServer) sender.getServer()).getServer().getServerCommandListener(); diff --git a/src/main/java/org/bukkit/craftbukkit/conversations/ConversationTracker.java b/src/main/java/org/bukkit/craftbukkit/conversations/ConversationTracker.java index eefa68a69..72127dde5 100644 --- a/src/main/java/org/bukkit/craftbukkit/conversations/ConversationTracker.java +++ b/src/main/java/org/bukkit/craftbukkit/conversations/ConversationTracker.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.conversations; import java.util.LinkedList; import java.util.logging.Level; - import org.bukkit.Bukkit; import org.bukkit.conversations.Conversation; import org.bukkit.conversations.ConversationAbandonedEvent; diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java index 2897713ad..64ceeda1a 100644 --- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java +++ b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java @@ -57,6 +57,8 @@ public class CraftEnchantment extends Enchantment { return EnchantmentTarget.WEARABLE; case TRIDENT: return EnchantmentTarget.TRIDENT; + case CROSSBOW: + return EnchantmentTarget.CROSSBOW; default: return null; } @@ -146,11 +148,17 @@ public class CraftEnchantment extends Enchantment { case 31: return "CHANNELING"; case 32: - return "MENDING"; + return "MULTISHOT"; case 33: + return "QUICK_CHARGE"; + case 34: + return "PIERCING"; + case 35: + return "MENDING"; + case 36: return "VANISHING_CURSE"; default: - return "UNKNOWN_ENCHANT_" + getName(); + return "UNKNOWN_ENCHANT_" + IRegistry.ENCHANTMENT.a(target); } } @@ -175,7 +183,7 @@ public class CraftEnchantment extends Enchantment { return false; } CraftEnchantment ench = (CraftEnchantment) other; - return !target.b(ench.target); + return !target.isCompatible(ench.target); } public net.minecraft.server.Enchantment getHandle() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java index 7c1625519..47b3fe555 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java @@ -12,10 +12,12 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti doesBounce = false; } + @Override public boolean doesBounce() { return doesBounce; } + @Override public void setBounce(boolean doesBounce) { this.doesBounce = doesBounce; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java index cc9d432e7..1aea5f3f0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java @@ -23,33 +23,40 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac return (EntityHorseAbstract) entity; } + @Override public void setVariant(Horse.Variant variant) { throw new UnsupportedOperationException("Not supported."); } + @Override public int getDomestication() { return getHandle().getTemper(); } + @Override public void setDomestication(int value) { Validate.isTrue(value >= 0, "Domestication cannot be less than zero"); Validate.isTrue(value <= getMaxDomestication(), "Domestication cannot be greater than the max domestication"); getHandle().setTemper(value); } + @Override public int getMaxDomestication() { return getHandle().getMaxDomestication(); } + @Override public void setMaxDomestication(int value) { Validate.isTrue(value > 0, "Max domestication cannot be zero or less"); getHandle().maxDomestication = value; } + @Override public double getJumpStrength() { return getHandle().getJumpStrength(); } + @Override public void setJumpStrength(double strength) { Validate.isTrue(strength >= 0, "Jump strength cannot be less than zero"); getHandle().getAttributeInstance(EntityHorse.attributeJumpStrength).setValue(strength); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java new file mode 100644 index 000000000..18520fec0 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java @@ -0,0 +1,74 @@ +package org.bukkit.craftbukkit.entity; + +import java.util.List; +import net.minecraft.server.EntityVillager; +import net.minecraft.server.EntityVillagerAbstract; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftMerchant; +import org.bukkit.entity.AbstractVillager; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.MerchantRecipe; + +public class CraftAbstractVillager extends CraftAgeable implements AbstractVillager, InventoryHolder { + + public CraftAbstractVillager(CraftServer server, EntityVillagerAbstract entity) { + super(server, entity); + } + + @Override + public EntityVillagerAbstract getHandle() { + return (EntityVillager) entity; + } + + @Override + public String toString() { + return "CraftAbstractVillager"; + } + + @Override + public Inventory getInventory() { + return new CraftInventory(getHandle().getInventory()); + } + + private CraftMerchant getMerchant() { + return getHandle().getCraftMerchant(); + } + + @Override + public List getRecipes() { + return getMerchant().getRecipes(); + } + + @Override + public void setRecipes(List recipes) { + this.getMerchant().setRecipes(recipes); + } + + @Override + public MerchantRecipe getRecipe(int i) { + return getMerchant().getRecipe(i); + } + + @Override + public void setRecipe(int i, MerchantRecipe merchantRecipe) { + getMerchant().setRecipe(i, merchantRecipe); + } + + @Override + public int getRecipeCount() { + return getMerchant().getRecipeCount(); + } + + @Override + public boolean isTrading() { + return getTrader() != null; + } + + @Override + public HumanEntity getTrader() { + return getMerchant().getTrader(); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java index edb07964a..f9ac60e24 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityAgeable; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Ageable; @@ -10,43 +9,52 @@ public class CraftAgeable extends CraftCreature implements Ageable { super(server, entity); } + @Override public int getAge() { return getHandle().getAge(); } + @Override public void setAge(int age) { getHandle().setAgeRaw(age); } + @Override public void setAgeLock(boolean lock) { getHandle().ageLocked = lock; } + @Override public boolean getAgeLock() { return getHandle().ageLocked; } + @Override public void setBaby() { if (isAdult()) { setAge(-24000); } } + @Override public void setAdult() { if (!isAdult()) { setAge(0); } } + @Override public boolean isAdult() { return getAge() >= 0; } + @Override public boolean canBreed() { return getAge() == 0; } + @Override public void setBreed(boolean breed) { if (breed) { setAge(0); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java index 734f54891..a482c2aab 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java @@ -20,6 +20,7 @@ public class CraftAmbient extends CraftMob implements Ambient { return "CraftAmbient"; } + @Override public EntityType getType() { return EntityType.UNKNOWN; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java index b06909c3e..599db583b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java @@ -1,7 +1,7 @@ package org.bukkit.craftbukkit.entity; -import java.util.UUID; import com.google.common.base.Preconditions; +import java.util.UUID; import net.minecraft.server.EntityAnimal; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Animals; @@ -40,11 +40,11 @@ public class CraftAnimals extends CraftAgeable implements Animals { @Override public void setLoveModeTicks(int ticks) { Preconditions.checkArgument(ticks >= 0, "Love mode ticks must be positive or 0"); - getHandle().d(ticks); // PAIL rename setLoveModeTicks + getHandle().setLoveTicks(ticks); } @Override public int getLoveModeTicks() { - return getHandle().bC; // PAIL rename loveTicks + return getHandle().loveTicks; } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java index 7e9239cf1..ab6cbf560 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java @@ -1,11 +1,11 @@ package org.bukkit.craftbukkit.entity; +import com.google.common.collect.ImmutableList; import java.util.List; import net.minecraft.server.EntityAreaEffectCloud; import net.minecraft.server.EntityLiving; import net.minecraft.server.MobEffect; import net.minecraft.server.MobEffectList; - import org.apache.commons.lang.Validate; import org.bukkit.Color; import org.bukkit.Particle; @@ -15,12 +15,10 @@ import org.bukkit.craftbukkit.potion.CraftPotionUtil; import org.bukkit.entity.AreaEffectCloud; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; +import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.projectiles.ProjectileSource; -import org.bukkit.potion.PotionData; - -import com.google.common.collect.ImmutableList; public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud { @@ -153,7 +151,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud } getHandle().effects.remove(existing); } - getHandle().a(CraftPotionUtil.fromBukkit(effect)); + getHandle().addEffect(CraftPotionUtil.fromBukkit(effect)); getHandle().refreshEffects(); return true; } @@ -216,11 +214,13 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud return CraftPotionUtil.toBukkit(getHandle().getType()); } + @Override public ProjectileSource getSource() { EntityLiving source = getHandle().getSource(); return (source == null) ? null : (LivingEntity) source.getBukkitEntity(); } + @Override public void setSource(ProjectileSource shooter) { if (shooter instanceof CraftLivingEntity) { getHandle().setSource((EntityLiving) ((CraftLivingEntity) shooter).getHandle()); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java index 07ce93f17..73714d71a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -306,6 +306,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public void setCanTick(final boolean tick) { this.getHandle().canTick = tick; + this.getHandle().canTickSetByAPI = true; } // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java index ff92f8584..29d23db41 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java @@ -1,27 +1,29 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; +import net.minecraft.server.BlockPosition; import net.minecraft.server.EntityArrow; - import org.apache.commons.lang.Validate; import org.bukkit.block.Block; import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.entity.Arrow; +import org.bukkit.entity.AbstractArrow; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.projectiles.ProjectileSource; -public class CraftArrow extends AbstractProjectile implements Arrow { +public class CraftArrow extends AbstractProjectile implements AbstractArrow { public CraftArrow(CraftServer server, EntityArrow entity) { super(server, entity); } + @Override public void setKnockbackStrength(int knockbackStrength) { Validate.isTrue(knockbackStrength >= 0, "Knockback cannot be negative"); getHandle().setKnockbackStrength(knockbackStrength); } + @Override public int getKnockbackStrength() { return getHandle().knockbackStrength; } @@ -37,18 +39,34 @@ public class CraftArrow extends AbstractProjectile implements Arrow { getHandle().setDamage(damage); } + @Override + public int getPierceLevel() { + return getHandle().getPierceLevel(); + } + + @Override + public void setPierceLevel(int pierceLevel) { + Preconditions.checkArgument(0 <= pierceLevel && pierceLevel <= Byte.MAX_VALUE, "Pierce level out of range, expected 0 < level < 127"); + + getHandle().setPierceLevel((byte) pierceLevel); + } + + @Override public boolean isCritical() { return getHandle().isCritical(); } + @Override public void setCritical(boolean critical) { getHandle().setCritical(critical); } + @Override public ProjectileSource getShooter() { return getHandle().projectileSource; } + @Override public void setShooter(ProjectileSource shooter) { if (shooter instanceof Entity) { getHandle().setShooter(((CraftEntity) shooter).getHandle()); @@ -69,8 +87,8 @@ public class CraftArrow extends AbstractProjectile implements Arrow { return null; } - EntityArrow handle = getHandle(); - return getWorld().getBlockAt(handle.tileX, handle.tileY, handle.tileZ); + BlockPosition pos = getHandle().getChunkCoordinates(); + return getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); } @Override @@ -102,29 +120,8 @@ public class CraftArrow extends AbstractProjectile implements Arrow { return "CraftArrow"; } + @Override public EntityType getType() { - return EntityType.ARROW; + return EntityType.UNKNOWN; } - - // Spigot start - private final Arrow.Spigot spigot = new Arrow.Spigot() - { - @Override - public double getDamage() - { - return getHandle().getDamage(); - } - - @Override - public void setDamage(double damage) - { - getHandle().setDamage( damage ); - } - }; - - public Arrow.Spigot spigot() - { - return spigot; - } - // Spigot end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java index 76ada1c37..e7061d9d7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java @@ -20,6 +20,7 @@ public class CraftBat extends CraftAmbient implements Bat { return "CraftBat"; } + @Override public EntityType getType() { return EntityType.BAT; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java index 830d7a840..089419ede 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityBlaze; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Blaze; import org.bukkit.entity.EntityType; @@ -21,6 +20,7 @@ public class CraftBlaze extends CraftMonster implements Blaze { return "CraftBlaze"; } + @Override public EntityType getType() { return EntityType.BLAZE; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java index 3613f5b3e..271950903 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java @@ -22,38 +22,46 @@ public class CraftBoat extends CraftVehicle implements Boat { getHandle().setType(getBoatType(species)); } + @Override public double getMaxSpeed() { return getHandle().maxSpeed; } + @Override public void setMaxSpeed(double speed) { if (speed >= 0D) { getHandle().maxSpeed = speed; } } + @Override public double getOccupiedDeceleration() { return getHandle().occupiedDeceleration; } + @Override public void setOccupiedDeceleration(double speed) { if (speed >= 0D) { getHandle().occupiedDeceleration = speed; } } + @Override public double getUnoccupiedDeceleration() { return getHandle().unoccupiedDeceleration; } + @Override public void setUnoccupiedDeceleration(double speed) { getHandle().unoccupiedDeceleration = speed; } + @Override public boolean getWorkOnLand() { return getHandle().landBoats; } + @Override public void setWorkOnLand(boolean workOnLand) { getHandle().landBoats = workOnLand; } @@ -68,6 +76,7 @@ public class CraftBoat extends CraftVehicle implements Boat { return "CraftBoat"; } + @Override public EntityType getType() { return EntityType.BOAT; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java new file mode 100644 index 000000000..836110b00 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java @@ -0,0 +1,53 @@ +package org.bukkit.craftbukkit.entity; + +import com.google.common.base.Preconditions; +import net.minecraft.server.EntityCat; +import net.minecraft.server.EnumColor; +import org.bukkit.DyeColor; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Cat; +import org.bukkit.entity.EntityType; + +public class CraftCat extends CraftTameableAnimal implements Cat { + + public CraftCat(CraftServer server, EntityCat entity) { + super(server, entity); + } + + @Override + public EntityCat getHandle() { + return (EntityCat) super.getHandle(); + } + + @Override + public EntityType getType() { + return EntityType.CAT; + } + + @Override + public String toString() { + return "CraftCat"; + } + + @Override + public Type getCatType() { + return Type.values()[getHandle().getCatType()]; + } + + @Override + public void setCatType(Type type) { + Preconditions.checkArgument(type != null, "Cannot have null Type"); + + getHandle().setCatType(type.ordinal()); + } + + @Override + public DyeColor getCollarColor() { + return DyeColor.getByWoolData((byte) getHandle().getCollarColor().getColorIndex()); + } + + @Override + public void setCollarColor(DyeColor color) { + getHandle().setCollarColor(EnumColor.fromColorIndex(color.getWoolData())); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java index 0648a851d..fceb2b2fb 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityCaveSpider; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.CaveSpider; import org.bukkit.entity.EntityType; @@ -21,6 +20,7 @@ public class CraftCaveSpider extends CraftSpider implements CaveSpider { return "CraftCaveSpider"; } + @Override public EntityType getType() { return EntityType.CAVE_SPIDER; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java index d20c2196c..47fcf1b1a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityChicken; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Chicken; import org.bukkit.entity.EntityType; @@ -22,6 +21,7 @@ public class CraftChicken extends CraftAnimals implements Chicken { return "CraftChicken"; } + @Override public EntityType getType() { return EntityType.CHICKEN; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java index 02fd230a3..c1829a0d0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java @@ -13,6 +13,7 @@ public class CraftComplexPart extends CraftEntity implements ComplexEntityPart { super(server, entity); } + @Override public ComplexLivingEntity getParent() { return (ComplexLivingEntity) ((EntityEnderDragon) getHandle().owner).getBukkitEntity(); } @@ -42,7 +43,8 @@ public class CraftComplexPart extends CraftEntity implements ComplexEntityPart { return "CraftComplexPart"; } + @Override public EntityType getType() { - return EntityType.COMPLEX_PART; + return EntityType.UNKNOWN; } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java index fc48ebd9b..31bfa02e8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityCow; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Cow; import org.bukkit.entity.EntityType; @@ -22,6 +21,7 @@ public class CraftCow extends CraftAnimals implements Cow { return "CraftCow"; } + @Override public EntityType getType() { return EntityType.COW; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java index ab2b20a0d..075a5e77e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; import net.minecraft.server.EntityCreeper; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Creeper; import org.bukkit.entity.EntityType; @@ -14,10 +13,12 @@ public class CraftCreeper extends CraftMonster implements Creeper { super(server, entity); } + @Override public boolean isPowered() { return getHandle().isPowered(); } + @Override public void setPowered(boolean powered) { CraftServer server = this.server; Creeper entity = (Creeper) this.getHandle().getBukkitEntity(); @@ -63,6 +64,16 @@ public class CraftCreeper extends CraftMonster implements Creeper { return getHandle().explosionRadius; } + @Override + public void explode() { + getHandle().explode(); + } + + @Override + public void ignite() { + getHandle().ignite(); + } + @Override public EntityCreeper getHandle() { return (EntityCreeper) entity; @@ -73,6 +84,7 @@ public class CraftCreeper extends CraftMonster implements Creeper { return "CraftCreeper"; } + @Override public EntityType getType() { return EntityType.CREEPER; } @@ -89,9 +101,5 @@ public class CraftCreeper extends CraftMonster implements Creeper { public int getFuseTicks() { return getHandle().fuseTicks; } - - public void explode() { - getHandle().explode(); - } // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java index 60c5188ec..1d0f43038 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java @@ -20,6 +20,7 @@ public class CraftEgg extends CraftProjectile implements Egg { return "CraftEgg"; } + @Override public EntityType getType() { return EntityType.EGG; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java index ffb863e60..46d8e36ac 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java @@ -49,6 +49,7 @@ public class CraftEnderCrystal extends CraftEntity implements EnderCrystal { return "CraftEnderCrystal"; } + @Override public EntityType getType() { return EntityType.ENDER_CRYSTAL; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java index a97623830..ee95e4e33 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java @@ -2,13 +2,10 @@ package org.bukkit.craftbukkit.entity; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; - import java.util.Set; - import net.minecraft.server.DragonControllerPhase; import net.minecraft.server.EntityComplexPart; import net.minecraft.server.EntityEnderDragon; - import org.bukkit.boss.BossBar; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.boss.CraftBossBar; @@ -28,6 +25,7 @@ public class CraftEnderDragon extends CraftComplexLivingEntity implements EnderD } } + @Override public Set getParts() { Builder builder = ImmutableSet.builder(); @@ -48,6 +46,7 @@ public class CraftEnderDragon extends CraftComplexLivingEntity implements EnderD return "CraftEnderDragon"; } + @Override public EntityType getType() { return EntityType.ENDER_DRAGON; } @@ -61,11 +60,11 @@ public class CraftEnderDragon extends CraftComplexLivingEntity implements EnderD public void setPhase(Phase phase) { getHandle().getDragonControllerManager().setControllerPhase(getMinecraftPhase(phase)); } - + public static Phase getBukkitPhase(DragonControllerPhase phase) { return Phase.values()[phase.b()]; } - + public static DragonControllerPhase getMinecraftPhase(Phase phase) { return DragonControllerPhase.getById(phase.ordinal()); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java index c3338710b..e6d050099 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java @@ -26,30 +26,47 @@ public class CraftEnderDragonPart extends CraftComplexPart implements EnderDrago return "CraftEnderDragonPart"; } + @Override public void damage(double amount) { getParent().damage(amount); } + @Override public void damage(double amount, Entity source) { getParent().damage(amount, source); } + @Override public double getHealth() { return getParent().getHealth(); } + @Override public void setHealth(double health) { getParent().setHealth(health); } + @Override + public double getAbsorptionAmount() { + return getParent().getAbsorptionAmount(); + } + + @Override + public void setAbsorptionAmount(double amount) { + getParent().setAbsorptionAmount(amount); + } + + @Override public double getMaxHealth() { return getParent().getMaxHealth(); } + @Override public void setMaxHealth(double health) { getParent().setMaxHealth(health); } + @Override public void resetMaxHealth() { getParent().resetMaxHealth(); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java index f42f9ab7e..32221ead3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java @@ -20,6 +20,7 @@ public class CraftEnderPearl extends CraftProjectile implements EnderPearl { return "CraftEnderPearl"; } + @Override public EntityType getType() { return EntityType.ENDER_PEARL; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java index 9bc6a6c0c..0c5f35934 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityEnderman; - import net.minecraft.server.IBlockData; import org.bukkit.Material; import org.bukkit.block.data.BlockData; @@ -18,6 +17,7 @@ public class CraftEnderman extends CraftMonster implements Enderman { } @Override public boolean teleportRandomly() { return getHandle().teleportRandomly(); } // Paper + @Override public MaterialData getCarriedMaterial() { IBlockData blockData = getHandle().getCarried(); return (blockData == null) ? Material.AIR.getNewData((byte) 0) : CraftMagicNumbers.getMaterial(blockData); @@ -29,6 +29,7 @@ public class CraftEnderman extends CraftMonster implements Enderman { return (blockData == null) ? null : CraftBlockData.fromData(blockData); } + @Override public void setCarriedMaterial(MaterialData data) { getHandle().setCarried(CraftMagicNumbers.getBlock(data)); } @@ -48,6 +49,7 @@ public class CraftEnderman extends CraftMonster implements Enderman { return "CraftEnderman"; } + @Override public EntityType getType() { return EntityType.ENDERMAN; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index bd938b91e..31db42e9f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -6,12 +6,138 @@ import com.google.common.collect.Lists; import java.util.List; import java.util.Set; import java.util.UUID; - -import javax.annotation.Nullable; - -import net.minecraft.server.*; - -import org.bukkit.Chunk; +import net.minecraft.server.AxisAlignedBB; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.DamageSource; +import net.minecraft.server.Entity; +import net.minecraft.server.EntityAmbient; +import net.minecraft.server.EntityAnimal; +import net.minecraft.server.EntityAreaEffectCloud; +import net.minecraft.server.EntityArmorStand; +import net.minecraft.server.EntityArrow; +import net.minecraft.server.EntityBat; +import net.minecraft.server.EntityBlaze; +import net.minecraft.server.EntityBoat; +import net.minecraft.server.EntityCat; +import net.minecraft.server.EntityCaveSpider; +import net.minecraft.server.EntityChicken; +import net.minecraft.server.EntityCod; +import net.minecraft.server.EntityComplexPart; +import net.minecraft.server.EntityCow; +import net.minecraft.server.EntityCreature; +import net.minecraft.server.EntityCreeper; +import net.minecraft.server.EntityDolphin; +import net.minecraft.server.EntityDragonFireball; +import net.minecraft.server.EntityDrowned; +import net.minecraft.server.EntityEgg; +import net.minecraft.server.EntityEnderCrystal; +import net.minecraft.server.EntityEnderDragon; +import net.minecraft.server.EntityEnderPearl; +import net.minecraft.server.EntityEnderSignal; +import net.minecraft.server.EntityEnderman; +import net.minecraft.server.EntityEndermite; +import net.minecraft.server.EntityEvoker; +import net.minecraft.server.EntityEvokerFangs; +import net.minecraft.server.EntityExperienceOrb; +import net.minecraft.server.EntityFallingBlock; +import net.minecraft.server.EntityFireball; +import net.minecraft.server.EntityFireworks; +import net.minecraft.server.EntityFish; +import net.minecraft.server.EntityFishingHook; +import net.minecraft.server.EntityFlying; +import net.minecraft.server.EntityFox; +import net.minecraft.server.EntityGhast; +import net.minecraft.server.EntityGiantZombie; +import net.minecraft.server.EntityGolem; +import net.minecraft.server.EntityGuardian; +import net.minecraft.server.EntityGuardianElder; +import net.minecraft.server.EntityHanging; +import net.minecraft.server.EntityHorse; +import net.minecraft.server.EntityHorseAbstract; +import net.minecraft.server.EntityHorseChestedAbstract; +import net.minecraft.server.EntityHorseDonkey; +import net.minecraft.server.EntityHorseMule; +import net.minecraft.server.EntityHorseSkeleton; +import net.minecraft.server.EntityHorseZombie; +import net.minecraft.server.EntityHuman; +import net.minecraft.server.EntityIllagerAbstract; +import net.minecraft.server.EntityIllagerIllusioner; +import net.minecraft.server.EntityIllagerWizard; +import net.minecraft.server.EntityIronGolem; +import net.minecraft.server.EntityItem; +import net.minecraft.server.EntityItemFrame; +import net.minecraft.server.EntityLargeFireball; +import net.minecraft.server.EntityLeash; +import net.minecraft.server.EntityLightning; +import net.minecraft.server.EntityLiving; +import net.minecraft.server.EntityLlama; +import net.minecraft.server.EntityLlamaSpit; +import net.minecraft.server.EntityLlamaTrader; +import net.minecraft.server.EntityMagmaCube; +import net.minecraft.server.EntityMinecartAbstract; +import net.minecraft.server.EntityMinecartChest; +import net.minecraft.server.EntityMinecartCommandBlock; +import net.minecraft.server.EntityMinecartFurnace; +import net.minecraft.server.EntityMinecartHopper; +import net.minecraft.server.EntityMinecartMobSpawner; +import net.minecraft.server.EntityMinecartRideable; +import net.minecraft.server.EntityMinecartTNT; +import net.minecraft.server.EntityMonster; +import net.minecraft.server.EntityMushroomCow; +import net.minecraft.server.EntityOcelot; +import net.minecraft.server.EntityPainting; +import net.minecraft.server.EntityPanda; +import net.minecraft.server.EntityParrot; +import net.minecraft.server.EntityPhantom; +import net.minecraft.server.EntityPig; +import net.minecraft.server.EntityPigZombie; +import net.minecraft.server.EntityPillager; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.EntityPolarBear; +import net.minecraft.server.EntityPotion; +import net.minecraft.server.EntityProjectile; +import net.minecraft.server.EntityPufferFish; +import net.minecraft.server.EntityRabbit; +import net.minecraft.server.EntityRavager; +import net.minecraft.server.EntitySalmon; +import net.minecraft.server.EntitySheep; +import net.minecraft.server.EntityShulker; +import net.minecraft.server.EntityShulkerBullet; +import net.minecraft.server.EntitySilverfish; +import net.minecraft.server.EntitySkeletonAbstract; +import net.minecraft.server.EntitySkeletonStray; +import net.minecraft.server.EntitySkeletonWither; +import net.minecraft.server.EntitySlime; +import net.minecraft.server.EntitySmallFireball; +import net.minecraft.server.EntitySnowball; +import net.minecraft.server.EntitySnowman; +import net.minecraft.server.EntitySpectralArrow; +import net.minecraft.server.EntitySpider; +import net.minecraft.server.EntitySquid; +import net.minecraft.server.EntityTNTPrimed; +import net.minecraft.server.EntityTameableAnimal; +import net.minecraft.server.EntityThrownExpBottle; +import net.minecraft.server.EntityThrownTrident; +import net.minecraft.server.EntityTippedArrow; +import net.minecraft.server.EntityTropicalFish; +import net.minecraft.server.EntityTurtle; +import net.minecraft.server.EntityVex; +import net.minecraft.server.EntityVillager; +import net.minecraft.server.EntityVillagerAbstract; +import net.minecraft.server.EntityVillagerTrader; +import net.minecraft.server.EntityVindicator; +import net.minecraft.server.EntityWaterAnimal; +import net.minecraft.server.EntityWitch; +import net.minecraft.server.EntityWither; +import net.minecraft.server.EntityWitherSkull; +import net.minecraft.server.EntityWolf; +import net.minecraft.server.EntityZombie; +import net.minecraft.server.EntityZombieHusk; +import net.minecraft.server.EntityZombieVillager; +import net.minecraft.server.EnumChatFormat; +import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.NBTTagCompound; +import org.bukkit.Chunk; // Paper import org.bukkit.EntityEffect; import org.bukkit.Location; import org.bukkit.Server; @@ -21,7 +147,11 @@ import org.bukkit.block.PistonMoveReaction; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.craftbukkit.util.CraftVector; +import org.bukkit.entity.Pose; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.metadata.MetadataValue; @@ -34,14 +164,15 @@ import org.bukkit.plugin.Plugin; import org.bukkit.util.BoundingBox; import org.bukkit.util.NumberConversions; import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; public abstract class CraftEntity implements org.bukkit.entity.Entity { private static PermissibleBase perm; + private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); protected final CraftServer server; protected Entity entity; private EntityDamageEvent lastDamageEvent; + private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); public CraftEntity(final CraftServer server, final Entity entity) { this.server = server; @@ -88,7 +219,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { else if (entity instanceof EntityPig) { return new CraftPig(server, (EntityPig) entity); } else if (entity instanceof EntityTameableAnimal) { if (entity instanceof EntityWolf) { return new CraftWolf(server, (EntityWolf) entity); } - else if (entity instanceof EntityOcelot) { return new CraftOcelot(server, (EntityOcelot) entity); } + else if (entity instanceof EntityCat) { return new CraftCat(server, (EntityCat) entity); } else if (entity instanceof EntityParrot) { return new CraftParrot(server, (EntityParrot) entity); } } else if (entity instanceof EntitySheep) { return new CraftSheep(server, (EntitySheep) entity); } @@ -96,6 +227,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { if (entity instanceof EntityHorseChestedAbstract){ if (entity instanceof EntityHorseDonkey) { return new CraftDonkey(server, (EntityHorseDonkey) entity); } else if (entity instanceof EntityHorseMule) { return new CraftMule(server, (EntityHorseMule) entity); } + else if (entity instanceof EntityLlamaTrader) { return new CraftTraderLlama(server, (EntityLlamaTrader) entity); } else if (entity instanceof EntityLlama) { return new CraftLlama(server, (EntityLlama) entity); } } else if (entity instanceof EntityHorse) { return new CraftHorse(server, (EntityHorse) entity); } else if (entity instanceof EntityHorseSkeleton) { return new CraftSkeletonHorse(server, (EntityHorseSkeleton) entity); } @@ -104,6 +236,9 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { else if (entity instanceof EntityRabbit) { return new CraftRabbit(server, (EntityRabbit) entity); } else if (entity instanceof EntityPolarBear) { return new CraftPolarBear(server, (EntityPolarBear) entity); } else if (entity instanceof EntityTurtle) { return new CraftTurtle(server, (EntityTurtle) entity); } + else if (entity instanceof EntityOcelot) { return new CraftOcelot(server, (EntityOcelot) entity); } + else if (entity instanceof EntityPanda) { return new CraftPanda(server, (EntityPanda) entity); } + else if (entity instanceof EntityFox) { return new CraftFox(server, (EntityFox) entity); } else { return new CraftAnimals(server, (EntityAnimal) entity); } } // Monsters @@ -144,8 +279,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { else { return new CraftSpellcaster(server, (EntityIllagerWizard) entity); } } else if (entity instanceof EntityVindicator) { return new CraftVindicator(server, (EntityVindicator) entity); } + else if (entity instanceof EntityPillager) { return new CraftPillager(server, (EntityPillager) entity); } else { return new CraftIllager(server, (EntityIllagerAbstract) entity); } } + else if (entity instanceof EntityRavager) { return new CraftRavager(server, (EntityRavager) entity); } else { return new CraftMonster(server, (EntityMonster) entity); } } @@ -154,7 +291,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { else if (entity instanceof EntityIronGolem) { return new CraftIronGolem(server, (EntityIronGolem) entity); } else if (entity instanceof EntityShulker) { return new CraftShulker(server, (EntityShulker) entity); } } - else if (entity instanceof EntityVillager) { return new CraftVillager(server, (EntityVillager) entity); } + else if (entity instanceof EntityVillagerAbstract) { + if (entity instanceof EntityVillager) { return new CraftVillager(server, (EntityVillager) entity); } + else if (entity instanceof EntityVillagerTrader) { return new CraftWanderingTrader(server, (EntityVillagerTrader) entity); } + else { return new CraftAbstractVillager(server, (EntityVillagerAbstract) entity); } + } else { return new CraftCreature(server, (EntityCreature) entity); } } // Slimes are a special (and broken) case @@ -185,10 +326,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { else { return new CraftComplexPart(server, (EntityComplexPart) entity); } } else if (entity instanceof EntityExperienceOrb) { return new CraftExperienceOrb(server, (EntityExperienceOrb) entity); } - else if (entity instanceof EntityTippedArrow) { - if (((EntityTippedArrow) entity).isTipped()) { return new CraftTippedArrow(server, (EntityTippedArrow) entity); } - else { return new CraftArrow(server, (EntityArrow) entity); } - } + else if (entity instanceof EntityTippedArrow) { return new CraftTippedArrow(server, (EntityTippedArrow) entity); } else if (entity instanceof EntitySpectralArrow) { return new CraftSpectralArrow(server, (EntitySpectralArrow) entity); } else if (entity instanceof EntityArrow) { if (entity instanceof EntityThrownTrident) { return new CraftTrident(server, (EntityThrownTrident) entity); } @@ -198,10 +336,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { else if (entity instanceof EntityProjectile) { if (entity instanceof EntityEgg) { return new CraftEgg(server, (EntityEgg) entity); } else if (entity instanceof EntitySnowball) { return new CraftSnowball(server, (EntitySnowball) entity); } - else if (entity instanceof EntityPotion) { - if (!((EntityPotion) entity).isLingering()) { return new CraftSplashPotion(server, (EntityPotion) entity); } - else { return new CraftLingeringPotion(server, (EntityPotion) entity); } - } + else if (entity instanceof EntityPotion) { return new CraftThrownPotion(server, (EntityPotion) entity); } else if (entity instanceof EntityEnderPearl) { return new CraftEnderPearl(server, (EntityEnderPearl) entity); } else if (entity instanceof EntityThrownExpBottle) { return new CraftThrownExpBottle(server, (EntityThrownExpBottle) entity); } } @@ -217,10 +352,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { else if (entity instanceof EntityEnderCrystal) { return new CraftEnderCrystal(server, (EntityEnderCrystal) entity); } else if (entity instanceof EntityFishingHook) { return new CraftFishHook(server, (EntityFishingHook) entity); } else if (entity instanceof EntityItem) { return new CraftItem(server, (EntityItem) entity); } - else if (entity instanceof EntityWeather) { - if (entity instanceof EntityLightning) { return new CraftLightningStrike(server, (EntityLightning) entity); } - else { return new CraftWeather(server, (EntityWeather) entity); } - } + else if (entity instanceof EntityLightning) { return new CraftLightningStrike(server, (EntityLightning) entity); } else if (entity instanceof EntityMinecartAbstract) { if (entity instanceof EntityMinecartFurnace) { return new CraftMinecartFurnace(server, (EntityMinecartFurnace) entity); } else if (entity instanceof EntityMinecartChest) { return new CraftMinecartChest(server, (EntityMinecartChest) entity); } @@ -245,10 +377,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { throw new AssertionError("Unknown entity " + (entity == null ? null : entity.getClass())); } + @Override public Location getLocation() { return new Location(getWorld(), entity.locX, entity.locY, entity.locZ, entity.getBukkitYaw(), entity.pitch); } + @Override public Location getLocation(Location loc) { if (loc != null) { loc.setWorld(getWorld()); @@ -262,23 +396,22 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return loc; } + @Override public Vector getVelocity() { - return new Vector(entity.motX, entity.motY, entity.motZ); + return CraftVector.toBukkit(entity.getMot()); } + @Override public void setVelocity(Vector velocity) { Preconditions.checkArgument(velocity != null, "velocity"); velocity.checkFinite(); - // Paper start - Warn server owners when plugins try to set super high velocities if (!(this instanceof org.bukkit.entity.Projectile) && isUnsafeVelocity(velocity)) { CraftServer.excessiveVelEx = new Exception("Excessive velocity set detected: tried to set velocity of entity " + entity.getName() + " id #" + getEntityId() + " to (" + velocity.getX() + "," + velocity.getY() + "," + velocity.getZ() + ")."); } // Paper end - entity.motX = velocity.getX(); - entity.motY = velocity.getY(); - entity.motZ = velocity.getZ(); + entity.setMot(CraftVector.toNMS(velocity)); entity.velocityChanged = true; } @@ -309,12 +442,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @Override public double getHeight() { - return getHandle().length; + return getHandle().getHeight(); } @Override public double getWidth() { - return getHandle().width; + return getHandle().getWidth(); } @Override @@ -323,6 +456,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return new BoundingBox(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); } + @Override public boolean isOnGround() { if (entity instanceof EntityArrow) { return ((EntityArrow) entity).inGround; @@ -330,6 +464,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return entity.onGround; } + @Override public World getWorld() { return entity.world.getWorld(); } @@ -349,10 +484,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { entity.setHeadRotation(yaw); } + @Override public boolean teleport(Location location) { return teleport(location, TeleportCause.PLUGIN); } + @Override public boolean teleport(Location location, TeleportCause cause) { Preconditions.checkArgument(location != null, "location"); location.checkFinite(); @@ -366,7 +503,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { // Let the server handle cross world teleports if (!location.getWorld().equals(getWorld())) { - entity.teleportTo(location, false); + entity.teleportTo(((CraftWorld) location.getWorld()).getHandle().getWorldProvider().getDimensionManager(), new BlockPosition(location.getX(), location.getY(), location.getZ())); return true; } @@ -374,20 +511,24 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { entity.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); // SPIGOT-619: Force sync head rotation also entity.setHeadRotation(location.getYaw()); - entity.world.entityJoinedWorld(entity, false); // Spigot - register to new chunk + ((net.minecraft.server.WorldServer) entity.world).chunkCheck(entity); // Spigot - register to new chunk return true; } + @Override public boolean teleport(org.bukkit.entity.Entity destination) { return teleport(destination.getLocation()); } + @Override public boolean teleport(org.bukkit.entity.Entity destination, TeleportCause cause) { return teleport(destination.getLocation(), cause); } + @Override public List getNearbyEntities(double x, double y, double z) { + org.spigotmc.AsyncCatcher.catchOp("getNearbyEntities"); // Spigot List notchEntityList = entity.world.getEntities(entity, entity.getBoundingBox().grow(x, y, z), null); List bukkitEntityList = new java.util.ArrayList(notchEntityList.size()); @@ -397,34 +538,42 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return bukkitEntityList; } + @Override public int getEntityId() { return entity.getId(); } + @Override public int getFireTicks() { return entity.fireTicks; } + @Override public int getMaxFireTicks() { return entity.getMaxFireTicks(); } + @Override public void setFireTicks(int ticks) { entity.fireTicks = ticks; } + @Override public void remove() { entity.die(); } + @Override public boolean isDead() { return !entity.isAlive(); } + @Override public boolean isValid() { - return entity.isAlive() && entity.valid; + return entity.isAlive() && entity.valid && entity.isChunkLoaded(); } + @Override public Server getServer() { return server; } @@ -447,10 +596,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { setVelocity(value); } + @Override public org.bukkit.entity.Entity getPassenger() { return isEmpty() ? null : getHandle().passengers.get(0).getBukkitEntity(); } + @Override public boolean setPassenger(org.bukkit.entity.Entity passenger) { Preconditions.checkArgument(!this.equals(passenger), "Entity cannot ride itself."); if (passenger instanceof CraftEntity) { @@ -486,10 +637,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return true; } + @Override public boolean isEmpty() { return !getHandle().isVehicle(); } + @Override public boolean eject() { if (isEmpty()) { return false; @@ -499,30 +652,37 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return true; } + @Override public float getFallDistance() { return getHandle().fallDistance; } + @Override public void setFallDistance(float distance) { getHandle().fallDistance = distance; } + @Override public void setLastDamageCause(EntityDamageEvent event) { lastDamageEvent = event; } + @Override public EntityDamageEvent getLastDamageCause() { return lastDamageEvent; } + @Override public UUID getUniqueId() { return getHandle().getUniqueID(); } + @Override public int getTicksLived() { return getHandle().ticksLived; } + @Override public void setTicksLived(int value) { if (value <= 0) { throw new IllegalArgumentException("Age must be at least 1 tick"); @@ -572,26 +732,32 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { // Paper end } + @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { server.getEntityMetadata().setMetadata(this, metadataKey, newMetadataValue); } + @Override public List getMetadata(String metadataKey) { return server.getEntityMetadata().getMetadata(this, metadataKey); } + @Override public boolean hasMetadata(String metadataKey) { return server.getEntityMetadata().hasMetadata(this, metadataKey); } + @Override public void removeMetadata(String metadataKey, Plugin owningPlugin) { server.getEntityMetadata().removeMetadata(this, metadataKey, owningPlugin); } + @Override public boolean isInsideVehicle() { return getHandle().isPassenger(); } + @Override public boolean leaveVehicle() { if (!isInsideVehicle()) { return false; @@ -601,6 +767,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return true; } + @Override public org.bukkit.entity.Entity getVehicle() { if (!isInsideVehicle()) { return null; @@ -800,6 +967,29 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return CraftBlock.notchToBlockFace(getHandle().getAdjustedDirection()); } + @Override + public CraftPersistentDataContainer getPersistentDataContainer() { + return persistentDataContainer; + } + + @Override + public Pose getPose() { + return Pose.values()[getHandle().getPose().ordinal()]; + } + + public void storeBukkitValues(NBTTagCompound c) { + if (!this.persistentDataContainer.isEmpty()) { + c.set("BukkitValues", this.persistentDataContainer.toTagCompound()); + } + } + + public void readBukkitValues(NBTTagCompound c) { + NBTTagCompound base = c.getCompound("BukkitValues"); + if (base != null) { + this.persistentDataContainer.putAll(base); + } + } + protected NBTTagCompound save() { NBTTagCompound nbttagcompound = new NBTTagCompound(); @@ -865,21 +1055,9 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return getHandle().spawnedViaMobSpawner; } + @Override public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason getEntitySpawnReason() { return getHandle().spawnReason; } // Paper end - - // Akarin start - @Nullable - @Override - public io.akarin.server.api.structure.Village getNearestVillage(@NotNull double xRadius, @NotNull double yRadius, @NotNull double zRadius) { - return entity.world.getWorld().getNearestVillage(getLocation(), xRadius, yRadius, zRadius); - } - - @Override - public List getVillagesInRange(@NotNull double xRadius, @NotNull double yRadius, @NotNull double zRadius) { - return entity.world.getWorld().getVillagesInRange(getLocation(), xRadius, yRadius, zRadius); - } - // Akarin end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java index 3302af0e4..fbad04567 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java @@ -10,10 +10,12 @@ public class CraftExperienceOrb extends CraftEntity implements ExperienceOrb { super(server, entity); } + @Override public int getExperience() { return getHandle().value; } + @Override public void setExperience(int value) { getHandle().value = value; } @@ -40,6 +42,7 @@ public class CraftExperienceOrb extends CraftEntity implements ExperienceOrb { return "CraftExperienceOrb"; } + @Override public EntityType getType() { return EntityType.EXPERIENCE_ORB; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java index b4322dff6..7a6676b4a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityFallingBlock; - import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.CraftServer; @@ -26,22 +25,27 @@ public class CraftFallingBlock extends CraftEntity implements FallingBlock { return "CraftFallingBlock"; } + @Override public EntityType getType() { return EntityType.FALLING_BLOCK; } + @Override public Material getMaterial() { return CraftMagicNumbers.getMaterial(getHandle().getBlock()).getItemType(); } + @Override public BlockData getBlockData() { return CraftBlockData.fromData(getHandle().getBlock()); } + @Override public boolean getDropItem() { return getHandle().dropItem; } + @Override public void setDropItem(boolean drop) { getHandle().dropItem = drop; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java index 7703cc726..f392f801b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityFireball; import net.minecraft.server.MathHelper; - import org.apache.commons.lang.Validate; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; @@ -15,26 +14,32 @@ public class CraftFireball extends AbstractProjectile implements Fireball { super(server, entity); } + @Override public float getYield() { return getHandle().bukkitYield; } + @Override public boolean isIncendiary() { return getHandle().isIncendiary; } + @Override public void setIsIncendiary(boolean isIncendiary) { getHandle().isIncendiary = isIncendiary; } + @Override public void setYield(float yield) { getHandle().bukkitYield = yield; } + @Override public ProjectileSource getShooter() { return getHandle().projectileSource; } + @Override public void setShooter(ProjectileSource shooter) { if (shooter instanceof CraftLivingEntity) { getHandle().shooter = ((CraftLivingEntity) shooter).getHandle(); @@ -44,10 +49,12 @@ public class CraftFireball extends AbstractProjectile implements Fireball { getHandle().projectileSource = shooter; } + @Override public Vector getDirection() { return new Vector(getHandle().dirX, getHandle().dirY, getHandle().dirZ); } + @Override public void setDirection(Vector direction) { Validate.notNull(direction, "Direction can not be null"); double x = direction.getX(); @@ -69,6 +76,7 @@ public class CraftFireball extends AbstractProjectile implements Fireball { return "CraftFireball"; } + @Override public EntityType getType() { return EntityType.UNKNOWN; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java index b39e33f4f..219a1e4c0 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java @@ -1,10 +1,10 @@ package org.bukkit.craftbukkit.entity; +import java.util.Random; import net.minecraft.server.EntityFireworks; import net.minecraft.server.EntityLiving; import net.minecraft.server.ItemStack; import net.minecraft.server.Items; - import org.bukkit.Material; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.inventory.CraftItemStack; @@ -13,7 +13,6 @@ import org.bukkit.entity.Firework; import org.bukkit.entity.LivingEntity; import org.bukkit.inventory.meta.FireworkMeta; -import java.util.Random; import java.util.UUID; public class CraftFirework extends CraftEntity implements Firework { @@ -74,8 +73,17 @@ public class CraftFirework extends CraftEntity implements Firework { getHandle().expectedLifespan = 0; } - // Paper start + @Override + public boolean isShotAtAngle() { + return getHandle().i(); + } + @Override + public void setShotAtAngle(boolean shotAtAngle) { + getHandle().getDataWatcher().set(EntityFireworks.d, shotAtAngle); + } + + // Paper start @Override public UUID getSpawningEntity() { return getHandle().spawningEntity; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java index 752b56435..9eb980137 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java @@ -4,7 +4,6 @@ import net.minecraft.server.BlockPosition; import net.minecraft.server.EntityFishingHook; import net.minecraft.server.EntityHuman; import net.minecraft.server.MathHelper; - import org.apache.commons.lang.Validate; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; @@ -18,6 +17,7 @@ public class CraftFishHook extends AbstractProjectile implements FishHook { super(server, entity); } + @Override public ProjectileSource getShooter() { if (getHandle().owner != null) { return getHandle().owner.getBukkitEntity(); @@ -26,6 +26,7 @@ public class CraftFishHook extends AbstractProjectile implements FishHook { return null; } + @Override public void setShooter(ProjectileSource shooter) { if (shooter instanceof CraftHumanEntity) { getHandle().owner = (EntityHuman) ((CraftHumanEntity) shooter).entity; @@ -42,10 +43,12 @@ public class CraftFishHook extends AbstractProjectile implements FishHook { return "CraftFishingHook"; } + @Override public EntityType getType() { return EntityType.FISHING_HOOK; } + @Override public double getBiteChance() { EntityFishingHook hook = getHandle(); @@ -58,6 +61,7 @@ public class CraftFishHook extends AbstractProjectile implements FishHook { return this.biteChance; } + @Override public void setBiteChance(double chance) { Validate.isTrue(chance >= 0 && chance <= 1, "The bite chance must be between 0 and 1."); this.biteChance = chance; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java new file mode 100644 index 000000000..2e2c253f4 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java @@ -0,0 +1,66 @@ +package org.bukkit.craftbukkit.entity; + +import com.google.common.base.Preconditions; +import net.minecraft.server.EntityFox; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Fox; + +public class CraftFox extends CraftAnimals implements Fox { + + public CraftFox(CraftServer server, EntityFox entity) { + super(server, entity); + } + + @Override + public EntityFox getHandle() { + return (EntityFox) super.getHandle(); + } + + @Override + public EntityType getType() { + return EntityType.FOX; + } + + @Override + public String toString() { + return "CraftFox"; + } + + @Override + public Type getFoxType() { + return Type.values()[getHandle().getFoxType().ordinal()]; + } + + @Override + public void setFoxType(Type type) { + Preconditions.checkArgument(type != null, "type"); + + getHandle().setFoxType(EntityFox.Type.values()[type.ordinal()]); + } + + @Override + public boolean isCrouching() { + return getHandle().isCrouching(); + } + + @Override + public void setCrouching(boolean crouching) { + getHandle().setCrouching(crouching); + } + + @Override + public boolean isSitting() { + return getHandle().isSitting(); + } + + @Override + public void setSitting(boolean sitting) { + getHandle().setSitting(sitting); + } + + @Override + public void setSleeping(boolean sleeping) { + getHandle().setSleeping(sleeping); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java index ee9516fc4..cac82ce76 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityGhast; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Ghast; @@ -22,6 +21,7 @@ public class CraftGhast extends CraftFlying implements Ghast { return "CraftGhast"; } + @Override public EntityType getType() { return EntityType.GHAST; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java index e5609130d..ecbead90a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityGiantZombie; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Giant; @@ -22,6 +21,7 @@ public class CraftGiant extends CraftMonster implements Giant { return "CraftGiant"; } + @Override public EntityType getType() { return EntityType.GIANT; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java index d9a871a8c..54a9f39d2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java @@ -13,17 +13,20 @@ public class CraftHanging extends CraftEntity implements Hanging { super(server, entity); } + @Override public BlockFace getAttachedFace() { return getFacing().getOppositeFace(); } + @Override public void setFacingDirection(BlockFace face) { setFacingDirection(face, false); } + @Override public boolean setFacingDirection(BlockFace face, boolean force) { EntityHanging hanging = getHandle(); - EnumDirection dir = hanging.direction; + EnumDirection dir = hanging.getDirection(); switch (face) { case SOUTH: default: @@ -47,8 +50,9 @@ public class CraftHanging extends CraftEntity implements Hanging { return true; } + @Override public BlockFace getFacing() { - EnumDirection direction = this.getHandle().direction; + EnumDirection direction = this.getHandle().getDirection(); if (direction == null) return BlockFace.SELF; return CraftBlock.notchToBlockFace(direction); } @@ -63,6 +67,7 @@ public class CraftHanging extends CraftEntity implements Hanging { return "CraftHanging"; } + @Override public EntityType getType() { return EntityType.UNKNOWN; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index cb7697f80..81cf5f47a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -4,13 +4,16 @@ import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Optional; import java.util.Set; -import net.minecraft.server.BlockAnvil; import net.minecraft.server.BlockBed; +import net.minecraft.server.BlockEnchantmentTable; import net.minecraft.server.BlockPosition; import net.minecraft.server.BlockWorkbench; +import net.minecraft.server.Blocks; import net.minecraft.server.ChatComponentText; import net.minecraft.server.Container; +import net.minecraft.server.Containers; import net.minecraft.server.CraftingManager; import net.minecraft.server.Entity; import net.minecraft.server.EntityHuman; @@ -19,24 +22,28 @@ import net.minecraft.server.EntityPlayer; import net.minecraft.server.EntityTypes; import net.minecraft.server.EnumMainHand; import net.minecraft.server.IBlockData; +import net.minecraft.server.IChatBaseComponent; import net.minecraft.server.IInventory; import net.minecraft.server.IMerchant; import net.minecraft.server.IRecipe; -import net.minecraft.server.ITileEntityContainer; import net.minecraft.server.ITileInventory; import net.minecraft.server.ItemCooldown; import net.minecraft.server.NBTTagCompound; import net.minecraft.server.PacketPlayInCloseWindow; import net.minecraft.server.PacketPlayOutOpenWindow; import net.minecraft.server.TileEntity; +import net.minecraft.server.TileEntityBarrel; import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.TileEntityBlastFurnace; import net.minecraft.server.TileEntityBrewingStand; import net.minecraft.server.TileEntityDispenser; import net.minecraft.server.TileEntityDropper; -import net.minecraft.server.TileEntityEnchantTable; -import net.minecraft.server.TileEntityFurnace; +import net.minecraft.server.TileEntityFurnaceFurnace; import net.minecraft.server.TileEntityHopper; +import net.minecraft.server.TileEntityLectern; import net.minecraft.server.TileEntityShulkerBox; +import net.minecraft.server.TileEntitySmoker; +import net.minecraft.server.Vec3D; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; @@ -48,10 +55,11 @@ import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.inventory.CraftContainer; import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest; import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer; import org.bukkit.craftbukkit.inventory.CraftInventoryView; import org.bukkit.craftbukkit.inventory.CraftItemStack; -import org.bukkit.craftbukkit.inventory.CraftMerchant; +import org.bukkit.craftbukkit.inventory.CraftMerchantCustom; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.entity.HumanEntity; @@ -84,34 +92,42 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { enderChest = new CraftInventory(entity.getEnderChest()); } + @Override public PlayerInventory getInventory() { return inventory; } + @Override public EntityEquipment getEquipment() { return inventory; } + @Override public Inventory getEnderChest() { return enderChest; } + @Override public MainHand getMainHand() { return getHandle().getMainHand()== EnumMainHand.LEFT ? MainHand.LEFT : MainHand.RIGHT; } + @Override public ItemStack getItemInHand() { return getInventory().getItemInHand(); } + @Override public void setItemInHand(ItemStack item) { getInventory().setItemInHand(item); } + @Override public ItemStack getItemOnCursor() { return CraftItemStack.asCraftMirror(getHandle().inventory.getCarried()); } + @Override public void setItemOnCursor(ItemStack item) { net.minecraft.server.ItemStack stack = CraftItemStack.asNMSCopy(item); getHandle().inventory.setCarried(stack); @@ -120,10 +136,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { } } - public boolean isSleeping() { - return getHandle().sleeping; - } - + @Override public int getSleepTicks() { return getHandle().sleepTicks; } @@ -134,9 +147,10 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { BlockPosition bed = getHandle().getBed(); if (world != null && bed != null) { - bed = EntityHuman.getBed(((CraftWorld) world).getHandle(), bed, getHandle().isRespawnForced()); - if (bed != null) { - return new Location(world, bed.getX(), bed.getY(), bed.getZ()); + Optional spawnLoc = EntityHuman.getBed(((CraftWorld) world).getHandle(), bed, getHandle().isRespawnForced()); + if (spawnLoc.isPresent()) { + Vec3D vec = spawnLoc.get(); + return new Location(world, vec.x, vec.y, vec.z); } } return null; @@ -159,7 +173,8 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public boolean sleep(Location location, boolean force) { - Preconditions.checkArgument(location != null, "Location == null"); + Preconditions.checkArgument(location != null, "Location cannot be null"); + Preconditions.checkArgument(location.getWorld() != null, "Location needs to be in a world"); Preconditions.checkArgument(location.getWorld().equals(getWorld()), "Cannot sleep across worlds"); BlockPosition blockposition = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()); @@ -168,7 +183,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return false; } - if (getHandle().a(blockposition, force) != EntityHuman.EnumBedResult.OK) { + if (getHandle().sleep(blockposition, force).left().isPresent()) { return false; } @@ -183,14 +198,15 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { public void wakeup(boolean setSpawnLocation) { Preconditions.checkState(isSleeping(), "Cannot wakeup if not sleeping"); - getHandle().a(true, true, setSpawnLocation); + getHandle().wakeup(true, true, setSpawnLocation); } @Override public Location getBedLocation() { Preconditions.checkState(isSleeping(), "Not sleeping"); - return new Location(getWorld(), getHandle().bedPosition.getX(), getHandle().bedPosition.getY(), getHandle().bedPosition.getZ()); + BlockPosition bed = getHandle().getBed(); + return new Location(getWorld(), bed.getX(), bed.getY(), bed.getZ()); } @Override @@ -198,63 +214,78 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return getHandle().getName(); } + @Override public boolean isOp() { return op; } + @Override public boolean isPermissionSet(String name) { return perm.isPermissionSet(name); } + @Override public boolean isPermissionSet(Permission perm) { return this.perm.isPermissionSet(perm); } + @Override public boolean hasPermission(String name) { return perm.hasPermission(name); } + @Override public boolean hasPermission(Permission perm) { return this.perm.hasPermission(perm); } + @Override public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { return perm.addAttachment(plugin, name, value); } + @Override public PermissionAttachment addAttachment(Plugin plugin) { return perm.addAttachment(plugin); } + @Override public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { return perm.addAttachment(plugin, name, value, ticks); } + @Override public PermissionAttachment addAttachment(Plugin plugin, int ticks) { return perm.addAttachment(plugin, ticks); } + @Override public void removeAttachment(PermissionAttachment attachment) { perm.removeAttachment(attachment); } + @Override public void recalculatePermissions() { perm.recalculatePermissions(); } + @Override public void setOp(boolean value) { this.op = value; perm.recalculatePermissions(); } + @Override public Set getEffectivePermissions() { return perm.getEffectivePermissions(); } + @Override public GameMode getGameMode() { return mode; } + @Override public void setGameMode(GameMode mode) { if (mode == null) { throw new IllegalArgumentException("Mode cannot be null"); @@ -278,17 +309,27 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return "CraftHumanEntity{" + "id=" + getEntityId() + "name=" + getName() + '}'; } + @Override public InventoryView getOpenInventory() { return getHandle().activeContainer.getBukkitView(); } + @Override public InventoryView openInventory(Inventory inventory) { if(!(getHandle() instanceof EntityPlayer)) return null; EntityPlayer player = (EntityPlayer) getHandle(); InventoryType type = inventory.getType(); Container formerContainer = getHandle().activeContainer; - IInventory iinventory = (inventory instanceof CraftInventory) ? ((CraftInventory) inventory).getInventory() : new org.bukkit.craftbukkit.inventory.InventoryWrapper(inventory); + ITileInventory iinventory = null; + if (inventory instanceof CraftInventoryDoubleChest) { + iinventory = ((CraftInventoryDoubleChest) inventory).tile; + } else if (inventory instanceof CraftInventory) { + CraftInventory craft = (CraftInventory) inventory; + if (craft.getInventory() instanceof ITileInventory) { + iinventory = (ITileInventory) craft.getInventory(); + } + } if (iinventory instanceof ITileInventory) { if (iinventory instanceof TileEntity) { @@ -303,41 +344,69 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { case PLAYER: case CHEST: case ENDER_CHEST: - getHandle().openContainer(iinventory); + if (iinventory instanceof ITileInventory) { + getHandle().openContainer((ITileInventory) iinventory); + } else { + Containers customSize; + switch (inventory.getSize()) { + case 9: + customSize = Containers.GENERIC_9X1; + break; + case 18: + customSize = Containers.GENERIC_9X2; + break; + case 27: + customSize = Containers.GENERIC_9X3; + break; + case 36: + case 41: // PLAYER + customSize = Containers.GENERIC_9X4; + break; + case 45: + customSize = Containers.GENERIC_9X5; + break; + case 54: + customSize = Containers.GENERIC_9X6; + break; + default: + throw new IllegalArgumentException("Unsupported custom inventory size " + inventory.getSize()); + } + openCustomInventory(inventory, player, customSize); + } break; case DISPENSER: if (iinventory instanceof TileEntityDispenser) { getHandle().openContainer((TileEntityDispenser) iinventory); } else { - openCustomInventory(inventory, player, "minecraft:dispenser"); + openCustomInventory(inventory, player, Containers.GENERIC_3X3); } break; case DROPPER: if (iinventory instanceof TileEntityDropper) { getHandle().openContainer((TileEntityDropper) iinventory); } else { - openCustomInventory(inventory, player, "minecraft:dropper"); + openCustomInventory(inventory, player, Containers.GENERIC_3X3); } break; case FURNACE: - if (iinventory instanceof TileEntityFurnace) { - getHandle().openContainer((TileEntityFurnace) iinventory); + if (iinventory instanceof TileEntityFurnaceFurnace) { + getHandle().openContainer((TileEntityFurnaceFurnace) iinventory); } else { - openCustomInventory(inventory, player, "minecraft:furnace"); + openCustomInventory(inventory, player, Containers.FURNACE); } break; case WORKBENCH: - openCustomInventory(inventory, player, "minecraft:crafting_table"); + openCustomInventory(inventory, player, Containers.CRAFTING); break; case BREWING: if (iinventory instanceof TileEntityBrewingStand) { getHandle().openContainer((TileEntityBrewingStand) iinventory); } else { - openCustomInventory(inventory, player, "minecraft:brewing_stand"); + openCustomInventory(inventory, player, Containers.BREWING_STAND); } break; case ENCHANTING: - openCustomInventory(inventory, player, "minecraft:enchanting_table"); + openCustomInventory(inventory, player, Containers.ENCHANTMENT); break; case HOPPER: if (iinventory instanceof TileEntityHopper) { @@ -345,33 +414,74 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { } else if (iinventory instanceof EntityMinecartHopper) { getHandle().openContainer((EntityMinecartHopper) iinventory); } else { - openCustomInventory(inventory, player, "minecraft:hopper"); + openCustomInventory(inventory, player, Containers.HOPPER); } break; case BEACON: if (iinventory instanceof TileEntityBeacon) { getHandle().openContainer((TileEntityBeacon) iinventory); } else { - openCustomInventory(inventory, player, "minecraft:beacon"); + openCustomInventory(inventory, player, Containers.BEACON); } break; case ANVIL: - if (iinventory instanceof BlockAnvil.TileEntityContainerAnvil) { - getHandle().openTileEntity((BlockAnvil.TileEntityContainerAnvil) iinventory); + if (iinventory instanceof ITileInventory) { + getHandle().openContainer((ITileInventory) iinventory); } else { - openCustomInventory(inventory, player, "minecraft:anvil"); + openCustomInventory(inventory, player, Containers.ANVIL); } break; case SHULKER_BOX: if (iinventory instanceof TileEntityShulkerBox) { getHandle().openContainer((TileEntityShulkerBox) iinventory); } else { - openCustomInventory(inventory, player, "minecraft:shulker_box"); + openCustomInventory(inventory, player, Containers.SHULKER_BOX); } break; + case BARREL: + if (iinventory instanceof TileEntityBarrel) { + getHandle().openContainer((TileEntityBarrel) iinventory); + } else { + openCustomInventory(inventory, player, Containers.GENERIC_9X3); + } + break; + case BLAST_FURNACE: + if (iinventory instanceof TileEntityBlastFurnace) { + getHandle().openContainer((TileEntityBlastFurnace) iinventory); + } else { + openCustomInventory(inventory, player, Containers.BLAST_FURNACE); + } + break; + case LECTERN: + if (iinventory instanceof TileEntityLectern) { + getHandle().openContainer((TileEntityLectern) iinventory); + } else { + openCustomInventory(inventory, player, Containers.LECTERN); + } + break; + case SMOKER: + if (iinventory instanceof TileEntitySmoker) { + getHandle().openContainer((TileEntitySmoker) iinventory); + } else { + openCustomInventory(inventory, player, Containers.SMOKER); + } + break; + case STONECUTTER: + openCustomInventory(inventory, player, Containers.STONECUTTER); + break; + case LOOM: + openCustomInventory(inventory, player, Containers.LOOM); + break; + case CARTOGRAPHY: + openCustomInventory(inventory, player, Containers.CARTOGRAPHY); + break; + case GRINDSTONE: + openCustomInventory(inventory, player, Containers.GRINDSTONE); + break; case CREATIVE: case CRAFTING: case MERCHANT: + default: throw new IllegalArgumentException("Can't open a " + type + " inventory!"); } if (getHandle().activeContainer == formerContainer) { @@ -381,29 +491,22 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return getHandle().activeContainer.getBukkitView(); } - private void openCustomInventory(Inventory inventory, EntityPlayer player, String windowType) { + private void openCustomInventory(Inventory inventory, EntityPlayer player, Containers windowType) { if (player.playerConnection == null) return; + Preconditions.checkArgument(windowType != null, "Unknown windowType"); Container container = new CraftContainer(inventory, this.getHandle(), player.nextContainerCounter()); container = CraftEventFactory.callInventoryOpenEvent(player, container); if(container == null) return; String title = container.getBukkitView().getTitle(); - int size = container.getBukkitView().getTopInventory().getSize(); - // Special cases - if (windowType.equals("minecraft:crafting_table") - || windowType.equals("minecraft:anvil") - || windowType.equals("minecraft:enchanting_table") - ) { - size = 0; - } - - player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title), size)); + player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); getHandle().activeContainer = container; getHandle().activeContainer.addSlotListener(player); } + @Override public InventoryView openWorkbench(Location location, boolean force) { if (!force) { Block block = location.getBlock(); @@ -414,13 +517,14 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { if (location == null) { location = getLocation(); } - getHandle().openTileEntity(new BlockWorkbench.TileEntityContainerWorkbench(getHandle().world, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()))); + getHandle().openContainer(((BlockWorkbench) Blocks.CRAFTING_TABLE).getInventory(null, getHandle().world, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()))); if (force) { getHandle().activeContainer.checkReachable = false; } return getHandle().activeContainer.getBukkitView(); } + @Override public InventoryView openEnchanting(Location location, boolean force) { if (!force) { Block block = location.getBlock(); @@ -434,13 +538,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { // If there isn't an enchant table we can force create one, won't be very useful though. BlockPosition pos = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()); - TileEntity container = getHandle().world.getTileEntity(pos); - if (container == null && force) { - container = new TileEntityEnchantTable(); - container.setWorld(getHandle().world); - container.setPosition(pos); - } - getHandle().openTileEntity((ITileEntityContainer) container); + getHandle().openContainer(((BlockEnchantmentTable) Blocks.ENCHANTING_TABLE).getInventory(null, getHandle().world, pos)); if (force) { getHandle().activeContainer.checkReachable = false; @@ -448,6 +546,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return getHandle().activeContainer.getBukkitView(); } + @Override public void openInventory(InventoryView inventory) { if (!(getHandle() instanceof EntityPlayer)) return; // TODO: NPC support? if (((EntityPlayer) getHandle()).playerConnection == null) return; @@ -471,10 +570,9 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { // Now open the window InventoryType type = inventory.getType(); - String windowType = CraftContainer.getNotchInventoryType(type); + Containers windowType = CraftContainer.getNotchInventoryType(type); String title = inventory.getTitle(); - int size = inventory.getTopInventory().getSize(); - player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title), size)); + player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title))); player.activeContainer = container; player.activeContainer.addSlotListener(player); } @@ -498,20 +596,28 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { } IMerchant mcMerchant; - if (merchant instanceof CraftVillager) { - mcMerchant = ((CraftVillager) merchant).getHandle(); - } else if (merchant instanceof CraftMerchant) { - mcMerchant = ((CraftMerchant) merchant).getMerchant(); + IChatBaseComponent name; + int level = 1; // note: using level 0 with active 'is-regular-villager'-flag allows hiding the name suffix + if (merchant instanceof CraftAbstractVillager) { + mcMerchant = ((CraftAbstractVillager) merchant).getHandle(); + name = ((CraftAbstractVillager) merchant).getHandle().getScoreboardDisplayName(); + if (merchant instanceof CraftVillager) { + level = ((CraftVillager) merchant).getHandle().getVillagerData().getLevel(); + } + } else if (merchant instanceof CraftMerchantCustom) { + mcMerchant = ((CraftMerchantCustom) merchant).getMerchant(); + name = ((CraftMerchantCustom) merchant).getMerchant().getScoreboardDisplayName(); } else { throw new IllegalArgumentException("Can't open merchant " + merchant.toString()); } mcMerchant.setTradingPlayer(this.getHandle()); - this.getHandle().openTrade(mcMerchant); + mcMerchant.openTrade(this.getHandle(), name, level); return this.getHandle().activeContainer.getBukkitView(); } + @Override public void closeInventory() { // Paper start getHandle().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.PLUGIN); @@ -521,6 +627,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { } // Paper end + @Override public boolean isBlocking() { return getHandle().isBlocking(); } @@ -530,10 +637,12 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return getHandle().isHandRaised(); } + @Override public boolean setWindowProperty(InventoryView.Property prop, int value) { return false; } + @Override public int getExpToLevel() { return getHandle().getExpToLevel(); } @@ -542,7 +651,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { public boolean hasCooldown(Material material) { Preconditions.checkArgument(material != null, "material"); - return getHandle().getCooldownTracker().a(CraftMagicNumbers.getItem(material)); + return getHandle().getCooldownTracker().hasCooldown(CraftMagicNumbers.getItem(material)); } @Override @@ -558,7 +667,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { Preconditions.checkArgument(material != null, "material"); Preconditions.checkArgument(ticks >= 0, "Cannot have negative cooldown"); - getHandle().getCooldownTracker().a(CraftMagicNumbers.getItem(material), ticks); + getHandle().getCooldownTracker().setCooldown(CraftMagicNumbers.getItem(material), ticks); } // Paper start @@ -607,17 +716,17 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return getHandle().undiscoverRecipes(bukkitKeysToMinecraftRecipes(recipes)); } - private Collection bukkitKeysToMinecraftRecipes(Collection recipeKeys) { - Collection recipes = new ArrayList<>(); + private Collection> bukkitKeysToMinecraftRecipes(Collection recipeKeys) { + Collection> recipes = new ArrayList<>(); CraftingManager manager = getHandle().world.getMinecraftServer().getCraftingManager(); for (NamespacedKey recipeKey : recipeKeys) { - IRecipe recipe = manager.a(CraftNamespacedKey.toMinecraft(recipeKey)); - if (recipe == null) { + Optional> recipe = manager.a(CraftNamespacedKey.toMinecraft(recipeKey)); + if (!recipe.isPresent()) { continue; } - recipes.add(recipe); + recipes.add(recipe.get()); } return recipes; @@ -626,9 +735,9 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public org.bukkit.entity.Entity getShoulderEntityLeft() { if (!getHandle().getShoulderEntityLeft().isEmpty()) { - Entity shoulder = EntityTypes.a(getHandle().getShoulderEntityLeft(), getHandle().world); + Optional shoulder = EntityTypes.a(getHandle().getShoulderEntityLeft(), getHandle().world); - return (shoulder == null) ? null : shoulder.getBukkitEntity(); + return (!shoulder.isPresent()) ? null : shoulder.get().getBukkitEntity(); } return null; @@ -645,9 +754,9 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public org.bukkit.entity.Entity getShoulderEntityRight() { if (!getHandle().getShoulderEntityRight().isEmpty()) { - Entity shoulder = EntityTypes.a(getHandle().getShoulderEntityRight(), getHandle().world); + Optional shoulder = EntityTypes.a(getHandle().getShoulderEntityRight(), getHandle().world); - return (shoulder == null) ? null : shoulder.getBukkitEntity(); + return (!shoulder.isPresent()) ? null : shoulder.get().getBukkitEntity(); } return null; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllager.java index 824af5780..9bdd1f1d4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllager.java @@ -4,7 +4,7 @@ import net.minecraft.server.EntityIllagerAbstract; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Illager; -public class CraftIllager extends CraftMonster implements Illager { +public class CraftIllager extends CraftRaider implements Illager { public CraftIllager(CraftServer server, EntityIllagerAbstract entity) { super(server, entity); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java index ddee207eb..9ca8eeff5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java @@ -20,10 +20,12 @@ public class CraftIronGolem extends CraftGolem implements IronGolem { return "CraftIronGolem"; } + @Override public boolean isPlayerCreated() { return getHandle().isPlayerCreated(); } + @Override public void setPlayerCreated(boolean playerCreated) { getHandle().setPlayerCreated(playerCreated); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java index 4128ba4c0..cb756b1ba 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java @@ -2,12 +2,11 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.Entity; import net.minecraft.server.EntityItem; - +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.EntityType; import org.bukkit.entity.Item; import org.bukkit.inventory.ItemStack; -import org.bukkit.craftbukkit.inventory.CraftItemStack; -import org.bukkit.craftbukkit.CraftServer; // Paper start import javax.annotation.Nullable; @@ -26,18 +25,22 @@ public class CraftItem extends CraftEntity implements Item { this(server, entity, entity); } + @Override public ItemStack getItemStack() { return CraftItemStack.asCraftMirror(item.getItemStack()); } + @Override public void setItemStack(ItemStack stack) { item.setItemStack(CraftItemStack.asNMSCopy(stack)); } + @Override public int getPickupDelay() { return item.pickupDelay; } + @Override public void setPickupDelay(int delay) { item.pickupDelay = Math.min(delay, Short.MAX_VALUE); } @@ -60,19 +63,23 @@ public class CraftItem extends CraftEntity implements Item { } @Nullable + @Override public UUID getOwner() { return item.getOwner(); } + @Override public void setOwner(@Nullable UUID owner) { item.setOwner(owner); } @Nullable + @Override public UUID getThrower() { return item.getThrower(); } + @Override public void setThrower(@Nullable UUID thrower) { item.setThrower(thrower); } @@ -83,6 +90,7 @@ public class CraftItem extends CraftEntity implements Item { return "CraftItem"; } + @Override public EntityType getType() { return EntityType.DROPPED_ITEM; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java index 227a9ffa0..9ad180d94 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java @@ -6,9 +6,7 @@ import net.minecraft.server.EntityItemFrame; import net.minecraft.server.EnumDirection; import net.minecraft.server.ItemStack; import net.minecraft.server.WorldServer; - import org.apache.commons.lang.Validate; - import org.bukkit.Rotation; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.CraftServer; @@ -26,7 +24,7 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame { @Override public boolean setFacingDirection(BlockFace face, boolean force) { EntityHanging hanging = getHandle(); - EnumDirection oldDir = hanging.direction; + EnumDirection oldDir = hanging.getDirection(); EnumDirection newDir = CraftBlock.blockFaceToNotch(face); getHandle().setDirection(newDir); @@ -51,23 +49,27 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame { old.die(); EntityItemFrame frame = new EntityItemFrame(world,position,direction); - frame.setItem(item); + frame.setItem(item, true, false); // Paper - fix itemframe sound world.addEntity(frame); this.entity = frame; } + @Override public void setItem(org.bukkit.inventory.ItemStack item) { setItem(item, true); } + @Override public void setItem(org.bukkit.inventory.ItemStack item, boolean playSound) { getHandle().setItem(CraftItemStack.asNMSCopy(item), true, playSound); } + @Override public org.bukkit.inventory.ItemStack getItem() { return CraftItemStack.asBukkitCopy(getHandle().getItem()); } + @Override public Rotation getRotation() { return toBukkitRotation(getHandle().getRotation()); } @@ -96,6 +98,7 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame { } } + @Override public void setRotation(Rotation rotation) { Validate.notNull(rotation, "Rotation cannot be null"); getHandle().setRotation(toInteger(rotation)); @@ -135,6 +138,7 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame { return "CraftItemFrame{item=" + getItem() + ", rotation=" + getRotation() + "}"; } + @Override public EntityType getType() { return EntityType.ITEM_FRAME; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java index ca0379403..9ab8f6606 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java @@ -26,6 +26,7 @@ public class CraftLargeFireball extends CraftFireball implements LargeFireball { return "CraftLargeFireball"; } + @Override public EntityType getType() { return EntityType.FIREBALL; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java index 710ed7a64..7114b5156 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityLeash; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.LeashHitch; @@ -21,6 +20,7 @@ public class CraftLeash extends CraftHanging implements LeashHitch { return "CraftLeash"; } + @Override public EntityType getType() { return EntityType.LEASH_HITCH; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java index ddd5ccd58..e41de11c1 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java @@ -10,6 +10,7 @@ public class CraftLightningStrike extends CraftEntity implements LightningStrike super(server, entity); } + @Override public boolean isEffect() { return ((EntityLightning) super.getHandle()).isEffect; } @@ -24,6 +25,7 @@ public class CraftLightningStrike extends CraftEntity implements LightningStrike return "CraftLightningStrike"; } + @Override public EntityType getType() { return EntityType.LIGHTNING; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLingeringPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLingeringPotion.java deleted file mode 100644 index 2a5482ff8..000000000 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLingeringPotion.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.bukkit.craftbukkit.entity; - -import net.minecraft.server.EntityPotion; -import org.apache.commons.lang.Validate; -import org.bukkit.Material; -import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.craftbukkit.inventory.CraftItemStack; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.LingeringPotion; -import org.bukkit.inventory.ItemStack; - -public class CraftLingeringPotion extends CraftThrownPotion implements LingeringPotion { - - public CraftLingeringPotion(CraftServer server, EntityPotion entity) { - super(server, entity); - } - - public void setItem(ItemStack item) { - // The ItemStack must not be null. - Validate.notNull(item, "ItemStack cannot be null."); - - // The ItemStack must be a potion. - Validate.isTrue(item.getType() == Material.LINGERING_POTION, "ItemStack must be a lingering potion. This item stack was " + item.getType() + "."); - - getHandle().setItem(CraftItemStack.asNMSCopy(item)); - } - - @Override - public EntityPotion getHandle() { - return (EntityPotion) entity; - } - - @Override - public String toString() { - return "CraftLingeringPotion"; - } - - @Override - public EntityType getType() { - return EntityType.LINGERING_POTION; - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index d6a4bc64a..b27fd44dc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -1,21 +1,21 @@ package org.bukkit.craftbukkit.entity; +import com.google.common.base.Preconditions; import com.google.common.collect.Sets; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Set; - import net.minecraft.server.DamageSource; import net.minecraft.server.EntityArmorStand; import net.minecraft.server.EntityArrow; import net.minecraft.server.EntityDragonFireball; import net.minecraft.server.EntityEgg; import net.minecraft.server.EntityEnderPearl; +import net.minecraft.server.EntityFireball; import net.minecraft.server.EntityFishingHook; import net.minecraft.server.EntityHuman; -import net.minecraft.server.EntityFireball; import net.minecraft.server.EntityInsentient; import net.minecraft.server.EntityLargeFireball; import net.minecraft.server.EntityLiving; @@ -25,16 +25,16 @@ import net.minecraft.server.EntityProjectile; import net.minecraft.server.EntityShulkerBullet; import net.minecraft.server.EntitySmallFireball; import net.minecraft.server.EntitySnowball; -import net.minecraft.server.EntityThrownExpBottle; -import net.minecraft.server.EntityTippedArrow; import net.minecraft.server.EntitySpectralArrow; +import net.minecraft.server.EntityThrownExpBottle; import net.minecraft.server.EntityThrownTrident; +import net.minecraft.server.EntityTippedArrow; +import net.minecraft.server.EntityTypes; import net.minecraft.server.EntityWither; import net.minecraft.server.EntityWitherSkull; import net.minecraft.server.GenericAttributes; import net.minecraft.server.MobEffect; import net.minecraft.server.MobEffectList; - import org.apache.commons.lang.Validate; import org.bukkit.FluidCollisionMode; import org.bukkit.Location; @@ -47,7 +47,9 @@ import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftEntityEquipment; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.potion.CraftPotionUtil; -import org.bukkit.entity.Arrow; +import org.bukkit.craftbukkit.entity.memory.CraftMemoryKey; +import org.bukkit.craftbukkit.entity.memory.CraftMemoryMapper; +import org.bukkit.entity.AbstractArrow; import org.bukkit.entity.DragonFireball; import org.bukkit.entity.Egg; import org.bukkit.entity.EnderPearl; @@ -70,6 +72,7 @@ import org.bukkit.entity.ThrownPotion; import org.bukkit.entity.TippedArrow; import org.bukkit.entity.Trident; import org.bukkit.entity.WitherSkull; +import org.bukkit.entity.memory.MemoryKey; import org.bukkit.event.entity.EntityPotionEffectEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.EntityEquipment; @@ -93,16 +96,18 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } } + @Override public double getHealth() { return Math.min(Math.max(0, getHandle().getHealth()), getMaxHealth()); } + @Override public void setHealth(double health) { health = (float) health; if ((health < 0) || (health > getMaxHealth())) { // Paper - Be more informative throw new IllegalArgumentException("Health must be between 0 and " + getMaxHealth() + ", but was " + health - + ". (attribute base value: " + this.getHandle().getAttributeInstance(GenericAttributes.maxHealth).b() + + ". (attribute base value: " + this.getHandle().getAttributeInstance(GenericAttributes.MAX_HEALTH).getBaseValue() + (this instanceof CraftPlayer ? ", player: " + this.getName() + ')' : ')')); } @@ -113,28 +118,45 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } } + @Override + public double getAbsorptionAmount() { + return getHandle().getAbsorptionHearts(); + } + + @Override + public void setAbsorptionAmount(double amount) { + Preconditions.checkArgument(amount >= 0 && Double.isFinite(amount), "amount < 0 or non-finite"); + + getHandle().setAbsorptionHearts((float) amount); + } + + @Override public double getMaxHealth() { return getHandle().getMaxHealth(); } + @Override public void setMaxHealth(double amount) { Validate.isTrue(amount > 0, "Max health must be greater than 0"); - getHandle().getAttributeInstance(GenericAttributes.maxHealth).setValue(amount); + getHandle().getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(amount); if (getHealth() > amount) { setHealth(amount); } } + @Override public void resetMaxHealth() { - setMaxHealth(getHandle().getAttributeInstance(GenericAttributes.maxHealth).getAttribute().getDefault()); + setMaxHealth(getHandle().getAttributeInstance(GenericAttributes.MAX_HEALTH).getAttribute().getDefault()); } + @Override public double getEyeHeight() { return getHandle().getHeadHeight(); } + @Override public double getEyeHeight(boolean ignorePose) { return getEyeHeight(); } @@ -162,51 +184,58 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return blocks; } + @Override public List getLineOfSight(Set transparent, int maxDistance) { return getLineOfSight(transparent, maxDistance, 0); } + @Override public Block getTargetBlock(Set transparent, int maxDistance) { List blocks = getLineOfSight(transparent, maxDistance, 1); return blocks.get(0); } // Paper start + @Override public Block getTargetBlock(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) { net.minecraft.server.MovingObjectPosition rayTrace = getHandle().getRayTrace(maxDistance, net.minecraft.server.MCUtil.getNMSFluidCollisionOption(fluidMode)); - return rayTrace == null ? null : org.bukkit.craftbukkit.block.CraftBlock.at(getHandle().world, rayTrace.getBlockPosition()); + return !(rayTrace instanceof net.minecraft.server.MovingObjectPositionBlock) ? null : org.bukkit.craftbukkit.block.CraftBlock.at(getHandle().world, ((net.minecraft.server.MovingObjectPositionBlock)rayTrace).getBlockPosition()); } + @Override public org.bukkit.block.BlockFace getTargetBlockFace(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) { net.minecraft.server.MovingObjectPosition rayTrace = getHandle().getRayTrace(maxDistance, net.minecraft.server.MCUtil.getNMSFluidCollisionOption(fluidMode)); - return rayTrace == null ? null : net.minecraft.server.MCUtil.toBukkitBlockFace(rayTrace.direction); + return !(rayTrace instanceof net.minecraft.server.MovingObjectPositionBlock) ? null : net.minecraft.server.MCUtil.toBukkitBlockFace(((net.minecraft.server.MovingObjectPositionBlock)rayTrace).getDirection()); } + @Override public com.destroystokyo.paper.block.TargetBlockInfo getTargetBlockInfo(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) { net.minecraft.server.MovingObjectPosition rayTrace = getHandle().getRayTrace(maxDistance, net.minecraft.server.MCUtil.getNMSFluidCollisionOption(fluidMode)); - return rayTrace == null ? null : new com.destroystokyo.paper.block.TargetBlockInfo(org.bukkit.craftbukkit.block.CraftBlock.at(getHandle().world, rayTrace.getBlockPosition()), net.minecraft.server.MCUtil.toBukkitBlockFace(rayTrace.direction)); + return !(rayTrace instanceof net.minecraft.server.MovingObjectPositionBlock) ? null : + new com.destroystokyo.paper.block.TargetBlockInfo(org.bukkit.craftbukkit.block.CraftBlock.at(getHandle().world, ((net.minecraft.server.MovingObjectPositionBlock)rayTrace).getBlockPosition()), + net.minecraft.server.MCUtil.toBukkitBlockFace(((net.minecraft.server.MovingObjectPositionBlock)rayTrace).getDirection())); } public Entity getTargetEntity(int maxDistance, boolean ignoreBlocks) { - net.minecraft.server.MovingObjectPosition rayTrace = rayTraceEntity(maxDistance, ignoreBlocks); - return rayTrace == null ? null : rayTrace.entity.getBukkitEntity(); + net.minecraft.server.MovingObjectPositionEntity rayTrace = rayTraceEntity(maxDistance, ignoreBlocks); + return rayTrace == null ? null : rayTrace.getEntity().getBukkitEntity(); } public com.destroystokyo.paper.entity.TargetEntityInfo getTargetEntityInfo(int maxDistance, boolean ignoreBlocks) { - net.minecraft.server.MovingObjectPosition rayTrace = rayTraceEntity(maxDistance, ignoreBlocks); - return rayTrace == null ? null : new com.destroystokyo.paper.entity.TargetEntityInfo(rayTrace.entity.getBukkitEntity(), new org.bukkit.util.Vector(rayTrace.pos.x, rayTrace.pos.y, rayTrace.pos.z)); + net.minecraft.server.MovingObjectPositionEntity rayTrace = rayTraceEntity(maxDistance, ignoreBlocks); + return rayTrace == null ? null : new com.destroystokyo.paper.entity.TargetEntityInfo(rayTrace.getEntity().getBukkitEntity(), new org.bukkit.util.Vector(rayTrace.getPos().x, rayTrace.getPos().y, rayTrace.getPos().z)); } - public net.minecraft.server.MovingObjectPosition rayTraceEntity(int maxDistance, boolean ignoreBlocks) { - net.minecraft.server.MovingObjectPosition rayTrace = getHandle().getTargetEntity(maxDistance); + public net.minecraft.server.MovingObjectPositionEntity rayTraceEntity(int maxDistance, boolean ignoreBlocks) { + net.minecraft.server.MovingObjectPositionEntity rayTrace = getHandle().getTargetEntity(maxDistance); if (rayTrace == null) { return null; } if (!ignoreBlocks) { - net.minecraft.server.MovingObjectPosition rayTraceBlocks = getHandle().getRayTrace(maxDistance, net.minecraft.server.FluidCollisionOption.NEVER); + net.minecraft.server.MovingObjectPosition rayTraceBlocks = getHandle().getRayTrace(maxDistance, net.minecraft.server.RayTrace.FluidCollisionOption.NONE); if (rayTraceBlocks != null) { net.minecraft.server.Vec3D eye = getHandle().getEyePosition(1.0F); - if (eye.distanceSquared(rayTraceBlocks.pos) <= eye.distanceSquared(rayTrace.pos)) { + if (eye.distanceSquared(rayTraceBlocks.getPos()) <= eye.distanceSquared(rayTrace.getPos())) { return null; } } @@ -215,6 +244,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } // Paper end + @Override public List getLastTwoTargetBlocks(Set transparent, int maxDistance) { return getLineOfSight(transparent, maxDistance, 2); } @@ -242,26 +272,32 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return this.getWorld().rayTraceBlocks(eyeLocation, direction, maxDistance, fluidCollisionMode, false); } + @Override public int getRemainingAir() { return getHandle().getAirTicks(); } + @Override public void setRemainingAir(int ticks) { getHandle().setAirTicks(ticks); } + @Override public int getMaximumAir() { return getHandle().maxAirTicks; } + @Override public void setMaximumAir(int ticks) { getHandle().maxAirTicks = ticks; } + @Override public void damage(double amount) { damage(amount, null); } + @Override public void damage(double amount, org.bukkit.entity.Entity source) { DamageSource reason = DamageSource.GENERIC; @@ -274,32 +310,39 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { entity.damageEntity(reason, (float) amount); } + @Override public Location getEyeLocation() { Location loc = getLocation(); loc.setY(loc.getY() + getEyeHeight()); return loc; } + @Override public int getMaximumNoDamageTicks() { return getHandle().maxNoDamageTicks; } + @Override public void setMaximumNoDamageTicks(int ticks) { getHandle().maxNoDamageTicks = ticks; } + @Override public double getLastDamage() { return getHandle().lastDamage; } + @Override public void setLastDamage(double damage) { getHandle().lastDamage = (float) damage; } + @Override public int getNoDamageTicks() { return getHandle().noDamageTicks; } + @Override public void setNoDamageTicks(int ticks) { getHandle().noDamageTicks = ticks; } @@ -318,6 +361,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return "CraftLivingEntity{" + "id=" + getEntityId() + '}'; } + @Override public Player getKiller() { return getHandle().killer == null ? null : (Player) getHandle().killer.getBukkitEntity(); } @@ -332,10 +376,12 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } // Paper end + @Override public boolean addPotionEffect(PotionEffect effect) { return addPotionEffect(effect, false); } + @Override public boolean addPotionEffect(PotionEffect effect, boolean force) { if (hasPotionEffect(effect.getType())) { if (!force) { @@ -347,6 +393,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return true; } + @Override public boolean addPotionEffects(Collection effects) { boolean success = true; for (PotionEffect effect : effects) { @@ -355,6 +402,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return success; } + @Override public boolean hasPotionEffect(PotionEffectType type) { return getHandle().hasEffect(MobEffectList.fromId(type.getId())); } @@ -365,10 +413,12 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return (handle == null) ? null : new PotionEffect(PotionEffectType.getById(MobEffectList.getId(handle.getMobEffect())), handle.getDuration(), handle.getAmplifier(), handle.isAmbient(), handle.isShowParticles()); } + @Override public void removePotionEffect(PotionEffectType type) { getHandle().removeEffect(MobEffectList.fromId(type.getId()), EntityPotionEffectEvent.Cause.PLUGIN); } + @Override public Collection getActivePotionEffects() { List effects = new ArrayList(); for (MobEffect handle : getHandle().effects.values()) { @@ -377,10 +427,12 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return effects; } + @Override public T launchProjectile(Class projectile) { return launchProjectile(projectile, null); } + @Override @SuppressWarnings("unchecked") public T launchProjectile(Class projectile, Vector velocity) { net.minecraft.server.World world = ((CraftWorld) getWorld()).getHandle(); @@ -395,7 +447,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } else if (EnderPearl.class.isAssignableFrom(projectile)) { launch = new EntityEnderPearl(world, getHandle()); ((EntityProjectile) launch).a(getHandle(), getHandle().pitch, getHandle().yaw, 0.0F, 1.5F, 1.0F); // ItemEnderPearl - } else if (Arrow.class.isAssignableFrom(projectile)) { + } else if (AbstractArrow.class.isAssignableFrom(projectile)) { if (TippedArrow.class.isAssignableFrom(projectile)) { launch = new EntityTippedArrow(world, getHandle()); ((EntityTippedArrow) launch).setType(CraftPotionUtil.fromBukkit(new PotionData(PotionType.WATER, false, false))); @@ -409,16 +461,18 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { ((EntityArrow) launch).a(getHandle(), getHandle().pitch, getHandle().yaw, 0.0F, 3.0F, 1.0F); // ItemBow } else if (ThrownPotion.class.isAssignableFrom(projectile)) { if (LingeringPotion.class.isAssignableFrom(projectile)) { - launch = new EntityPotion(world, getHandle(), CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.LINGERING_POTION, 1))); + launch = new EntityPotion(world, getHandle()); + ((EntityPotion) launch).setItem(CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.LINGERING_POTION, 1))); } else { - launch = new EntityPotion(world, getHandle(), CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.SPLASH_POTION, 1))); + launch = new EntityPotion(world, getHandle()); + ((EntityPotion) launch).setItem(CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.SPLASH_POTION, 1))); } ((EntityProjectile) launch).a(getHandle(), getHandle().pitch, getHandle().yaw, -20.0F, 0.5F, 1.0F); // ItemSplashPotion } else if (ThrownExpBottle.class.isAssignableFrom(projectile)) { launch = new EntityThrownExpBottle(world, getHandle()); ((EntityProjectile) launch).a(getHandle(), getHandle().pitch, getHandle().yaw, -20.0F, 0.7F, 1.0F); // ItemExpBottle } else if (FishHook.class.isAssignableFrom(projectile) && getHandle() instanceof EntityHuman) { - launch = new EntityFishingHook(world, (EntityHuman) getHandle()); + launch = new EntityFishingHook((EntityHuman) getHandle(), world, 0, 0); } else if (Fireball.class.isAssignableFrom(projectile)) { Location location = getEyeLocation(); Vector direction = location.getDirection().multiply(10); @@ -439,7 +493,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { Location location = getEyeLocation(); Vector direction = location.getDirection(); - launch = new EntityLlamaSpit(world); + launch = EntityTypes.LLAMA_SPIT.a(world); ((EntityLlamaSpit) launch).shooter = getHandle(); ((EntityLlamaSpit) launch).shoot(direction.getX(), direction.getY(), direction.getZ(), 1.5F, 10.0F); // EntityLlama @@ -461,32 +515,39 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return (T) launch.getBukkitEntity(); } + @Override public EntityType getType() { return EntityType.UNKNOWN; } + @Override public boolean hasLineOfSight(Entity other) { return getHandle().hasLineOfSight(((CraftEntity) other).getHandle()); } + @Override public boolean getRemoveWhenFarAway() { return getHandle() instanceof EntityInsentient && !((EntityInsentient) getHandle()).persistent; } + @Override public void setRemoveWhenFarAway(boolean remove) { if (getHandle() instanceof EntityInsentient) { ((EntityInsentient) getHandle()).persistent = !remove; } } + @Override public EntityEquipment getEquipment() { return equipment; } + @Override public void setCanPickupItems(boolean pickup) { getHandle().canPickUpLoot = pickup; } + @Override public boolean getCanPickupItems() { return getHandle().canPickUpLoot; } @@ -500,6 +561,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return super.teleport(location, cause); } + @Override public boolean isLeashed() { if (!(getHandle() instanceof EntityInsentient)) { return false; @@ -507,6 +569,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return ((EntityInsentient) getHandle()).getLeashHolder() != null; } + @Override public Entity getLeashHolder() throws IllegalStateException { if (!isLeashed()) { throw new IllegalStateException("Entity not leashed"); @@ -522,6 +585,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return true; } + @Override public boolean setLeashHolder(Entity holder) { if ((getHandle() instanceof EntityWither) || !(getHandle() instanceof EntityInsentient)) { return false; @@ -565,6 +629,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return getHandle().isRiptiding(); } + @Override + public boolean isSleeping() { + return getHandle().isSleeping(); + } + @Override public AttributeInstance getAttribute(Attribute attribute) { return getHandle().craftAttributes.getAttribute(attribute); @@ -592,6 +661,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { return getHandle().collides; } + @Override + public T getMemory(MemoryKey memoryKey) { + return (T) getHandle().getBehaviorController().getMemory(CraftMemoryKey.fromMemoryKey(memoryKey)).map(CraftMemoryMapper::fromNms).orElse(null); + } + + @Override + public void setMemory(MemoryKey memoryKey, T t) { + getHandle().getBehaviorController().setMemory(CraftMemoryKey.fromMemoryKey(memoryKey), CraftMemoryMapper.toNms(t)); + } + // Paper start @Override public int getArrowsStuck() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java index dace70b4f..5e005c9e4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityMagmaCube; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.MagmaCube; @@ -12,6 +11,7 @@ public class CraftMagmaCube extends CraftSlime implements MagmaCube { super(server, entity); } + @Override public EntityMagmaCube getHandle() { return (EntityMagmaCube) entity; } @@ -21,6 +21,7 @@ public class CraftMagmaCube extends CraftSlime implements MagmaCube { return "CraftMagmaCube"; } + @Override public EntityType getType() { return EntityType.MAGMA_CUBE; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java index 7d3198120..2d82ea40a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.Blocks; import net.minecraft.server.EntityMinecartAbstract; - import net.minecraft.server.IBlockData; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.CraftServer; @@ -17,44 +16,54 @@ public abstract class CraftMinecart extends CraftVehicle implements Minecart { super(server, entity); } + @Override public void setDamage(double damage) { getHandle().setDamage((float) damage); } + @Override public double getDamage() { return getHandle().getDamage(); } + @Override public double getMaxSpeed() { return getHandle().maxSpeed; } + @Override public void setMaxSpeed(double speed) { if (speed >= 0D) { getHandle().maxSpeed = speed; } } + @Override public boolean isSlowWhenEmpty() { return getHandle().slowWhenEmpty; } + @Override public void setSlowWhenEmpty(boolean slow) { getHandle().slowWhenEmpty = slow; } + @Override public Vector getFlyingVelocityMod() { return getHandle().getFlyingVelocityMod(); } + @Override public void setFlyingVelocityMod(Vector flying) { getHandle().setFlyingVelocityMod(flying); } + @Override public Vector getDerailedVelocityMod() { return getHandle().getDerailedVelocityMod(); } + @Override public void setDerailedVelocityMod(Vector derailed) { getHandle().setDerailedVelocityMod(derailed); } @@ -64,6 +73,7 @@ public abstract class CraftMinecart extends CraftVehicle implements Minecart { return (EntityMinecartAbstract) entity; } + @Override public void setDisplayBlock(MaterialData material) { if(material != null) { IBlockData block = CraftMagicNumbers.getBlock(material); @@ -87,6 +97,7 @@ public abstract class CraftMinecart extends CraftVehicle implements Minecart { } } + @Override public MaterialData getDisplayBlock() { IBlockData blockData = getHandle().getDisplayBlock(); return CraftMagicNumbers.getMaterial(blockData); @@ -98,10 +109,12 @@ public abstract class CraftMinecart extends CraftVehicle implements Minecart { return CraftBlockData.fromData(blockData); } + @Override public void setDisplayBlockOffset(int offset) { getHandle().setDisplayBlockOffset(offset); } + @Override public int getDisplayBlockOffset() { return getHandle().getDisplayBlockOffset(); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java index e0b99207b..ab4807b2c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.entity; import com.destroystokyo.paper.loottable.PaperLootableEntityInventory; // Paper import net.minecraft.server.EntityMinecartChest; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.inventory.CraftInventory; import org.bukkit.entity.EntityType; @@ -18,6 +17,7 @@ public class CraftMinecartChest extends CraftMinecartContainer implements Storag inventory = new CraftInventory(entity); } + @Override public Inventory getInventory() { return inventory; } @@ -27,6 +27,7 @@ public class CraftMinecartChest extends CraftMinecartContainer implements Storag return "CraftMinecartChest{" + "inventory=" + inventory + '}'; } + @Override public EntityType getType() { return EntityType.MINECART_CHEST; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java index b178acd47..89affac56 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java @@ -1,9 +1,7 @@ package org.bukkit.craftbukkit.entity; import java.util.Set; - import net.minecraft.server.EntityMinecartCommandBlock; - import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.craftbukkit.CraftServer; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java index 6790fa2fe..fcc978784 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java @@ -28,7 +28,7 @@ public abstract class CraftMinecartContainer extends CraftMinecart implements Lo @Override public LootTable getLootTable() { - MinecraftKey nmsTable = getHandle().getLootTable(); + MinecraftKey nmsTable = getHandle().lootTable; if (nmsTable == null) { return null; // return empty loot table? } @@ -49,6 +49,6 @@ public abstract class CraftMinecartContainer extends CraftMinecart implements Lo public void setLootTable(LootTable table, long seed) { // Paper MinecraftKey newKey = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey()); - getHandle().a(newKey, seed); + getHandle().setLootTable(newKey, seed); } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java index 2d2d94523..b024359c9 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityMinecartFurnace; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.minecart.PoweredMinecart; @@ -17,6 +16,7 @@ public class CraftMinecartFurnace extends CraftMinecart implements PoweredMineca return "CraftMinecartFurnace"; } + @Override public EntityType getType() { return EntityType.MINECART_FURNACE; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java index 1937f7b9a..f5b31237f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.entity; import com.destroystokyo.paper.loottable.PaperLootableEntityInventory; // Paper import net.minecraft.server.EntityMinecartHopper; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.inventory.CraftInventory; import org.bukkit.entity.EntityType; @@ -22,10 +21,12 @@ public final class CraftMinecartHopper extends CraftMinecartContainer implements return "CraftMinecartHopper{" + "inventory=" + inventory + '}'; } + @Override public EntityType getType() { return EntityType.MINECART_HOPPER; } + @Override public Inventory getInventory() { return inventory; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java index a78d81691..b6c86c01f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityMinecartMobSpawner; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.minecart.SpawnerMinecart; @@ -16,6 +15,7 @@ final class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMine return "CraftMinecartMobSpawner"; } + @Override public EntityType getType() { return EntityType.MINECART_MOB_SPAWNER; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java index 9305d8841..1c2b32fc4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityMinecartAbstract; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.minecart.RideableMinecart; @@ -16,6 +15,7 @@ public class CraftMinecartRideable extends CraftMinecart implements RideableMine return "CraftMinecartRideable"; } + @Override public EntityType getType() { return EntityType.MINECART; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java index 0c8109bb1..02c5589bc 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityMinecartTNT; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.minecart.ExplosiveMinecart; @@ -16,6 +15,7 @@ final class CraftMinecartTNT extends CraftMinecart implements ExplosiveMinecart return "CraftMinecartTNT"; } + @Override public EntityType getType() { return EntityType.MINECART_TNT; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java index 40a429942..56c233872 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java @@ -70,6 +70,7 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob { } // Paper start + @Override public boolean isInDaylight() { return getHandle().isInDaylight(); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java index 72dedbc8f..6bfb4bc35 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityMonster; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Monster; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java index 3dd7ea3f2..1ca04ec4e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java @@ -1,7 +1,7 @@ package org.bukkit.craftbukkit.entity; +import com.google.common.base.Preconditions; import net.minecraft.server.EntityMushroomCow; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.MushroomCow; @@ -16,11 +16,24 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow { return (EntityMushroomCow) entity; } + @Override + public Variant getVariant() { + return Variant.values()[getHandle().getVariant().ordinal()]; + } + + @Override + public void setVariant(Variant variant) { + Preconditions.checkArgument(variant != null, "variant"); + + getHandle().setVariant(EntityMushroomCow.Type.values()[variant.ordinal()]); + } + @Override public String toString() { return "CraftMushroomCow"; } + @Override public EntityType getType() { return EntityType.MUSHROOM_COW; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java index e73c2c9f1..cbd2b6f54 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java @@ -1,12 +1,11 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityOcelot; -import org.apache.commons.lang.Validate; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Ocelot; -public class CraftOcelot extends CraftTameableAnimal implements Ocelot { +public class CraftOcelot extends CraftAnimals implements Ocelot { public CraftOcelot(CraftServer server, EntityOcelot ocelot) { super(server, ocelot); } @@ -16,13 +15,14 @@ public class CraftOcelot extends CraftTameableAnimal implements Ocelot { return (EntityOcelot) entity; } + @Override public Type getCatType() { - return Type.getType(getHandle().getCatType()); + return Type.WILD_OCELOT; } + @Override public void setCatType(Type type) { - Validate.notNull(type, "Cat type cannot be null"); - getHandle().setCatType(type.getId()); + throw new UnsupportedOperationException("Cats are now a different entity!"); } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java index 9c29a56da..7960839b2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java @@ -1,9 +1,9 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityPainting; +import net.minecraft.server.EntityTypes; import net.minecraft.server.Paintings; import net.minecraft.server.WorldServer; - import org.bukkit.Art; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.CraftArt; @@ -18,30 +18,34 @@ public class CraftPainting extends CraftHanging implements Painting { super(server, entity); } + @Override public Art getArt() { Paintings art = getHandle().art; return CraftArt.NotchToBukkit(art); } + @Override public boolean setArt(Art art) { return setArt(art, false); } + @Override public boolean setArt(Art art, boolean force) { EntityPainting painting = this.getHandle(); Paintings oldArt = painting.art; painting.art = CraftArt.BukkitToNotch(art); - painting.setDirection(painting.direction); + painting.setDirection(painting.getDirection()); if (!force && !painting.survives()) { // Revert painting since it doesn't fit painting.art = oldArt; - painting.setDirection(painting.direction); + painting.setDirection(painting.getDirection()); return false; } this.update(); return true; } + @Override public boolean setFacingDirection(BlockFace face, boolean force) { if (super.setFacingDirection(face, force)) { update(); @@ -53,10 +57,10 @@ public class CraftPainting extends CraftHanging implements Painting { private void update() { WorldServer world = ((CraftWorld) getWorld()).getHandle(); - EntityPainting painting = new EntityPainting(world); + EntityPainting painting = EntityTypes.PAINTING.a(world); painting.blockPosition = getHandle().blockPosition; painting.art = getHandle().art; - painting.setDirection(getHandle().direction); + painting.setDirection(getHandle().getDirection()); getHandle().die(); getHandle().velocityChanged = true; // because this occurs when the painting is broken, so it might be important world.addEntity(painting); @@ -73,6 +77,7 @@ public class CraftPainting extends CraftHanging implements Painting { return "CraftPainting{art=" + getArt() + "}"; } + @Override public EntityType getType() { return EntityType.PAINTING; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java new file mode 100644 index 000000000..feab3601d --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java @@ -0,0 +1,61 @@ +package org.bukkit.craftbukkit.entity; + +import com.google.common.base.Preconditions; +import net.minecraft.server.EntityPanda; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Panda; + +public class CraftPanda extends CraftAnimals implements Panda { + + public CraftPanda(CraftServer server, EntityPanda entity) { + super(server, entity); + } + + @Override + public EntityPanda getHandle() { + return (EntityPanda) super.getHandle(); + } + + @Override + public EntityType getType() { + return EntityType.PANDA; + } + + @Override + public String toString() { + return "CraftPanda"; + } + + @Override + public Gene getMainGene() { + return fromNms(getHandle().getMainGene()); + } + + @Override + public void setMainGene(Gene gene) { + getHandle().setMainGene(toNms(gene)); + } + + @Override + public Gene getHiddenGene() { + return fromNms(getHandle().getHiddenGene()); + } + + @Override + public void setHiddenGene(Gene gene) { + getHandle().setHiddenGene(toNms(gene)); + } + + public static Gene fromNms(EntityPanda.Gene gene) { + Preconditions.checkArgument(gene != null, "Gene may not be null"); + + return Gene.values()[gene.ordinal()]; + } + + public static EntityPanda.Gene toNms(Gene gene) { + Preconditions.checkArgument(gene != null, "Gene may not be null"); + + return EntityPanda.Gene.values()[gene.ordinal()]; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java index 82bc7a6f0..85fee3f21 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityPig; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Pig; @@ -11,14 +10,17 @@ public class CraftPig extends CraftAnimals implements Pig { super(server, entity); } + @Override public boolean hasSaddle() { return getHandle().hasSaddle(); } + @Override public void setSaddle(boolean saddled) { getHandle().setSaddle(saddled); } + @Override public EntityPig getHandle() { return (EntityPig) entity; } @@ -28,6 +30,7 @@ public class CraftPig extends CraftAnimals implements Pig { return "CraftPig"; } + @Override public EntityType getType() { return EntityType.PIG; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java index c8d66f311..10c12ef5a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityPigZombie; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.PigZombie; @@ -12,18 +11,22 @@ public class CraftPigZombie extends CraftZombie implements PigZombie { super(server, entity); } + @Override public int getAnger() { return getHandle().angerLevel; } + @Override public void setAnger(int level) { getHandle().angerLevel = level; } + @Override public void setAngry(boolean angry) { setAnger(angry ? 400 : 0); } + @Override public boolean isAngry() { return getAnger() > 0; } @@ -38,6 +41,7 @@ public class CraftPigZombie extends CraftZombie implements PigZombie { return "CraftPigZombie"; } + @Override public EntityType getType() { return EntityType.PIG_ZOMBIE; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java new file mode 100644 index 000000000..d889fe8c3 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java @@ -0,0 +1,35 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityPillager; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Pillager; +import org.bukkit.inventory.Inventory; + +public class CraftPillager extends CraftIllager implements Pillager { + + public CraftPillager(CraftServer server, EntityPillager entity) { + super(server, entity); + } + + @Override + public EntityPillager getHandle() { + return (EntityPillager) super.getHandle(); + } + + @Override + public EntityType getType() { + return EntityType.PILLAGER; + } + + @Override + public String toString() { + return "CraftPillager"; + } + + @Override + public Inventory getInventory() { + return new CraftInventory(getHandle().getInventory()); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 192eef85b..e920545df 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -5,13 +5,9 @@ import com.destroystokyo.paper.profile.CraftPlayerProfile; import com.destroystokyo.paper.profile.PlayerProfile; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; import com.google.common.io.BaseEncoding; -import com.koloboke.collect.map.hash.HashObjObjMap; -import com.koloboke.collect.map.hash.HashObjObjMaps; import com.mojang.authlib.GameProfile; import io.netty.buffer.Unpooled; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.ref.WeakReference; @@ -19,7 +15,6 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -30,8 +25,7 @@ import java.util.UUID; import java.util.WeakHashMap; import java.util.logging.Level; import java.util.logging.Logger; -import net.md_5.bungee.api.chat.BaseComponent; - +import javax.annotation.Nullable; import net.minecraft.server.AdvancementDataPlayer; import net.minecraft.server.AdvancementProgress; import net.minecraft.server.AttributeInstance; @@ -44,9 +38,8 @@ import net.minecraft.server.Container; import net.minecraft.server.Entity; import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityPlayer; -import net.minecraft.server.EntityTracker; -import net.minecraft.server.EntityTrackerEntry; import net.minecraft.server.EnumChatFormat; +import net.minecraft.server.EnumColor; import net.minecraft.server.EnumGamemode; import net.minecraft.server.IChatBaseComponent; import net.minecraft.server.MapIcon; @@ -68,37 +61,47 @@ import net.minecraft.server.PacketPlayOutUpdateAttributes; import net.minecraft.server.PacketPlayOutUpdateHealth; import net.minecraft.server.PacketPlayOutWorldEvent; import net.minecraft.server.PacketPlayOutWorldParticles; +import net.minecraft.server.PlayerChunkMap; import net.minecraft.server.PlayerConnection; import net.minecraft.server.TileEntitySign; import net.minecraft.server.Vec3D; import net.minecraft.server.WhiteListEntry; import net.minecraft.server.WorldServer; - -import org.apache.commons.lang.Validate; import org.apache.commons.lang.NotImplementedException; -import org.bukkit.*; +import org.apache.commons.lang.Validate; import org.bukkit.Achievement; import org.bukkit.BanList; -import org.bukkit.Statistic; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Instrument; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Note; +import org.bukkit.OfflinePlayer; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.Statistic; import org.bukkit.Statistic.Type; +import org.bukkit.WeatherType; import org.bukkit.block.data.BlockData; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.conversations.Conversation; import org.bukkit.conversations.ConversationAbandonedEvent; import org.bukkit.conversations.ManuallyAbandonedConversationCanceller; -import org.bukkit.craftbukkit.CraftParticle; -import org.bukkit.craftbukkit.block.CraftSign; -import org.bukkit.craftbukkit.block.data.CraftBlockData; -import org.bukkit.craftbukkit.conversations.ConversationTracker; import org.bukkit.craftbukkit.CraftEffect; import org.bukkit.craftbukkit.CraftOfflinePlayer; +import org.bukkit.craftbukkit.CraftParticle; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftSound; import org.bukkit.craftbukkit.CraftStatistic; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.advancement.CraftAdvancement; import org.bukkit.craftbukkit.advancement.CraftAdvancementProgress; +import org.bukkit.craftbukkit.block.CraftSign; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.craftbukkit.conversations.ConversationTracker; import org.bukkit.craftbukkit.map.CraftMapView; import org.bukkit.craftbukkit.map.RenderData; import org.bukkit.craftbukkit.scoreboard.CraftScoreboard; @@ -110,6 +113,7 @@ import org.bukkit.event.player.PlayerRegisterChannelEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerUnregisterChannelEvent; import org.bukkit.inventory.InventoryView.Property; +import org.bukkit.inventory.ItemStack; import org.bukkit.map.MapCursor; import org.bukkit.map.MapView; import org.bukkit.metadata.MetadataValue; @@ -117,7 +121,7 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.messaging.StandardMessenger; import org.bukkit.scoreboard.Scoreboard; -import javax.annotation.Nullable; +import net.md_5.bungee.api.chat.BaseComponent; // Spigot @DelegateDeserialization(CraftOfflinePlayer.class) public class CraftPlayer extends CraftHumanEntity implements Player { @@ -126,7 +130,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private boolean hasPlayedBefore = false; private final ConversationTracker conversationTracker = new ConversationTracker(); private final Set channels = new HashSet(); - private Map>> hiddenPlayers = Collections.emptyMap(); // Akarin + private final Map>> hiddenPlayers = new HashMap<>(); private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); private int hash = 0; private double health = 20; @@ -167,10 +171,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { perm.recalculatePermissions(); } + @Override public boolean isOnline() { return server.getPlayer(getUniqueId()) != null; } + @Override public InetSocketAddress getAddress() { if (getHandle().playerConnection == null) return null; @@ -421,7 +427,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void kickPlayer(String message) { - org.spigotmc.AsyncCatcher.catchOp( "player kick"); // Spigot + org.spigotmc.AsyncCatcher.catchOp("player kick"); // Spigot if (getHandle().playerConnection == null) return; getHandle().playerConnection.disconnect(message == null ? "" : message); @@ -530,6 +536,27 @@ public class CraftPlayer extends CraftHumanEntity implements Player { case 9: instrumentName = "xylophone"; break; + case 10: + instrumentName = "iron_xylophone"; + break; + case 11: + instrumentName = "cow_bell"; + break; + case 12: + instrumentName = "didgeridoo"; + break; + case 13: + instrumentName = "bit"; + break; + case 14: + instrumentName = "banjo"; + break; + case 15: + instrumentName = "pling"; + break; + case 16: + instrumentName = "xylophone"; + break; } float f = (float) Math.pow(2.0D, (note.getId() - 12.0D) / 12.0D); getHandle().playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(CraftSound.getSoundEffect("block.note_block." + instrumentName), net.minecraft.server.SoundCategory.RECORDS, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), 3.0f, f)); @@ -626,6 +653,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void sendSignChange(Location loc, String[] lines) { + sendSignChange(loc, lines, DyeColor.BLACK); + } + + @Override + public void sendSignChange(Location loc, String[] lines, DyeColor dyeColor) { if (getHandle().playerConnection == null) { return; } @@ -635,6 +667,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } Validate.notNull(loc, "Location can not be null"); + Validate.notNull(dyeColor, "DyeColor can not be null"); if (lines.length < 4) { throw new IllegalArgumentException("Must have at least 4 lines"); } @@ -642,6 +675,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { IChatBaseComponent[] components = CraftSign.sanitizeLines(lines); TileEntitySign sign = new TileEntitySign(); sign.setPosition(new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); + sign.setColor(EnumColor.fromColorIndex(dyeColor.getWoolData())); System.arraycopy(components, 0, sign.lines, 0, sign.lines.length); getHandle().playerConnection.sendPacket(sign.getUpdatePacket()); @@ -693,7 +727,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } } - PacketPlayOutMap packet = new PacketPlayOutMap(map.getId(), map.getScale().getValue(), true, icons, data.buffer, 0, 0, 128, 128); + PacketPlayOutMap packet = new PacketPlayOutMap(map.getId(), map.getScale().getValue(), true, map.isLocked(), icons, data.buffer, 0, 0, 128, 128); getHandle().playerConnection.sendPacket(packet); } @@ -755,8 +789,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (fromWorld == toWorld) { entity.playerConnection.teleport(to); } else { - // Paper - Configurable suffocation check - server.getHandle().moveToWorld(entity, toWorld.dimension, true, to, !toWorld.paperConfig.disableTeleportationSuffocationCheck); + server.getHandle().moveToWorld(entity, toWorld.getWorldProvider().getDimensionManager(), true, to, !toWorld.paperConfig.disableTeleportationSuffocationCheck); } return true; } @@ -811,7 +844,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void setSleepingIgnored(boolean isSleeping) { getHandle().fauxSleeping = isSleeping; - ((CraftWorld) getWorld()).getHandle().checkSleepStatus(); + ((CraftWorld) getWorld()).getHandle().everyoneSleeping(); } @Override @@ -1042,7 +1075,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { net.minecraft.server.ItemStack itemstack = net.minecraft.server.EnchantmentManager.getRandomEquippedItemWithEnchant(net.minecraft.server.Enchantments.MENDING, handle); if (!itemstack.isEmpty() && itemstack.getItem().usesDurability()) { - net.minecraft.server.EntityExperienceOrb orb = new net.minecraft.server.EntityExperienceOrb(handle.world); + net.minecraft.server.EntityExperienceOrb orb = net.minecraft.server.EntityTypes.EXPERIENCE_ORB.create(handle.world); orb.value = amount; orb.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM; orb.locX = handle.locX; @@ -1171,23 +1204,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } hidingPlugins = new HashSet<>(); hidingPlugins.add(getPluginWeakReference(plugin)); - // Akarin start - copy on write - HashObjObjMap>> toImmutable = HashObjObjMaps.newMutableMap(hiddenPlayers); - toImmutable.put(player.getUniqueId(), hidingPlugins); - hiddenPlayers = toImmutable; - //hiddenPlayers.put(player.getUniqueId(), hidingPlugins); - // Akarin end + hiddenPlayers.put(player.getUniqueId(), hidingPlugins); // Remove this player from the hidden player's EntityTrackerEntry - EntityPlayer other = ((CraftPlayer) player).getHandle(); // Paper start + EntityPlayer other = ((CraftPlayer) player).getHandle(); unregisterPlayer(other); } private void unregisterPlayer(EntityPlayer other) { - EntityTracker tracker = ((WorldServer) entity.world).tracker; + PlayerChunkMap tracker = ((WorldServer) entity.world).getChunkProvider().playerChunkMap; // Paper end - - EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId()); + PlayerChunkMap.EntityTracker entry = tracker.trackedEntities.get(other.getId()); if (entry != null) { entry.clear(getHandle()); } @@ -1225,24 +1252,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (!hidingPlugins.isEmpty()) { return; // Some other plugins still want the player hidden } - // Akarin start - copy on write - HashObjObjMap>> toImmutable = HashObjObjMaps.newMutableMap(hiddenPlayers); - toImmutable.remove(player.getUniqueId()); - hiddenPlayers = toImmutable; - //hiddenPlayers.remove(player.getUniqueId()); - // Akarin end + hiddenPlayers.remove(player.getUniqueId()); // Paper start EntityPlayer other = ((CraftPlayer) player).getHandle(); registerPlayer(other); } private void registerPlayer(EntityPlayer other) { - EntityTracker tracker = ((WorldServer) entity.world).tracker; + PlayerChunkMap tracker = ((WorldServer) entity.world).getChunkProvider().playerChunkMap; // Paper end getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, other)); - EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId()); + PlayerChunkMap.EntityTracker entry = tracker.trackedEntities.get(other.getId()); if (entry != null && !entry.trackedPlayers.contains(getHandle())) { entry.updatePlayer(getHandle()); } @@ -1276,7 +1298,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { reregisterPlayer(handle); //Respawn the player then update their position and selected slot - connection.sendPacket(new net.minecraft.server.PacketPlayOutRespawn(handle.dimension, handle.world.getDifficulty(), handle.world.getWorldData().getType(), handle.playerInteractManager.getGameMode())); + connection.sendPacket(new net.minecraft.server.PacketPlayOutRespawn(handle.dimension, handle.world.getWorldData().getType(), handle.playerInteractManager.getGameMode())); handle.updateAbilities(); connection.sendPacket(new net.minecraft.server.PacketPlayOutPosition(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), new HashSet<>(), 0)); net.minecraft.server.MinecraftServer.getServer().getPlayerList().updateClient(handle); @@ -1289,12 +1311,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper end public void removeDisconnectingPlayer(Player player) { - // Akarin start - copy on write - HashObjObjMap>> toImmutable = HashObjObjMaps.newMutableMap(hiddenPlayers); - toImmutable.remove(player.getUniqueId()); - hiddenPlayers = HashObjObjMaps.newImmutableMap(toImmutable); - //hiddenPlayers.remove(player.getUniqueId()); - // Akarin end + hiddenPlayers.remove(player.getUniqueId()); } @Override @@ -1548,11 +1565,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (container.getBukkitView().getType() != prop.getType()) { return false; } - // Paper start - if (prop == Property.REPAIR_COST && container instanceof net.minecraft.server.ContainerAnvil) { - ((net.minecraft.server.ContainerAnvil) container).levelCost = value; - } - // Paper end getHandle().setContainerData(container, prop.getId(), value); return true; } @@ -1905,24 +1917,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this.getHandle().affectsSpawning; } - @Override - public int getViewDistance() { - return getHandle().getViewDistance(); - } - - @Override - public void setViewDistance(int viewDistance) { - ((WorldServer) getHandle().world).getPlayerChunkMap().updateViewDistance(getHandle(), viewDistance); - } - // Paper end - - @Override - public void updateCommands() { - if (getHandle().playerConnection == null) return; - - getHandle().server.getCommandDispatcher().a(getHandle()); - } - @Override public void setResourcePack(String url, String hash) { Validate.notNull(url, "Resource pack URL cannot be null"); @@ -1948,6 +1942,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setResourcePackStatus(org.bukkit.event.player.PlayerResourcePackStatusEvent.Status status) { this.resourcePackStatus = status; } + // Paper end + + @Override + public void updateCommands() { + if (getHandle().playerConnection == null) return; + + getHandle().server.getCommandDispatcher().a(getHandle()); + } + + @Override + public void openBook(ItemStack book) { + Validate.isTrue(book != null, "book == null"); + Validate.isTrue(book.getType() == Material.WRITTEN_BOOK, "Book must be Material.WRITTEN_BOOK"); + + ItemStack hand = getInventory().getItemInMainHand(); + getInventory().setItemInMainHand(book); + getHandle().openBook(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(book), net.minecraft.server.EnumHand.MAIN_HAND); + getInventory().setItemInMainHand(hand); + } //Paper start public float getCooldownPeriod() { @@ -1970,6 +1983,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { super.remove(); } } + + @Override + public int getViewDistance() { + throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement"); // TODO + } + + @Override + public void setViewDistance(int viewDistance) { + throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement"); // TODO + } //Paper end // Spigot start @@ -2016,7 +2039,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { ret.add( getServer().getPlayer( u ) ); } - return com.koloboke.collect.set.hash.HashObjSets.newImmutableSet( ret ); // Akarin - koloboke + return java.util.Collections.unmodifiableSet( ret ); } @Override @@ -2028,7 +2051,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void sendMessage(BaseComponent... components) { if ( getHandle().playerConnection == null ) return; - PacketPlayOutChat packet = new PacketPlayOutChat(null, net.minecraft.server.ChatMessageType.CHAT); + PacketPlayOutChat packet = new PacketPlayOutChat(null, net.minecraft.server.ChatMessageType.SYSTEM); packet.components = components; getHandle().playerConnection.sendPacket(packet); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java index 335acc24d..649684fc8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityProjectile; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Projectile; import org.bukkit.projectiles.ProjectileSource; @@ -12,10 +11,12 @@ public abstract class CraftProjectile extends AbstractProjectile implements Proj super(server, entity); } + @Override public ProjectileSource getShooter() { return getHandle().projectileSource; } + @Override public void setShooter(ProjectileSource shooter) { if (shooter instanceof CraftLivingEntity) { getHandle().shooter = (EntityLiving) ((CraftLivingEntity) shooter).entity; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPufferFish.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPufferFish.java index 2701de75a..647971d5e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPufferFish.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPufferFish.java @@ -2,8 +2,8 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityPufferFish; import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.entity.PufferFish; import org.bukkit.entity.EntityType; +import org.bukkit.entity.PufferFish; public class CraftPufferFish extends CraftFish implements PufferFish { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java index 61330d243..a75d7a303 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java @@ -1,12 +1,12 @@ package org.bukkit.craftbukkit.entity; -import net.minecraft.server.World; import net.minecraft.server.EntityRabbit; import net.minecraft.server.PathfinderGoalSelector; +import net.minecraft.server.World; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.EntityType; import org.bukkit.entity.Rabbit; -import org.bukkit.craftbukkit.CraftWorld; public class CraftRabbit extends CraftAnimals implements Rabbit { @@ -31,7 +31,7 @@ public class CraftRabbit extends CraftAnimals implements Rabbit { @Override public Type getRabbitType() { - int type = getHandle().getRabbitType(); + int type = getHandle().getRabbitType(); return CraftMagicMapping.fromMagic(type); } @@ -41,12 +41,12 @@ public class CraftRabbit extends CraftAnimals implements Rabbit { if (getRabbitType() == Type.THE_KILLER_BUNNY) { // Reset goals and target finders. World world = ((CraftWorld) this.getWorld()).getHandle(); - entity.goalSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null); - entity.targetSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null); + entity.goalSelector = new PathfinderGoalSelector(world != null && world.getMethodProfiler() != null ? world.getMethodProfiler() : null); + entity.targetSelector = new PathfinderGoalSelector(world != null && world.getMethodProfiler() != null ? world.getMethodProfiler() : null); entity.initializePathFinderGoals(); } - entity.setRabbitType(CraftMagicMapping.toMagic(type)); + entity.setRabbitType(CraftMagicMapping.toMagic(type)); } private static class CraftMagicMapping { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java new file mode 100644 index 000000000..f8b92b425 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java @@ -0,0 +1,52 @@ +package org.bukkit.craftbukkit.entity; + +import com.google.common.base.Preconditions; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.EntityRaider; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.entity.Raider; + +public abstract class CraftRaider extends CraftMonster implements Raider { + + public CraftRaider(CraftServer server, EntityRaider entity) { + super(server, entity); + } + + @Override + public EntityRaider getHandle() { + return (EntityRaider) super.getHandle(); + } + + @Override + public String toString() { + return "CraftRaider"; + } + + @Override + public Block getPatrolTarget() { + return getHandle().getPatrolTarget() == null ? null : CraftBlock.at(getHandle().world, getHandle().getPatrolTarget()); + } + + @Override + public void setPatrolTarget(Block block) { + if (block == null) { + getHandle().setPatrolTarget((BlockPosition) null); + } else { + Preconditions.checkArgument(block.getWorld().equals(this.getWorld()), "Block must be in same world"); + + getHandle().setPatrolTarget(new BlockPosition(block.getX(), block.getY(), block.getZ())); + } + } + + @Override + public boolean isPatrolLeader() { + return getHandle().isPatrolLeader(); + } + + @Override + public void setPatrolLeader(boolean leader) { + getHandle().setPatrolLeader(leader); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java new file mode 100644 index 000000000..3cb2e6cc5 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityRavager; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Ravager; + +public class CraftRavager extends CraftRaider implements Ravager { + + public CraftRavager(CraftServer server, EntityRavager entity) { + super(server, entity); + } + + @Override + public EntityRavager getHandle() { + return (EntityRavager) super.getHandle(); + } + + @Override + public EntityType getType() { + return EntityType.RAVAGER; + } + + @Override + public String toString() { + return "CraftRavager"; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java index 4d91f5760..0e4a9ce09 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java @@ -2,8 +2,8 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntitySalmon; import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.entity.Salmon; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Salmon; public class CraftSalmon extends CraftFish implements Salmon { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java index f7253554c..fef86120d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntitySheep; - import net.minecraft.server.EnumColor; import org.bukkit.DyeColor; import org.bukkit.craftbukkit.CraftServer; @@ -13,18 +12,22 @@ public class CraftSheep extends CraftAnimals implements Sheep { super(server, entity); } + @Override public DyeColor getColor() { return DyeColor.getByWoolData((byte) getHandle().getColor().getColorIndex()); } + @Override public void setColor(DyeColor color) { getHandle().setColor(EnumColor.fromColorIndex(color.getWoolData())); } + @Override public boolean isSheared() { return getHandle().isSheared(); } + @Override public void setSheared(boolean flag) { getHandle().setSheared(flag); } @@ -39,6 +42,7 @@ public class CraftSheep extends CraftAnimals implements Sheep { return "CraftSheep"; } + @Override public EntityType getType() { return EntityType.SHEEP; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulker.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulker.java index d25b742e7..d18531378 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulker.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulker.java @@ -1,6 +1,5 @@ package org.bukkit.craftbukkit.entity; -import com.google.common.base.Preconditions; import net.minecraft.server.EntityShulker; import org.bukkit.DyeColor; import org.bukkit.craftbukkit.CraftServer; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java index ef9477519..0fe4b0e8c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntitySilverfish; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Silverfish; @@ -21,6 +20,7 @@ public class CraftSilverfish extends CraftMonster implements Silverfish { return "CraftSilverfish"; } + @Override public EntityType getType() { return EntityType.SILVERFISH; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java index 4fa5e84ea..02df66ecf 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.entity; import com.destroystokyo.paper.entity.CraftRangedEntity; import net.minecraft.server.EntitySkeletonAbstract; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Skeleton; @@ -23,6 +22,7 @@ public class CraftSkeleton extends CraftMonster implements Skeleton, CraftRanged return "CraftSkeleton"; } + @Override public EntityType getType() { return EntityType.SKELETON; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java index 496d0c0ca..2a7d1d4ec 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java @@ -33,14 +33,17 @@ public class CraftSkeletonHorse extends CraftAbstractHorse implements SkeletonHo return (EntityHorseSkeleton) super.getHandle(); } + @Override public int getTrapTime() { return getHandle().getTrapTime(); } + @Override public boolean isTrap() { return getHandle().isTrap(); } + @Override public void setTrap(boolean trap) { getHandle().setTrap(trap); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java index 8403c1e01..6e9f1b66d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntitySlime; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Slime; @@ -12,10 +11,12 @@ public class CraftSlime extends CraftMob implements Slime { super(server, entity); } + @Override public int getSize() { return getHandle().getSize(); } + @Override public void setSize(int size) { getHandle().setSize(size, true); } @@ -30,6 +31,7 @@ public class CraftSlime extends CraftMob implements Slime { return "CraftSlime"; } + @Override public EntityType getType() { return EntityType.SLIME; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java index 720097004..02fac8b4a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java @@ -20,6 +20,7 @@ public class CraftSmallFireball extends CraftFireball implements SmallFireball { return "CraftSmallFireball"; } + @Override public EntityType getType() { return EntityType.SMALL_FIREBALL; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java index 44de7496c..222977d79 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java @@ -20,6 +20,7 @@ public class CraftSnowball extends CraftProjectile implements Snowball { return "CraftSnowball"; } + @Override public EntityType getType() { return EntityType.SNOWBALL; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java index 2e3d8fcdf..e482b1c9d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java @@ -31,6 +31,7 @@ public class CraftSnowman extends CraftGolem implements Snowman, CraftRangedEnti return "CraftSnowman"; } + @Override public EntityType getType() { return EntityType.SNOWMAN; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java index 2a07fe1b2..a3f452aca 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntitySpider; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Spider; @@ -22,6 +21,7 @@ public class CraftSpider extends CraftMonster implements Spider { return "CraftSpider"; } + @Override public EntityType getType() { return EntityType.SPIDER; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSplashPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSplashPotion.java deleted file mode 100644 index 1ef057b86..000000000 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSplashPotion.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.bukkit.craftbukkit.entity; - -import net.minecraft.server.EntityPotion; -import org.apache.commons.lang.Validate; -import org.bukkit.Material; -import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.craftbukkit.inventory.CraftItemStack; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.SplashPotion; -import org.bukkit.inventory.ItemStack; - -public class CraftSplashPotion extends CraftThrownPotion implements SplashPotion { - - public CraftSplashPotion(CraftServer server, EntityPotion entity) { - super(server, entity); - } - - @Override - public void setItem(ItemStack item) { - // The ItemStack must not be null. - Validate.notNull(item, "ItemStack cannot be null."); - - // The ItemStack must be a potion. - Validate.isTrue(item.getType() == Material.SPLASH_POTION, "ItemStack must be a splash potion. This item stack was " + item.getType() + "."); - - getHandle().setItem(CraftItemStack.asNMSCopy(item)); - } - - @Override - public EntityPotion getHandle() { - return (EntityPotion) entity; - } - - @Override - public String toString() { - return "CraftSplashPotion"; - } - - @Override - public EntityType getType() { - return EntityType.SPLASH_POTION; - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java index 433a7c6ac..6cb09623e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntitySquid; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Squid; @@ -22,6 +21,7 @@ public class CraftSquid extends CraftWaterMob implements Squid { return "CraftSquid"; } + @Override public EntityType getType() { return EntityType.SQUID; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java index dd9c65939..4ef91a37d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityTNTPrimed; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -14,26 +13,32 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed { super(server, entity); } + @Override public float getYield() { return getHandle().yield; } + @Override public boolean isIncendiary() { return getHandle().isIncendiary; } + @Override public void setIsIncendiary(boolean isIncendiary) { getHandle().isIncendiary = isIncendiary; } + @Override public void setYield(float yield) { getHandle().yield = yield; } + @Override public int getFuseTicks() { return getHandle().getFuseTicks(); } + @Override public void setFuseTicks(int fuseTicks) { getHandle().setFuseTicks(fuseTicks); } @@ -48,10 +53,12 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed { return "CraftTNTPrimed"; } + @Override public EntityType getType() { return EntityType.PRIMED_TNT; } + @Override public Entity getSource() { EntityLiving source = getHandle().getSource(); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java index 2e959321b..407b95caf 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java @@ -1,13 +1,12 @@ package org.bukkit.craftbukkit.entity; +import java.util.UUID; import net.minecraft.server.EntityTameableAnimal; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.AnimalTamer; import org.bukkit.entity.Creature; import org.bukkit.entity.Tameable; -import java.util.UUID; - public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creature { public CraftTameableAnimal(CraftServer server, EntityTameableAnimal entity) { super(server, entity); @@ -33,6 +32,7 @@ public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creat getHandle().setOwnerUUID(uuid); } + @Override public AnimalTamer getOwner() { if (getOwnerUUID() == null) { return null; @@ -46,10 +46,12 @@ public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creat return owner; } + @Override public boolean isTamed() { return getHandle().isTamed(); } + @Override public void setOwner(AnimalTamer tamer) { if (tamer != null) { setTamed(true); @@ -61,6 +63,7 @@ public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creat } } + @Override public void setTamed(boolean tame) { getHandle().setTamed(tame); if (!tame) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java index fb3416e65..338bc530c 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java @@ -20,6 +20,7 @@ public class CraftThrownExpBottle extends CraftProjectile implements ThrownExpBo return "EntityThrownExpBottle"; } + @Override public EntityType getType() { return EntityType.THROWN_EXP_BOTTLE; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java index b19539935..2400f3309 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java @@ -1,10 +1,10 @@ package org.bukkit.craftbukkit.entity; +import com.google.common.collect.ImmutableList; import java.util.Collection; import net.minecraft.server.EntityPotion; import net.minecraft.server.MobEffect; import net.minecraft.server.PotionUtil; - import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.craftbukkit.CraftServer; @@ -15,13 +15,12 @@ import org.bukkit.entity.ThrownPotion; import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; -import com.google.common.collect.ImmutableList; - -public abstract class CraftThrownPotion extends CraftProjectile implements ThrownPotion { +public class CraftThrownPotion extends CraftProjectile implements ThrownPotion { public CraftThrownPotion(CraftServer server, EntityPotion entity) { super(server, entity); } + @Override public Collection getEffects() { ImmutableList.Builder builder = ImmutableList.builder(); for (MobEffect effect : PotionUtil.getEffects(getHandle().getItem())) { @@ -30,12 +29,29 @@ public abstract class CraftThrownPotion extends CraftProjectile implements Throw return builder.build(); } + @Override public ItemStack getItem() { return CraftItemStack.asBukkitCopy(getHandle().getItem()); } + @Override + public void setItem(ItemStack item) { + // The ItemStack must not be null. + Validate.notNull(item, "ItemStack cannot be null."); + + // The ItemStack must be a potion. + Validate.isTrue(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack must be a lingering or splash potion. This item stack was " + item.getType() + "."); + + getHandle().setItem(CraftItemStack.asNMSCopy(item)); + } + @Override public EntityPotion getHandle() { return (EntityPotion) entity; } + + @Override + public EntityType getType() { + return EntityType.SPLASH_POTION; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTippedArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTippedArrow.java index 435203b88..ecdaa2b97 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTippedArrow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTippedArrow.java @@ -1,25 +1,21 @@ package org.bukkit.craftbukkit.entity; +import com.google.common.collect.ImmutableList; import java.util.List; - +import net.minecraft.server.EntityTippedArrow; +import net.minecraft.server.MobEffect; +import net.minecraft.server.MobEffectList; import org.apache.commons.lang.Validate; import org.bukkit.Color; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.potion.CraftPotionUtil; +import org.bukkit.entity.Arrow; import org.bukkit.entity.EntityType; -import org.bukkit.entity.TippedArrow; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import org.bukkit.potion.PotionType; -import com.google.common.collect.ImmutableList; - -import net.minecraft.server.EntityTippedArrow; -import net.minecraft.server.MobEffect; -import net.minecraft.server.MobEffectList; - -public class CraftTippedArrow extends CraftArrow implements TippedArrow { +public class CraftTippedArrow extends CraftArrow implements Arrow { public CraftTippedArrow(CraftServer server, EntityTippedArrow entity) { super(server, entity); @@ -37,7 +33,7 @@ public class CraftTippedArrow extends CraftArrow implements TippedArrow { @Override public EntityType getType() { - return EntityType.TIPPED_ARROW; + return EntityType.ARROW; } @Override @@ -55,14 +51,13 @@ public class CraftTippedArrow extends CraftArrow implements TippedArrow { } getHandle().effects.remove(existing); } - getHandle().a(CraftPotionUtil.fromBukkit(effect)); + getHandle().addEffect(CraftPotionUtil.fromBukkit(effect)); getHandle().refreshEffects(); return true; } @Override public void clearCustomEffects() { - Validate.isTrue(getBasePotionData().getType() != PotionType.UNCRAFTABLE, "Tipped Arrows must have at least 1 effect"); getHandle().effects.clear(); getHandle().refreshEffects(); } @@ -103,7 +98,6 @@ public class CraftTippedArrow extends CraftArrow implements TippedArrow { if (existing == null) { return false; } - Validate.isTrue(getBasePotionData().getType() != PotionType.UNCRAFTABLE || !getHandle().effects.isEmpty(), "Tipped Arrows must have at least 1 effect"); getHandle().effects.remove(existing); getHandle().refreshEffects(); return true; @@ -112,7 +106,6 @@ public class CraftTippedArrow extends CraftArrow implements TippedArrow { @Override public void setBasePotionData(PotionData data) { Validate.notNull(data, "PotionData cannot be null"); - Validate.isTrue(data.getType() != PotionType.UNCRAFTABLE || !getHandle().effects.isEmpty(), "Tipped Arrows must have at least 1 effect"); getHandle().setType(CraftPotionUtil.fromBukkit(data)); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTraderLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTraderLlama.java new file mode 100644 index 000000000..38a8649c6 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTraderLlama.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityLlamaTrader; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.TraderLlama; + +public class CraftTraderLlama extends CraftLlama implements TraderLlama { + + public CraftTraderLlama(CraftServer server, EntityLlamaTrader entity) { + super(server, entity); + } + + @Override + public EntityLlamaTrader getHandle() { + return (EntityLlamaTrader) super.getHandle(); + } + + @Override + public String toString() { + return "CraftTraderLlama"; + } + + @Override + public EntityType getType() { + return EntityType.TRADER_LLAMA; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java index b09da64c3..2f7df3074 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java @@ -41,11 +41,11 @@ public class CraftVex extends CraftMonster implements Vex { @Override public boolean isCharging() { - return getHandle().dA(); + return getHandle().isCharging(); } @Override public void setCharging(boolean charging) { - getHandle().a(charging); + getHandle().setCharging(charging); } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java index 342a3408b..f291a8d75 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java @@ -1,26 +1,21 @@ package org.bukkit.craftbukkit.entity; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import javax.annotation.Nullable; - -import net.minecraft.server.*; +import com.google.common.base.Preconditions; +import java.util.Locale; +import net.minecraft.server.EntityVillager; +import net.minecraft.server.IRegistry; +import net.minecraft.server.VillagerProfession; +import net.minecraft.server.IBlockData; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.BlockBed; import org.apache.commons.lang.Validate; +import org.bukkit.Location; import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.craftbukkit.inventory.CraftInventory; -import org.bukkit.craftbukkit.inventory.CraftMerchant; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.entity.EntityType; -import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Villager; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.MerchantRecipe; -public class CraftVillager extends CraftAgeable implements Villager, InventoryHolder { - - private static final Map careerIDMap = new HashMap<>(); - private CraftMerchant merchant; +public class CraftVillager extends CraftAbstractVillager implements Villager { public CraftVillager(CraftServer server, EntityVillager entity) { super(server, entity); @@ -36,131 +31,85 @@ public class CraftVillager extends CraftAgeable implements Villager, InventoryHo return "CraftVillager"; } + @Override public EntityType getType() { return EntityType.VILLAGER; } + @Override public Profession getProfession() { - return Profession.values()[getHandle().getProfession() + 1]; // Offset by 1 from the zombie types + return CraftVillager.nmsToBukkitProfession(getHandle().getVillagerData().getProfession()); } + @Override public void setProfession(Profession profession) { Validate.notNull(profession); - Validate.isTrue(!profession.isZombie(), "Profession is reserved for Zombies: ", profession); - getHandle().setProfession(profession.ordinal() - 1); + getHandle().setVillagerData(getHandle().getVillagerData().withProfession(CraftVillager.bukkitToNmsProfession(profession))); } @Override - public Career getCareer() { - return getCareer(getProfession(), getHandle().careerId); + public Type getVillagerType() { + return Type.valueOf(IRegistry.VILLAGER_TYPE.getKey(getHandle().getVillagerData().getType()).getKey().toUpperCase(Locale.ROOT)); } @Override - public void setCareer(Career career) { - setCareer(career, true); + public void setVillagerType(Type type) { + Validate.notNull(type); + getHandle().setVillagerData(getHandle().getVillagerData().withType(IRegistry.VILLAGER_TYPE.get(CraftNamespacedKey.toMinecraft(type.getKey())))); } @Override - public void setCareer(Career career, boolean resetTrades) { - if (career == null) { - getHandle().careerId = 0; // reset career - } else { - Validate.isTrue(career.getProfession() == getProfession(), "Career assignment mismatch. Found (" + getProfession() + ") Required (" + career.getProfession() + ")"); - getHandle().careerId = getCareerID(career); + public int getVillagerLevel() { + return getHandle().getVillagerData().getLevel(); + } + + @Override + public void setVillagerLevel(int level) { + Preconditions.checkArgument(1 <= level && level <= 5, "level must be between [1, 5]"); + + getHandle().setVillagerData(getHandle().getVillagerData().withLevel(level)); + } + + @Override + public int getVillagerExperience() { + return getHandle().getExperience(); + } + + @Override + public void setVillagerExperience(int experience) { + Preconditions.checkArgument(experience >= 0, "Experience must be positive"); + + getHandle().setExperience(experience); + } + + @Override + public boolean sleep(Location location) { + Preconditions.checkArgument(location != null, "Location cannot be null"); + Preconditions.checkArgument(location.getWorld() != null, "Location needs to be in a world"); + Preconditions.checkArgument(location.getWorld().equals(getWorld()), "Cannot sleep across worlds"); + + BlockPosition position = new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + IBlockData iblockdata = getHandle().world.getType(position); + if (!(iblockdata.getBlock() instanceof BlockBed)) { + return false; } - if (resetTrades) { - getHandle().trades = null; - getHandle().careerLevel = 0; // SPIGOT-4310 - getHandle().populateTrades(); - } + getHandle().e(position); // PAIL rename sleep + return true; } @Override - public Inventory getInventory() { - return new CraftInventory(getHandle().inventory); + public void wakeup() { + Preconditions.checkState(isSleeping(), "Cannot wakeup if not sleeping"); + + getHandle().dy(); // PAIL rename wakeup } - private CraftMerchant getMerchant() { - return (merchant == null) ? merchant = new CraftMerchant(getHandle()) : merchant; + public static Profession nmsToBukkitProfession(VillagerProfession nms) { + return Profession.valueOf(IRegistry.VILLAGER_PROFESSION.getKey(nms).getKey().toUpperCase(Locale.ROOT)); } - @Override - public List getRecipes() { - return getMerchant().getRecipes(); - } - - @Override - public void setRecipes(List recipes) { - this.getMerchant().setRecipes(recipes); - } - - @Override - public MerchantRecipe getRecipe(int i) { - return getMerchant().getRecipe(i); - } - - @Override - public void setRecipe(int i, MerchantRecipe merchantRecipe) { - getMerchant().setRecipe(i, merchantRecipe); - } - - @Override - public int getRecipeCount() { - return getMerchant().getRecipeCount(); - } - - @Override - public boolean isTrading() { - return getTrader() != null; - } - - @Override - public HumanEntity getTrader() { - return getMerchant().getTrader(); - } - - @Override - public int getRiches() { - return getHandle().riches; - } - - @Override - public void setRiches(int riches) { - getHandle().riches = riches; - } - - @Nullable - private static Career getCareer(Profession profession, int id) { - Validate.isTrue(id > 0, "Career id must be greater than 0"); - - List careers = profession.getCareers(); - for (Career c : careers) { - if (careerIDMap.containsKey(c) && careerIDMap.get(c) == id) { - return c; - } - } - - return null; - } - - private static int getCareerID(Career career) { - return careerIDMap.getOrDefault(career, 0); - } - - static { - // build Career -> ID map - int id = 0; - for (Profession prof : Profession.values()) { - List careers = prof.getCareers(); - if (!careers.isEmpty()) { - for (Career c : careers) { - careerIDMap.put(c, ++id); - } - } - - Validate.isTrue(id == careers.size(), "Career id registration mismatch"); - id = 0; - } + public static VillagerProfession bukkitToNmsProfession(Profession bukkit) { + return IRegistry.VILLAGER_PROFESSION.get(CraftNamespacedKey.toMinecraft(bukkit.getKey())); } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java index 64e4fd402..477635444 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java @@ -1,8 +1,15 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; +import java.util.Locale; import java.util.UUID; import net.minecraft.server.EntityZombieVillager; +import net.minecraft.server.IRegistry; +import net.minecraft.server.MinecraftKey; +import net.minecraft.server.MobEffects; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Villager; @@ -31,12 +38,13 @@ public class CraftVillagerZombie extends CraftZombie implements ZombieVillager { @Override public Villager.Profession getVillagerProfession() { - return Villager.Profession.values()[getHandle().getProfession() + Villager.Profession.FARMER.ordinal()]; + return Villager.Profession.valueOf(IRegistry.VILLAGER_PROFESSION.getKey(getHandle().getVillagerData().getProfession()).getKey().toUpperCase(Locale.ROOT)); } @Override public void setVillagerProfession(Villager.Profession profession) { - getHandle().setProfession(profession == null ? 0 : profession.ordinal() - Villager.Profession.FARMER.ordinal()); + Validate.notNull(profession); + getHandle().setVillagerData(getHandle().getVillagerData().withProfession(IRegistry.VILLAGER_PROFESSION.get(new MinecraftKey(profession.name().toLowerCase(Locale.ROOT))))); } @Override @@ -56,8 +64,22 @@ public class CraftVillagerZombie extends CraftZombie implements ZombieVillager { if (time < 0) { getHandle().conversionTime = -1; getHandle().getDataWatcher().set(EntityZombieVillager.CONVERTING, false); + getHandle().persistent = false; // CraftBukkit - SPIGOT-4684 update persistence + getHandle().conversionPlayer = null; + getHandle().removeEffect(MobEffects.INCREASE_DAMAGE, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); } else { getHandle().startConversion((UUID) null, time); } } + + @Override + public OfflinePlayer getConversionPlayer() { + return (getHandle().conversionPlayer == null) ? null : Bukkit.getOfflinePlayer(getHandle().conversionPlayer); + } + + @Override + public void setConversionPlayer(OfflinePlayer conversionPlayer) { + if (!this.isConverting()) return; + getHandle().conversionPlayer = (conversionPlayer == null) ? null : conversionPlayer.getUniqueId(); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java new file mode 100644 index 000000000..795e6afd8 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityVillagerTrader; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.WanderingTrader; + +public class CraftWanderingTrader extends CraftAbstractVillager implements WanderingTrader { + + public CraftWanderingTrader(CraftServer server, EntityVillagerTrader entity) { + super(server, entity); + } + + @Override + public EntityVillagerTrader getHandle() { + return (EntityVillagerTrader) entity; + } + + @Override + public String toString() { + return "CraftWanderingTrader"; + } + + @Override + public EntityType getType() { + return EntityType.WANDERING_TRADER; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java index 39e8d89bf..2be883986 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.server.EntityWaterAnimal; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.WaterMob; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWeather.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWeather.java deleted file mode 100644 index 91a749334..000000000 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWeather.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.bukkit.craftbukkit.entity; - -import net.minecraft.server.EntityWeather; -import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Weather; - -public class CraftWeather extends CraftEntity implements Weather { - public CraftWeather(final CraftServer server, final EntityWeather entity) { - super(server, entity); - } - - @Override - public EntityWeather getHandle() { - return (EntityWeather) entity; - } - - @Override - public String toString() { - return "CraftWeather"; - } - - public EntityType getType() { - return EntityType.WEATHER; - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java index ac465bda2..b43a2bbd5 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java @@ -1,19 +1,18 @@ package org.bukkit.craftbukkit.entity; -import com.destroystokyo.paper.entity.CraftRangedEntity; import net.minecraft.server.EntityWitch; import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.entity.Witch; import org.bukkit.entity.EntityType; - +import org.bukkit.entity.Witch; // Paper start +import com.destroystokyo.paper.entity.CraftRangedEntity; import com.google.common.base.Preconditions; import org.bukkit.Material; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; // Paper end -public class CraftWitch extends CraftMonster implements Witch, CraftRangedEntity { // Paper +public class CraftWitch extends CraftRaider implements Witch, CraftRangedEntity { public CraftWitch(CraftServer server, EntityWitch entity) { super(server, entity); } @@ -28,6 +27,7 @@ public class CraftWitch extends CraftMonster implements Witch, CraftRangedEntity return "CraftWitch"; } + @Override public EntityType getType() { return EntityType.WITCH; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java index a1d04ff28..03cf6136e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java @@ -30,6 +30,7 @@ public class CraftWither extends CraftMonster implements Wither, CraftRangedEnti return "CraftWither"; } + @Override public EntityType getType() { return EntityType.WITHER; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java index 563177e9a..93616809d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java @@ -30,6 +30,7 @@ public class CraftWitherSkull extends CraftFireball implements WitherSkull { return "CraftWitherSkull"; } + @Override public EntityType getType() { return EntityType.WITHER_SKULL; } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java index 55ce37c7f..80244fba3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java @@ -12,10 +12,12 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { super(server, wolf); } + @Override public boolean isAngry() { return getHandle().isAngry(); } + @Override public void setAngry(boolean angry) { getHandle().setAngry(angry); } @@ -30,10 +32,12 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { return EntityType.WOLF; } + @Override public DyeColor getCollarColor() { return DyeColor.getByWoolData((byte) getHandle().getCollarColor().getColorIndex()); } + @Override public void setCollarColor(DyeColor color) { getHandle().setCollarColor(EnumColor.fromColorIndex(color.getWoolData())); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java index c516d3475..c4320dbb6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java @@ -3,7 +3,6 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; import net.minecraft.server.EntityZombie; import net.minecraft.server.EntityZombieVillager; - import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.EntityType; import org.bukkit.entity.Villager; @@ -25,18 +24,22 @@ public class CraftZombie extends CraftMonster implements Zombie { return "CraftZombie"; } + @Override public EntityType getType() { return EntityType.ZOMBIE; } + @Override public boolean isBaby() { return getHandle().isBaby(); } + @Override public void setBaby(boolean flag) { getHandle().setBaby(flag); } + @Override public boolean isVillager() { return getHandle() instanceof EntityZombieVillager; } @@ -79,30 +82,37 @@ public class CraftZombie extends CraftMonster implements Zombie { } // Paper start + @Override public boolean isDrowning() { return getHandle().isDrowning(); } + @Override public void startDrowning(int drownedConversionTime) { getHandle().startDrownedConversion(drownedConversionTime); } + @Override public void stopDrowning() { getHandle().stopDrowning(); } - public void setArmsRaised(boolean raised) { - getHandle().setArmsRaised(raised); - } - - public boolean isArmsRaised() { - return getHandle().isArmsRaised(); - } - + @Override public boolean shouldBurnInDay() { return getHandle().shouldBurnInDay(); } + @Override + public boolean isArmsRaised() { + return getHandle().isArmsRaisedZombie(); + } + + @Override + public void setArmsRaised(final boolean raised) { + getHandle().setArmsRaisedZombie(raised); + } + + @Override public void setShouldBurnInDay(boolean shouldBurnInDay) { getHandle().setShouldBurnInDay(shouldBurnInDay); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryKey.java b/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryKey.java new file mode 100644 index 000000000..fee6bc588 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryKey.java @@ -0,0 +1,19 @@ +package org.bukkit.craftbukkit.entity.memory; + +import net.minecraft.server.IRegistry; +import net.minecraft.server.MemoryModuleType; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.entity.memory.MemoryKey; + +public final class CraftMemoryKey { + + private CraftMemoryKey() {} + + public static MemoryModuleType fromMemoryKey(MemoryKey memoryKey) { + return (MemoryModuleType) IRegistry.MEMORY_MODULE_TYPE.get(CraftNamespacedKey.toMinecraft(memoryKey.getKey())); + } + + public static MemoryKey toMemoryKey(MemoryModuleType memoryModuleType) { + return MemoryKey.getByKey(CraftNamespacedKey.fromMinecraft(IRegistry.MEMORY_MODULE_TYPE.getKey(memoryModuleType))); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryMapper.java b/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryMapper.java new file mode 100644 index 000000000..e7eacfc74 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/entity/memory/CraftMemoryMapper.java @@ -0,0 +1,44 @@ +package org.bukkit.craftbukkit.entity.memory; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.GlobalPos; +import net.minecraft.server.MinecraftSerializableLong; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; + +public final class CraftMemoryMapper { + + private CraftMemoryMapper() {} + + public static Object fromNms(Object object) { + if (object instanceof GlobalPos) { + return fromNms((GlobalPos) object); + } else if (object instanceof MinecraftSerializableLong) { + return ((MinecraftSerializableLong) object).a(); + } + + throw new UnsupportedOperationException("Do not know how to map " + object); + } + + public static Object toNms(Object object) { + if (object == null) { + return null; + } else if (object instanceof Location) { + return toNms((Location) object); + } else if (object instanceof Long) { + return MinecraftSerializableLong.a((Long) object); + } + + throw new UnsupportedOperationException("Do not know how to map " + object); + } + + public static Location fromNms(GlobalPos globalPos) { + return new org.bukkit.Location(((CraftServer) Bukkit.getServer()).getServer().getWorldServer(globalPos.getDimensionManager()).getWorld(), globalPos.getBlockPosition().getX(), globalPos.getBlockPosition().getY(), globalPos.getBlockPosition().getZ()); + } + + public static GlobalPos toNms(Location location) { + return GlobalPos.create(((CraftWorld) location.getWorld()).getHandle().getWorldProvider().getDimensionManager(), new BlockPosition(location.getX(), location.getY(), location.getZ())); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 72febcc70..dc15703fd 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1,5 +1,9 @@ package org.bukkit.craftbukkit.event; +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.common.collect.Lists; +import com.mojang.datafixers.util.Either; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; @@ -7,13 +11,61 @@ import java.util.EnumMap; import java.util.List; import java.util.Map; import javax.annotation.Nullable; - -import com.google.common.base.Function; -import com.google.common.base.Functions; -import com.google.common.collect.Lists; - -import net.minecraft.server.*; - +import net.minecraft.server.BlockPosition; +import net.minecraft.server.BlockPropertyInstrument; +import net.minecraft.server.ChatMessage; +import net.minecraft.server.ChatModifier; +import net.minecraft.server.Container; +import net.minecraft.server.ContainerMerchant; +import net.minecraft.server.DamageSource; +import net.minecraft.server.DimensionManager; +import net.minecraft.server.Entity; +import net.minecraft.server.EntityAnimal; +import net.minecraft.server.EntityAreaEffectCloud; +import net.minecraft.server.EntityDamageSource; +import net.minecraft.server.EntityDamageSourceIndirect; +import net.minecraft.server.EntityEnderCrystal; +import net.minecraft.server.EntityEnderDragon; +import net.minecraft.server.EntityExperienceOrb; +import net.minecraft.server.EntityFireworks; +import net.minecraft.server.EntityGhast; +import net.minecraft.server.EntityGolem; +import net.minecraft.server.EntityHuman; +import net.minecraft.server.EntityInsentient; +import net.minecraft.server.EntityItem; +import net.minecraft.server.EntityLiving; +import net.minecraft.server.EntityMonster; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.EntityPotion; +import net.minecraft.server.EntitySheep; +import net.minecraft.server.EntitySlime; +import net.minecraft.server.EntityRaider; +import net.minecraft.server.EntityTypes; +import net.minecraft.server.EntityVillager; +import net.minecraft.server.EntityWaterAnimal; +import net.minecraft.server.EnumDirection; +import net.minecraft.server.EnumHand; +import net.minecraft.server.EnumItemSlot; +import net.minecraft.server.Explosion; +import net.minecraft.server.GeneratorAccess; +import net.minecraft.server.IBlockData; +import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.IInventory; +import net.minecraft.server.IProjectile; +import net.minecraft.server.ItemActionContext; +import net.minecraft.server.ItemStack; +import net.minecraft.server.Items; +import net.minecraft.server.MinecraftKey; +import net.minecraft.server.MobEffect; +import net.minecraft.server.MovingObjectPosition; +import net.minecraft.server.MovingObjectPositionBlock; +import net.minecraft.server.MovingObjectPositionEntity; +import net.minecraft.server.NPC; +import net.minecraft.server.PacketPlayInCloseWindow; +import net.minecraft.server.Raid; +import net.minecraft.server.Unit; +import net.minecraft.server.World; +import net.minecraft.server.WorldServer; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Server; @@ -21,6 +73,7 @@ import org.bukkit.Statistic.Type; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.CraftRaid; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftStatistic; import org.bukkit.craftbukkit.CraftWorld; @@ -29,6 +82,7 @@ import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.entity.CraftRaider; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; import org.bukkit.craftbukkit.inventory.CraftItemStack; @@ -37,64 +91,137 @@ import org.bukkit.craftbukkit.potion.CraftPotionUtil; import org.bukkit.craftbukkit.util.CraftDamageSource; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.AreaEffectCloud; -import org.bukkit.entity.Arrow; import org.bukkit.entity.Bat; import org.bukkit.entity.Creeper; import org.bukkit.entity.EntityType; import org.bukkit.entity.ExperienceOrb; import org.bukkit.entity.Firework; +import org.bukkit.entity.Item; import org.bukkit.entity.LightningStrike; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Pig; import org.bukkit.entity.PigZombie; import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; +import org.bukkit.entity.Raider; +import org.bukkit.entity.Sheep; import org.bukkit.entity.ThrownExpBottle; import org.bukkit.entity.ThrownPotion; +import org.bukkit.entity.Vehicle; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Villager.Profession; import org.bukkit.entity.ExperienceOrb; // Paper import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.Event.Result; -import org.bukkit.event.block.*; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockDropItemEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockGrowEvent; +import org.bukkit.event.block.BlockIgniteEvent; import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; -import org.bukkit.event.entity.*; +import org.bukkit.event.block.BlockMultiPlaceEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.block.BlockShearEntityEvent; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.EntityBlockFormEvent; +import org.bukkit.event.block.FluidLevelChangeEvent; +import org.bukkit.event.block.MoistureChangeEvent; +import org.bukkit.event.block.NotePlayEvent; +import org.bukkit.event.entity.AreaEffectCloudApplyEvent; +import org.bukkit.event.entity.BatToggleSleepEvent; +import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.CreeperPowerEvent; +import org.bukkit.event.entity.EntityBreakDoorEvent; +import org.bukkit.event.entity.EntityBreedEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDamageByBlockEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityPickupItemEvent; +import org.bukkit.event.entity.EntityPlaceEvent; +import org.bukkit.event.entity.EntityPotionEffectEvent; +import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.entity.EntityTameEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.event.entity.EntityToggleGlideEvent; +import org.bukkit.event.entity.EntityToggleSwimEvent; +import org.bukkit.event.entity.EntityTransformEvent; +import org.bukkit.event.entity.ExpBottleEvent; +import org.bukkit.event.entity.FireworkExplodeEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.entity.HorseJumpEvent; +import org.bukkit.event.entity.ItemDespawnEvent; +import org.bukkit.event.entity.ItemMergeEvent; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.entity.LingeringPotionSplashEvent; +import org.bukkit.event.entity.PigZapEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.PlayerLeashEntityEvent; +import org.bukkit.event.entity.PotionSplashEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.event.entity.VillagerCareerChangeEvent; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.event.inventory.PrepareItemCraftEvent; -import org.bukkit.event.player.*; +import org.bukkit.event.inventory.TradeSelectEvent; +import org.bukkit.event.player.PlayerBedEnterEvent; import org.bukkit.event.player.PlayerBedEnterEvent.BedEnterResult; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerBucketFillEvent; +import org.bukkit.event.player.PlayerEditBookEvent; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerExpChangeEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerItemBreakEvent; +import org.bukkit.event.player.PlayerItemMendEvent; +import org.bukkit.event.player.PlayerLevelChangeEvent; +import org.bukkit.event.player.PlayerRecipeDiscoverEvent; +import org.bukkit.event.player.PlayerStatisticIncrementEvent; +import org.bukkit.event.player.PlayerUnleashEntityEvent; import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.event.vehicle.VehicleCreateEvent; +import org.bukkit.event.raid.RaidTriggerEvent; +import org.bukkit.event.raid.RaidFinishEvent; +import org.bukkit.event.raid.RaidStopEvent; +import org.bukkit.event.raid.RaidSpawnWaveEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.meta.BookMeta; -import org.bukkit.entity.AbstractHorse; -import org.bukkit.entity.Vehicle; -import org.bukkit.event.vehicle.VehicleCreateEvent; import org.bukkit.potion.PotionEffect; +import org.bukkit.event.entity.SpawnerSpawnEvent; // Spigot + public class CraftEventFactory { public static final DamageSource MELTING = CraftDamageSource.copyOf(DamageSource.BURN); public static final DamageSource POISON = CraftDamageSource.copyOf(DamageSource.MAGIC); public static org.bukkit.block.Block blockDamage; // For use in EntityDamageByBlockEvent public static Entity entityDamage; // For use in EntityDamageByEntityEvent - public static boolean isWorldGen(GeneratorAccess world) { return world instanceof net.minecraft.server.RegionLimitedWorldAccess; } // Paper // helper methods - private static boolean canBuild(CraftWorld world, Player player, int x, int z) { - WorldServer worldServer = world.getHandle(); + private static boolean canBuild(World world, Player player, int x, int z) { int spawnSize = Bukkit.getServer().getSpawnRadius(); - if (world.getHandle().dimension != DimensionManager.OVERWORLD) return true; + if (world.getWorldProvider().getDimensionManager() != DimensionManager.OVERWORLD) return true; if (spawnSize <= 0) return true; if (((CraftServer) Bukkit.getServer()).getHandle().getOPs().isEmpty()) return true; if (player.isOp()) return true; - BlockPosition chunkcoordinates = worldServer.getSpawn(); + BlockPosition chunkcoordinates = world.getSpawn(); int distanceFromSpawn = Math.max(Math.abs(x - chunkcoordinates.getX()), Math.abs(z - chunkcoordinates.getZ())); return distanceFromSpawn > spawnSize; @@ -108,41 +235,47 @@ public class CraftEventFactory { /** * PlayerBedEnterEvent */ - public static EntityHuman.EnumBedResult callPlayerBedEnterEvent(EntityHuman player, BlockPosition bed, EntityHuman.EnumBedResult nmsBedResult) { - BedEnterResult bedEnterResult; - switch (nmsBedResult) { - case OK: - bedEnterResult = BedEnterResult.OK; - break; - case NOT_POSSIBLE_HERE: - bedEnterResult = BedEnterResult.NOT_POSSIBLE_HERE; - break; - case NOT_POSSIBLE_NOW: - bedEnterResult = BedEnterResult.NOT_POSSIBLE_NOW; - break; - case TOO_FAR_AWAY: - bedEnterResult = BedEnterResult.TOO_FAR_AWAY; - break; - case NOT_SAFE: - bedEnterResult = BedEnterResult.NOT_SAFE; - break; - default: - bedEnterResult = BedEnterResult.OTHER_PROBLEM; - } + public static Either callPlayerBedEnterEvent(EntityHuman player, BlockPosition bed, Either nmsBedResult) { + BedEnterResult bedEnterResult = nmsBedResult.mapBoth(new Function() { + @Override + public BedEnterResult apply(EntityHuman.EnumBedResult t) { + switch (t) { + case NOT_POSSIBLE_HERE: + return BedEnterResult.NOT_POSSIBLE_HERE; + case NOT_POSSIBLE_NOW: + return BedEnterResult.NOT_POSSIBLE_NOW; + case TOO_FAR_AWAY: + return BedEnterResult.TOO_FAR_AWAY; + case NOT_SAFE: + return BedEnterResult.NOT_SAFE; + default: + return BedEnterResult.OTHER_PROBLEM; + } + } + }, t -> BedEnterResult.OK).map(java.util.function.Function.identity(), java.util.function.Function.identity()); PlayerBedEnterEvent event = new PlayerBedEnterEvent((Player) player.getBukkitEntity(), CraftBlock.at(player.world, bed), bedEnterResult); Bukkit.getServer().getPluginManager().callEvent(event); Result result = event.useBed(); if (result == Result.ALLOW) { - return EntityHuman.EnumBedResult.OK; + return Either.right(Unit.INSTANCE); } else if (result == Result.DENY) { - return EntityHuman.EnumBedResult.OTHER_PROBLEM; + return Either.left(EntityHuman.EnumBedResult.OTHER_PROBLEM); } return nmsBedResult; } + /** + * Trade Index Change Event + */ + public static TradeSelectEvent callTradeSelectEvent(EntityPlayer player, int newIndex, ContainerMerchant merchant) { + TradeSelectEvent tradeSelectEvent = new TradeSelectEvent(merchant.getBukkitView(), newIndex); + Bukkit.getPluginManager().callEvent(tradeSelectEvent); + return tradeSelectEvent; + } + /** * Block place methods */ @@ -155,7 +288,7 @@ public class CraftEventFactory { boolean canBuild = true; for (int i = 0; i < blockStates.size(); i++) { - if (!canBuild(craftWorld, player, blockStates.get(i).getX(), blockStates.get(i).getZ())) { + if (!canBuild(world, player, blockStates.get(i).getX(), blockStates.get(i).getZ())) { canBuild = false; break; } @@ -183,7 +316,7 @@ public class CraftEventFactory { Block blockClicked = craftWorld.getBlockAt(clickedX, clickedY, clickedZ); Block placedBlock = replacedBlockState.getBlock(); - boolean canBuild = canBuild(craftWorld, player, placedBlock.getX(), placedBlock.getZ()); + boolean canBuild = canBuild(world, player, placedBlock.getX(), placedBlock.getZ()); org.bukkit.inventory.ItemStack item; EquipmentSlot equipmentSlot; @@ -226,46 +359,47 @@ public class CraftEventFactory { /** * Bucket methods */ - public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemInHand) { - return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, who, clickedX, clickedY, clickedZ, clickedFace, itemInHand, Items.BUCKET); + public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(World world, EntityHuman who, BlockPosition changed, BlockPosition clicked, EnumDirection clickedFace, ItemStack itemInHand) { + return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, world, who, changed, clicked, clickedFace, itemInHand, Items.BUCKET); } - public static PlayerBucketFillEvent callPlayerBucketFillEvent(EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemInHand, net.minecraft.server.Item bucket) { - return (PlayerBucketFillEvent) getPlayerBucketEvent(true, who, clickedX, clickedY, clickedZ, clickedFace, itemInHand, bucket); + public static PlayerBucketFillEvent callPlayerBucketFillEvent(World world, EntityHuman who, BlockPosition changed, BlockPosition clicked, EnumDirection clickedFace, ItemStack itemInHand, net.minecraft.server.Item bucket) { + return (PlayerBucketFillEvent) getPlayerBucketEvent(true, world, who, clicked, changed, clickedFace, itemInHand, bucket); } - private static PlayerEvent getPlayerBucketEvent(boolean isFilling, EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemstack, net.minecraft.server.Item item) { + private static PlayerEvent getPlayerBucketEvent(boolean isFilling, World world, EntityHuman who, BlockPosition changed, BlockPosition clicked, EnumDirection clickedFace, ItemStack itemstack, net.minecraft.server.Item item) { + Player player = (Player) who.getBukkitEntity(); // Paper start - add EnumHand - return getPlayerBucketEvent(isFilling, who, clickedX, clickedY, clickedZ, clickedFace, itemstack, item, null); + return getPlayerBucketEvent(isFilling, world, who, changed, clicked, clickedFace, itemstack, item, null); } - public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemInHand, EnumHand enumHand) { - return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, who, clickedX, clickedY, clickedZ, clickedFace, itemInHand, Items.BUCKET, enumHand); + public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(World world, EntityHuman who, BlockPosition changed, BlockPosition clicked, EnumDirection clickedFace, ItemStack itemstack, EnumHand enumHand) { + return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, world, who, changed, clicked, clickedFace, itemstack, Items.BUCKET, enumHand); } - public static PlayerBucketFillEvent callPlayerBucketFillEvent(EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemInHand, net.minecraft.server.Item bucket, EnumHand enumHand) { - return (PlayerBucketFillEvent) getPlayerBucketEvent(true, who, clickedX, clickedY, clickedZ, clickedFace, itemInHand, bucket, enumHand); + public static PlayerBucketFillEvent callPlayerBucketFillEvent(World world, EntityHuman who, BlockPosition changed, BlockPosition clicked, EnumDirection clickedFace, ItemStack itemInHand, net.minecraft.server.Item bucket, EnumHand enumHand) { + return (PlayerBucketFillEvent) getPlayerBucketEvent(true, world, who, clicked, changed, clickedFace, itemInHand, bucket, enumHand); } - private static PlayerEvent getPlayerBucketEvent(boolean isFilling, EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemstack, net.minecraft.server.Item item, EnumHand enumHand) { + private static PlayerEvent getPlayerBucketEvent(boolean isFilling, World world, EntityHuman who, BlockPosition changed, BlockPosition clicked, EnumDirection clickedFace, ItemStack itemstack, net.minecraft.server.Item item, EnumHand enumHand) { // Paper end Player player = (who == null) ? null : (Player) who.getBukkitEntity(); CraftItemStack itemInHand = CraftItemStack.asNewCraftStack(item); Material bucket = CraftMagicNumbers.getMaterial(itemstack.getItem()); - CraftWorld craftWorld = (CraftWorld) player.getWorld(); CraftServer craftServer = (CraftServer) player.getServer(); - Block blockClicked = craftWorld.getBlockAt(clickedX, clickedY, clickedZ); + Block block = CraftBlock.at(world, changed); + Block blockClicked = CraftBlock.at(world, clicked); BlockFace blockFace = CraftBlock.notchToBlockFace(clickedFace); - PlayerEvent event = null; + PlayerEvent event; if (isFilling) { - event = new PlayerBucketFillEvent(player, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == EnumHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand - ((PlayerBucketFillEvent) event).setCancelled(!canBuild(craftWorld, player, clickedX, clickedZ)); + event = new PlayerBucketFillEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == EnumHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand + ((PlayerBucketFillEvent) event).setCancelled(!canBuild(world, player, changed.getX(), changed.getZ())); } else { - event = new PlayerBucketEmptyEvent(player, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == EnumHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand - ((PlayerBucketEmptyEvent) event).setCancelled(!canBuild(craftWorld, player, clickedX, clickedZ)); + event = new PlayerBucketEmptyEvent(player, block, blockClicked, blockFace, bucket, itemInHand, enumHand == null ? null : enumHand == EnumHand.OFF_HAND ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND); // Paper - add enumHand + ((PlayerBucketEmptyEvent) event).setCancelled(!canBuild(world, player, changed.getX(), changed.getZ())); } craftServer.getPluginManager().callEvent(event); @@ -296,7 +430,7 @@ public class CraftEventFactory { Block blockClicked = null; if (position != null) { - blockClicked = craftWorld.getBlockAt(position); // Akarin + blockClicked = craftWorld.getBlockAt(position.getX(), position.getY(), position.getZ()); } else { switch (action) { case LEFT_CLICK_BLOCK: @@ -347,10 +481,10 @@ public class CraftEventFactory { /** * EntityShootBowEvent */ - public static EntityShootBowEvent callEntityShootBowEvent(EntityLiving who, /*bow*/ItemStack itemstack, /*arrow*/ ItemStack arrowItem, EntityArrow entityArrow, float force) { // Paper + public static EntityShootBowEvent callEntityShootBowEvent(EntityLiving who, ItemStack itemstack, ItemStack arrowItem, IProjectile entityArrow, float force) { // paper LivingEntity shooter = (LivingEntity) who.getBukkitEntity(); CraftItemStack itemInHand = CraftItemStack.asCraftMirror(itemstack); - Arrow arrow = (Arrow) entityArrow.getBukkitEntity(); + org.bukkit.entity.Entity arrow = ((Entity) entityArrow).getBukkitEntity(); // Paper if (itemInHand != null && (itemInHand.getType() == Material.AIR || itemInHand.getAmount() == 0)) { itemInHand = null; @@ -362,6 +496,16 @@ public class CraftEventFactory { return event; } + /** + * VillagerCareerChangeEvent + */ + public static VillagerCareerChangeEvent callVillagerCareerChangeEvent(EntityVillager vilager, Profession future, VillagerCareerChangeEvent.ChangeReason reason) { + VillagerCareerChangeEvent event = new VillagerCareerChangeEvent((Villager) vilager.getBukkitEntity(), future, reason); + Bukkit.getPluginManager().callEvent(event); + + return event; + } + /** * BlockDamageEvent */ @@ -390,7 +534,7 @@ public class CraftEventFactory { boolean isNpc = entity instanceof NPC; if (spawnReason != SpawnReason.CUSTOM) { - if (isAnimal && !world.allowAnimals || isMonster && !world.allowMonsters || isNpc && !world.getServer().getServer().getSpawnNPCs()) { + if (isAnimal && !world.getWorld().getAllowAnimals() || isMonster && !world.getWorld().getAllowMonsters() || isNpc && !world.getServer().getServer().getSpawnNPCs()) { entity.dead = true; return false; } @@ -475,7 +619,6 @@ public class CraftEventFactory { CraftServer craftServer = (CraftServer) entity.getServer(); CreatureSpawnEvent event = new CreatureSpawnEvent(entity, spawnReason); - if (isWorldGen(entityliving.world)) return event; // Paper - do not call during world gen craftServer.getPluginManager().callEvent(event); return event; } @@ -586,7 +729,7 @@ public class CraftEventFactory { CraftBlockState state = CraftBlockState.getBlockState(world, target, flag); state.setData(block); - BlockSpreadEvent event = new BlockSpreadEvent(world.getWorld().getBlockAt(target), world.getWorld().getBlockAt(source), state); // Akarin + BlockSpreadEvent event = new BlockSpreadEvent(world.getWorld().getBlockAt(target.getX(), target.getY(), target.getZ()), world.getWorld().getBlockAt(source.getX(), source.getY(), source.getZ()), state); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { @@ -643,10 +786,6 @@ public class CraftEventFactory { victim.expToDrop = event.getDroppedExp(); victim.newExp = event.getNewExp(); - if (event.getKeepInventory()) { - return event; - } - for (org.bukkit.inventory.ItemStack stack : event.getDrops()) { if (stack == null || stack.getType() == Material.AIR) continue; @@ -661,11 +800,11 @@ public class CraftEventFactory { private static void populateFields(EntityLiving victim, EntityDeathEvent event) { event.setReviveHealth(event.getEntity().getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).getValue()); event.setShouldPlayDeathSound(!victim.silentDeath && !victim.isSilent()); - SoundEffect soundEffect = victim.getDeathSoundEffect(); + net.minecraft.server.SoundEffect soundEffect = victim.getDeathSoundEffect(); event.setDeathSound(soundEffect != null ? org.bukkit.craftbukkit.CraftSound.getSoundByEffect(soundEffect) : null); - event.setDeathSoundCategory(org.bukkit.SoundCategory.valueOf(victim.getDeathSoundCategory().name())); + event.setDeathSoundCategory(org.bukkit.SoundCategory.valueOf(victim.getSoundCategory().name())); event.setDeathSoundVolume(victim.getDeathSoundVolume()); - event.setDeathSoundPitch(victim.getDeathSoundPitch()); + event.setDeathSoundPitch(victim.getSoundPitch()); } // Play death sound manually @@ -675,8 +814,8 @@ public class CraftEventFactory { double x = event.getEntity().getLocation().getX(); double y = event.getEntity().getLocation().getY(); double z = event.getEntity().getLocation().getZ(); - SoundEffect soundEffect = org.bukkit.craftbukkit.CraftSound.getSoundEffect(event.getDeathSound()); - SoundCategory soundCategory = SoundCategory.valueOf(event.getDeathSoundCategory().name()); + net.minecraft.server.SoundEffect soundEffect = org.bukkit.craftbukkit.CraftSound.getSoundEffect(event.getDeathSound()); + net.minecraft.server.SoundCategory soundCategory = net.minecraft.server.SoundCategory.valueOf(event.getDeathSoundCategory().name()); victim.world.sendSoundEffect(source, x, y, z, soundEffect, soundCategory, event.getDeathSoundVolume(), event.getDeathSoundPitch()); } } @@ -691,6 +830,10 @@ public class CraftEventFactory { } private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map modifiers, Map> modifierFunctions) { + return handleEntityDamageEvent(entity, source, modifiers, modifierFunctions, false); + } + + private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map modifiers, Map> modifierFunctions, boolean cancelled) { if (source.isExplosion()) { DamageCause damageCause; Entity damager = entityDamage; @@ -708,6 +851,7 @@ public class CraftEventFactory { } event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions); } + event.setCancelled(cancelled); callEvent(event); @@ -730,15 +874,19 @@ public class CraftEventFactory { cause = DamageCause.THORNS; } - return callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions); + return callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions, cancelled); } else if (source == DamageSource.OUT_OF_WORLD) { - EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers, modifierFunctions)); + EntityDamageEvent event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers, modifierFunctions); + event.setCancelled(cancelled); + callEvent(event); if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } return event; } else if (source == DamageSource.LAVA) { - EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions)); + EntityDamageEvent event = (new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions)); + event.setCancelled(cancelled); + callEvent(event); if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } @@ -747,7 +895,7 @@ public class CraftEventFactory { DamageCause cause = null; Block damager = blockDamage; blockDamage = null; - if (source == DamageSource.CACTUS) { + if (source == DamageSource.CACTUS || source == DamageSource.SWEET_BERRY_BUSH) { cause = DamageCause.CONTACT; } else if (source == DamageSource.HOT_FLOOR) { cause = DamageCause.HOT_FLOOR; @@ -756,7 +904,9 @@ public class CraftEventFactory { } else { throw new IllegalStateException(String.format("Unhandled damage of %s by %s from %s", entity, damager, source.translationIndex)); } - EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions)); + EntityDamageEvent event = new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions); + event.setCancelled(cancelled); + callEvent(event); if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } @@ -778,7 +928,9 @@ public class CraftEventFactory { } else { throw new IllegalStateException(String.format("Unhandled damage of %s by %s from %s", entity, damager.getHandle(), source.translationIndex)); } - EntityDamageEvent event = callEvent(new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions)); + EntityDamageEvent event = new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions); + event.setCancelled(cancelled); + callEvent(event); if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } @@ -817,20 +969,24 @@ public class CraftEventFactory { } if (cause != null) { - return callEntityDamageEvent(null, entity, cause, modifiers, modifierFunctions); + return callEntityDamageEvent(null, entity, cause, modifiers, modifierFunctions, cancelled); } throw new IllegalStateException(String.format("Unhandled damage of %s from %s", entity, source.translationIndex)); } private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map modifiers, Map> modifierFunctions) { + return callEntityDamageEvent(damager, damagee, cause, modifiers, modifierFunctions, false); + } + + private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map modifiers, Map> modifierFunctions, boolean cancelled) { EntityDamageEvent event; if (damager != null) { event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); } else { event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); } - + event.setCancelled(cancelled); callEvent(event); if (!event.isCancelled()) { @@ -872,6 +1028,10 @@ public class CraftEventFactory { } public static boolean handleNonLivingEntityDamageEvent(Entity entity, DamageSource source, double damage, boolean cancelOnZeroDamage) { + return handleNonLivingEntityDamageEvent(entity, source, damage, cancelOnZeroDamage, false); + } + + public static boolean handleNonLivingEntityDamageEvent(Entity entity, DamageSource source, double damage, boolean cancelOnZeroDamage, boolean cancelled) { if (entity instanceof EntityEnderCrystal && !(source instanceof EntityDamageSource)) { return false; } @@ -882,7 +1042,8 @@ public class CraftEventFactory { modifiers.put(DamageModifier.BASE, damage); functions.put(DamageModifier.BASE, ZERO); - final EntityDamageEvent event = handleEntityDamageEvent(entity, source, modifiers, functions); + final EntityDamageEvent event = handleEntityDamageEvent(entity, source, modifiers, functions, cancelled); + if (event == null) { return false; } @@ -926,7 +1087,7 @@ public class CraftEventFactory { } public static boolean handleBlockGrowEvent(World world, BlockPosition pos, IBlockData newData, int flag) { - Block block = world.getWorld().getBlockAt(pos); // Akarin + Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); CraftBlockState state = (CraftBlockState) block.getState(); state.setData(newData); @@ -947,7 +1108,11 @@ public class CraftEventFactory { } public static FoodLevelChangeEvent callFoodLevelChangeEvent(EntityHuman entity, int level) { - FoodLevelChangeEvent event = new FoodLevelChangeEvent(entity.getBukkitEntity(), level); + return callFoodLevelChangeEvent(entity, level, null); + } + + public static FoodLevelChangeEvent callFoodLevelChangeEvent(EntityHuman entity, int level, ItemStack item) { + FoodLevelChangeEvent event = new FoodLevelChangeEvent(entity.getBukkitEntity(), level, (item == null) ? null : CraftItemStack.asBukkitCopy(item)); entity.getBukkitEntity().getServer().getPluginManager().callEvent(event); return event; } @@ -977,7 +1142,7 @@ public class CraftEventFactory { } public static EntityChangeBlockEvent callEntityChangeBlockEvent(Entity entity, BlockPosition position, IBlockData newBlock, boolean cancelled) { - Block block = entity.world.getWorld().getBlockAt(position); // Akarin + Block block = entity.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()); EntityChangeBlockEvent event = new EntityChangeBlockEvent(entity.getBukkitEntity(), block, CraftBlockData.fromData(newBlock)); event.setCancelled(cancelled); @@ -992,20 +1157,20 @@ public class CraftEventFactory { } public static EntityTargetEvent callEntityTargetEvent(Entity entity, Entity target, EntityTargetEvent.TargetReason reason) { - EntityTargetEvent event = new EntityTargetEvent(entity.getBukkitEntity(), target == null ? null : target.getBukkitEntity(), reason); + EntityTargetEvent event = new EntityTargetEvent(entity.getBukkitEntity(), (target == null) ? null : target.getBukkitEntity(), reason); entity.getBukkitEntity().getServer().getPluginManager().callEvent(event); return event; } public static EntityTargetLivingEntityEvent callEntityTargetLivingEvent(Entity entity, EntityLiving target, EntityTargetEvent.TargetReason reason) { - EntityTargetLivingEntityEvent event = new EntityTargetLivingEntityEvent(entity.getBukkitEntity(), (LivingEntity) target.getBukkitEntity(), reason); + EntityTargetLivingEntityEvent event = new EntityTargetLivingEntityEvent(entity.getBukkitEntity(), (target == null) ? null : (LivingEntity) target.getBukkitEntity(), reason); entity.getBukkitEntity().getServer().getPluginManager().callEvent(event); return event; } - public static EntityBreakDoorEvent callEntityBreakDoorEvent(Entity entity, int x, int y, int z) { + public static EntityBreakDoorEvent callEntityBreakDoorEvent(Entity entity, BlockPosition pos) { org.bukkit.entity.Entity entity1 = entity.getBukkitEntity(); - Block block = entity1.getWorld().getBlockAt(x, y, z); + Block block = CraftBlock.at(entity.world, pos); EntityBreakDoorEvent event = new EntityBreakDoorEvent((LivingEntity) entity1, block); entity1.getServer().getPluginManager().callEvent(event); @@ -1051,9 +1216,9 @@ public class CraftEventFactory { } // Paper start - public static com.destroystokyo.paper.event.entity.ProjectileCollideEvent callProjectileCollideEvent(Entity entity, MovingObjectPosition position) { + public static com.destroystokyo.paper.event.entity.ProjectileCollideEvent callProjectileCollideEvent(Entity entity, MovingObjectPositionEntity position) { Projectile projectile = (Projectile) entity.getBukkitEntity(); - org.bukkit.entity.Entity collided = position.entity.getBukkitEntity(); + org.bukkit.entity.Entity collided = position.getEntity().getBukkitEntity(); com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = new com.destroystokyo.paper.event.entity.ProjectileCollideEvent(projectile, collided); if (projectile.getShooter() instanceof Player && collided instanceof Player) { @@ -1075,17 +1240,26 @@ public class CraftEventFactory { return event; } - public static ProjectileHitEvent callProjectileHitEvent(Entity entity, MovingObjectPosition position) { - Block hitBlock = null; - BlockFace hitFace = null; - if (position.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { - hitBlock = CraftBlock.at(entity.world, position.getBlockPosition()); - hitFace = CraftBlock.notchToBlockFace(position.direction); + public static void callProjectileHitEvent(Entity entity, MovingObjectPosition position) { + if (position.getType() == MovingObjectPosition.EnumMovingObjectType.MISS) { + return; } - ProjectileHitEvent event = new ProjectileHitEvent((Projectile) entity.getBukkitEntity(), position.entity == null ? null : position.entity.getBukkitEntity(), hitBlock, hitFace); + Block hitBlock = null; + BlockFace hitFace = null; + if (position.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + MovingObjectPositionBlock positionBlock = (MovingObjectPositionBlock) position; + hitBlock = CraftBlock.at(entity.world, positionBlock.getBlockPosition()); + hitFace = CraftBlock.notchToBlockFace(positionBlock.getDirection()); + } + + org.bukkit.entity.Entity hitEntity = null; + if (position.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + hitEntity = ((MovingObjectPositionEntity) position).getEntity().getBukkitEntity(); + } + + ProjectileHitEvent event = new ProjectileHitEvent((Projectile) entity.getBukkitEntity(), hitEntity, hitBlock, hitFace); entity.world.getServer().getPluginManager().callEvent(event); - return event; } public static ExpBottleEvent callExpBottleEvent(Entity entity, int exp) { @@ -1096,13 +1270,13 @@ public class CraftEventFactory { } public static BlockRedstoneEvent callRedstoneChange(World world, BlockPosition pos, int oldCurrent, int newCurrent) { - BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(pos), oldCurrent, newCurrent); // Akarin + BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()), oldCurrent, newCurrent); world.getServer().getPluginManager().callEvent(event); return event; } public static NotePlayEvent callNotePlayEvent(World world, BlockPosition pos, BlockPropertyInstrument instrument, int note) { - NotePlayEvent event = new NotePlayEvent(world.getWorld().getBlockAt(pos), org.bukkit.Instrument.getByType((byte) instrument.ordinal()), new org.bukkit.Note(note)); // Akarin + NotePlayEvent event = new NotePlayEvent(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()), org.bukkit.Instrument.getByType((byte) instrument.ordinal()), new org.bukkit.Note(note)); world.getServer().getPluginManager().callEvent(event); return event; } @@ -1114,8 +1288,8 @@ public class CraftEventFactory { } public static BlockIgniteEvent callBlockIgniteEvent(World world, BlockPosition block, BlockPosition source) { - org.bukkit.craftbukkit.CraftWorld bukkitWorld = world.getWorld(); // Akarin - Block igniter = bukkitWorld.getBlockAt(source); // Akarin + org.bukkit.World bukkitWorld = world.getWorld(); + Block igniter = bukkitWorld.getBlockAt(source.getX(), source.getY(), source.getZ()); IgniteCause cause; switch (igniter.getType()) { case LAVA: @@ -1129,8 +1303,7 @@ public class CraftEventFactory { cause = IgniteCause.SPREAD; } - BlockIgniteEvent event = new BlockIgniteEvent(bukkitWorld.getBlockAt(block), cause, igniter); // Akarin - if (isWorldGen(world)) return event; // Paper - do not call during world gen + BlockIgniteEvent event = new BlockIgniteEvent(bukkitWorld.getBlockAt(block.getX(), block.getY(), block.getZ()), cause, igniter); world.getServer().getPluginManager().callEvent(event); return event; } @@ -1150,12 +1323,14 @@ public class CraftEventFactory { case FIREBALL: cause = IgniteCause.FIREBALL; break; + case ARROW: + cause = IgniteCause.ARROW; + break; default: cause = IgniteCause.FLINT_AND_STEEL; } BlockIgniteEvent event = new BlockIgniteEvent(bukkitWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), cause, bukkitIgniter); - if (isWorldGen(world)) return event; // Paper - do not call during world gen world.getServer().getPluginManager().callEvent(event); return event; } @@ -1170,7 +1345,7 @@ public class CraftEventFactory { } public static BlockIgniteEvent callBlockIgniteEvent(World world, BlockPosition pos, IgniteCause cause, Entity igniter) { - BlockIgniteEvent event = new BlockIgniteEvent(world.getWorld().getBlockAt(pos), cause, igniter.getBukkitEntity()); // Akarin + BlockIgniteEvent event = new BlockIgniteEvent(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()), cause, igniter.getBukkitEntity()); world.getServer().getPluginManager().callEvent(event); return event; } @@ -1225,7 +1400,7 @@ public class CraftEventFactory { c.setChatModifier(modi); if (c instanceof ChatMessage) { ChatMessage cm = (ChatMessage) c; - Object[] oo = cm.l(); + Object[] oo = cm.getArgs(); for (int i = 0; i < oo.length; i++) { Object o = oo[i]; if (o instanceof IChatBaseComponent) { @@ -1233,7 +1408,7 @@ public class CraftEventFactory { } } } - List ls = c.a(); + List ls = c.getSiblings(); if (ls != null) { for (int i = 0; i < ls.size(); i++) { ls.set(i, stripEvents(ls.get(i))); @@ -1254,6 +1429,13 @@ public class CraftEventFactory { return event; } + public static BlockShearEntityEvent callBlockShearEntityEvent(EntitySheep animal, org.bukkit.block.Block dispenser, CraftItemStack is) { + Sheep sheep = (Sheep) animal.getBukkitEntity(); + BlockShearEntityEvent bse = new BlockShearEntityEvent(dispenser, sheep, is); + Bukkit.getPluginManager().callEvent(bse); + return bse; + } + public static Cancellable handleStatisticsIncrease(EntityHuman entityHuman, net.minecraft.server.Statistic statistic, int current, int incrementation) { Player player = ((EntityPlayer) entityHuman).getBukkitEntity(); Event event; @@ -1316,7 +1498,7 @@ public class CraftEventFactory { */ public static SpawnerSpawnEvent callSpawnerSpawnEvent(Entity spawnee, BlockPosition pos) { org.bukkit.craftbukkit.entity.CraftEntity entity = spawnee.getBukkitEntity(); - BlockState state = ((CraftWorld) entity.getWorld()).getBlockAt(pos).getState(); // Akarin + BlockState state = entity.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()).getState(); if (!(state instanceof org.bukkit.block.CreatureSpawner)) { state = null; } @@ -1363,8 +1545,10 @@ public class CraftEventFactory { public static BlockPhysicsEvent callBlockPhysicsEvent(GeneratorAccess world, BlockPosition blockposition) { org.bukkit.block.Block block = CraftBlock.at(world, blockposition); BlockPhysicsEvent event = new BlockPhysicsEvent(block, block.getBlockData()); - if (isWorldGen(world)) return event; // Paper - do not call during world gen - Bukkit.getPluginManager().callEvent(event); // Paper + // Suppress during worldgen + if (world instanceof World) { + world.getMinecraftWorld().getMinecraftServer().server.getPluginManager().callEvent(event); + } return event; } @@ -1400,7 +1584,6 @@ public class CraftEventFactory { } EntityPotionEffectEvent event = new EntityPotionEffectEvent((LivingEntity) entity.getBukkitEntity(), bukkitOldEffect, bukkitNewEffect, cause, action, willOverride); - if (isWorldGen(entity.world)) return event; // Paper - do not call during world gen Bukkit.getPluginManager().callEvent(event); return event; @@ -1419,7 +1602,6 @@ public class CraftEventFactory { blockState.setData(block); BlockFormEvent event = (entity == null) ? new BlockFormEvent(blockState.getBlock(), blockState) : new EntityBlockFormEvent(entity.getBukkitEntity(), blockState.getBlock(), blockState); - if (isWorldGen(world)) return true; // Paper - do not call during world gen world.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { @@ -1440,4 +1622,40 @@ public class CraftEventFactory { Bukkit.getPluginManager().callEvent(event); return !event.isCancelled(); } + + public static EntityPickupItemEvent callEntityPickupItemEvent(Entity who, EntityItem item, int remaining, boolean cancelled) { + EntityPickupItemEvent event = new EntityPickupItemEvent((LivingEntity) who.getBukkitEntity(), (Item) item.getBukkitEntity(), remaining); + event.setCancelled(cancelled); + Bukkit.getPluginManager().callEvent(event); + return event; + } + + /** + * Raid events + */ + public static boolean callRaidTriggerEvent(Raid raid, EntityPlayer player) { + RaidTriggerEvent event = new RaidTriggerEvent(new CraftRaid(raid), raid.i().getWorld(), player.getBukkitEntity()); + Bukkit.getPluginManager().callEvent(event); + return !event.isCancelled(); + } + + public static void callRaidFinishEvent(Raid raid, List players) { + RaidFinishEvent event = new RaidFinishEvent(new CraftRaid(raid), raid.i().getWorld(), players); + Bukkit.getPluginManager().callEvent(event); + } + + public static void callRaidStopEvent(Raid raid, RaidStopEvent.Reason reason) { + RaidStopEvent event = new RaidStopEvent(new CraftRaid(raid), raid.i().getWorld(), reason); + Bukkit.getPluginManager().callEvent(event); + } + + public static void callRaidSpawnWaveEvent(Raid raid, EntityRaider leader, List raiders) { + Raider craftLeader = (CraftRaider) leader.getBukkitEntity(); + List craftRaiders = new ArrayList<>(); + for (EntityRaider entityRaider : raiders) { + craftRaiders.add((Raider) entityRaider.getBukkitEntity()); + } + RaidSpawnWaveEvent event = new RaidSpawnWaveEvent(new CraftRaid(raid), raid.i().getWorld(), craftLeader, craftRaiders); + Bukkit.getPluginManager().callEvent(event); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java index 29695da2e..4570ed999 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java @@ -159,7 +159,7 @@ public final class CraftChunkData implements ChunkGenerator.ChunkData { private ChunkSection getChunkSection(int y, boolean create) { ChunkSection section = sections[y >> 4]; if (create && section == null) { - sections[y >> 4] = section = new ChunkSection(y, create, null, world instanceof org.bukkit.craftbukkit.CraftWorld ? ((org.bukkit.craftbukkit.CraftWorld) world).getHandle() : null, true); // Paper - Anti-Xray + sections[y >> 4] = section = new ChunkSection(y, null, world instanceof org.bukkit.craftbukkit.CraftWorld ? ((org.bukkit.craftbukkit.CraftWorld) world).getHandle() : null, true); // Paper - Anti-Xray } return section; } diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java index 04c0adf7c..68d38655f 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java @@ -1,30 +1,46 @@ package org.bukkit.craftbukkit.generator; import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; -import it.unimi.dsi.fastutil.longs.LongSet; import java.util.List; -import java.util.Map; import java.util.Random; - -import net.minecraft.server.*; - +import net.minecraft.server.BiomeBase; +import net.minecraft.server.Block; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.ChunkSection; +import net.minecraft.server.EnumCreatureType; +import net.minecraft.server.GeneratorAccess; +import net.minecraft.server.GeneratorSettingsDefault; +import net.minecraft.server.HeightMap; +import net.minecraft.server.IChunkAccess; +import net.minecraft.server.ITileEntity; +import net.minecraft.server.MobSpawnerCat; +import net.minecraft.server.MobSpawnerPatrol; +import net.minecraft.server.MobSpawnerPhantom; +import net.minecraft.server.RegionLimitedWorldAccess; +import net.minecraft.server.StructureGenerator; +import net.minecraft.server.TileEntity; +import net.minecraft.server.VillageSiege; +import net.minecraft.server.World; +import net.minecraft.server.WorldGenFeatureConfiguration; +import net.minecraft.server.WorldGenStage; +import net.minecraft.server.WorldGenerator; +import net.minecraft.server.WorldServer; import org.bukkit.block.Biome; -import org.bukkit.generator.BlockPopulator; -import org.bukkit.generator.ChunkGenerator; import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.generator.ChunkGenerator.BiomeGrid; +import org.bukkit.generator.ChunkGenerator.ChunkData; public class CustomChunkGenerator extends InternalChunkGenerator { private final ChunkGenerator generator; private final WorldServer world; private final long seed; private final Random random; - public final boolean asyncSupported; // Paper - private final WorldChunkManager chunkManager; - private final WorldGenStronghold strongholdGen = new WorldGenStronghold(); - private final GeneratorSettingsDefault settings = new GeneratorSettingsDefault(); + private final StructureGenerator strongholdGen = WorldGenerator.STRONGHOLD; + private final MobSpawnerPhantom mobSpawnerPhantom = new MobSpawnerPhantom(); + private final MobSpawnerPatrol mobSpawnerPatrol = new MobSpawnerPatrol(); + private final MobSpawnerCat mobSpawnerCat = new MobSpawnerCat(); + private final VillageSiege villageSiege = new VillageSiege(); private static class CustomBiomeGrid implements BiomeGrid { BiomeBase[] biome; @@ -41,34 +57,33 @@ public class CustomChunkGenerator extends InternalChunkGenerator getDefaultPopulators(org.bukkit.World world) { - return generator.getDefaultPopulators(world); + public int getBaseHeight(int i, int j, HeightMap.Type heightmap_type) { + return 0; } @Override @@ -126,10 +139,6 @@ public class CustomChunkGenerator extends InternalChunkGenerator structuregenerator) { - return biomebase.b(structuregenerator); - } - - // Taken from ChunkGeneratorAbstract - private final Map, Long2ObjectMap> structureStartCache = Maps.newHashMap(); - - @Override - public Long2ObjectMap getStructureStartCache(StructureGenerator structuregenerator) { - return (Long2ObjectMap) this.structureStartCache.computeIfAbsent(structuregenerator, (s) -> { - return new ExpiringMap(8192, 10000); // Paper - already synchronized - }); - } - - // Taken from ChunkGeneratorAbstract - private final Map, Long2ObjectMap> structureCache = Maps.newHashMap(); - - @Override - public Long2ObjectMap getStructureCache(StructureGenerator structuregenerator) { - return (Long2ObjectMap) this.structureCache.computeIfAbsent(structuregenerator, (s) -> { - return new ExpiringMap(8192, 10000); // Paper - already synchronized - }); - } - - @Override - public WorldChunkManager getWorldChunkManager() { - return chunkManager; - } - @Override public long getSeed() { return seed; diff --git a/src/main/java/org/bukkit/craftbukkit/generator/InternalChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/InternalChunkGenerator.java index b0710cd82..d98b1be39 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/InternalChunkGenerator.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/InternalChunkGenerator.java @@ -1,8 +1,13 @@ package org.bukkit.craftbukkit.generator; -import net.minecraft.server.GeneratorSettings; -import org.bukkit.generator.ChunkGenerator; +import net.minecraft.server.GeneratorAccess; +import net.minecraft.server.GeneratorSettingsDefault; +import net.minecraft.server.WorldChunkManager; // Do not implement functions to this class, add to NormalChunkGenerator -public abstract class InternalChunkGenerator extends ChunkGenerator implements net.minecraft.server.ChunkGenerator { +public abstract class InternalChunkGenerator extends net.minecraft.server.ChunkGenerator { + + public InternalChunkGenerator(GeneratorAccess generatorAccess, WorldChunkManager worldChunkManager, C c0) { + super(generatorAccess, worldChunkManager, c0); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/generator/NetherChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/NetherChunkGenerator.java deleted file mode 100644 index 59d7bbec5..000000000 --- a/src/main/java/org/bukkit/craftbukkit/generator/NetherChunkGenerator.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bukkit.craftbukkit.generator; - -import net.minecraft.server.World; - -/** - * This class is useless. Just fyi. - */ -public class NetherChunkGenerator extends NormalChunkGenerator { - public NetherChunkGenerator(World world, long seed) { - super(world, seed); - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/generator/NormalChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/NormalChunkGenerator.java deleted file mode 100644 index 97a373771..000000000 --- a/src/main/java/org/bukkit/craftbukkit/generator/NormalChunkGenerator.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.bukkit.craftbukkit.generator; - -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.LongSet; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import net.minecraft.server.*; - -import org.bukkit.generator.BlockPopulator; - -public class NormalChunkGenerator extends InternalChunkGenerator { - private final World world; // Spigot - private final ChunkGenerator generator; - - public NormalChunkGenerator(World world, long seed) { - this.world = world; // Spigot - generator = world.worldProvider.getChunkGenerator(); - } - - @Override - public ChunkData generateChunkData(org.bukkit.World world, Random random, int x, int z, BiomeGrid biome) { - throw new UnsupportedOperationException("Not supported."); - } - - @Override - public boolean canSpawn(org.bukkit.World world, int x, int z) { - return true; // PAIL - } - - @Override - public List getDefaultPopulators(org.bukkit.World world) { - return new ArrayList(); - } - - @Override - public List getMobsFor(EnumCreatureType enumCreatureType, BlockPosition blockPosition) { - return generator.getMobsFor(enumCreatureType, blockPosition); - } - - @Override - public BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockPosition, int i, boolean flag) { - return generator.findNearestMapFeature(world, s, blockPosition, i, flag); - } - - @Override - public void createChunk(IChunkAccess ichunkaccess) { - generator.createChunk(ichunkaccess); - } - - @Override - public void addFeatures(RegionLimitedWorldAccess regionlimitedworldaccess, WorldGenStage.Features worldgenstage_features) { - generator.addFeatures(regionlimitedworldaccess, worldgenstage_features); - } - - @Override - public void addDecorations(RegionLimitedWorldAccess regionlimitedworldaccess) { - generator.addDecorations(regionlimitedworldaccess); - } - - @Override - public void addMobs(RegionLimitedWorldAccess regionlimitedworldaccess) { - generator.addMobs(regionlimitedworldaccess); - } - - @Override - public C getSettings() { - return (C) generator.getSettings(); - } - - @Override - public int a(World world, boolean flag, boolean flag1) { - return generator.a(world, flag, flag1); - } - - @Override - public boolean canSpawnStructure(BiomeBase biomebase, StructureGenerator structuregenerator) { - return generator.canSpawnStructure(biomebase, structuregenerator); - } - - @Override - public WorldGenFeatureConfiguration getFeatureConfiguration(BiomeBase biomebase, StructureGenerator structuregenerator) { - return generator.getFeatureConfiguration(biomebase, structuregenerator); - } - - @Override - public Long2ObjectMap getStructureStartCache(StructureGenerator structuregenerator) { - return generator.getStructureStartCache(structuregenerator); - } - - @Override - public Long2ObjectMap getStructureCache(StructureGenerator structuregenerator) { - return generator.getStructureCache(structuregenerator); - } - - @Override - public WorldChunkManager getWorldChunkManager() { - return generator.getWorldChunkManager(); - } - - @Override - public long getSeed() { - return generator.getSeed(); - } - - @Override - public int getSpawnHeight() { - return generator.getSpawnHeight(); - } - - @Override - public int getGenerationDepth() { - return generator.getGenerationDepth(); - } - - // Spigot start - @Override - public World getWorld() { - return this.world; - } - // Spigot end -} diff --git a/src/main/java/org/bukkit/craftbukkit/generator/SkyLandsChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/SkyLandsChunkGenerator.java deleted file mode 100644 index e32799694..000000000 --- a/src/main/java/org/bukkit/craftbukkit/generator/SkyLandsChunkGenerator.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.bukkit.craftbukkit.generator; - -import net.minecraft.server.World; - -/** - * This class is useless. Just fyi. - */ -public class SkyLandsChunkGenerator extends NormalChunkGenerator { - public SkyLandsChunkGenerator(World world, long seed) { - super(world, seed); - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/help/CustomHelpTopic.java b/src/main/java/org/bukkit/craftbukkit/help/CustomHelpTopic.java index 6dee2296f..78b91bb2b 100644 --- a/src/main/java/org/bukkit/craftbukkit/help/CustomHelpTopic.java +++ b/src/main/java/org/bukkit/craftbukkit/help/CustomHelpTopic.java @@ -17,6 +17,7 @@ public class CustomHelpTopic extends HelpTopic { this.fullText = shortText + "\n" + fullText; } + @Override public boolean canSee(CommandSender sender) { if (sender instanceof ConsoleCommandSender) { return true; diff --git a/src/main/java/org/bukkit/craftbukkit/help/CustomIndexHelpTopic.java b/src/main/java/org/bukkit/craftbukkit/help/CustomIndexHelpTopic.java index 2089a5f52..77134d74b 100644 --- a/src/main/java/org/bukkit/craftbukkit/help/CustomIndexHelpTopic.java +++ b/src/main/java/org/bukkit/craftbukkit/help/CustomIndexHelpTopic.java @@ -1,13 +1,12 @@ package org.bukkit.craftbukkit.help; -import org.bukkit.command.CommandSender; -import org.bukkit.help.HelpMap; -import org.bukkit.help.HelpTopic; -import org.bukkit.help.IndexHelpTopic; - import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import org.bukkit.command.CommandSender; +import org.bukkit.help.HelpMap; +import org.bukkit.help.HelpTopic; +import org.bukkit.help.IndexHelpTopic; /** */ diff --git a/src/main/java/org/bukkit/craftbukkit/help/HelpYamlReader.java b/src/main/java/org/bukkit/craftbukkit/help/HelpYamlReader.java index 60a6221b4..d3f17d4cd 100644 --- a/src/main/java/org/bukkit/craftbukkit/help/HelpYamlReader.java +++ b/src/main/java/org/bukkit/craftbukkit/help/HelpYamlReader.java @@ -1,19 +1,17 @@ package org.bukkit.craftbukkit.help; -import org.bukkit.ChatColor; -import org.bukkit.Server; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.help.HelpTopic; - import com.google.common.base.Charsets; - import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; +import org.bukkit.ChatColor; +import org.bukkit.Server; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.help.HelpTopic; /** * HelpYamlReader is responsible for processing the contents of the help.yml file. diff --git a/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopic.java b/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopic.java index 6f4b22b99..6133235c1 100644 --- a/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopic.java +++ b/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopic.java @@ -34,6 +34,7 @@ public class MultipleCommandAliasHelpTopic extends HelpTopic { fullText = ChatColor.GOLD + "Alias for: " + ChatColor.WHITE + getShortText(); } + @Override public boolean canSee(CommandSender sender) { if (amendedPermission == null) { if (sender instanceof ConsoleCommandSender) { diff --git a/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopicFactory.java b/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopicFactory.java index 36ddc9768..de3ed3c96 100644 --- a/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopicFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopicFactory.java @@ -9,6 +9,7 @@ import org.bukkit.help.HelpTopicFactory; */ public class MultipleCommandAliasHelpTopicFactory implements HelpTopicFactory { + @Override public HelpTopic createTopic(MultipleCommandAlias multipleCommandAlias) { return new MultipleCommandAliasHelpTopic(multipleCommandAlias); } diff --git a/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java b/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java index c7daccd5c..cbf9d190a 100644 --- a/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java +++ b/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java @@ -3,14 +3,28 @@ package org.bukkit.craftbukkit.help; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; - -import org.bukkit.command.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.MultipleCommandAlias; +import org.bukkit.command.PluginCommand; +import org.bukkit.command.PluginIdentifiableCommand; import org.bukkit.command.defaults.BukkitCommand; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.command.VanillaCommandWrapper; -import org.bukkit.help.*; - -import java.util.*; +import org.bukkit.help.GenericCommandHelpTopic; +import org.bukkit.help.HelpMap; +import org.bukkit.help.HelpTopic; +import org.bukkit.help.HelpTopicComparator; +import org.bukkit.help.HelpTopicFactory; +import org.bukkit.help.IndexHelpTopic; /** * Standard implementation of {@link HelpMap} for CraftBukkit servers. @@ -40,6 +54,7 @@ public class SimpleHelpMap implements HelpMap { registerHelpTopicFactory(MultipleCommandAlias.class, new MultipleCommandAliasHelpTopicFactory()); } + @Override public synchronized HelpTopic getHelpTopic(String topicName) { if (topicName.equals("")) { return defaultTopic; @@ -52,10 +67,12 @@ public class SimpleHelpMap implements HelpMap { return null; } + @Override public Collection getHelpTopics() { return helpTopics.values(); } + @Override public synchronized void addTopic(HelpTopic topic) { // Existing topics take priority if (!helpTopics.containsKey(topic.getName())) { @@ -63,10 +80,12 @@ public class SimpleHelpMap implements HelpMap { } } + @Override public synchronized void clear() { helpTopics.clear(); } + @Override public List getIgnoredPlugins() { return yaml.getIgnoredPlugins(); } @@ -202,6 +221,7 @@ public class SimpleHelpMap implements HelpMap { return false; } + @Override public void registerHelpTopicFactory(Class commandClass, HelpTopicFactory factory) { if (!Command.class.isAssignableFrom(commandClass) && !CommandExecutor.class.isAssignableFrom(commandClass)) { throw new IllegalArgumentException("commandClass must implement either Command or CommandExecutor!"); @@ -211,6 +231,7 @@ public class SimpleHelpMap implements HelpMap { private class IsCommandTopicPredicate implements Predicate { + @Override public boolean apply(HelpTopic topic) { return topic.getName().charAt(0) == '/'; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlastingRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlastingRecipe.java new file mode 100644 index 000000000..f6e32ca09 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlastingRecipe.java @@ -0,0 +1,30 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.MinecraftServer; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.BlastingRecipe; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.RecipeChoice; + +public class CraftBlastingRecipe extends BlastingRecipe implements CraftRecipe { + public CraftBlastingRecipe(NamespacedKey key, ItemStack result, RecipeChoice source, float experience, int cookingTime) { + super(key, result, source, experience, cookingTime); + } + + public static CraftBlastingRecipe fromBukkitRecipe(BlastingRecipe recipe) { + if (recipe instanceof CraftBlastingRecipe) { + return (CraftBlastingRecipe) recipe; + } + CraftBlastingRecipe ret = new CraftBlastingRecipe(recipe.getKey(), recipe.getResult(), recipe.getInputChoice(), recipe.getExperience(), recipe.getCookingTime()); + ret.setGroup(recipe.getGroup()); + return ret; + } + + @Override + public void addToCraftingManager() { + ItemStack result = this.getResult(); + + MinecraftServer.getServer().getCraftingManager().addRecipe(new net.minecraft.server.RecipeBlasting(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), toNMS(this.getInputChoice(), true), CraftItemStack.asNMSCopy(result), getExperience(), getCookingTime())); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java new file mode 100644 index 000000000..d5149c246 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java @@ -0,0 +1,30 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.GeneratorAccess; +import net.minecraft.server.IInventory; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.inventory.BlockInventoryHolder; +import org.bukkit.inventory.Inventory; + +public class CraftBlockInventoryHolder implements BlockInventoryHolder { + + private final Block block; + private final Inventory inventory; + + public CraftBlockInventoryHolder(GeneratorAccess world, BlockPosition pos, IInventory inv) { + this.block = CraftBlock.at(world, pos); + this.inventory = new CraftInventory(inv); + } + + @Override + public Block getBlock() { + return block; + } + + @Override + public Inventory getInventory() { + return inventory; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftCampfireRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftCampfireRecipe.java new file mode 100644 index 000000000..5c61cf965 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftCampfireRecipe.java @@ -0,0 +1,30 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.MinecraftServer; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.CampfireRecipe; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.RecipeChoice; + +public class CraftCampfireRecipe extends CampfireRecipe implements CraftRecipe { + public CraftCampfireRecipe(NamespacedKey key, ItemStack result, RecipeChoice source, float experience, int cookingTime) { + super(key, result, source, experience, cookingTime); + } + + public static CraftCampfireRecipe fromBukkitRecipe(CampfireRecipe recipe) { + if (recipe instanceof CraftCampfireRecipe) { + return (CraftCampfireRecipe) recipe; + } + CraftCampfireRecipe ret = new CraftCampfireRecipe(recipe.getKey(), recipe.getResult(), recipe.getInputChoice(), recipe.getExperience(), recipe.getCookingTime()); + ret.setGroup(recipe.getGroup()); + return ret; + } + + @Override + public void addToCraftingManager() { + ItemStack result = this.getResult(); + + MinecraftServer.getServer().getCraftingManager().addRecipe(new net.minecraft.server.RecipeCampfire(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), toNMS(this.getInputChoice(), true), CraftItemStack.asNMSCopy(result), getExperience(), getCookingTime())); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java index 4c71d9fea..ae119756b 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java @@ -1,29 +1,37 @@ package org.bukkit.craftbukkit.inventory; import net.minecraft.server.ChatComponentText; -import org.bukkit.craftbukkit.entity.CraftPlayer; -import org.bukkit.entity.HumanEntity; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; - import net.minecraft.server.Container; import net.minecraft.server.ContainerAnvil; import net.minecraft.server.ContainerBeacon; +import net.minecraft.server.ContainerBlastFurnace; import net.minecraft.server.ContainerBrewingStand; +import net.minecraft.server.ContainerCartography; import net.minecraft.server.ContainerChest; import net.minecraft.server.ContainerDispenser; import net.minecraft.server.ContainerEnchantTable; -import net.minecraft.server.ContainerFurnace; +import net.minecraft.server.ContainerFurnaceFurnace; +import net.minecraft.server.ContainerGrindstone; import net.minecraft.server.ContainerHopper; +import net.minecraft.server.ContainerLectern; +import net.minecraft.server.ContainerLoom; +import net.minecraft.server.ContainerProperties; import net.minecraft.server.ContainerShulkerBox; +import net.minecraft.server.ContainerSmoker; +import net.minecraft.server.ContainerStonecutter; import net.minecraft.server.ContainerWorkbench; +import net.minecraft.server.Containers; import net.minecraft.server.EntityHuman; import net.minecraft.server.IInventory; import net.minecraft.server.ItemStack; import net.minecraft.server.PacketPlayOutOpenWindow; import net.minecraft.server.PlayerInventory; import net.minecraft.server.Slot; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; public class CraftContainer extends Container { @@ -34,8 +42,8 @@ public class CraftContainer extends Container { private final int cachedSize; public CraftContainer(InventoryView view, EntityHuman player, int id) { + super(getNotchInventoryType(view.getType()), id); this.view = view; - this.windowId = id; // TODO: Do we need to check that it really is a CraftInventory? IInventory top = ((CraftInventory) view.getTopInventory()).getInventory(); PlayerInventory bottom = (PlayerInventory) ((CraftInventory) view.getBottomInventory()).getInventory(); @@ -66,6 +74,11 @@ public class CraftContainer extends Container { public InventoryType getType() { return inventory.getType(); } + + @Override + public String getTitle() { + return inventory instanceof CraftInventoryCustom ? ((CraftInventoryCustom.MinecraftInventory) ((CraftInventory) inventory).getInventory()).getTitle() : inventory.getType().getDefaultTitle(); + } }, player, id); } @@ -91,7 +104,7 @@ public class CraftContainer extends Container { cachedTitle = view.getTitle(); if (view.getPlayer() instanceof CraftPlayer) { CraftPlayer player = (CraftPlayer) view.getPlayer(); - String type = getNotchInventoryType(cachedType); + Containers type = getNotchInventoryType(cachedType); IInventory top = ((CraftInventory) view.getTopInventory()).getInventory(); PlayerInventory bottom = (PlayerInventory) ((CraftInventory) view.getBottomInventory()).getInventory(); this.items.clear(); @@ -100,75 +113,113 @@ public class CraftContainer extends Container { setupSlots(top, bottom, player.getHandle()); } int size = getSize(); - player.getHandle().playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.windowId, type, new ChatComponentText(cachedTitle), size)); + player.getHandle().playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.windowId, type, new ChatComponentText(cachedTitle))); player.updateInventory(); } return true; } - public static String getNotchInventoryType(InventoryType type) { + public static Containers getNotchInventoryType(InventoryType type) { switch (type) { case WORKBENCH: - return "minecraft:crafting_table"; + return Containers.CRAFTING; case FURNACE: - return "minecraft:furnace"; + return Containers.FURNACE; case DISPENSER: - return "minecraft:dispenser"; + return Containers.GENERIC_3X3; case ENCHANTING: - return "minecraft:enchanting_table"; + return Containers.ENCHANTMENT; case BREWING: - return "minecraft:brewing_stand"; + return Containers.BREWING_STAND; case BEACON: - return "minecraft:beacon"; + return Containers.BEACON; case ANVIL: - return "minecraft:anvil"; + return Containers.ANVIL; case HOPPER: - return "minecraft:hopper"; + return Containers.HOPPER; case DROPPER: - return "minecraft:dropper"; + return Containers.GENERIC_3X3; case SHULKER_BOX: - return "minecraft:shulker_box"; + return Containers.SHULKER_BOX; + case BLAST_FURNACE: + return Containers.BLAST_FURNACE; + case LECTERN: + return Containers.LECTERN; + case SMOKER: + return Containers.SMOKER; + case LOOM: + return Containers.LOOM; + case CARTOGRAPHY: + return Containers.CARTOGRAPHY; + case GRINDSTONE: + return Containers.GRINDSTONE; + case STONECUTTER: + return Containers.STONECUTTER; default: - return "minecraft:chest"; + return Containers.GENERIC_9X3; } } private void setupSlots(IInventory top, PlayerInventory bottom, EntityHuman entityhuman) { + int windowId = -1; switch (cachedType) { case CREATIVE: break; // TODO: This should be an error? case PLAYER: case CHEST: - delegate = new ContainerChest(bottom, top, entityhuman); + case ENDER_CHEST: + case BARREL: + delegate = new ContainerChest(Containers.GENERIC_9X3, windowId, bottom, top, top.getSize() / 9); break; case DISPENSER: case DROPPER: - delegate = new ContainerDispenser(bottom, top); + delegate = new ContainerDispenser(windowId, bottom, top); break; case FURNACE: - delegate = new ContainerFurnace(bottom, top); + delegate = new ContainerFurnaceFurnace(windowId, bottom, top, new ContainerProperties(4)); break; case CRAFTING: // TODO: This should be an error? case WORKBENCH: setupWorkbench(top, bottom); // SPIGOT-3812 - manually set up slots so we can use the delegated inventory and not the automatically created one break; case ENCHANTING: - delegate = new ContainerEnchantTable(bottom, entityhuman.world, entityhuman.getChunkCoordinates()); + delegate = new ContainerEnchantTable(windowId, bottom); break; case BREWING: - delegate = new ContainerBrewingStand(bottom, top); + delegate = new ContainerBrewingStand(windowId, bottom, top, new ContainerProperties(2)); break; case HOPPER: - delegate = new ContainerHopper(bottom, top, entityhuman); + delegate = new ContainerHopper(windowId, bottom, top); break; case ANVIL: - delegate = new ContainerAnvil(bottom, entityhuman.world, entityhuman.getChunkCoordinates(), entityhuman); + delegate = new ContainerAnvil(windowId, bottom); break; case BEACON: - delegate = new ContainerBeacon(bottom, top); + delegate = new ContainerBeacon(windowId, bottom); break; case SHULKER_BOX: - delegate = new ContainerShulkerBox(bottom, top, entityhuman); + delegate = new ContainerShulkerBox(windowId, bottom, top); + break; + case BLAST_FURNACE: + delegate = new ContainerBlastFurnace(windowId, bottom, top, new ContainerProperties(4)); + break; + case LECTERN: + delegate = new ContainerLectern(windowId, top, new ContainerProperties(1), bottom); + break; + case SMOKER: + delegate = new ContainerSmoker(windowId, bottom, top, new ContainerProperties(4)); + break; + case LOOM: + delegate = new ContainerLoom(windowId, bottom); + break; + case CARTOGRAPHY: + delegate = new ContainerCartography(windowId, bottom); + break; + case GRINDSTONE: + delegate = new ContainerGrindstone(windowId, bottom); + break; + case STONECUTTER: + delegate = new ContainerStonecutter(windowId, bottom); break; } @@ -179,7 +230,7 @@ public class CraftContainer extends Container { // SPIGOT-4598 - we should still delegate the shift click handler if (cachedType == InventoryType.WORKBENCH) { - delegate = new ContainerWorkbench(bottom, entityhuman.world, entityhuman.getChunkCoordinates()); + delegate = new ContainerWorkbench(windowId, bottom); } } @@ -217,4 +268,9 @@ public class CraftContainer extends Container { public boolean canUse(EntityHuman entity) { return true; } + + @Override + public Containers getType() { + return getNotchInventoryType(cachedType); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java index 3ed9e2bb0..3eb2402e7 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.inventory; import net.minecraft.server.EntityInsentient; import net.minecraft.server.EnumItemSlot; - import org.bukkit.craftbukkit.entity.CraftLivingEntity; import org.bukkit.entity.Entity; import org.bukkit.inventory.EntityEquipment; @@ -46,38 +45,47 @@ public class CraftEntityEquipment implements EntityEquipment { setItemInMainHand(stack); } + @Override public ItemStack getHelmet() { return getEquipment(EnumItemSlot.HEAD); } + @Override public void setHelmet(ItemStack helmet) { setEquipment(EnumItemSlot.HEAD, helmet); } + @Override public ItemStack getChestplate() { return getEquipment(EnumItemSlot.CHEST); } + @Override public void setChestplate(ItemStack chestplate) { setEquipment(EnumItemSlot.CHEST, chestplate); } + @Override public ItemStack getLeggings() { return getEquipment(EnumItemSlot.LEGS); } + @Override public void setLeggings(ItemStack leggings) { setEquipment(EnumItemSlot.LEGS, leggings); } + @Override public ItemStack getBoots() { return getEquipment(EnumItemSlot.FEET); } + @Override public void setBoots(ItemStack boots) { setEquipment(EnumItemSlot.FEET, boots); } + @Override public ItemStack[] getArmorContents() { ItemStack[] armor = new ItemStack[]{ getEquipment(EnumItemSlot.FEET), @@ -88,6 +96,7 @@ public class CraftEntityEquipment implements EntityEquipment { return armor; } + @Override public void setArmorContents(ItemStack[] items) { setEquipment(EnumItemSlot.FEET, items.length >= 1 ? items[0] : null); setEquipment(EnumItemSlot.LEGS, items.length >= 2 ? items[1] : null); @@ -103,12 +112,14 @@ public class CraftEntityEquipment implements EntityEquipment { entity.getHandle().setSlot(slot, CraftItemStack.asNMSCopy(stack)); } + @Override public void clear() { for (EnumItemSlot slot : EnumItemSlot.values()) { setEquipment(slot, null); } } + @Override public Entity getHolder() { return entity; } @@ -143,51 +154,59 @@ public class CraftEntityEquipment implements EntityEquipment { setDropChance(EnumItemSlot.OFFHAND, chance); } + @Override public float getHelmetDropChance() { return getDropChance(EnumItemSlot.HEAD); } + @Override public void setHelmetDropChance(float chance) { setDropChance(EnumItemSlot.HEAD, chance); } + @Override public float getChestplateDropChance() { return getDropChance(EnumItemSlot.CHEST); } + @Override public void setChestplateDropChance(float chance) { setDropChance(EnumItemSlot.CHEST, chance); } + @Override public float getLeggingsDropChance() { return getDropChance(EnumItemSlot.LEGS); } + @Override public void setLeggingsDropChance(float chance) { setDropChance(EnumItemSlot.LEGS, chance); } + @Override public float getBootsDropChance() { return getDropChance(EnumItemSlot.FEET); } + @Override public void setBootsDropChance(float chance) { setDropChance(EnumItemSlot.FEET, chance); } private void setDropChance(EnumItemSlot slot, float chance) { if (slot == EnumItemSlot.MAINHAND || slot == EnumItemSlot.OFFHAND) { - ((EntityInsentient) entity.getHandle()).dropChanceHand[slot.b()] = chance - 0.1F; + ((EntityInsentient) entity.getHandle()).dropChanceHand[slot.b()] = chance; } else { - ((EntityInsentient) entity.getHandle()).dropChanceArmor[slot.b()] = chance - 0.1F; + ((EntityInsentient) entity.getHandle()).dropChanceArmor[slot.b()] = chance; } } private float getDropChance(EnumItemSlot slot) { if (slot == EnumItemSlot.MAINHAND || slot == EnumItemSlot.OFFHAND) { - return ((EntityInsentient) entity.getHandle()).dropChanceHand[slot.b()] + 0.1F; + return ((EntityInsentient) entity.getHandle()).dropChanceHand[slot.b()]; } else { - return ((EntityInsentient) entity.getHandle()).dropChanceArmor[slot.b()] + 0.1F; + return ((EntityInsentient) entity.getHandle()).dropChanceArmor[slot.b()]; } } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java index a38d08a15..fddae1a78 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java @@ -25,6 +25,6 @@ public class CraftFurnaceRecipe extends FurnaceRecipe implements CraftRecipe { public void addToCraftingManager() { ItemStack result = this.getResult(); - MinecraftServer.getServer().getCraftingManager().a(new net.minecraft.server.FurnaceRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), toNMS(this.getInputChoice(), true), CraftItemStack.asNMSCopy(result), getExperience(), getCookingTime())); + MinecraftServer.getServer().getCraftingManager().addRecipe(new net.minecraft.server.FurnaceRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), toNMS(this.getInputChoice(), true), CraftItemStack.asNMSCopy(result), getExperience(), getCookingTime())); } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java index 01af98293..026a0c399 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java @@ -3,30 +3,30 @@ package org.bukkit.craftbukkit.inventory; import java.util.HashMap; import java.util.List; import java.util.ListIterator; - import net.minecraft.server.IHopper; import net.minecraft.server.IInventory; import net.minecraft.server.InventoryCrafting; import net.minecraft.server.InventoryEnderChest; import net.minecraft.server.InventoryMerchant; import net.minecraft.server.PlayerInventory; -import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.TileEntityBarrel; +import net.minecraft.server.TileEntityBlastFurnace; import net.minecraft.server.TileEntityBrewingStand; import net.minecraft.server.TileEntityDispenser; import net.minecraft.server.TileEntityDropper; import net.minecraft.server.TileEntityFurnace; +import net.minecraft.server.TileEntityLectern; import net.minecraft.server.TileEntityShulkerBox; - +import net.minecraft.server.TileEntitySmoker; import org.apache.commons.lang.Validate; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.craftbukkit.util.CraftLegacy; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; -import org.bukkit.Material; -import org.bukkit.craftbukkit.util.CraftChatMessage; -import org.bukkit.craftbukkit.util.CraftLegacy; public class CraftInventory implements Inventory { protected final IInventory inventory; @@ -39,14 +39,12 @@ public class CraftInventory implements Inventory { return inventory; } + @Override public int getSize() { return getInventory().getSize(); } - public String getName() { - return CraftChatMessage.fromComponent(getInventory().getDisplayName()); - } - + @Override public ItemStack getItem(int index) { net.minecraft.server.ItemStack item = getInventory().getItem(index); return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item); @@ -74,12 +72,14 @@ public class CraftInventory implements Inventory { setContents(items); } + @Override public ItemStack[] getContents() { List mcItems = getInventory().getContents(); return asCraftMirror(mcItems); } + @Override public void setContents(ItemStack[] items) { if (getSize() < items.length) { throw new IllegalArgumentException("Invalid inventory size; expected " + getSize() + " or less"); @@ -94,10 +94,12 @@ public class CraftInventory implements Inventory { } } + @Override public void setItem(int index, ItemStack item) { getInventory().setItem(index, CraftItemStack.asNMSCopy(item)); } + @Override public boolean contains(Material material) { Validate.notNull(material, "Material cannot be null"); material = CraftLegacy.fromLegacy(material); @@ -109,6 +111,7 @@ public class CraftInventory implements Inventory { return false; } + @Override public boolean contains(ItemStack item) { if (item == null) { return false; @@ -121,6 +124,7 @@ public class CraftInventory implements Inventory { return false; } + @Override public boolean contains(Material material, int amount) { Validate.notNull(material, "Material cannot be null"); material = CraftLegacy.fromLegacy(material); @@ -137,6 +141,7 @@ public class CraftInventory implements Inventory { return false; } + @Override public boolean contains(ItemStack item, int amount) { if (item == null) { return false; @@ -152,6 +157,7 @@ public class CraftInventory implements Inventory { return false; } + @Override public boolean containsAtLeast(ItemStack item, int amount) { if (item == null) { return false; @@ -167,6 +173,7 @@ public class CraftInventory implements Inventory { return false; } + @Override public HashMap all(Material material) { Validate.notNull(material, "Material cannot be null"); material = CraftLegacy.fromLegacy(material); @@ -182,6 +189,7 @@ public class CraftInventory implements Inventory { return slots; } + @Override public HashMap all(ItemStack item) { HashMap slots = new HashMap(); if (item != null) { @@ -195,6 +203,7 @@ public class CraftInventory implements Inventory { return slots; } + @Override public int first(Material material) { Validate.notNull(material, "Material cannot be null"); material = CraftLegacy.fromLegacy(material); @@ -208,6 +217,7 @@ public class CraftInventory implements Inventory { return -1; } + @Override public int first(ItemStack item) { return first(item, true); } @@ -233,6 +243,7 @@ public class CraftInventory implements Inventory { return -1; } + @Override public int firstEmpty() { ItemStack[] inventory = getStorageContents(); for (int i = 0; i < inventory.length; i++) { @@ -271,6 +282,7 @@ public class CraftInventory implements Inventory { return -1; } + @Override public HashMap addItem(ItemStack... items) { Validate.noNullElements(items, "Item cannot be null"); HashMap leftover = new HashMap(); @@ -336,6 +348,7 @@ public class CraftInventory implements Inventory { return leftover; } + @Override public HashMap removeItem(ItemStack... items) { // Paper start return removeItem(false, items); @@ -397,6 +410,7 @@ public class CraftInventory implements Inventory { return getInventory().getMaxStackSize(); } + @Override public void remove(Material material) { Validate.notNull(material, "Material cannot be null"); material = CraftLegacy.fromLegacy(material); @@ -408,6 +422,7 @@ public class CraftInventory implements Inventory { } } + @Override public void remove(ItemStack item) { ItemStack[] items = getStorageContents(); for (int i = 0; i < items.length; i++) { @@ -417,20 +432,24 @@ public class CraftInventory implements Inventory { } } + @Override public void clear(int index) { setItem(index, null); } + @Override public void clear() { for (int i = 0; i < getSize(); i++) { clear(i); } } + @Override public ListIterator iterator() { return new InventoryIterator(this); } + @Override public ListIterator iterator(int index) { if (index < 0) { index += getSize() + 1; // ie, with -1, previous() will return the last element @@ -438,16 +457,14 @@ public class CraftInventory implements Inventory { return new InventoryIterator(this, index); } + @Override public List getViewers() { return this.inventory.getViewers(); } - public String getTitle() { - return getName(); - } - + @Override public InventoryType getType() { - // Thanks to Droppers extending Dispensers, order is important. + // Thanks to Droppers extending Dispensers, Blast Furnaces & Smokers extending Furnace, order is important. if (inventory instanceof InventoryCrafting) { return inventory.getSize() >= 9 ? InventoryType.WORKBENCH : InventoryType.CRAFTING; } else if (inventory instanceof PlayerInventory) { @@ -456,6 +473,10 @@ public class CraftInventory implements Inventory { return InventoryType.DROPPER; } else if (inventory instanceof TileEntityDispenser) { return InventoryType.DISPENSER; + } else if (inventory instanceof TileEntityBlastFurnace) { + return InventoryType.BLAST_FURNACE; + } else if (inventory instanceof TileEntitySmoker) { + return InventoryType.SMOKER; } else if (inventory instanceof TileEntityFurnace) { return InventoryType.FURNACE; } else if (this instanceof CraftInventoryEnchanting) { @@ -468,7 +489,7 @@ public class CraftInventory implements Inventory { return InventoryType.ENDER_CHEST; } else if (inventory instanceof InventoryMerchant) { return InventoryType.MERCHANT; - } else if (inventory instanceof TileEntityBeacon) { + } else if (this instanceof CraftInventoryBeacon) { return InventoryType.BEACON; } else if (this instanceof CraftInventoryAnvil) { return InventoryType.ANVIL; @@ -476,19 +497,34 @@ public class CraftInventory implements Inventory { return InventoryType.HOPPER; } else if (inventory instanceof TileEntityShulkerBox) { return InventoryType.SHULKER_BOX; + } else if (inventory instanceof TileEntityBarrel) { + return InventoryType.BARREL; + } else if (inventory instanceof TileEntityLectern.LecternInventory) { + return InventoryType.LECTERN; + } else if (this instanceof CraftInventoryLoom) { + return InventoryType.LOOM; + } else if (this instanceof CraftInventoryCartography) { + return InventoryType.CARTOGRAPHY; + } else if (this instanceof CraftInventoryGrindstone) { + return InventoryType.GRINDSTONE; + } else if (this instanceof CraftInventoryStonecutter) { + return InventoryType.STONECUTTER; } else { return InventoryType.CHEST; } } + @Override public InventoryHolder getHolder() { return inventory.getOwner(); } + @Override public int getMaxStackSize() { return inventory.getMaxStackSize(); } + @Override public void setMaxStackSize(int size) { inventory.setMaxStackSize(size); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java index ca19600da..9374c2706 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java @@ -5,54 +5,18 @@ import net.minecraft.server.ContainerAnvil; import net.minecraft.server.IInventory; import org.bukkit.Location; import org.bukkit.inventory.AnvilInventory; -import org.bukkit.inventory.ItemStack; -public class CraftInventoryAnvil extends CraftInventory implements AnvilInventory { +public class CraftInventoryAnvil extends CraftResultInventory implements AnvilInventory { private final Location location; - private final IInventory resultInventory; private final ContainerAnvil container; public CraftInventoryAnvil(Location location, IInventory inventory, IInventory resultInventory, ContainerAnvil container) { - super(inventory); + super(inventory, resultInventory); this.location = location; - this.resultInventory = resultInventory; this.container = container; } - public IInventory getResultInventory() { - return resultInventory; - } - - public IInventory getIngredientsInventory() { - return inventory; - } - - @Override - public ItemStack getItem(int slot) { - if (slot < getIngredientsInventory().getSize()) { - net.minecraft.server.ItemStack item = getIngredientsInventory().getItem(slot); - return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item); - } else { - net.minecraft.server.ItemStack item = getResultInventory().getItem(slot - getIngredientsInventory().getSize()); - return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item); - } - } - - @Override - public void setItem(int index, ItemStack item) { - if (index < getIngredientsInventory().getSize()) { - getIngredientsInventory().setItem(index, CraftItemStack.asNMSCopy(item)); - } else { - getResultInventory().setItem((index - getIngredientsInventory().getSize()), CraftItemStack.asNMSCopy(item)); - } - } - - @Override - public int getSize() { - return getResultInventory().getSize() + getIngredientsInventory().getSize(); - } - @Override public Location getLocation() { return location; @@ -65,12 +29,12 @@ public class CraftInventoryAnvil extends CraftInventory implements AnvilInventor @Override public int getRepairCost() { - return container.levelCost; + return container.levelCost.get(); } @Override public void setRepairCost(int i) { - container.levelCost = i; + container.levelCost.set(i); } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBeacon.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBeacon.java index 43c4107c6..163c572ca 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBeacon.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBeacon.java @@ -1,18 +1,20 @@ package org.bukkit.craftbukkit.inventory; -import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.IInventory; import org.bukkit.inventory.BeaconInventory; import org.bukkit.inventory.ItemStack; public class CraftInventoryBeacon extends CraftInventory implements BeaconInventory { - public CraftInventoryBeacon(TileEntityBeacon beacon) { + public CraftInventoryBeacon(IInventory beacon) { super(beacon); } + @Override public void setItem(ItemStack item) { setItem(0, item); } + @Override public ItemStack getItem() { return getItem(0); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBrewer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBrewer.java index 86c89e869..5fa833041 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBrewer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBrewer.java @@ -1,20 +1,21 @@ package org.bukkit.craftbukkit.inventory; +import net.minecraft.server.IInventory; import org.bukkit.block.BrewingStand; import org.bukkit.inventory.BrewerInventory; import org.bukkit.inventory.ItemStack; -import net.minecraft.server.IInventory; - public class CraftInventoryBrewer extends CraftInventory implements BrewerInventory { public CraftInventoryBrewer(IInventory inventory) { super(inventory); } + @Override public ItemStack getIngredient() { return getItem(3); } + @Override public void setIngredient(ItemStack ingredient) { setItem(3, ingredient); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCartography.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCartography.java new file mode 100644 index 000000000..9458de90e --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCartography.java @@ -0,0 +1,11 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.IInventory; +import org.bukkit.inventory.CartographyInventory; + +public class CraftInventoryCartography extends CraftResultInventory implements CartographyInventory { + + public CraftInventoryCartography(IInventory inventory, IInventory resultInventory) { + super(inventory, resultInventory); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java index 3a375e77d..25eff35e0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java @@ -2,10 +2,8 @@ package org.bukkit.craftbukkit.inventory; import java.util.Arrays; import java.util.List; - -import net.minecraft.server.IRecipe; import net.minecraft.server.IInventory; - +import net.minecraft.server.IRecipe; import org.bukkit.inventory.CraftingInventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; @@ -83,18 +81,21 @@ public class CraftInventoryCrafting extends CraftInventory implements CraftingIn } } + @Override public ItemStack[] getMatrix() { List matrix = getMatrixInventory().getContents(); return asCraftMirror(matrix); } + @Override public ItemStack getResult() { net.minecraft.server.ItemStack item = getResultInventory().getItem(0); if (!item.isEmpty()) return CraftItemStack.asCraftMirror(item); return null; } + @Override public void setMatrix(ItemStack[] contents) { if (getMatrixInventory().getSize() > contents.length) { throw new IllegalArgumentException("Invalid inventory size; expected " + getMatrixInventory().getSize() + " or less"); @@ -109,11 +110,13 @@ public class CraftInventoryCrafting extends CraftInventory implements CraftingIn } } + @Override public void setResult(ItemStack item) { List contents = getResultInventory().getContents(); contents.set(0, CraftItemStack.asNMSCopy(item)); } + @Override public Recipe getRecipe() { IRecipe recipe = getInventory().getCurrentRecipe(); return recipe == null ? null : recipe.toBukkitRecipe(); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java index 6e17b4fd9..c7f942454 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java @@ -3,9 +3,10 @@ package org.bukkit.craftbukkit.inventory; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import net.minecraft.server.ChatComponentText; - -import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.EntityHuman; +import net.minecraft.server.IInventory; +import net.minecraft.server.ItemStack; +import net.minecraft.server.NonNullList; import org.apache.commons.lang.Validate; import org.bukkit.Location; import org.bukkit.craftbukkit.entity.CraftHumanEntity; @@ -13,12 +14,6 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.InventoryHolder; -import net.minecraft.server.EntityHuman; -import net.minecraft.server.IInventory; -import net.minecraft.server.ItemStack; -import net.minecraft.server.NonNullList; -import org.bukkit.craftbukkit.util.CraftChatMessage; - public class CraftInventoryCustom extends CraftInventory { public CraftInventoryCustom(InventoryHolder owner, InventoryType type) { super(new MinecraftInventory(owner, type)); @@ -40,7 +35,7 @@ public class CraftInventoryCustom extends CraftInventory { private final NonNullList items; private int maxStack = MAX_STACK; private final List viewers; - private final IChatBaseComponent title; + private final String title; private InventoryType type; private final InventoryHolder owner; @@ -61,20 +56,23 @@ public class CraftInventoryCustom extends CraftInventory { public MinecraftInventory(InventoryHolder owner, int size, String title) { Validate.notNull(title, "Title cannot be null"); this.items = NonNullList.a(size, ItemStack.a); - this.title = CraftChatMessage.fromString(title)[0]; + this.title = title; this.viewers = new ArrayList(); this.owner = owner; this.type = InventoryType.CHEST; } + @Override public int getSize() { return items.size(); } + @Override public ItemStack getItem(int i) { return items.get(i); } + @Override public ItemStack splitStack(int i, int j) { ItemStack stack = this.getItem(i); ItemStack result; @@ -90,6 +88,7 @@ public class CraftInventoryCustom extends CraftInventory { return result; } + @Override public ItemStack splitWithoutUpdate(int i) { ItemStack stack = this.getItem(i); ItemStack result; @@ -104,6 +103,7 @@ public class CraftInventoryCustom extends CraftInventory { return result; } + @Override public void setItem(int i, ItemStack itemstack) { items.set(i, itemstack); if (itemstack != ItemStack.a && this.getMaxStackSize() > 0 && itemstack.getCount() > this.getMaxStackSize()) { @@ -111,32 +111,40 @@ public class CraftInventoryCustom extends CraftInventory { } } + @Override public int getMaxStackSize() { return maxStack; } + @Override public void setMaxStackSize(int size) { maxStack = size; } + @Override public void update() {} + @Override public boolean a(EntityHuman entityhuman) { return true; } + @Override public List getContents() { return items; } + @Override public void onOpen(CraftHumanEntity who) { viewers.add(who); } + @Override public void onClose(CraftHumanEntity who) { viewers.remove(who); } + @Override public List getViewers() { return viewers; } @@ -145,10 +153,12 @@ public class CraftInventoryCustom extends CraftInventory { return type; } + @Override public InventoryHolder getOwner() { return owner; } + @Override public boolean b(int i, ItemStack itemstack) { return true; } @@ -163,52 +173,22 @@ public class CraftInventoryCustom extends CraftInventory { } - @Override - public int getProperty(int i) { - return 0; - } - - @Override - public void setProperty(int i, int j) { - } - - @Override - public int h() { - return 0; - } - @Override public void clear() { items.clear(); } - @Override - public IChatBaseComponent getDisplayName() { - return title; - } - - @Override - public IChatBaseComponent getCustomName() { - return title; - } - - @Override - public boolean hasCustomName() { - return title != null; - } - - @Override - public IChatBaseComponent getScoreboardDisplayName() { - return title; - } - @Override public Location getLocation() { return null; } + public String getTitle() { + return title; + } + @Override - public boolean P_() { + public boolean isNotEmpty() { Iterator iterator = this.items.iterator(); ItemStack itemstack; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryDoubleChest.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryDoubleChest.java index 799f8ea5d..e917db0b0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryDoubleChest.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryDoubleChest.java @@ -1,23 +1,24 @@ package org.bukkit.craftbukkit.inventory; -import net.minecraft.server.ChatMessage; +import net.minecraft.server.BlockChest; import net.minecraft.server.ITileInventory; +import net.minecraft.server.InventoryLargeChest; +import org.bukkit.Location; import org.bukkit.block.DoubleChest; import org.bukkit.inventory.DoubleChestInventory; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import net.minecraft.server.InventoryLargeChest; -import org.bukkit.Location; - public class CraftInventoryDoubleChest extends CraftInventory implements DoubleChestInventory { + public ITileInventory tile; private final CraftInventory left; private final CraftInventory right; - public CraftInventoryDoubleChest(CraftInventory left, CraftInventory right) { - super(new InventoryLargeChest(new ChatMessage("container.chestDouble"), (ITileInventory) left.getInventory(), (ITileInventory) right.getInventory())); - this.left = left; - this.right = right; + public CraftInventoryDoubleChest(BlockChest.DoubleInventory block) { + super(block.inventorylargechest); + this.tile = block; + this.left = new CraftInventory(block.inventorylargechest.left); + this.right = new CraftInventory(block.inventorylargechest.right); } public CraftInventoryDoubleChest(InventoryLargeChest largeChest) { @@ -34,10 +35,12 @@ public class CraftInventoryDoubleChest extends CraftInventory implements DoubleC } } + @Override public Inventory getLeftSide() { return left; } + @Override public Inventory getRightSide() { return right; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java index 37a631ebe..043012545 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java @@ -1,36 +1,41 @@ package org.bukkit.craftbukkit.inventory; +import net.minecraft.server.TileEntityFurnace; import org.bukkit.block.Furnace; import org.bukkit.inventory.FurnaceInventory; import org.bukkit.inventory.ItemStack; -import net.minecraft.server.TileEntityFurnace; - public class CraftInventoryFurnace extends CraftInventory implements FurnaceInventory { public CraftInventoryFurnace(TileEntityFurnace inventory) { super(inventory); } + @Override public ItemStack getResult() { return getItem(2); } + @Override public ItemStack getFuel() { return getItem(1); } + @Override public ItemStack getSmelting() { return getItem(0); } + @Override public void setFuel(ItemStack stack) { setItem(1,stack); } + @Override public void setResult(ItemStack stack) { setItem(2,stack); } + @Override public void setSmelting(ItemStack stack) { setItem(0,stack); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryGrindstone.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryGrindstone.java new file mode 100644 index 000000000..ce89ce764 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryGrindstone.java @@ -0,0 +1,11 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.IInventory; +import org.bukkit.inventory.GrindstoneInventory; + +public class CraftInventoryGrindstone extends CraftResultInventory implements GrindstoneInventory { + + public CraftInventoryGrindstone(IInventory inventory, IInventory resultInventory) { + super(inventory, resultInventory); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java index 2f6852404..9a47a1adc 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java @@ -10,10 +10,12 @@ public class CraftInventoryHorse extends CraftSaddledInventory implements HorseI super(inventory); } + @Override public ItemStack getArmor() { return getItem(1); } + @Override public void setArmor(ItemStack stack) { setItem(1, stack); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLectern.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLectern.java new file mode 100644 index 000000000..f60ed85ef --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLectern.java @@ -0,0 +1,17 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.IInventory; +import org.bukkit.block.Lectern; +import org.bukkit.inventory.LecternInventory; + +public class CraftInventoryLectern extends CraftInventory implements LecternInventory { + + public CraftInventoryLectern(IInventory inventory) { + super(inventory); + } + + @Override + public Lectern getHolder() { + return (Lectern) inventory.getOwner(); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLoom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLoom.java new file mode 100644 index 000000000..d3c541799 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryLoom.java @@ -0,0 +1,11 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.IInventory; +import org.bukkit.inventory.LoomInventory; + +public class CraftInventoryLoom extends CraftResultInventory implements LoomInventory { + + public CraftInventoryLoom(IInventory inventory, IInventory resultInventory) { + super(inventory, resultInventory); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryMerchant.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryMerchant.java index 10b125300..3b40adcf5 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryMerchant.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryMerchant.java @@ -1,13 +1,18 @@ package org.bukkit.craftbukkit.inventory; +import net.minecraft.server.IMerchant; import net.minecraft.server.InventoryMerchant; +import org.bukkit.inventory.Merchant; import org.bukkit.inventory.MerchantInventory; import org.bukkit.inventory.MerchantRecipe; public class CraftInventoryMerchant extends CraftInventory implements MerchantInventory { - public CraftInventoryMerchant(InventoryMerchant merchant) { - super(merchant); + private final IMerchant merchant; + + public CraftInventoryMerchant(IMerchant merchant, InventoryMerchant inventory) { + super(inventory); + this.merchant = merchant; } @Override @@ -25,4 +30,9 @@ public class CraftInventoryMerchant extends CraftInventory implements MerchantIn public InventoryMerchant getInventory() { return (InventoryMerchant) inventory; } + + @Override + public Merchant getMerchant() { + return merchant.getCraftMerchant(); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java index 60446f247..ef4cd7a7b 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -5,7 +5,6 @@ import net.minecraft.server.EntityPlayer; import net.minecraft.server.PacketPlayOutHeldItemSlot; import net.minecraft.server.PacketPlayOutSetSlot; import net.minecraft.server.PlayerInventory; - import org.apache.commons.lang.Validate; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.HumanEntity; @@ -103,48 +102,59 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i player.playerConnection.sendPacket(new PacketPlayOutSetSlot(player.defaultContainer.windowId, index, CraftItemStack.asNMSCopy(item))); } + @Override public int getHeldItemSlot() { return getInventory().itemInHandIndex; } + @Override public void setHeldItemSlot(int slot) { Validate.isTrue(slot >= 0 && slot < PlayerInventory.getHotbarSize(), "Slot is not between 0 and 8 inclusive"); this.getInventory().itemInHandIndex = slot; ((CraftPlayer) this.getHolder()).getHandle().playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(slot)); } + @Override public ItemStack getHelmet() { return getItem(getSize() - 2); } + @Override public ItemStack getChestplate() { return getItem(getSize() - 3); } + @Override public ItemStack getLeggings() { return getItem(getSize() - 4); } + @Override public ItemStack getBoots() { return getItem(getSize() - 5); } + @Override public void setHelmet(ItemStack helmet) { setItem(getSize() - 2, helmet); } + @Override public void setChestplate(ItemStack chestplate) { setItem(getSize() - 3, chestplate); } + @Override public void setLeggings(ItemStack leggings) { setItem(getSize() - 4, leggings); } + @Override public void setBoots(ItemStack boots) { setItem(getSize() - 5, boots); } + @Override public ItemStack[] getArmorContents() { return asCraftMirror(getInventory().armor); } @@ -219,34 +229,42 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i throw new UnsupportedOperationException("Cannot set drop chance for PlayerInventory"); } + @Override public float getHelmetDropChance() { return 1; } + @Override public void setHelmetDropChance(float chance) { throw new UnsupportedOperationException("Cannot set drop chance for PlayerInventory"); } + @Override public float getChestplateDropChance() { return 1; } + @Override public void setChestplateDropChance(float chance) { throw new UnsupportedOperationException("Cannot set drop chance for PlayerInventory"); } + @Override public float getLeggingsDropChance() { return 1; } + @Override public void setLeggingsDropChance(float chance) { throw new UnsupportedOperationException("Cannot set drop chance for PlayerInventory"); } + @Override public float getBootsDropChance() { return 1; } + @Override public void setBootsDropChance(float chance) { throw new UnsupportedOperationException("Cannot set drop chance for PlayerInventory"); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryStonecutter.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryStonecutter.java new file mode 100644 index 000000000..e4135b679 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryStonecutter.java @@ -0,0 +1,11 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.IInventory; +import org.bukkit.inventory.StonecutterInventory; + +public class CraftInventoryStonecutter extends CraftResultInventory implements StonecutterInventory { + + public CraftInventoryStonecutter(IInventory inventory, IInventory resultInventory) { + super(inventory, resultInventory); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java index ac2335091..4c6492a92 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java @@ -1,16 +1,15 @@ package org.bukkit.craftbukkit.inventory; +import net.minecraft.server.Container; import org.bukkit.GameMode; import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryType; -import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.ItemStack; -import net.minecraft.server.Container; - public class CraftInventoryView extends InventoryView { private final Container container; private final CraftHumanEntity player; @@ -65,6 +64,11 @@ public class CraftInventoryView extends InventoryView { return CraftItemStack.asCraftMirror(container.getSlot(slot).getItem()); } + @Override + public String getTitle() { + return CraftChatMessage.fromComponent(container.getTitle()); + } + public boolean isInTop(int rawSlot) { return rawSlot < viewing.getSize(); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java index 6a86cb7eb..3cddf254a 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -1,7 +1,7 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.collect.ImmutableSet; import java.util.Collection; - import org.apache.commons.lang.Validate; import org.bukkit.Color; import org.bukkit.Material; @@ -11,8 +11,6 @@ import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import com.google.common.collect.ImmutableSet; - public final class CraftItemFactory implements ItemFactory { static final Color DEFAULT_LEATHER_COLOR = Color.fromRGB(0xA06540); static final Collection KNOWN_NBT_ATTRIBUTE_NAMES; @@ -34,12 +32,14 @@ public final class CraftItemFactory implements ItemFactory { .add("generic.luck") .add("horse.jumpStrength") .add("zombie.spawnReinforcements") + .add("generic.attackKnockback") .build(); } private CraftItemFactory() { } + @Override public boolean isApplicable(ItemMeta meta, ItemStack itemstack) { if (itemstack == null) { return false; @@ -47,6 +47,7 @@ public final class CraftItemFactory implements ItemFactory { return isApplicable(meta, itemstack.getType()); } + @Override public boolean isApplicable(ItemMeta meta, Material type) { type = CraftLegacy.fromLegacy(type); // This may be called from legacy item stacks, try to get the right material if (type == null || meta == null) { @@ -59,6 +60,7 @@ public final class CraftItemFactory implements ItemFactory { return ((CraftMetaItem) meta).applicableTo(type); } + @Override public ItemMeta getItemMeta(Material material) { Validate.notNull(material, "Material cannot be null"); return getItemMeta(material, null); @@ -87,6 +89,7 @@ public final class CraftItemFactory implements ItemFactory { case ZOMBIE_WALL_HEAD: return meta instanceof CraftMetaSkull ? meta : new CraftMetaSkull(meta); case LEATHER_HELMET: + case LEATHER_HORSE_ARMOR: case LEATHER_CHESTPLATE: case LEATHER_LEGGINGS: case LEATHER_BOOTS: @@ -139,18 +142,20 @@ public final class CraftItemFactory implements ItemFactory { return meta instanceof CraftMetaBanner ? meta : new CraftMetaBanner(meta); case BAT_SPAWN_EGG: case BLAZE_SPAWN_EGG: + case CAT_SPAWN_EGG: case CAVE_SPIDER_SPAWN_EGG: case CHICKEN_SPAWN_EGG: case COD_SPAWN_EGG: case COW_SPAWN_EGG: case CREEPER_SPAWN_EGG: case DOLPHIN_SPAWN_EGG: - case DROWNED_SPAWN_EGG: case DONKEY_SPAWN_EGG: + case DROWNED_SPAWN_EGG: case ELDER_GUARDIAN_SPAWN_EGG: case ENDERMAN_SPAWN_EGG: case ENDERMITE_SPAWN_EGG: case EVOKER_SPAWN_EGG: + case FOX_SPAWN_EGG: case GHAST_SPAWN_EGG: case GUARDIAN_SPAWN_EGG: case HORSE_SPAWN_EGG: @@ -160,12 +165,15 @@ public final class CraftItemFactory implements ItemFactory { case MOOSHROOM_SPAWN_EGG: case MULE_SPAWN_EGG: case OCELOT_SPAWN_EGG: + case PANDA_SPAWN_EGG: case PARROT_SPAWN_EGG: case PHANTOM_SPAWN_EGG: case PIG_SPAWN_EGG: + case PILLAGER_SPAWN_EGG: case POLAR_BEAR_SPAWN_EGG: case PUFFERFISH_SPAWN_EGG: case RABBIT_SPAWN_EGG: + case RAVAGER_SPAWN_EGG: case SALMON_SPAWN_EGG: case SHEEP_SPAWN_EGG: case SHULKER_SPAWN_EGG: @@ -176,11 +184,13 @@ public final class CraftItemFactory implements ItemFactory { case SPIDER_SPAWN_EGG: case SQUID_SPAWN_EGG: case STRAY_SPAWN_EGG: + case TRADER_LLAMA_SPAWN_EGG: case TROPICAL_FISH_SPAWN_EGG: case TURTLE_SPAWN_EGG: case VEX_SPAWN_EGG: case VILLAGER_SPAWN_EGG: case VINDICATOR_SPAWN_EGG: + case WANDERING_TRADER_SPAWN_EGG: case WITCH_SPAWN_EGG: case WITHER_SKELETON_SPAWN_EGG: case WOLF_SPAWN_EGG: @@ -189,17 +199,28 @@ public final class CraftItemFactory implements ItemFactory { case ZOMBIE_SPAWN_EGG: case ZOMBIE_VILLAGER_SPAWN_EGG: return meta instanceof CraftMetaSpawnEgg ? meta : new CraftMetaSpawnEgg(meta); + case ARMOR_STAND: + return meta instanceof CraftMetaArmorStand ? meta : new CraftMetaArmorStand(meta); case KNOWLEDGE_BOOK: return meta instanceof CraftMetaKnowledgeBook ? meta : new CraftMetaKnowledgeBook(meta); - case ARMOR_STAND: - return meta instanceof CraftMetaArmorStand ? meta : new CraftMetaArmorStand(meta); // Paper case FURNACE: case CHEST: case TRAPPED_CHEST: case JUKEBOX: case DISPENSER: case DROPPER: - case SIGN: + case ACACIA_SIGN: + case ACACIA_WALL_SIGN: + case BIRCH_SIGN: + case BIRCH_WALL_SIGN: + case DARK_OAK_SIGN: + case DARK_OAK_WALL_SIGN: + case JUNGLE_SIGN: + case JUNGLE_WALL_SIGN: + case OAK_SIGN: + case OAK_WALL_SIGN: + case SPRUCE_SIGN: + case SPRUCE_WALL_SIGN: case SPAWNER: case BREWING_STAND: case ENCHANTING_TABLE: @@ -230,14 +251,26 @@ public final class CraftItemFactory implements ItemFactory { case RED_SHULKER_BOX: case BLACK_SHULKER_BOX: case ENDER_CHEST: - return new CraftMetaBlockState(meta, material); + case BARREL: + case BELL: + case BLAST_FURNACE: + case CAMPFIRE: + case JIGSAW: + case LECTERN: + case SMOKER: + return new CraftMetaBlockState(meta, material); case TROPICAL_FISH_BUCKET: return meta instanceof CraftMetaTropicalFishBucket ? meta : new CraftMetaTropicalFishBucket(meta); + case CROSSBOW: + return meta instanceof CraftMetaCrossbow ? meta : new CraftMetaCrossbow(meta); + case SUSPICIOUS_STEW: + return meta instanceof CraftMetaSuspiciousStew ? meta : new CraftMetaSuspiciousStew(meta); default: return new CraftMetaItem(meta); } } + @Override public boolean equals(ItemMeta meta1, ItemMeta meta2) { if (meta1 == meta2) { return true; @@ -275,11 +308,13 @@ public final class CraftItemFactory implements ItemFactory { return instance; } + @Override public ItemMeta asMetaFor(ItemMeta meta, ItemStack stack) { Validate.notNull(stack, "Stack cannot be null"); return asMetaFor(meta, stack.getType()); } + @Override public ItemMeta asMetaFor(ItemMeta meta, Material material) { Validate.notNull(material, "Material cannot be null"); if (!(meta instanceof CraftMetaItem)) { @@ -288,6 +323,7 @@ public final class CraftItemFactory implements ItemFactory { return getItemMeta(material, (CraftMetaItem) meta); } + @Override public Color getDefaultLeatherColor() { return DEFAULT_LEATHER_COLOR; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index ca9399bdb..b1ea5b93d 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -1,31 +1,24 @@ package org.bukkit.craftbukkit.inventory; -import static org.bukkit.craftbukkit.inventory.CraftMetaItem.ENCHANTMENTS; -import static org.bukkit.craftbukkit.inventory.CraftMetaItem.ENCHANTMENTS_ID; -import static org.bukkit.craftbukkit.inventory.CraftMetaItem.ENCHANTMENTS_LVL; - -import java.util.Iterator; +import static org.bukkit.craftbukkit.inventory.CraftMetaItem.*; +import com.google.common.collect.ImmutableMap; import java.util.Map; - import net.minecraft.server.EnchantmentManager; import net.minecraft.server.Item; import net.minecraft.server.NBTTagCompound; import net.minecraft.server.NBTTagList; - import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.enchantments.CraftEnchantment; +import org.bukkit.craftbukkit.util.CraftLegacy; import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; -import com.google.common.collect.ImmutableMap; -import org.bukkit.craftbukkit.enchantments.CraftEnchantment; -import org.bukkit.craftbukkit.util.CraftLegacy; -import org.bukkit.craftbukkit.util.CraftNamespacedKey; - @DelegateDeserialization(ItemStack.class) public final class CraftItemStack extends ItemStack { @@ -47,9 +40,6 @@ public final class CraftItemStack extends ItemStack { net.minecraft.server.ItemStack stack = new net.minecraft.server.ItemStack(item, original.getAmount()); if (original.hasItemMeta()) { setItemMeta(stack, original.getItemMeta()); - } else { - // Converted after setItemMeta - stack.convertStack(); } return stack; } @@ -307,6 +297,7 @@ public final class CraftItemStack extends ItemStack { case ZOMBIE_WALL_HEAD: return new CraftMetaSkull(item.getTag()); case LEATHER_HELMET: + case LEATHER_HORSE_ARMOR: case LEATHER_CHESTPLATE: case LEATHER_LEGGINGS: case LEATHER_BOOTS: @@ -359,18 +350,20 @@ public final class CraftItemStack extends ItemStack { return new CraftMetaBanner(item.getTag()); case BAT_SPAWN_EGG: case BLAZE_SPAWN_EGG: + case CAT_SPAWN_EGG: case CAVE_SPIDER_SPAWN_EGG: case CHICKEN_SPAWN_EGG: case COD_SPAWN_EGG: case COW_SPAWN_EGG: case CREEPER_SPAWN_EGG: case DOLPHIN_SPAWN_EGG: - case DROWNED_SPAWN_EGG: case DONKEY_SPAWN_EGG: + case DROWNED_SPAWN_EGG: case ELDER_GUARDIAN_SPAWN_EGG: case ENDERMAN_SPAWN_EGG: case ENDERMITE_SPAWN_EGG: case EVOKER_SPAWN_EGG: + case FOX_SPAWN_EGG: case GHAST_SPAWN_EGG: case GUARDIAN_SPAWN_EGG: case HORSE_SPAWN_EGG: @@ -380,12 +373,15 @@ public final class CraftItemStack extends ItemStack { case MOOSHROOM_SPAWN_EGG: case MULE_SPAWN_EGG: case OCELOT_SPAWN_EGG: + case PANDA_SPAWN_EGG: case PARROT_SPAWN_EGG: case PHANTOM_SPAWN_EGG: case PIG_SPAWN_EGG: + case PILLAGER_SPAWN_EGG: case POLAR_BEAR_SPAWN_EGG: case PUFFERFISH_SPAWN_EGG: case RABBIT_SPAWN_EGG: + case RAVAGER_SPAWN_EGG: case SALMON_SPAWN_EGG: case SHEEP_SPAWN_EGG: case SHULKER_SPAWN_EGG: @@ -396,11 +392,13 @@ public final class CraftItemStack extends ItemStack { case SPIDER_SPAWN_EGG: case SQUID_SPAWN_EGG: case STRAY_SPAWN_EGG: + case TRADER_LLAMA_SPAWN_EGG: case TROPICAL_FISH_SPAWN_EGG: case TURTLE_SPAWN_EGG: case VEX_SPAWN_EGG: case VILLAGER_SPAWN_EGG: case VINDICATOR_SPAWN_EGG: + case WANDERING_TRADER_SPAWN_EGG: case WITCH_SPAWN_EGG: case WITHER_SKELETON_SPAWN_EGG: case WOLF_SPAWN_EGG: @@ -409,17 +407,28 @@ public final class CraftItemStack extends ItemStack { case ZOMBIE_SPAWN_EGG: case ZOMBIE_VILLAGER_SPAWN_EGG: return new CraftMetaSpawnEgg(item.getTag()); + case ARMOR_STAND: + return new CraftMetaArmorStand(item.getTag()); case KNOWLEDGE_BOOK: return new CraftMetaKnowledgeBook(item.getTag()); - case ARMOR_STAND: - return new CraftMetaArmorStand(item.getTag()); // Paper case FURNACE: case CHEST: case TRAPPED_CHEST: case JUKEBOX: case DISPENSER: case DROPPER: - case SIGN: + case ACACIA_SIGN: + case ACACIA_WALL_SIGN: + case BIRCH_SIGN: + case BIRCH_WALL_SIGN: + case DARK_OAK_SIGN: + case DARK_OAK_WALL_SIGN: + case JUNGLE_SIGN: + case JUNGLE_WALL_SIGN: + case OAK_SIGN: + case OAK_WALL_SIGN: + case SPRUCE_SIGN: + case SPRUCE_WALL_SIGN: case SPAWNER: case BREWING_STAND: case ENCHANTING_TABLE: @@ -450,9 +459,20 @@ public final class CraftItemStack extends ItemStack { case RED_SHULKER_BOX: case BLACK_SHULKER_BOX: case ENDER_CHEST: + case BARREL: + case BELL: + case BLAST_FURNACE: + case CAMPFIRE: + case JIGSAW: + case LECTERN: + case SMOKER: return new CraftMetaBlockState(item.getTag(), CraftMagicNumbers.getMaterial(item.getItem())); case TROPICAL_FISH_BUCKET: return new CraftMetaTropicalFishBucket(item.getTag()); + case CROSSBOW: + return new CraftMetaCrossbow(item.getTag()); + case SUSPICIOUS_STEW: + return new CraftMetaSuspiciousStew(item.getTag()); default: return new CraftMetaItem(item.getTag()); } @@ -492,7 +512,7 @@ public final class CraftItemStack extends ItemStack { item.setTag(tag); ((CraftMetaItem) itemMeta).applyToItem(tag); - item.convertStack(); + item.convertStack(((CraftMetaItem) itemMeta).getVersion()); return true; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchant.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchant.java index 7569b29dc..50bc720d4 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchant.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchant.java @@ -25,7 +25,7 @@ public class CraftMerchant implements Merchant { @Override public List getRecipes() { - return Collections.unmodifiableList(Lists.transform(merchant.getOffers(null), new Function() { + return Collections.unmodifiableList(Lists.transform(merchant.getOffers(), new Function() { @Override public MerchantRecipe apply(net.minecraft.server.MerchantRecipe recipe) { return recipe.asBukkit(); @@ -35,7 +35,7 @@ public class CraftMerchant implements Merchant { @Override public void setRecipes(List recipes) { - MerchantRecipeList recipesList = merchant.getOffers(null); + MerchantRecipeList recipesList = merchant.getOffers(); recipesList.clear(); for (MerchantRecipe recipe : recipes) { recipesList.add(CraftMerchantRecipe.fromBukkit(recipe).toMinecraft()); @@ -44,17 +44,17 @@ public class CraftMerchant implements Merchant { @Override public MerchantRecipe getRecipe(int i) { - return merchant.getOffers(null).get(i).asBukkit(); + return merchant.getOffers().get(i).asBukkit(); } @Override public void setRecipe(int i, MerchantRecipe merchantRecipe) { - merchant.getOffers(null).set(i, CraftMerchantRecipe.fromBukkit(merchantRecipe).toMinecraft()); + merchant.getOffers().set(i, CraftMerchantRecipe.fromBukkit(merchantRecipe).toMinecraft()); } @Override public int getRecipeCount() { - return merchant.getOffers(null).size(); + return merchant.getOffers().size(); } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java index 4f8edbe3b..b8f2904f1 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java @@ -1,7 +1,5 @@ package org.bukkit.craftbukkit.inventory; -import org.apache.commons.lang.Validate; -import net.minecraft.server.BlockPosition; import net.minecraft.server.ChatComponentText; import net.minecraft.server.EntityHuman; import net.minecraft.server.IChatBaseComponent; @@ -9,12 +7,16 @@ import net.minecraft.server.IMerchant; import net.minecraft.server.ItemStack; import net.minecraft.server.MerchantRecipe; import net.minecraft.server.MerchantRecipeList; +import net.minecraft.server.SoundEffect; +import net.minecraft.server.SoundEffects; import net.minecraft.server.World; +import org.apache.commons.lang.Validate; public class CraftMerchantCustom extends CraftMerchant { public CraftMerchantCustom(String title) { super(new MinecraftMerchant(title)); + getMerchant().craftMerchant = this; } @Override @@ -22,20 +24,35 @@ public class CraftMerchantCustom extends CraftMerchant { return "CraftMerchantCustom"; } - private static class MinecraftMerchant implements IMerchant { + @Override + public MinecraftMerchant getMerchant() { + return (MinecraftMerchant) super.getMerchant(); + } + + public static class MinecraftMerchant implements IMerchant { private final IChatBaseComponent title; private final MerchantRecipeList trades = new MerchantRecipeList(); private EntityHuman tradingPlayer; + private World tradingWorld; + protected CraftMerchant craftMerchant; public MinecraftMerchant(String title) { Validate.notNull(title, "Title cannot be null"); this.title = new ChatComponentText(title); } + @Override + public CraftMerchant getCraftMerchant() { + return craftMerchant; + } + @Override public void setTradingPlayer(EntityHuman entityhuman) { this.tradingPlayer = entityhuman; + if (entityhuman != null) { + this.tradingWorld = entityhuman.world; + } } @Override @@ -44,7 +61,7 @@ public class CraftMerchantCustom extends CraftMerchant { } @Override - public MerchantRecipeList getOffers(EntityHuman entityhuman) { + public MerchantRecipeList getOffers() { return this.trades; } @@ -55,22 +72,35 @@ public class CraftMerchantCustom extends CraftMerchant { } @Override - public void a(ItemStack itemstack) { + public void i(ItemStack itemstack) { } - @Override public IChatBaseComponent getScoreboardDisplayName() { return title; } @Override public World getWorld() { - return null; + return this.tradingWorld; } @Override - public BlockPosition getPosition() { - return null; + public int getExperience() { + return 0; // xp + } + + @Override + public void s(int i) { + } + + @Override + public boolean ea() { + return false; // is-regular-villager flag (hides some gui elements: xp bar, name suffix) + } + + @Override + public SoundEffect eb() { + return SoundEffects.ENTITY_VILLAGER_YES; } } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java index 1730cc93b..ff7c65634 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantRecipe.java @@ -16,14 +16,16 @@ public class CraftMerchantRecipe extends MerchantRecipe { addIngredient(CraftItemStack.asBukkitCopy(merchantRecipe.buyingItem2)); } - public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward) { - super(result, uses, maxUses, experienceReward); + public CraftMerchantRecipe(ItemStack result, int uses, int maxUses, boolean experienceReward, int experience, float priceMultiplier) { + super(result, uses, maxUses, experienceReward, experience, priceMultiplier); this.handle = new net.minecraft.server.MerchantRecipe( net.minecraft.server.ItemStack.a, net.minecraft.server.ItemStack.a, CraftItemStack.asNMSCopy(result), uses, maxUses, + experience, + priceMultiplier, this ); this.setExperienceReward(experienceReward); @@ -59,6 +61,26 @@ public class CraftMerchantRecipe extends MerchantRecipe { handle.rewardExp = flag; } + @Override + public int getVillagerExperience() { + return handle.xp; + } + + @Override + public void setVillagerExperience(int villagerExperience) { + handle.xp = villagerExperience; + } + + @Override + public float getPriceMultiplier() { + return handle.priceMultiplier; + } + + @Override + public void setPriceMultiplier(float priceMultiplier) { + handle.priceMultiplier = priceMultiplier; + } + public net.minecraft.server.MerchantRecipe toMinecraft() { List ingredients = getIngredients(); Preconditions.checkState(!ingredients.isEmpty(), "No offered ingredients"); @@ -73,7 +95,7 @@ public class CraftMerchantRecipe extends MerchantRecipe { if (recipe instanceof CraftMerchantRecipe) { return (CraftMerchantRecipe) recipe; } else { - CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward()); + CraftMerchantRecipe craft = new CraftMerchantRecipe(recipe.getResult(), recipe.getUses(), recipe.getMaxUses(), recipe.hasExperienceReward(), recipe.getVillagerExperience(), recipe.getPriceMultiplier()); craft.setIngredients(recipe.getIngredients()); return craft; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java index c00b89c8d..3723facca 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java @@ -1,44 +1,35 @@ package org.bukkit.craftbukkit.inventory; -import com.destroystokyo.paper.inventory.meta.ArmorStandMeta; -import com.google.common.collect.ImmutableMap; -import com.mojang.datafixers.Dynamic; - -import net.minecraft.server.DataConverterTypes; -import net.minecraft.server.DynamicOpsNBT; -import net.minecraft.server.MinecraftServer; +import com.google.common.collect.ImmutableMap.Builder; +import java.util.Map; import net.minecraft.server.NBTBase; import net.minecraft.server.NBTTagCompound; - -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; -import org.bukkit.craftbukkit.util.CraftMagicNumbers; -import java.util.Map; - -// Paper - Created entire class @DelegateDeserialization(CraftMetaItem.SerializableMeta.class) -public class CraftMetaArmorStand extends CraftMetaItem implements ArmorStandMeta { +public class CraftMetaArmorStand extends CraftMetaItem implements com.destroystokyo.paper.inventory.meta.ArmorStandMeta { // Paper static final ItemMetaKey ENTITY_TAG = new ItemMetaKey("EntityTag", "entity-tag"); + // Paper start static final ItemMetaKey INVISIBLE = new ItemMetaKey("Invisible", "invisible"); static final ItemMetaKey NO_BASE_PLATE = new ItemMetaKey("NoBasePlate", "no-base-plate"); static final ItemMetaKey SHOW_ARMS = new ItemMetaKey("ShowArms", "show-arms"); static final ItemMetaKey SMALL = new ItemMetaKey("Small", "small"); static final ItemMetaKey MARKER = new ItemMetaKey("Marker", "marker"); - private NBTTagCompound entityTag; - private boolean invisible; private boolean noBasePlate; private boolean showArms; private boolean small; private boolean marker; + // Paper end + NBTTagCompound entityTag; CraftMetaArmorStand(CraftMetaItem meta) { super(meta); - + + // Paper start if (!(meta instanceof CraftMetaArmorStand)) { return; } @@ -49,6 +40,7 @@ public class CraftMetaArmorStand extends CraftMetaItem implements ArmorStandMeta this.showArms = standMeta.showArms; this.small = standMeta.small; this.marker = standMeta.marker; + // Paper end } CraftMetaArmorStand(NBTTagCompound tag) { @@ -57,6 +49,7 @@ public class CraftMetaArmorStand extends CraftMetaItem implements ArmorStandMeta if (tag.hasKey(ENTITY_TAG.NBT)) { entityTag = tag.getCompound(ENTITY_TAG.NBT); + // Paper start if (entityTag.hasKey(INVISIBLE.NBT)) { invisible = entityTag.getBoolean(INVISIBLE.NBT); } @@ -76,12 +69,14 @@ public class CraftMetaArmorStand extends CraftMetaItem implements ArmorStandMeta if (entityTag.hasKey(MARKER.NBT)) { marker = entityTag.getBoolean(MARKER.NBT); } + // Paper end } } CraftMetaArmorStand(Map map) { super(map); + // Paper start boolean invis = SerializableMeta.getBoolean(map, INVISIBLE.BUKKIT); boolean noBase = SerializableMeta.getBoolean(map, NO_BASE_PLATE.BUKKIT); boolean showArms = SerializableMeta.getBoolean(map, SHOW_ARMS.BUKKIT); @@ -93,12 +88,30 @@ public class CraftMetaArmorStand extends CraftMetaItem implements ArmorStandMeta this.showArms = showArms; this.small = small; this.marker = marker; + // Paper end + } + + @Override + void deserializeInternal(NBTTagCompound tag, Object context) { + super.deserializeInternal(tag, context); + + if (tag.hasKey(ENTITY_TAG.NBT)) { + entityTag = tag.getCompound(ENTITY_TAG.NBT); + } + } + + @Override + void serializeInternal(Map internalTags) { + if (entityTag != null && !entityTag.isEmpty()) { + internalTags.put(ENTITY_TAG.NBT, entityTag); + } } @Override void applyToItem(NBTTagCompound tag) { super.applyToItem(tag); + // Paper start if (!isArmorStandEmpty() && entityTag == null) { entityTag = new NBTTagCompound(); } @@ -122,6 +135,7 @@ public class CraftMetaArmorStand extends CraftMetaItem implements ArmorStandMeta if (isMarker()) { entityTag.setBoolean(MARKER.NBT, marker); } + // Paper end if (entityTag != null) { tag.set(ENTITY_TAG.NBT, entityTag); @@ -148,9 +162,51 @@ public class CraftMetaArmorStand extends CraftMetaItem implements ArmorStandMeta } @Override - ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaArmorStand) { + CraftMetaArmorStand that = (CraftMetaArmorStand) meta; + + // Paper start + return invisible == that.invisible && + noBasePlate == that.noBasePlate && + showArms == that.showArms && + small == that.small && + marker == that.marker; + // Paper end + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaArmorStand || isArmorStandEmpty()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + + // Paper start + hash += entityTag != null ? 73 * hash + entityTag.hashCode() : 0; + hash += isInvisible() ? 61 * hash + 1231 : 0; + hash += hasNoBasePlate() ? 61 * hash + 1231 : 0; + hash += shouldShowArms() ? 61 * hash + 1231 : 0; + hash += isSmall() ? 61 * hash + 1231 : 0; + hash += isMarker() ? 61 * hash + 1231 : 0; + // Paper end + + return original != hash ? CraftMetaArmorStand.class.hashCode() ^ hash : hash; + } + + @Override + Builder serialize(Builder builder) { super.serialize(builder); + // Paper start if (isInvisible()) { builder.put(INVISIBLE.BUKKIT, invisible); } @@ -170,69 +226,23 @@ public class CraftMetaArmorStand extends CraftMetaItem implements ArmorStandMeta if (isMarker()) { builder.put(MARKER.BUKKIT, marker); } + // Paper end return builder; } @Override - void deserializeInternal(NBTTagCompound tag, Object context) { - super.deserializeInternal(tag, context); + public CraftMetaArmorStand clone() { + CraftMetaArmorStand clone = (CraftMetaArmorStand) super.clone(); - if (tag.hasKey(ENTITY_TAG.NBT)) { - entityTag = tag.getCompound(ENTITY_TAG.NBT); - MinecraftServer.getServer().dataConverterManager.update(DataConverterTypes.ENTITY, new Dynamic(DynamicOpsNBT.a, entityTag), -1, Bukkit.getUnsafe().getDataVersion()); - - if (entityTag.hasKey(INVISIBLE.NBT)) { - invisible = entityTag.getBoolean(INVISIBLE.NBT); - } - - if (entityTag.hasKey(NO_BASE_PLATE.NBT)) { - noBasePlate = entityTag.getBoolean(NO_BASE_PLATE.NBT); - } - - if (entityTag.hasKey(SHOW_ARMS.NBT)) { - showArms = entityTag.getBoolean(SHOW_ARMS.NBT); - } - - if (entityTag.hasKey(SMALL.NBT)) { - small = entityTag.getBoolean(SMALL.NBT); - } - - if (entityTag.hasKey(MARKER.NBT)) { - marker = entityTag.getBoolean(MARKER.NBT); - } - } - } - - @Override - boolean equalsCommon(CraftMetaItem meta) { - if (!super.equalsCommon(meta)) { - return false; - } - if (meta instanceof CraftMetaArmorStand) { - CraftMetaArmorStand that = (CraftMetaArmorStand) meta; - - return invisible == that.invisible && - noBasePlate == that.noBasePlate && - showArms == that.showArms && - small == that.small && - marker == that.marker; - } - return true; - } - - @Override - boolean notUncommon(CraftMetaItem meta) { - return super.notUncommon(meta) && (meta instanceof CraftMetaArmorStand || isArmorStandEmpty()); - } - - @Override - void serializeInternal(Map internalTags) { if (entityTag != null) { - internalTags.put(ENTITY_TAG.NBT, entityTag); + clone.entityTag = entityTag.clone(); } + + return clone; } + // Paper start @Override public boolean isInvisible() { return invisible; @@ -282,30 +292,5 @@ public class CraftMetaArmorStand extends CraftMetaItem implements ArmorStandMeta public void setMarker(boolean marker) { this.marker = marker; } - - @Override - int applyHash() { - final int original; - int hash = original = super.applyHash(); - - hash += entityTag != null ? 73 * hash + entityTag.hashCode() : 0; - hash += isInvisible() ? 61 * hash + 1231 : 0; - hash += hasNoBasePlate() ? 61 * hash + 1231 : 0; - hash += shouldShowArms() ? 61 * hash + 1231 : 0; - hash += isSmall() ? 61 * hash + 1231 : 0; - hash += isMarker() ? 61 * hash + 1231 : 0; - - return original != hash ? CraftMetaArmorStand.class.hashCode() ^ hash : hash; - } - - @Override - public CraftMetaArmorStand clone() { - CraftMetaArmorStand clone = (CraftMetaArmorStand) super.clone(); - - if (entityTag != null) { - clone.entityTag = entityTag.clone(); - } - - return clone; - } + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java index f96f6af03..1529f30f7 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java @@ -8,8 +8,12 @@ import net.minecraft.server.NBTBase; import net.minecraft.server.NBTTagCompound; import net.minecraft.server.TileEntity; import net.minecraft.server.TileEntityBanner; +import net.minecraft.server.TileEntityBarrel; import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.TileEntityBell; +import net.minecraft.server.TileEntityBlastFurnace; import net.minecraft.server.TileEntityBrewingStand; +import net.minecraft.server.TileEntityCampfire; import net.minecraft.server.TileEntityChest; import net.minecraft.server.TileEntityCommand; import net.minecraft.server.TileEntityComparator; @@ -19,22 +23,30 @@ import net.minecraft.server.TileEntityEnchantTable; import net.minecraft.server.TileEntityEndGateway; import net.minecraft.server.TileEntityEnderChest; import net.minecraft.server.TileEntityFurnace; +import net.minecraft.server.TileEntityFurnaceFurnace; import net.minecraft.server.TileEntityHopper; +import net.minecraft.server.TileEntityJigsaw; import net.minecraft.server.TileEntityJukeBox; +import net.minecraft.server.TileEntityLectern; import net.minecraft.server.TileEntityLightDetector; import net.minecraft.server.TileEntityMobSpawner; import net.minecraft.server.TileEntityShulkerBox; import net.minecraft.server.TileEntitySign; import net.minecraft.server.TileEntitySkull; +import net.minecraft.server.TileEntitySmoker; import net.minecraft.server.TileEntityStructure; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.block.BlockState; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.craftbukkit.block.CraftBanner; +import org.bukkit.craftbukkit.block.CraftBarrel; import org.bukkit.craftbukkit.block.CraftBeacon; +import org.bukkit.craftbukkit.block.CraftBell; +import org.bukkit.craftbukkit.block.CraftBlastFurnace; import org.bukkit.craftbukkit.block.CraftBlockEntityState; import org.bukkit.craftbukkit.block.CraftBrewingStand; +import org.bukkit.craftbukkit.block.CraftCampfire; import org.bukkit.craftbukkit.block.CraftChest; import org.bukkit.craftbukkit.block.CraftCommandBlock; import org.bukkit.craftbukkit.block.CraftComparator; @@ -47,10 +59,13 @@ import org.bukkit.craftbukkit.block.CraftEndGateway; import org.bukkit.craftbukkit.block.CraftEnderChest; import org.bukkit.craftbukkit.block.CraftFurnace; import org.bukkit.craftbukkit.block.CraftHopper; +import org.bukkit.craftbukkit.block.CraftJigsaw; import org.bukkit.craftbukkit.block.CraftJukebox; +import org.bukkit.craftbukkit.block.CraftLectern; import org.bukkit.craftbukkit.block.CraftShulkerBox; import org.bukkit.craftbukkit.block.CraftSign; import org.bukkit.craftbukkit.block.CraftSkull; +import org.bukkit.craftbukkit.block.CraftSmoker; import org.bukkit.craftbukkit.block.CraftStructureBlock; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.meta.BlockStateMeta; @@ -174,7 +189,18 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta case JUKEBOX: case DISPENSER: case DROPPER: - case SIGN: + case ACACIA_SIGN: + case ACACIA_WALL_SIGN: + case BIRCH_SIGN: + case BIRCH_WALL_SIGN: + case DARK_OAK_SIGN: + case DARK_OAK_WALL_SIGN: + case JUNGLE_SIGN: + case JUNGLE_WALL_SIGN: + case OAK_SIGN: + case OAK_WALL_SIGN: + case SPRUCE_SIGN: + case SPRUCE_WALL_SIGN: case SPAWNER: case BREWING_STAND: case ENCHANTING_TABLE: @@ -205,6 +231,13 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta case RED_SHULKER_BOX: case BLACK_SHULKER_BOX: case ENDER_CHEST: + case BARREL: + case BELL: + case BLAST_FURNACE: + case CAMPFIRE: + case JIGSAW: + case LECTERN: + case SMOKER: return true; } return false; @@ -255,8 +288,18 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta TileEntity te = (blockEntityTag == null) ? null : TileEntity.create(blockEntityTag); switch (material) { - case SIGN: - case WALL_SIGN: + case ACACIA_SIGN: + case ACACIA_WALL_SIGN: + case BIRCH_SIGN: + case BIRCH_WALL_SIGN: + case DARK_OAK_SIGN: + case DARK_OAK_WALL_SIGN: + case JUNGLE_SIGN: + case JUNGLE_WALL_SIGN: + case OAK_SIGN: + case OAK_WALL_SIGN: + case SPRUCE_SIGN: + case SPRUCE_WALL_SIGN: if (te == null) { te = new TileEntitySign(); } @@ -269,7 +312,7 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta return new CraftChest(material, (TileEntityChest) te); case FURNACE: if (te == null) { - te = new TileEntityFurnace(); + te = new TileEntityFurnaceFurnace(); } return new CraftFurnace(material, (TileEntityFurnace) te); case DISPENSER: @@ -422,6 +465,41 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta te = new TileEntityComparator(); } return new CraftComparator(material, (TileEntityComparator) te); + case BARREL: + if (te == null){ + te = new TileEntityBarrel(); + } + return new CraftBarrel(material, (TileEntityBarrel) te); + case BELL: + if (te == null){ + te = new TileEntityBell(); + } + return new CraftBell(material, (TileEntityBell) te); + case BLAST_FURNACE: + if (te == null){ + te = new TileEntityBlastFurnace(); + } + return new CraftBlastFurnace(material, (TileEntityBlastFurnace) te); + case CAMPFIRE: + if (te == null){ + te = new TileEntityCampfire(); + } + return new CraftCampfire(material, (TileEntityCampfire) te); + case JIGSAW: + if (te == null){ + te = new TileEntityJigsaw(); + } + return new CraftJigsaw(material, (TileEntityJigsaw) te); + case LECTERN: + if (te == null){ + te = new TileEntityLectern(); + } + return new CraftLectern(material, (TileEntityLectern) te); + case SMOKER: + if (te == null){ + te = new TileEntitySmoker(); + } + return new CraftSmoker(material, (TileEntitySmoker) te); default: throw new IllegalStateException("Missing blockState for " + material); } @@ -433,8 +511,18 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta boolean valid; switch (material) { - case SIGN: - case WALL_SIGN: + case ACACIA_SIGN: + case ACACIA_WALL_SIGN: + case BIRCH_SIGN: + case BIRCH_WALL_SIGN: + case DARK_OAK_SIGN: + case DARK_OAK_WALL_SIGN: + case JUNGLE_SIGN: + case JUNGLE_WALL_SIGN: + case OAK_SIGN: + case OAK_WALL_SIGN: + case SPRUCE_SIGN: + case SPRUCE_WALL_SIGN: valid = blockState instanceof CraftSign; break; case CHEST: @@ -556,6 +644,27 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta case COMPARATOR: valid = blockState instanceof CraftComparator; break; + case BARREL: + valid = blockState instanceof CraftBarrel; + break; + case BELL: + valid = blockState instanceof CraftBell; + break; + case BLAST_FURNACE: + valid = blockState instanceof CraftBlastFurnace; + break; + case CAMPFIRE: + valid = blockState instanceof CraftCampfire; + break; + case JIGSAW: + valid = blockState instanceof CraftJigsaw; + break; + case LECTERN: + valid = blockState instanceof CraftLectern; + break; + case SMOKER: + valid = blockState instanceof CraftSmoker; + break; default: valid = false; break; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java index 20cddd506..7262920c1 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java @@ -1,33 +1,29 @@ package org.bukkit.craftbukkit.inventory; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import net.minecraft.server.NBTTagCompound; -import net.minecraft.server.NBTTagList; - -import org.apache.commons.lang.Validate; -import org.bukkit.Material; -import org.bukkit.configuration.serialization.DelegateDeserialization; -import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; -import org.bukkit.craftbukkit.util.CraftMagicNumbers; -import org.bukkit.inventory.meta.BookMeta; - import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap.Builder; -import java.util.AbstractList; -import net.minecraft.server.IChatBaseComponent.ChatSerializer; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.IChatBaseComponent.ChatSerializer; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; import net.minecraft.server.NBTTagString; +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.inventory.meta.BookMeta; // Spigot start import static org.spigotmc.ValidateUtils.*; +import java.util.AbstractList; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.chat.ComponentSerializer; -import net.minecraft.server.ChatBaseComponent; // Spigot end @DelegateDeserialization(SerializableMeta.class) @@ -37,7 +33,7 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta { static final ItemMetaKey BOOK_PAGES = new ItemMetaKey("pages"); static final ItemMetaKey RESOLVED = new ItemMetaKey("resolved"); static final ItemMetaKey GENERATION = new ItemMetaKey("generation"); - static final int MAX_PAGES = 50; + static final int MAX_PAGES = 100; static final int MAX_PAGE_LENGTH = 320; // 256 limit + 64 characters to allow for psuedo colour codes static final int MAX_TITLE_LENGTH = 32; private static final boolean OVERRIDE_CHECKS = Boolean.getBoolean("disable.book-limits"); // Paper - Add override @@ -140,7 +136,7 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta { if (hasPages()) { NBTTagList list = new NBTTagList(); for (IChatBaseComponent page : pages) { - list.add(new NBTTagString(CraftChatMessage.fromComponent(page))); + list.add(new NBTTagString(page == null ? "" : page.e())); // PAIL getLegacyString } itemData.set(BOOK_PAGES.NBT, list); } @@ -173,26 +169,32 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta { } } + @Override public boolean hasAuthor() { return !Strings.isNullOrEmpty(author); } + @Override public boolean hasTitle() { return !Strings.isNullOrEmpty(title); } + @Override public boolean hasPages() { return !pages.isEmpty(); } + @Override public boolean hasGeneration() { return generation != null; } + @Override public String getTitle() { return this.title; } + @Override public boolean setTitle(final String title) { if (title == null) { this.title = null; @@ -205,10 +207,12 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta { return true; } + @Override public String getAuthor() { return this.author; } + @Override public void setAuthor(final String author) { this.author = author; } @@ -223,11 +227,13 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta { this.generation = (generation == null) ? null : generation.ordinal(); } + @Override public String getPage(final int page) { Validate.isTrue(isValidPage(page), "Invalid page number"); return CraftChatMessage.fromComponent(pages.get(page - 1)); } + @Override public void setPage(final int page, final String text) { if (!isValidPage(page)) { throw new IllegalArgumentException("Invalid page number " + page + "/" + pages.size()); @@ -237,12 +243,14 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta { pages.set(page - 1, CraftChatMessage.fromString(newText, true)[0]); } + @Override public void setPages(final String... pages) { this.pages.clear(); addPage(pages); } + @Override public void addPage(final String... pages) { for (String page : pages) { if (this.pages.size() >= MAX_PAGES && !OVERRIDE_CHECKS) { @@ -259,14 +267,17 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta { } } + @Override public int getPageCount() { return pages.size(); } + @Override public List getPages() { return pages.stream().map(CraftChatMessage::fromComponent).collect(ImmutableList.toImmutableList()); } + @Override public void setPages(List pages) { this.pages.clear(); for (String page : pages) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java index 5050b6099..e6ca5e707 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java @@ -1,21 +1,18 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.collect.ImmutableMap.Builder; import java.util.Map; - +import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.IChatBaseComponent.ChatSerializer; import net.minecraft.server.NBTTagCompound; import net.minecraft.server.NBTTagList; - +import net.minecraft.server.NBTTagString; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.meta.BookMeta; -import com.google.common.collect.ImmutableMap.Builder; -import net.minecraft.server.IChatBaseComponent.ChatSerializer; -import net.minecraft.server.IChatBaseComponent; -import net.minecraft.server.NBTTagString; - @DelegateDeserialization(SerializableMeta.class) class CraftMetaBookSigned extends CraftMetaBook implements BookMeta { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java index 267581ec2..62b3dcc23 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java @@ -1,17 +1,14 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.collect.ImmutableMap.Builder; import java.util.Map; - import net.minecraft.server.NBTTagCompound; - import org.bukkit.FireworkEffect; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; import org.bukkit.inventory.meta.FireworkEffectMeta; -import com.google.common.collect.ImmutableMap.Builder; - @DelegateDeserialization(SerializableMeta.class) class CraftMetaCharge extends CraftMetaItem implements FireworkEffectMeta { static final ItemMetaKey EXPLOSION = new ItemMetaKey("Explosion", "firework-effect"); @@ -31,7 +28,7 @@ class CraftMetaCharge extends CraftMetaItem implements FireworkEffectMeta { setEffect(SerializableMeta.getObject(FireworkEffect.class, map, EXPLOSION.BUKKIT, true)); } - + CraftMetaCharge(NBTTagCompound tag) { super(tag); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java new file mode 100644 index 000000000..15fc0115c --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCrossbow.java @@ -0,0 +1,202 @@ +package org.bukkit.craftbukkit.inventory; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import net.minecraft.server.ItemArrow; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.CrossbowMeta; + +@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) +public class CraftMetaCrossbow extends CraftMetaItem implements CrossbowMeta { + + static final ItemMetaKey CHARGED = new ItemMetaKey("Charged", "charged"); + static final ItemMetaKey CHARGED_PROJECTILES = new ItemMetaKey("ChargedProjectiles", "charged-projectiles"); + // + private boolean charged; + private List chargedProjectiles; + + CraftMetaCrossbow(CraftMetaItem meta) { + super(meta); + + if (!(meta instanceof CraftMetaCrossbow)) { + return; + } + + CraftMetaCrossbow crossbow = (CraftMetaCrossbow) meta; + this.charged = crossbow.charged; + + if (crossbow.hasChargedProjectiles()) { + this.chargedProjectiles = new ArrayList<>(crossbow.chargedProjectiles); + } + } + + CraftMetaCrossbow(NBTTagCompound tag) { + super(tag); + + charged = tag.getBoolean(CHARGED.NBT); + + if (tag.hasKeyOfType(CHARGED_PROJECTILES.NBT, CraftMagicNumbers.NBT.TAG_LIST)) { + NBTTagList list = tag.getList(CHARGED_PROJECTILES.NBT, CraftMagicNumbers.NBT.TAG_COMPOUND); + + if (list != null && !list.isEmpty()) { + chargedProjectiles = new ArrayList<>(); + + for (int i = 0; i < list.size(); i++) { + NBTTagCompound nbttagcompound1 = list.getCompound(i); + + chargedProjectiles.add(CraftItemStack.asCraftMirror(net.minecraft.server.ItemStack.a(nbttagcompound1))); + } + } + } + } + + CraftMetaCrossbow(Map map) { + super(map); + + Boolean charged = SerializableMeta.getObject(Boolean.class, map, CHARGED.BUKKIT, true); + if (charged != null) { + this.charged = charged; + } + + Iterable projectiles = SerializableMeta.getObject(Iterable.class, map, CHARGED_PROJECTILES.BUKKIT, true); + if (projectiles != null) { + for (Object stack : projectiles) { + if (stack instanceof ItemStack) { + addChargedProjectile((ItemStack) stack); + } + } + } + } + + @Override + void applyToItem(NBTTagCompound tag) { + super.applyToItem(tag); + + tag.setBoolean(CHARGED.NBT, charged); + if (hasChargedProjectiles()) { + NBTTagList list = new NBTTagList(); + + for (ItemStack item : chargedProjectiles) { + NBTTagCompound saved = new NBTTagCompound(); + CraftItemStack.asNMSCopy(item).save(saved); + list.add(saved); + } + + tag.set(CHARGED_PROJECTILES.NBT, list); + } + } + + @Override + boolean applicableTo(Material type) { + switch (type) { + case CROSSBOW: + return true; + default: + return false; + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isCrossbowEmpty(); + } + + boolean isCrossbowEmpty() { + return !(hasChargedProjectiles()); + } + + @Override + public boolean hasChargedProjectiles() { + return chargedProjectiles != null; + } + + @Override + public List getChargedProjectiles() { + return (chargedProjectiles == null) ? null : ImmutableList.copyOf(chargedProjectiles); + } + + @Override + public void setChargedProjectiles(List projectiles) { + chargedProjectiles = null; + charged = false; + + if (projectiles == null) { + return; + } + + for (ItemStack i : projectiles) { + addChargedProjectile(i); + } + } + + @Override + public void addChargedProjectile(ItemStack item) { + Preconditions.checkArgument(item != null, "item"); + Preconditions.checkArgument(item.getType() == Material.FIREWORK_ROCKET || CraftMagicNumbers.getItem(item.getType()) instanceof ItemArrow, "Item %s is not an arrow or firework rocket", item); + + if (chargedProjectiles == null) { + chargedProjectiles = new ArrayList<>(); + } + + charged = true; + chargedProjectiles.add(item); + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaCrossbow) { + CraftMetaCrossbow that = (CraftMetaCrossbow) meta; + + return this.charged == that.charged + && (hasChargedProjectiles() ? that.hasChargedProjectiles() && this.chargedProjectiles.equals(that.chargedProjectiles) : !that.hasChargedProjectiles()); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaCrossbow || isCrossbowEmpty()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + + if (hasChargedProjectiles()) { + hash = 61 * hash + (this.charged ? 1 : 0); + hash = 61 * hash + chargedProjectiles.hashCode(); + } + + return original != hash ? CraftMetaCrossbow.class.hashCode() ^ hash : hash; + } + + @Override + public CraftMetaCrossbow clone() { + return (CraftMetaCrossbow) super.clone(); + } + + @Override + ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { + super.serialize(builder); + + builder.put(CHARGED.BUKKIT, charged); + if (hasChargedProjectiles()) { + builder.put(CHARGED_PROJECTILES.BUKKIT, chargedProjectiles); + } + + return builder; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java index 8d44e55e6..f5feea207 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java @@ -1,19 +1,16 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; import java.util.HashMap; import java.util.Map; - import net.minecraft.server.NBTTagCompound; - import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.meta.EnchantmentStorageMeta; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; - @DelegateDeserialization(SerializableMeta.class) class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorageMeta { static final ItemMetaKey STORED_ENCHANTMENTS = new ItemMetaKey("StoredEnchantments", "stored-enchants"); @@ -126,10 +123,12 @@ class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorage return !hasStoredEnchants(); } + @Override public boolean hasStoredEnchant(Enchantment ench) { return hasStoredEnchants() && enchantments.containsKey(ench); } + @Override public int getStoredEnchantLevel(Enchantment ench) { Integer level = hasStoredEnchants() ? enchantments.get(ench) : null; if (level == null) { @@ -138,10 +137,12 @@ class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorage return level; } + @Override public Map getStoredEnchants() { return hasStoredEnchants() ? ImmutableMap.copyOf(enchantments) : ImmutableMap.of(); } + @Override public boolean addStoredEnchant(Enchantment ench, int level, boolean ignoreRestrictions) { if (enchantments == null) { enchantments = new HashMap(4); @@ -154,14 +155,17 @@ class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorage return false; } + @Override public boolean removeStoredEnchant(Enchantment ench) { return hasStoredEnchants() && enchantments.remove(ench) != null; } + @Override public boolean hasStoredEnchants() { return !(enchantments == null || enchantments.isEmpty()); } + @Override public boolean hasConflictingStoredEnchant(Enchantment ench) { return checkConflictingEnchants(enchantments, ench); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java index b82e2fdf7..7a1c4d619 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java @@ -1,13 +1,13 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap.Builder; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; - import net.minecraft.server.NBTTagCompound; import net.minecraft.server.NBTTagList; - import org.apache.commons.lang.Validate; import org.bukkit.Color; import org.bukkit.FireworkEffect; @@ -20,9 +20,6 @@ import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.meta.FireworkMeta; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap.Builder; - @DelegateDeserialization(SerializableMeta.class) class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { /* @@ -93,7 +90,11 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { List effects = this.effects = new ArrayList(fireworkEffects.size()); for (int i = 0; i < fireworkEffects.size(); i++) { - effects.add(getEffect((NBTTagCompound) fireworkEffects.get(i))); + try { + effects.add(getEffect((NBTTagCompound) fireworkEffects.get(i))); + } catch (IllegalArgumentException ex) { + // Ignore invalid effects + } } } @@ -187,6 +188,7 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { safelyAddEffects(effects); } + @Override public boolean hasEffects() { return !(effects == null || effects.isEmpty()); } @@ -333,6 +335,7 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { return meta; } + @Override public void addEffect(FireworkEffect effect) { Validate.notNull(effect, "Effect cannot be null"); if (this.effects == null) { @@ -341,6 +344,7 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { this.effects.add(effect); } + @Override public void addEffects(FireworkEffect...effects) { Validate.notNull(effects, "Effects cannot be null"); if (effects.length == 0) { @@ -358,19 +362,23 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { } } + @Override public void addEffects(Iterable effects) { Validate.notNull(effects, "Effects cannot be null"); safelyAddEffects(effects); } + @Override public List getEffects() { return this.effects == null ? ImmutableList.of() : ImmutableList.copyOf(this.effects); } + @Override public int getEffectsSize() { return this.effects == null ? 0 : this.effects.size(); } + @Override public void removeEffect(int index) { if (this.effects == null) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); @@ -379,14 +387,17 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { } } + @Override public void clearEffects() { this.effects = null; } + @Override public int getPower() { return this.power; } + @Override public void setPower(int power) { Validate.isTrue(power >= 0, "Power cannot be less than zero: ", power); Validate.isTrue(power < 0x80, "Power cannot be more than 127: ", power); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index ec91ab72d..973727899 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -1,5 +1,20 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.ImmutableSortedMap; // Paper +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import com.google.common.collect.SetMultimap; +import com.google.common.collect.Sets; +import com.google.gson.JsonParseException; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -7,35 +22,41 @@ import java.lang.annotation.Target; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; +import java.util.EnumSet; +import java.util.Comparator; // Paper import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.SetMultimap; +import java.util.Set; +import java.util.TreeMap; // Paper +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import net.minecraft.server.ChatComponentText; +import net.minecraft.server.EnumChatFormat; import net.minecraft.server.EnumItemSlot; import net.minecraft.server.GenericAttributes; import net.minecraft.server.IChatBaseComponent; -import com.google.common.collect.ImmutableSortedMap; +import net.minecraft.server.ItemBlock; import net.minecraft.server.NBTBase; +import net.minecraft.server.NBTCompressedStreamTools; import net.minecraft.server.NBTTagCompound; import net.minecraft.server.NBTTagList; import net.minecraft.server.NBTTagString; - +import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.Validate; import org.apache.commons.lang3.EnumUtils; import org.bukkit.Material; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; +import org.bukkit.block.data.BlockData; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.configuration.serialization.SerializableAs; @@ -43,8 +64,11 @@ import org.bukkit.craftbukkit.CraftEquipmentSlot; import org.bukkit.craftbukkit.Overridden; import org.bukkit.craftbukkit.attribute.CraftAttributeInstance; import org.bukkit.craftbukkit.attribute.CraftAttributeMap; +import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.inventory.CraftMetaItem.ItemMetaKey.Specific; -import org.bukkit.craftbukkit.inventory.tags.CraftCustomItemTagContainer; +import org.bukkit.craftbukkit.inventory.tags.DeprecatedCustomTagContainer; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftNBTTagConfigSerializer; @@ -52,31 +76,12 @@ import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.meta.BlockDataMeta; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.Repairable; import org.bukkit.inventory.meta.tags.CustomItemTagContainer; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Sets; -import com.google.gson.JsonParseException; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.LinkedHashMap; -import java.util.Set; -import java.util.TreeMap; -import java.util.logging.Level; -import java.util.logging.Logger; -import net.minecraft.server.EnumChatFormat; -import net.minecraft.server.NBTCompressedStreamTools; -import org.apache.commons.codec.binary.Base64; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import org.bukkit.persistence.PersistentDataContainer; // Spigot start import static org.spigotmc.ValidateUtils.*; @@ -111,7 +116,7 @@ import java.util.Collections; *
  • SerializableMeta.Deserializers deserializer() */ @DelegateDeserialization(CraftMetaItem.SerializableMeta.class) -class CraftMetaItem implements ItemMeta, Damageable, Repairable { +class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { static class ItemMetaKey { @@ -148,6 +153,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { static { classMap = ImmutableMap., String>builder() + .put(CraftMetaArmorStand.class, "ARMOR_STAND") .put(CraftMetaBanner.class, "BANNER") .put(CraftMetaBlockState.class, "TILE_ENTITY") .put(CraftMetaBook.class, "BOOK") @@ -162,7 +168,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { .put(CraftMetaCharge.class, "FIREWORK_EFFECT") .put(CraftMetaKnowledgeBook.class, "KNOWLEDGE_BOOK") .put(CraftMetaTropicalFishBucket.class, "TROPICAL_FISH_BUCKET") - .put(CraftMetaArmorStand.class, "ARMOR_STAND") + .put(CraftMetaCrossbow.class, "CROSSBOW") + .put(CraftMetaSuspiciousStew.class, "SUSPICIOUS_STEW") .put(CraftMetaItem.class, "UNSPECIFIC") .build(); @@ -201,6 +208,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { } } + @Override public Map serialize() { throw new AssertionError(); } @@ -235,6 +243,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { @Specific(Specific.To.NBT) static final ItemMetaKey DISPLAY = new ItemMetaKey("display"); static final ItemMetaKey LORE = new ItemMetaKey("Lore", "lore"); + static final ItemMetaKey CUSTOM_MODEL_DATA = new ItemMetaKey("CustomModelData", "custom-model-data"); static final ItemMetaKey ENCHANTMENTS = new ItemMetaKey("Enchantments", "enchants"); @Specific(Specific.To.NBT) static final ItemMetaKey ENCHANTMENTS_ID = new ItemMetaKey("id"); @@ -262,6 +271,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { static final ItemMetaKey UNBREAKABLE = new ItemMetaKey("Unbreakable"); @Specific(Specific.To.NBT) static final ItemMetaKey DAMAGE = new ItemMetaKey("Damage"); + @Specific(Specific.To.NBT) + static final ItemMetaKey BLOCK_DATA = new ItemMetaKey("BlockStateTag"); static final ItemMetaKey BUKKIT_CUSTOM_TAG = new ItemMetaKey("PublicBukkitValues"); // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values static final ItemMetaKey CAN_DESTROY = new ItemMetaKey("CanDestroy"); @@ -270,7 +281,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { private IChatBaseComponent displayName; private IChatBaseComponent locName; - private List lore; + private List lore; + private Integer customModelData; + private NBTTagCompound blockData; private EnchantmentMap enchantments; // Paper private Multimap attributeModifiers; private int repairCost; @@ -283,11 +296,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { // Paper end private static final Set HANDLED_TAGS = Sets.newHashSet(); - private static final CraftCustomTagTypeRegistry TAG_TYPE_REGISTRY = new CraftCustomTagTypeRegistry(); + private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); private NBTTagCompound internalTag; private final Map unhandledTags = new TreeMap<>(); // Paper - private final CraftCustomItemTagContainer publicItemTagContainer = new CraftCustomItemTagContainer(TAG_TYPE_REGISTRY); + private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); + + private int version = CraftMagicNumbers.INSTANCE.getDataVersion(); // Internal use only CraftMetaItem(CraftMetaItem meta) { if (meta == null) { @@ -298,15 +313,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { this.locName = meta.locName; if (meta.hasLore()) { - this.lore = new ArrayList(meta.lore); + this.lore = new ArrayList(meta.lore); } + this.customModelData = meta.customModelData; + this.blockData = meta.blockData; + if (meta.enchantments != null) { // Spigot this.enchantments = new EnchantmentMap(meta.enchantments); // Paper } if (meta.hasAttributeModifiers()) { - this.attributeModifiers = HashMultimap.create(meta.attributeModifiers); + this.attributeModifiers = LinkedHashMultimap.create(meta.attributeModifiers); } this.repairCost = meta.repairCost; @@ -323,12 +341,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { } // Paper end this.unhandledTags.putAll(meta.unhandledTags); - this.publicItemTagContainer.putAll(meta.publicItemTagContainer.getRaw()); + this.persistentDataContainer.putAll(meta.persistentDataContainer.getRaw()); this.internalTag = meta.internalTag; if (this.internalTag != null) { deserializeInternal(internalTag, meta); } + + this.version = meta.version; } CraftMetaItem(NBTTagCompound tag) { @@ -353,15 +373,26 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { if (display.hasKey(LORE.NBT)) { NBTTagList list = display.getList(LORE.NBT, CraftMagicNumbers.NBT.TAG_STRING); - lore = new ArrayList(list.size()); + lore = new ArrayList(list.size()); for (int index = 0; index < list.size(); index++) { - String line = limit( list.getString(index), 1024 ); // Spigot - lore.add(line); + String line = limit( list.getString(index), 8192 ); // Spigot + try { + lore.add(IChatBaseComponent.ChatSerializer.a(line)); + } catch (JsonParseException ex) { + // Ignore (stripped like Vanilla) + } } } } + if (tag.hasKeyOfType(CUSTOM_MODEL_DATA.NBT, CraftMagicNumbers.NBT.TAG_INT)) { + customModelData = tag.getInt(CUSTOM_MODEL_DATA.NBT); + } + if (tag.hasKeyOfType(BLOCK_DATA.NBT, CraftMagicNumbers.NBT.TAG_COMPOUND)) { + blockData = tag.getCompound(BLOCK_DATA.NBT); + } + this.enchantments = buildEnchantments(tag, ENCHANTMENTS); this.attributeModifiers = buildModifiers(tag, ATTRIBUTES); @@ -382,7 +413,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { NBTTagCompound compound = tag.getCompound(BUKKIT_CUSTOM_TAG.NBT); Set keys = compound.getKeys(); for (String key : keys) { - publicItemTagContainer.put(key, compound.get(key)); + persistentDataContainer.put(key, compound.get(key)); } } // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values @@ -441,7 +472,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { } static Multimap buildModifiers(NBTTagCompound tag, ItemMetaKey key) { - Multimap modifiers = HashMultimap.create(); + Multimap modifiers = LinkedHashMultimap.create(); if (!tag.hasKeyOfType(key.NBT, CraftMagicNumbers.NBT.TAG_LIST)) { return modifiers; } @@ -503,7 +534,17 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { Iterable lore = SerializableMeta.getObject(Iterable.class, map, LORE.BUKKIT, true); if (lore != null) { - safelyAdd(lore, this.lore = new ArrayList(), Integer.MAX_VALUE); + safelyAdd(lore, this.lore = new ArrayList(), Integer.MAX_VALUE); + } + + Integer customModelData = SerializableMeta.getObject(Integer.class, map, CUSTOM_MODEL_DATA.BUKKIT, true); + if (customModelData != null) { + setCustomModelData(customModelData); + } + + Map blockData = SerializableMeta.getObject(Map.class, map, BLOCK_DATA.BUKKIT, true); + if (blockData != null) { + this.blockData = (NBTTagCompound) CraftNBTTagConfigSerializer.deserialize(blockData); } enchantments = buildEnchantments(map, ENCHANTMENTS); @@ -584,7 +625,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { Map nbtMap = SerializableMeta.getObject(Map.class, map, BUKKIT_CUSTOM_TAG.BUKKIT, true); if (nbtMap != null) { - this.publicItemTagContainer.putAll((NBTTagCompound) CraftNBTTagConfigSerializer.deserialize(nbtMap)); + this.persistentDataContainer.putAll((NBTTagCompound) CraftNBTTagConfigSerializer.deserialize(nbtMap)); } } @@ -620,7 +661,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { static Multimap buildModifiers(Map map, ItemMetaKey key) { Map mods = SerializableMeta.getObject(Map.class, map, key.BUKKIT, true); - Multimap result = HashMultimap.create(); + Multimap result = LinkedHashMultimap.create(); if (mods == null) { return result; } @@ -667,6 +708,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { setDisplayTag(itemTag, LORE.NBT, createStringList(lore)); } + if (hasCustomModelData()) { + itemTag.setInt(CUSTOM_MODEL_DATA.NBT, customModelData); + } + + if (hasBlockData()) { + itemTag.set(BLOCK_DATA.NBT, blockData); + } + if (hideFlag != 0) { itemTag.setInt(HIDEFLAGS.NBT, hideFlag); } @@ -691,7 +740,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { .map(this::serializeNamespaced) .collect(java.util.stream.Collectors.toList()); - itemTag.set(CAN_PLACE_ON.NBT, createStringList(items)); + itemTag.set(CAN_PLACE_ON.NBT, createNonComponentStringList(items)); } if (hasDestroyableKeys()) { @@ -699,7 +748,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { .map(this::serializeNamespaced) .collect(java.util.stream.Collectors.toList()); - itemTag.set(CAN_DESTROY.NBT, createStringList(items)); + itemTag.set(CAN_DESTROY.NBT, createNonComponentStringList(items)); } // Paper end @@ -707,9 +756,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { itemTag.set(e.getKey(), e.getValue()); } - if (!publicItemTagContainer.isEmpty()) { + if (!persistentDataContainer.isEmpty()) { NBTTagCompound bukkitCustomCompound = new NBTTagCompound(); - Map rawPublicMap = publicItemTagContainer.getRaw(); + Map rawPublicMap = persistentDataContainer.getRaw(); for (Map.Entry nbtBaseEntry : rawPublicMap.entrySet()) { bukkitCustomCompound.set(nbtBaseEntry.getKey(), nbtBaseEntry.getValue()); @@ -718,7 +767,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { } } - static NBTTagList createStringList(List list) { + // Paper start + static NBTTagList createNonComponentStringList(List list) { if (list == null || list.isEmpty()) { return null; } @@ -730,6 +780,21 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { return tagList; } + // Paper end + + NBTTagList createStringList(List list) { + if (list == null || list.isEmpty()) { + return null; + } + + NBTTagList tagList = new NBTTagList(); + for (IChatBaseComponent value : list) { + // SPIGOT-5342 - horrible hack as 0 version does not go through the Mojang updater + tagList.add(new NBTTagString(version <= 0 || version >= 1803 ? CraftChatMessage.toJSON(value) : CraftChatMessage.fromComponent(value, EnumChatFormat.DARK_PURPLE))); // SPIGOT-4935 + } + + return tagList; + } static void applyEnchantments(Map enchantments, NBTTagCompound tag, ItemMetaKey key) { if (enchantments == null /*|| enchantments.size() == 0*/) { // Spigot - remove size check @@ -800,18 +865,20 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { @Overridden boolean isEmpty() { - return !(hasDisplayName() || hasLocalizedName() || hasEnchants() || hasLore() || hasRepairCost() || !unhandledTags.isEmpty() || !publicItemTagContainer.isEmpty() || hideFlag != 0 || isUnbreakable() || hasDamage() || hasAttributeModifiers() - || hasPlaceableKeys() || hasDestroyableKeys()); // Paper - Implement an API for CanPlaceOn and CanDestroy NBT values + return !(hasDisplayName() || hasLocalizedName() || hasEnchants() || hasLore() || hasCustomModelData() || hasBlockData() || hasRepairCost() || !unhandledTags.isEmpty() || !persistentDataContainer.isEmpty() || hideFlag != 0 || isUnbreakable() || hasDamage() || hasAttributeModifiers() || hasPlaceableKeys() || hasDestroyableKeys()); // Paper - Implement an API for CanPlaceOn and CanDestroy NBT values } + @Override public String getDisplayName() { return CraftChatMessage.fromComponent(displayName, EnumChatFormat.WHITE); } + @Override public final void setDisplayName(String name) { this.displayName = CraftChatMessage.wrapOrNull(name); } + @Override public boolean hasDisplayName() { return displayName != null; } @@ -831,19 +898,23 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { return locName != null; } + @Override public boolean hasLore() { return this.lore != null && !this.lore.isEmpty(); } + @Override public boolean hasRepairCost() { return repairCost > 0; } + @Override public boolean hasEnchant(Enchantment ench) { Validate.notNull(ench, "Enchantment cannot be null"); return hasEnchants() && enchantments.containsKey(ench); } + @Override public int getEnchantLevel(Enchantment ench) { Validate.notNull(ench, "Enchantment cannot be null"); Integer level = hasEnchants() ? enchantments.get(ench) : null; @@ -853,10 +924,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { return level; } + @Override public Map getEnchants() { return hasEnchants() ? ImmutableSortedMap.copyOfSorted(enchantments) : ImmutableMap.of(); // Paper } + @Override public boolean addEnchant(Enchantment ench, int level, boolean ignoreRestrictions) { Validate.notNull(ench, "Enchantment cannot be null"); if (enchantments == null) { @@ -870,6 +943,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { return false; } + @Override public boolean removeEnchant(Enchantment ench) { Validate.notNull(ench, "Enchantment cannot be null"); // Spigot start @@ -882,10 +956,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { // Spigot end } + @Override public boolean hasEnchants() { return !(enchantments == null || enchantments.isEmpty()); } + @Override public boolean hasConflictingEnchant(Enchantment ench) { return checkConflictingEnchants(enchantments, ench); } @@ -927,16 +1003,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { return (byte) (1 << hideFlag.ordinal()); } + @Override public List getLore() { - return this.lore == null ? null : new ArrayList(this.lore); + return this.lore == null ? null : new ArrayList(Lists.transform(this.lore, (line) -> CraftChatMessage.fromComponent(line, EnumChatFormat.DARK_PURPLE))); } + @Override public void setLore(List lore) { // too tired to think if .clone is better if (lore == null) { this.lore = null; } else { if (this.lore == null) { - safelyAdd(lore, this.lore = new ArrayList(lore.size()), Integer.MAX_VALUE); + safelyAdd(lore, this.lore = new ArrayList(lore.size()), Integer.MAX_VALUE); } else { this.lore.clear(); safelyAdd(lore, this.lore, Integer.MAX_VALUE); @@ -944,10 +1022,43 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { } } + @Override + public boolean hasCustomModelData() { + return customModelData != null; + } + + @Override + public int getCustomModelData() { + Preconditions.checkState(hasCustomModelData(), "We don't have CustomModelData! Check hasCustomModelData first!"); + return customModelData; + } + + @Override + public void setCustomModelData(Integer data) { + this.customModelData = data; + } + + @Override + public boolean hasBlockData() { + return this.blockData != null; + } + + @Override + public BlockData getBlockData(Material material) { + return CraftBlockData.fromData(ItemBlock.getBlockState(CraftMagicNumbers.getBlock(material).getBlockData(), blockData)); + } + + @Override + public void setBlockData(BlockData blockData) { + this.blockData = (blockData == null) ? null : ((CraftBlockData) blockData).toStates(); + } + + @Override public int getRepairCost() { return repairCost; } + @Override public void setRepairCost(int cost) { // TODO: Does this have limits? repairCost = cost; } @@ -974,14 +1085,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { private void checkAttributeList() { if (attributeModifiers == null) { - attributeModifiers = HashMultimap.create(); + attributeModifiers = LinkedHashMultimap.create(); } } @Override public Multimap getAttributeModifiers(@Nullable EquipmentSlot slot) { checkAttributeList(); - SetMultimap result = HashMultimap.create(); + SetMultimap result = LinkedHashMultimap.create(); for (Map.Entry entry : attributeModifiers.entries()) { if (entry.getValue().getSlot() == null || entry.getValue().getSlot() == slot) { result.put(entry.getKey(), entry.getValue()); @@ -1010,11 +1121,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { @Override public void setAttributeModifiers(@Nullable Multimap attributeModifiers) { if (attributeModifiers == null || attributeModifiers.isEmpty()) { - this.attributeModifiers = HashMultimap.create(); + this.attributeModifiers = LinkedHashMultimap.create(); return; } - Iterator> iterator = attributeModifiers.entries().iterator(); + + checkAttributeList(); this.attributeModifiers.clear(); + + Iterator> iterator = attributeModifiers.entries().iterator(); while (iterator.hasNext()) { Map.Entry next = iterator.next(); @@ -1077,7 +1191,12 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { @Override public CustomItemTagContainer getCustomTagContainer() { - return this.publicItemTagContainer; + return new DeprecatedCustomTagContainer(this.getPersistentDataContainer()); + } + + @Override + public PersistentDataContainer getPersistentDataContainer() { + return this.persistentDataContainer; } private static boolean compareModifiers(Multimap first, Multimap second) { @@ -1137,13 +1256,16 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { && (this.hasLocalizedName()? that.hasLocalizedName()&& this.locName.equals(that.locName) : !that.hasLocalizedName()) && (this.hasEnchants() ? that.hasEnchants() && this.enchantments.equals(that.enchantments) : !that.hasEnchants()) && (this.hasLore() ? that.hasLore() && this.lore.equals(that.lore) : !that.hasLore()) + && (this.hasCustomModelData() ? that.hasCustomModelData() && this.customModelData.equals(that.customModelData) : !that.hasCustomModelData()) + && (this.hasBlockData() ? that.hasBlockData() && this.blockData.equals(that.blockData) : !that.hasBlockData()) && (this.hasRepairCost() ? that.hasRepairCost() && this.repairCost == that.repairCost : !that.hasRepairCost()) && (this.hasAttributeModifiers() ? that.hasAttributeModifiers() && compareModifiers(this.attributeModifiers, that.attributeModifiers) : !that.hasAttributeModifiers()) && (this.unhandledTags.equals(that.unhandledTags)) - && (this.publicItemTagContainer.equals(that.publicItemTagContainer)) + && (this.persistentDataContainer.equals(that.persistentDataContainer)) && (this.hideFlag == that.hideFlag) && (this.isUnbreakable() == that.isUnbreakable()) && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage()) + && (this.version == that.version) // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values && (this.hasPlaceableKeys() ? that.hasPlaceableKeys() && this.placeableKeys.equals(that.placeableKeys) : !that.hasPlaceableKeys()) && (this.hasDestroyableKeys() ? that.hasDestroyableKeys() && this.destroyableKeys.equals(that.destroyableKeys) : !that.hasDestroyableKeys()); @@ -1171,14 +1293,17 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { hash = 61 * hash + (hasDisplayName() ? this.displayName.hashCode() : 0); hash = 61 * hash + (hasLocalizedName()? this.locName.hashCode() : 0); hash = 61 * hash + (hasLore() ? this.lore.hashCode() : 0); + hash = 61 * hash + (hasCustomModelData() ? this.customModelData.hashCode() : 0); + hash = 61 * hash + (hasBlockData() ? this.blockData.hashCode() : 0); hash = 61 * hash + (hasEnchants() ? this.enchantments.hashCode() : 0); hash = 61 * hash + (hasRepairCost() ? this.repairCost : 0); hash = 61 * hash + unhandledTags.hashCode(); - hash = 61 * hash + (!publicItemTagContainer.isEmpty() ? publicItemTagContainer.hashCode() : 0); + hash = 61 * hash + (!persistentDataContainer.isEmpty() ? persistentDataContainer.hashCode() : 0); hash = 61 * hash + hideFlag; hash = 61 * hash + (isUnbreakable() ? 1231 : 1237); hash = 61 * hash + (hasDamage() ? this.damage : 0); hash = 61 * hash + (hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0); + hash = 61 * hash + version; // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values hash = 61 * hash + (hasPlaceableKeys() ? this.placeableKeys.hashCode() : 0); hash = 61 * hash + (hasDestroyableKeys() ? this.destroyableKeys.hashCode() : 0); @@ -1192,22 +1317,24 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { try { CraftMetaItem clone = (CraftMetaItem) super.clone(); if (this.lore != null) { - clone.lore = new ArrayList(this.lore); + clone.lore = new ArrayList(this.lore); } + clone.customModelData = this.customModelData; + clone.blockData = this.blockData; if (this.enchantments != null) { clone.enchantments = new EnchantmentMap(this.enchantments); // Paper } if (this.hasAttributeModifiers()) { - clone.attributeModifiers = HashMultimap.create(this.attributeModifiers); + clone.attributeModifiers = LinkedHashMultimap.create(this.attributeModifiers); } clone.hideFlag = this.hideFlag; clone.unbreakable = this.unbreakable; clone.damage = this.damage; + clone.version = this.version; // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values if (this.placeableKeys != null) { clone.placeableKeys = Sets.newHashSet(this.placeableKeys); } - if (this.destroyableKeys != null) { clone.destroyableKeys = Sets.newHashSet(this.destroyableKeys); } @@ -1218,6 +1345,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { } } + @Override public final Map serialize() { ImmutableMap.Builder map = ImmutableMap.builder(); map.put(SerializableMeta.TYPE_FIELD, SerializableMeta.classMap.get(getClass())); @@ -1235,7 +1363,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { } if (hasLore()) { - builder.put(LORE.BUKKIT, ImmutableList.copyOf(lore)); + builder.put(LORE.BUKKIT, ImmutableList.copyOf(Lists.transform(lore, CraftChatMessage::fromComponent))); + } + + if (hasCustomModelData()) { + builder.put(CUSTOM_MODEL_DATA.BUKKIT, customModelData); + } + if (hasBlockData()) { + builder.put(BLOCK_DATA.BUKKIT, CraftNBTTagConfigSerializer.serialize(blockData)); } serializeEnchantments(enchantments, builder, ENCHANTMENTS); @@ -1295,8 +1430,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { } } - if (!publicItemTagContainer.isEmpty()) { // Store custom tags, wrapped in their compound - builder.put(BUKKIT_CUSTOM_TAG.BUKKIT, publicItemTagContainer.serialize()); + if (!persistentDataContainer.isEmpty()) { // Store custom tags, wrapped in their compound + builder.put(BUKKIT_CUSTOM_TAG.BUKKIT, persistentDataContainer.serialize()); } return builder; @@ -1341,7 +1476,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { builder.put(key.BUKKIT, mods); } - static void safelyAdd(Iterable addFrom, Collection addTo, int maxItemLength) { + static void safelyAdd(Iterable addFrom, Collection addTo, int maxItemLength) { if (addFrom == null) { return; } @@ -1352,7 +1487,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { throw new IllegalArgumentException(addFrom + " cannot contain non-string " + object.getClass().getName()); } - addTo.add(""); + addTo.add(new ChatComponentText("")); } else { String page = object.toString(); @@ -1360,7 +1495,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { page = page.substring(0, maxItemLength); } - addTo.add(page); + addTo.add(CraftChatMessage.wrapOrEmpty(page)); } } } @@ -1384,11 +1519,22 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { return SerializableMeta.classMap.get(getClass()) + "_META:" + serialize(); // TODO: cry } + public int getVersion() { + return version; + } + + @Override + public void setVersion(int version) { + this.version = version; + } + public static Set getHandledTags() { synchronized (HANDLED_TAGS) { if (HANDLED_TAGS.isEmpty()) { HANDLED_TAGS.addAll(Arrays.asList( DISPLAY.NBT, + CUSTOM_MODEL_DATA.NBT, + BLOCK_DATA.NBT, REPAIR.NBT, ENCHANTMENTS.NBT, HIDEFLAGS.NBT, @@ -1422,6 +1568,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT, CraftMetaKnowledgeBook.BOOK_RECIPES.NBT, CraftMetaTropicalFishBucket.VARIANT.NBT, + CraftMetaCrossbow.CHARGED.NBT, + CraftMetaCrossbow.CHARGED_PROJECTILES.NBT, + CraftMetaSuspiciousStew.EFFECTS.NBT, // Paper start CraftMetaArmorStand.ENTITY_TAG.NBT, CraftMetaArmorStand.INVISIBLE.NBT, @@ -1592,7 +1741,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable { Namespaced resource = null; try { if (isTag) { - resource = new NamespacedTag(key.b(), key.getKey()); + resource = new NamespacedTag(key.getNamespace(), key.getKey()); } else { resource = CraftNamespacedKey.fromMinecraft(key); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java index 29471e0f7..2d2d73cc0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java @@ -59,6 +59,7 @@ public class CraftMetaKnowledgeBook extends CraftMetaItem implements KnowledgeBo } } + @Override void applyToItem(NBTTagCompound itemData) { super.applyToItem(itemData); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java index f321d854d..ecb12457a 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java @@ -1,20 +1,16 @@ package org.bukkit.craftbukkit.inventory; -import static org.bukkit.craftbukkit.inventory.CraftItemFactory.DEFAULT_LEATHER_COLOR; - +import static org.bukkit.craftbukkit.inventory.CraftItemFactory.*; +import com.google.common.collect.ImmutableMap.Builder; import java.util.Map; - import net.minecraft.server.NBTTagCompound; import net.minecraft.server.NBTTagInt; - import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; import org.bukkit.inventory.meta.LeatherArmorMeta; -import com.google.common.collect.ImmutableMap.Builder; - @DelegateDeserialization(SerializableMeta.class) class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta { static final ItemMetaKey COLOR = new ItemMetaKey("color"); @@ -72,6 +68,7 @@ class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta { boolean applicableTo(Material type) { switch(type) { case LEATHER_HELMET: + case LEATHER_HORSE_ARMOR: case LEATHER_CHESTPLATE: case LEATHER_LEGGINGS: case LEATHER_BOOTS: @@ -86,10 +83,12 @@ class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta { return (CraftMetaLeatherArmor) super.clone(); } + @Override public Color getColor() { return color; } + @Override public void setColor(Color color) { this.color = color == null ? DEFAULT_LEATHER_COLOR : color; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java index e5b1a7302..7489e63a1 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java @@ -1,23 +1,20 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import java.util.Map; - import net.minecraft.server.NBTTagCompound; import net.minecraft.server.NBTTagInt; import net.minecraft.server.NBTTagString; - import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.meta.MapMeta; import org.bukkit.map.MapView; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; -import org.bukkit.craftbukkit.util.CraftMagicNumbers; - @DelegateDeserialization(SerializableMeta.class) class CraftMetaMap extends CraftMetaItem implements MapMeta { static final ItemMetaKey MAP_SCALING = new ItemMetaKey("map_is_scaling", "scaling"); @@ -102,7 +99,7 @@ class CraftMetaMap extends CraftMetaItem implements MapMeta { if (hasMapId()){ tag.setInt(MAP_ID.NBT, getMapId()); } - + if (hasScaling()) { tag.setBoolean(MAP_SCALING.NBT, isScaling()); } @@ -170,10 +167,12 @@ class CraftMetaMap extends CraftMetaItem implements MapMeta { return scaling != SCALING_EMPTY; } + @Override public boolean isScaling() { return scaling == SCALING_TRUE; } + @Override public void setScaling(boolean scaling) { this.scaling = scaling ? SCALING_TRUE : SCALING_FALSE; } @@ -251,6 +250,7 @@ class CraftMetaMap extends CraftMetaItem implements MapMeta { } + @Override public CraftMetaMap clone() { return (CraftMetaMap) super.clone(); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java index 29fbdcc83..bb921c928 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java @@ -1,29 +1,25 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap.Builder; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; - import net.minecraft.server.NBTTagCompound; -import net.minecraft.server.NBTTagInt; import net.minecraft.server.NBTTagList; - import org.apache.commons.lang.Validate; import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.craftbukkit.potion.CraftPotionUtil; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionType; -import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; -import org.bukkit.craftbukkit.potion.CraftPotionUtil; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap.Builder; @DelegateDeserialization(SerializableMeta.class) class CraftMetaPotion extends CraftMetaItem implements PotionMeta { @@ -179,10 +175,12 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { return type; } + @Override public boolean hasCustomEffects() { return customEffects != null; } + @Override public List getCustomEffects() { if (hasCustomEffects()) { return ImmutableList.copyOf(customEffects); @@ -190,6 +188,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { return ImmutableList.of(); } + @Override public boolean addCustomEffect(PotionEffect effect, boolean overwrite) { Validate.notNull(effect, "Potion effect must not be null"); @@ -214,6 +213,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { } } + @Override public boolean removeCustomEffect(PotionEffectType type) { Validate.notNull(type, "Potion effect type must not be null"); @@ -236,11 +236,13 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { return changed; } + @Override public boolean hasCustomEffect(PotionEffectType type) { Validate.notNull(type, "Potion effect type must not be null"); return indexOfEffect(type) != -1; } + @Override public boolean setMainEffect(PotionEffectType type) { Validate.notNull(type, "Potion effect type must not be null"); int index = indexOfEffect(type); @@ -267,6 +269,7 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { return -1; } + @Override public boolean clearCustomEffects() { boolean changed = hasCustomEffects(); customEffects = null; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java index 87e51cf8a..aee97b9f0 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java @@ -1,15 +1,14 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.collect.ImmutableMap.Builder; +import com.mojang.authlib.GameProfile; import java.util.Map; - import com.destroystokyo.paper.profile.CraftPlayerProfile; import com.destroystokyo.paper.profile.PlayerProfile; import net.minecraft.server.GameProfileSerializer; import net.minecraft.server.NBTBase; import net.minecraft.server.NBTTagCompound; import net.minecraft.server.TileEntitySkull; -import net.minecraft.server.*; - import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -19,11 +18,7 @@ import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.meta.SkullMeta; -import com.google.common.collect.ImmutableMap.Builder; -import com.mojang.authlib.GameProfile; - import javax.annotation.Nullable; - @DelegateDeserialization(SerializableMeta.class) class CraftMetaSkull extends CraftMetaItem implements SkullMeta { @@ -129,10 +124,12 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { return (CraftMetaSkull) super.clone(); } + @Override public boolean hasOwner() { return profile != null && profile.getName() != null; } + @Override public String getOwner() { return hasOwner() ? profile.getName() : null; } @@ -165,6 +162,7 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { return null; } + @Override public boolean setOwner(String name) { if (name != null && name.length() > MAX_OWNER_LENGTH) { return false; @@ -175,7 +173,7 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { } else { // Paper start - Use Online Players Skull GameProfile newProfile = null; - EntityPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(name); + net.minecraft.server.EntityPlayer player = net.minecraft.server.MinecraftServer.getServer().getPlayerList().getPlayer(name); if (player != null) newProfile = player.getProfile(); if (newProfile == null) newProfile = new GameProfile(null, name); profile = newProfile; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java index 81f9bb629..082f85119 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSpawnEgg.java @@ -1,18 +1,13 @@ package org.bukkit.craftbukkit.inventory; import com.google.common.collect.ImmutableMap.Builder; -import com.mojang.datafixers.Dynamic; import java.util.Map; -import net.minecraft.server.DataConverterTypes; -import net.minecraft.server.DynamicOpsNBT; import net.minecraft.server.MinecraftKey; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.NBTBase; import net.minecraft.server.NBTTagCompound; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.craftbukkit.util.CraftLegacy; -import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.entity.EntityType; import org.bukkit.inventory.meta.SpawnEggMeta; import org.bukkit.material.MaterialData; @@ -117,18 +112,20 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta { switch (type) { case BAT_SPAWN_EGG: case BLAZE_SPAWN_EGG: + case CAT_SPAWN_EGG: case CAVE_SPIDER_SPAWN_EGG: case CHICKEN_SPAWN_EGG: case COD_SPAWN_EGG: case COW_SPAWN_EGG: case CREEPER_SPAWN_EGG: case DOLPHIN_SPAWN_EGG: - case DROWNED_SPAWN_EGG: case DONKEY_SPAWN_EGG: + case DROWNED_SPAWN_EGG: case ELDER_GUARDIAN_SPAWN_EGG: case ENDERMAN_SPAWN_EGG: case ENDERMITE_SPAWN_EGG: case EVOKER_SPAWN_EGG: + case FOX_SPAWN_EGG: case GHAST_SPAWN_EGG: case GUARDIAN_SPAWN_EGG: case HORSE_SPAWN_EGG: @@ -138,12 +135,15 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta { case MOOSHROOM_SPAWN_EGG: case MULE_SPAWN_EGG: case OCELOT_SPAWN_EGG: + case PANDA_SPAWN_EGG: case PARROT_SPAWN_EGG: case PHANTOM_SPAWN_EGG: case PIG_SPAWN_EGG: + case PILLAGER_SPAWN_EGG: case POLAR_BEAR_SPAWN_EGG: case PUFFERFISH_SPAWN_EGG: case RABBIT_SPAWN_EGG: + case RAVAGER_SPAWN_EGG: case SALMON_SPAWN_EGG: case SHEEP_SPAWN_EGG: case SHULKER_SPAWN_EGG: @@ -154,18 +154,20 @@ public class CraftMetaSpawnEgg extends CraftMetaItem implements SpawnEggMeta { case SPIDER_SPAWN_EGG: case SQUID_SPAWN_EGG: case STRAY_SPAWN_EGG: + case TRADER_LLAMA_SPAWN_EGG: case TROPICAL_FISH_SPAWN_EGG: case TURTLE_SPAWN_EGG: case VEX_SPAWN_EGG: case VILLAGER_SPAWN_EGG: case VINDICATOR_SPAWN_EGG: + case WANDERING_TRADER_SPAWN_EGG: case WITCH_SPAWN_EGG: case WITHER_SKELETON_SPAWN_EGG: case WOLF_SPAWN_EGG: case ZOMBIE_HORSE_SPAWN_EGG: case ZOMBIE_PIGMAN_SPAWN_EGG: case ZOMBIE_SPAWN_EGG: - case ZOMBIE_VILLAGER_SPAWN_EGG: + case ZOMBIE_VILLAGER_SPAWN_EGG: return true; default: return false; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java new file mode 100644 index 000000000..7ebc488fa --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSuspiciousStew.java @@ -0,0 +1,239 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap.Builder; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.inventory.meta.SuspiciousStewMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) +public class CraftMetaSuspiciousStew extends CraftMetaItem implements SuspiciousStewMeta { + + static final ItemMetaKey DURATION = new ItemMetaKey("EffectDuration", "duration"); + static final ItemMetaKey EFFECTS = new ItemMetaKey("Effects", "effects"); + static final ItemMetaKey ID = new ItemMetaKey("EffectId", "id"); + + private List customEffects; + + CraftMetaSuspiciousStew(CraftMetaItem meta) { + super(meta); + if (!(meta instanceof CraftMetaSuspiciousStew)) { + return; + } + CraftMetaSuspiciousStew stewMeta = ((CraftMetaSuspiciousStew) meta); + if (stewMeta.hasCustomEffects()) { + this.customEffects = new ArrayList(stewMeta.customEffects); + } + } + + CraftMetaSuspiciousStew(NBTTagCompound tag) { + super(tag); + if (tag.hasKey(EFFECTS.NBT)) { + NBTTagList list = tag.getList(EFFECTS.NBT, CraftMagicNumbers.NBT.TAG_COMPOUND); + int length = list.size(); + customEffects = new ArrayList(length); + + for (int i = 0; i < length; i++) { + NBTTagCompound effect = list.getCompound(i); + PotionEffectType type = PotionEffectType.getById(effect.getByte(ID.NBT)); + if (type == null) { + continue; + } + int duration = effect.getInt(DURATION.NBT); + customEffects.add(new PotionEffect(type, duration, 0)); + } + } + } + + CraftMetaSuspiciousStew(Map map) { + super(map); + + Iterable rawEffectList = SerializableMeta.getObject(Iterable.class, map, EFFECTS.BUKKIT, true); + if (rawEffectList == null) { + return; + } + + for (Object obj : rawEffectList) { + if (!(obj instanceof PotionEffect)) { + throw new IllegalArgumentException("Object in effect list is not valid. " + obj.getClass()); + } + addCustomEffect((PotionEffect) obj, true); + } + } + + @Override + void applyToItem(NBTTagCompound tag) { + super.applyToItem(tag); + + if (customEffects != null) { + NBTTagList effectList = new NBTTagList(); + tag.set(EFFECTS.NBT, effectList); + + for (PotionEffect effect : customEffects) { + NBTTagCompound effectData = new NBTTagCompound(); + effectData.setByte(ID.NBT, ((byte) effect.getType().getId())); + effectData.setInt(DURATION.NBT, effect.getDuration()); + effectList.add(effectData); + } + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isStewEmpty(); + } + + boolean isStewEmpty() { + return !hasCustomEffects(); + } + + @Override + boolean applicableTo(Material type) { + return type == Material.SUSPICIOUS_STEW; + } + + @Override + public CraftMetaSuspiciousStew clone() { + CraftMetaSuspiciousStew clone = ((CraftMetaSuspiciousStew) super.clone()); + if (this.customEffects != null) { + clone.customEffects = new ArrayList(this.customEffects); + } + return clone; + } + + @Override + public boolean hasCustomEffects() { + return customEffects != null; + } + + @Override + public List getCustomEffects() { + if (hasCustomEffects()) { + return ImmutableList.copyOf(customEffects); + } + return ImmutableList.of(); + } + + @Override + public boolean addCustomEffect(PotionEffect effect, boolean overwrite) { + Validate.notNull(effect, "Potion effect must not be null"); + + int index = indexOfEffect(effect.getType()); + if (index != -1) { + if (overwrite) { + PotionEffect old = customEffects.get(index); + if (old.getDuration() == effect.getDuration()) { + return false; + } + customEffects.set(index, effect); + return true; + } else { + return false; + } + } else { + if (customEffects == null) { + customEffects = new ArrayList(); + } + customEffects.add(effect); + return true; + } + } + + @Override + public boolean removeCustomEffect(PotionEffectType type) { + Validate.notNull(type, "Potion effect type must not be null"); + + if (!hasCustomEffects()) { + return false; + } + + boolean changed = false; + Iterator iterator = customEffects.iterator(); + while (iterator.hasNext()) { + PotionEffect effect = iterator.next(); + if (type.equals(effect.getType())) { + iterator.remove(); + changed = true; + } + } + if (customEffects.isEmpty()) { + customEffects = null; + } + return changed; + } + + @Override + public boolean hasCustomEffect(PotionEffectType type) { + Validate.notNull(type, "Potion effect type must not be null"); + return indexOfEffect(type) != -1; + } + + private int indexOfEffect(PotionEffectType type) { + if (!hasCustomEffects()) { + return -1; + } + + for (int i = 0; i < customEffects.size(); i++) { + if (customEffects.get(i).getType().equals(type)) { + return i; + } + } + return -1; + } + + @Override + public boolean clearCustomEffects() { + boolean changed = hasCustomEffects(); + customEffects = null; + return changed; + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + if (hasCustomEffects()) { + hash = 73 * hash + customEffects.hashCode(); + } + return original != hash ? CraftMetaSuspiciousStew.class.hashCode() ^ hash : hash; + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaSuspiciousStew) { + CraftMetaSuspiciousStew that = (CraftMetaSuspiciousStew) meta; + + return (this.hasCustomEffects() ? that.hasCustomEffects() && this.customEffects.equals(that.customEffects) : !that.hasCustomEffects()); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaSuspiciousStew || isStewEmpty()); + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + + if (hasCustomEffects()) { + builder.put(EFFECTS.BUKKIT, ImmutableList.copyOf(this.customEffects)); + } + + return builder; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java index f27df320b..eee51f07a 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaTropicalFishBucket.java @@ -1,15 +1,13 @@ package org.bukkit.craftbukkit.inventory; +import com.google.common.collect.ImmutableMap; import java.util.Map; - import net.minecraft.server.NBTTagCompound; +import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.configuration.serialization.DelegateDeserialization; -import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; - -import com.google.common.collect.ImmutableMap; -import org.bukkit.DyeColor; import org.bukkit.craftbukkit.entity.CraftTropicalFish; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.entity.TropicalFish; import org.bukkit.inventory.meta.TropicalFishBucketMeta; @@ -151,6 +149,7 @@ class CraftMetaTropicalFishBucket extends CraftMetaItem implements TropicalFishB } + @Override public CraftMetaTropicalFishBucket clone() { return (CraftMetaTropicalFishBucket) super.clone(); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java index 18743dda4..ef29599a8 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java @@ -1,6 +1,5 @@ package org.bukkit.craftbukkit.inventory; -import com.google.common.base.Preconditions; import java.util.ArrayList; import java.util.List; import net.minecraft.server.RecipeItemStack; diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftResultInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftResultInventory.java new file mode 100644 index 000000000..ff7f589a2 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftResultInventory.java @@ -0,0 +1,47 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.IInventory; +import org.bukkit.inventory.ItemStack; + +public class CraftResultInventory extends CraftInventory { + + private final IInventory resultInventory; + + public CraftResultInventory(IInventory inventory, IInventory resultInventory) { + super(inventory); + this.resultInventory = resultInventory; + } + + public IInventory getResultInventory() { + return resultInventory; + } + + public IInventory getIngredientsInventory() { + return inventory; + } + + @Override + public ItemStack getItem(int slot) { + if (slot < getIngredientsInventory().getSize()) { + net.minecraft.server.ItemStack item = getIngredientsInventory().getItem(slot); + return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item); + } else { + net.minecraft.server.ItemStack item = getResultInventory().getItem(slot - getIngredientsInventory().getSize()); + return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item); + } + } + + @Override + public void setItem(int index, ItemStack item) { + if (index < getIngredientsInventory().getSize()) { + getIngredientsInventory().setItem(index, CraftItemStack.asNMSCopy(item)); + } else { + getResultInventory().setItem((index - getIngredientsInventory().getSize()), CraftItemStack.asNMSCopy(item)); + } + } + + @Override + public int getSize() { + return getResultInventory().getSize() + getIngredientsInventory().getSize(); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java index 1d06a5976..6dbd249f5 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java @@ -1,12 +1,10 @@ package org.bukkit.craftbukkit.inventory; import java.util.Map; - import net.minecraft.server.MinecraftServer; import net.minecraft.server.NonNullList; import net.minecraft.server.RecipeItemStack; import net.minecraft.server.ShapedRecipes; - import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.inventory.ItemStack; @@ -44,6 +42,7 @@ public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { return ret; } + @Override public void addToCraftingManager() { String[] shape = this.getShape(); Map ingred = this.getChoiceMap(); @@ -57,6 +56,6 @@ public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { } } - MinecraftServer.getServer().getCraftingManager().a(new ShapedRecipes(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), width, shape.length, data, CraftItemStack.asNMSCopy(this.getResult()))); + MinecraftServer.getServer().getCraftingManager().addRecipe(new ShapedRecipes(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), width, shape.length, data, CraftItemStack.asNMSCopy(this.getResult()))); } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java index 0773b1359..4aba511fe 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java @@ -1,12 +1,10 @@ package org.bukkit.craftbukkit.inventory; import java.util.List; - import net.minecraft.server.MinecraftServer; import net.minecraft.server.NonNullList; import net.minecraft.server.RecipeItemStack; import net.minecraft.server.ShapelessRecipes; - import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.inventory.ItemStack; @@ -38,6 +36,7 @@ public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe return ret; } + @Override public void addToCraftingManager() { List ingred = this.getChoiceList(); NonNullList data = NonNullList.a(ingred.size(), RecipeItemStack.a); @@ -45,6 +44,6 @@ public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe data.set(i, toNMS(ingred.get(i), true)); } - MinecraftServer.getServer().getCraftingManager().a(new ShapelessRecipes(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), CraftItemStack.asNMSCopy(this.getResult()), data)); + MinecraftServer.getServer().getCraftingManager().addRecipe(new ShapelessRecipes(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), CraftItemStack.asNMSCopy(this.getResult()), data)); } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmokingRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmokingRecipe.java new file mode 100644 index 000000000..400437e2c --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmokingRecipe.java @@ -0,0 +1,30 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.MinecraftServer; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.RecipeChoice; +import org.bukkit.inventory.SmokingRecipe; + +public class CraftSmokingRecipe extends SmokingRecipe implements CraftRecipe { + public CraftSmokingRecipe(NamespacedKey key, ItemStack result, RecipeChoice source, float experience, int cookingTime) { + super(key, result, source, experience, cookingTime); + } + + public static CraftSmokingRecipe fromBukkitRecipe(SmokingRecipe recipe) { + if (recipe instanceof CraftSmokingRecipe) { + return (CraftSmokingRecipe) recipe; + } + CraftSmokingRecipe ret = new CraftSmokingRecipe(recipe.getKey(), recipe.getResult(), recipe.getInputChoice(), recipe.getExperience(), recipe.getCookingTime()); + ret.setGroup(recipe.getGroup()); + return ret; + } + + @Override + public void addToCraftingManager() { + ItemStack result = this.getResult(); + + MinecraftServer.getServer().getCraftingManager().addRecipe(new net.minecraft.server.RecipeSmoking(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), toNMS(this.getInputChoice(), true), CraftItemStack.asNMSCopy(result), getExperience(), getCookingTime())); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftStonecuttingRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftStonecuttingRecipe.java new file mode 100644 index 000000000..512a0e9d3 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftStonecuttingRecipe.java @@ -0,0 +1,30 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.MinecraftServer; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.RecipeChoice; +import org.bukkit.inventory.StonecuttingRecipe; + +public class CraftStonecuttingRecipe extends StonecuttingRecipe implements CraftRecipe { + public CraftStonecuttingRecipe(NamespacedKey key, ItemStack result, RecipeChoice source) { + super(key, result, source); + } + + public static CraftStonecuttingRecipe fromBukkitRecipe(StonecuttingRecipe recipe) { + if (recipe instanceof CraftStonecuttingRecipe) { + return (CraftStonecuttingRecipe) recipe; + } + CraftStonecuttingRecipe ret = new CraftStonecuttingRecipe(recipe.getKey(), recipe.getResult(), recipe.getInputChoice()); + ret.setGroup(recipe.getGroup()); + return ret; + } + + @Override + public void addToCraftingManager() { + ItemStack result = this.getResult(); + + MinecraftServer.getServer().getCraftingManager().addRecipe(new net.minecraft.server.RecipeStonecutting(CraftNamespacedKey.toMinecraft(this.getKey()), this.getGroup(), toNMS(this.getInputChoice(), true), CraftItemStack.asNMSCopy(result))); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/InventoryIterator.java b/src/main/java/org/bukkit/craftbukkit/inventory/InventoryIterator.java index e3b5f42ad..de558eef3 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/InventoryIterator.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/InventoryIterator.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.inventory; import java.util.ListIterator; - import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -20,32 +19,39 @@ public class InventoryIterator implements ListIterator { this.nextIndex = index; } + @Override public boolean hasNext() { return nextIndex < inventory.getSize(); } + @Override public ItemStack next() { lastDirection = true; return inventory.getItem(nextIndex++); } + @Override public int nextIndex() { return nextIndex; } + @Override public boolean hasPrevious() { return nextIndex > 0; } + @Override public ItemStack previous() { lastDirection = false; return inventory.getItem(--nextIndex); } + @Override public int previousIndex() { return nextIndex - 1; } + @Override public void set(ItemStack item) { if (lastDirection == null) { throw new IllegalStateException("No current item!"); @@ -54,11 +60,13 @@ public class InventoryIterator implements ListIterator { inventory.setItem(i, item); } + @Override public void add(ItemStack item) { throw new UnsupportedOperationException("Can't change the size of an inventory!"); } + @Override public void remove() { throw new UnsupportedOperationException("Can't change the size of an inventory!"); } -} \ No newline at end of file +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/InventoryWrapper.java b/src/main/java/org/bukkit/craftbukkit/inventory/InventoryWrapper.java deleted file mode 100644 index c280dbbc8..000000000 --- a/src/main/java/org/bukkit/craftbukkit/inventory/InventoryWrapper.java +++ /dev/null @@ -1,191 +0,0 @@ -package org.bukkit.craftbukkit.inventory; - -import com.google.common.base.Predicates; -import com.google.common.collect.Iterables; -import java.util.ArrayList; -import java.util.List; -import net.minecraft.server.EntityHuman; -import net.minecraft.server.IChatBaseComponent; -import net.minecraft.server.IInventory; -import net.minecraft.server.ItemStack; -import org.bukkit.Location; -import org.bukkit.craftbukkit.entity.CraftHumanEntity; -import org.bukkit.craftbukkit.util.CraftChatMessage; -import org.bukkit.entity.HumanEntity; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; - -public class InventoryWrapper implements IInventory { - - private final Inventory inventory; - private final List viewers = new ArrayList(); - - public InventoryWrapper(Inventory inventory) { - this.inventory = inventory; - } - - @Override - public int getSize() { - return inventory.getSize(); - } - - @Override - public ItemStack getItem(int i) { - return CraftItemStack.asNMSCopy(inventory.getItem(i)); - } - - @Override - public ItemStack splitStack(int i, int j) { - // Copied from CraftItemStack - ItemStack stack = getItem(i); - ItemStack result; - if (stack.isEmpty()) { - return stack; - } - if (stack.getCount() <= j) { - this.setItem(i, ItemStack.a); - result = stack; - } else { - result = CraftItemStack.copyNMSStack(stack, j); - stack.subtract(j); - } - this.update(); - return result; - } - - @Override - public ItemStack splitWithoutUpdate(int i) { - // Copied from CraftItemStack - ItemStack stack = getItem(i); - ItemStack result; - if (stack.isEmpty()) { - return stack; - } - if (stack.getCount() <= 1) { - this.setItem(i, ItemStack.a); - result = stack; - } else { - result = CraftItemStack.copyNMSStack(stack, 1); - stack.subtract(1); - } - return result; - } - - @Override - public void setItem(int i, ItemStack itemstack) { - inventory.setItem(i, CraftItemStack.asBukkitCopy(itemstack)); - } - - @Override - public int getMaxStackSize() { - return inventory.getMaxStackSize(); - } - - @Override - public void update() { - } - - @Override - public boolean a(EntityHuman entityhuman) { - return true; - } - - @Override - public void startOpen(EntityHuman entityhuman) { - } - - @Override - public void closeContainer(EntityHuman entityhuman) { - } - - @Override - public boolean b(int i, ItemStack itemstack) { - return true; - } - - @Override - public int getProperty(int i) { - return 0; - } - - @Override - public void setProperty(int i, int j) { - } - - @Override - public int h() { - return 0; - } - - @Override - public void clear() { - inventory.clear(); - } - - @Override - public List getContents() { - int size = getSize(); - List items = new ArrayList(size); - - for (int i = 0; i < size; i++) { - items.add(getItem(i)); - } - - return items; - } - - @Override - public void onOpen(CraftHumanEntity who) { - viewers.add(who); - } - - @Override - public void onClose(CraftHumanEntity who) { - viewers.remove(who); - } - - @Override - public List getViewers() { - return viewers; - } - - @Override - public InventoryHolder getOwner() { - return inventory.getHolder(); - } - - @Override - public void setMaxStackSize(int size) { - inventory.setMaxStackSize(size); - } - - @Override - public IChatBaseComponent getDisplayName() { - return CraftChatMessage.fromStringOrNull(inventory.getName()); - } - - @Override - public IChatBaseComponent getCustomName() { - return getDisplayName(); - } - - @Override - public boolean hasCustomName() { - return inventory.getName() != null; - } - - @Override - public IChatBaseComponent getScoreboardDisplayName() { - return getDisplayName(); - } - - @Override - public Location getLocation() { - return inventory.getLocation(); - } - - @Override - public boolean P_() { - return Iterables.any(inventory, Predicates.notNull()); - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java index 165225e73..1223bfc7f 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java @@ -1,28 +1,42 @@ package org.bukkit.craftbukkit.inventory; +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import java.util.Iterator; - +import java.util.Map; +import net.minecraft.server.IRecipe; +import net.minecraft.server.MinecraftKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.Recipes; import org.bukkit.inventory.Recipe; -import net.minecraft.server.IRecipe; -import net.minecraft.server.MinecraftServer; - public class RecipeIterator implements Iterator { - private final Iterator recipes; + private final Iterator, Object2ObjectLinkedOpenHashMap>>> recipes; + private Iterator> current; public RecipeIterator() { - this.recipes = MinecraftServer.getServer().getCraftingManager().recipes.values().iterator(); + this.recipes = MinecraftServer.getServer().getCraftingManager().recipes.entrySet().iterator(); } + @Override public boolean hasNext() { - return recipes.hasNext(); + return (current != null && current.hasNext()) || recipes.hasNext(); } + @Override public Recipe next() { - return recipes.next().toBukkitRecipe(); + if (current == null || !current.hasNext()) { + current = recipes.next().getValue().values().iterator(); + } + + return current.next().toBukkitRecipe(); } + @Override public void remove() { - recipes.remove(); + if (current == null) { + throw new IllegalStateException("next() not yet called"); + } + + current.remove(); } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/tags/CraftCustomItemTagContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/tags/CraftCustomItemTagContainer.java deleted file mode 100644 index fe663bbae..000000000 --- a/src/main/java/org/bukkit/craftbukkit/inventory/tags/CraftCustomItemTagContainer.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.bukkit.craftbukkit.inventory.tags; - -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import net.minecraft.server.NBTBase; -import net.minecraft.server.NBTTagCompound; -import org.apache.commons.lang.Validate; -import org.bukkit.NamespacedKey; -import org.bukkit.craftbukkit.inventory.CraftCustomTagTypeRegistry; -import org.bukkit.craftbukkit.util.CraftNBTTagConfigSerializer; -import org.bukkit.inventory.meta.tags.CustomItemTagContainer; -import org.bukkit.inventory.meta.tags.ItemTagAdapterContext; -import org.bukkit.inventory.meta.tags.ItemTagType; - -public final class CraftCustomItemTagContainer implements CustomItemTagContainer { - - private final Map customTags = new HashMap<>(); - private final CraftCustomTagTypeRegistry tagTypeRegistry; - private final CraftItemTagAdapterContext adapterContext; - - public CraftCustomItemTagContainer(Map customTags, CraftCustomTagTypeRegistry tagTypeRegistry) { - this(tagTypeRegistry); - this.customTags.putAll(customTags); - } - - public CraftCustomItemTagContainer(CraftCustomTagTypeRegistry tagTypeRegistry) { - this.tagTypeRegistry = tagTypeRegistry; - this.adapterContext = new CraftItemTagAdapterContext(this.tagTypeRegistry); - } - - @Override - public void setCustomTag(NamespacedKey key, ItemTagType type, Z value) { - Validate.notNull(key, "The provided key for the custom value was null"); - Validate.notNull(type, "The provided type for the custom value was null"); - Validate.notNull(value, "The provided value for the custom value was null"); - - this.customTags.put(key.toString(), tagTypeRegistry.wrap(type.getPrimitiveType(), type.toPrimitive(value, adapterContext))); - } - - @Override - public boolean hasCustomTag(NamespacedKey key, ItemTagType type) { - Validate.notNull(key, "The provided key for the custom value was null"); - Validate.notNull(type, "The provided type for the custom value was null"); - - NBTBase value = this.customTags.get(key.toString()); - if (value == null) { - return false; - } - - return tagTypeRegistry.isInstanceOf(type.getPrimitiveType(), value); - } - - @Override - public Z getCustomTag(NamespacedKey key, ItemTagType type) { - Validate.notNull(key, "The provided key for the custom value was null"); - Validate.notNull(type, "The provided type for the custom value was null"); - - NBTBase value = this.customTags.get(key.toString()); - if (value == null) { - return null; - } - - return type.fromPrimitive(tagTypeRegistry.extract(type.getPrimitiveType(), value), adapterContext); - } - - @Override - public void removeCustomTag(NamespacedKey key) { - Validate.notNull(key, "The provided key for the custom value was null"); - - this.customTags.remove(key.toString()); - } - - @Override - public boolean isEmpty() { - return this.customTags.isEmpty(); - } - - @Override - public ItemTagAdapterContext getAdapterContext() { - return this.adapterContext; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof CraftCustomItemTagContainer)) { - return false; - } - - Map myRawMap = getRaw(); - Map theirRawMap = ((CraftCustomItemTagContainer) obj).getRaw(); - - return Objects.equals(myRawMap, theirRawMap); - } - - public NBTTagCompound toTagCompound() { - NBTTagCompound tag = new NBTTagCompound(); - for (Entry entry : this.customTags.entrySet()) { - tag.set(entry.getKey(), entry.getValue()); - } - return tag; - } - - public void put(String key, NBTBase base) { - this.customTags.put(key, base); - } - - public void putAll(Map map) { - this.customTags.putAll(map); - } - - public void putAll(NBTTagCompound compound) { - for (String key : compound.getKeys()) { - this.customTags.put(key, compound.get(key)); - } - } - - public Map getRaw() { - return this.customTags; - } - - @Override - public int hashCode() { - int hashCode = 3; - hashCode += this.customTags.hashCode(); // We will simply add the maps hashcode - return hashCode; - } - - public Map serialize() { - return (Map) CraftNBTTagConfigSerializer.serialize(toTagCompound()); - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/tags/CraftItemTagAdapterContext.java b/src/main/java/org/bukkit/craftbukkit/inventory/tags/CraftItemTagAdapterContext.java deleted file mode 100644 index 5b81cad1f..000000000 --- a/src/main/java/org/bukkit/craftbukkit/inventory/tags/CraftItemTagAdapterContext.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.bukkit.craftbukkit.inventory.tags; - -import org.bukkit.craftbukkit.inventory.CraftCustomTagTypeRegistry; -import org.bukkit.inventory.meta.tags.CustomItemTagContainer; -import org.bukkit.inventory.meta.tags.ItemTagAdapterContext; - -public final class CraftItemTagAdapterContext implements ItemTagAdapterContext { - - private final CraftCustomTagTypeRegistry registry; - - public CraftItemTagAdapterContext(CraftCustomTagTypeRegistry registry) { - this.registry = registry; - } - - /** - * Creates a new and empty tag container instance - * - * @return the fresh container instance - */ - @Override - public CustomItemTagContainer newTagContainer() { - return new CraftCustomItemTagContainer(this.registry); - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedContainerTagType.java b/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedContainerTagType.java new file mode 100644 index 000000000..b2d113b48 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedContainerTagType.java @@ -0,0 +1,48 @@ +package org.bukkit.craftbukkit.inventory.tags; + +import org.apache.commons.lang3.Validate; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; +import org.bukkit.inventory.meta.tags.CustomItemTagContainer; +import org.bukkit.inventory.meta.tags.ItemTagType; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +public final class DeprecatedContainerTagType implements PersistentDataType { + + private final ItemTagType deprecated; + + DeprecatedContainerTagType(ItemTagType deprecated) { + this.deprecated = deprecated; + } + + @Override + public Class getPrimitiveType() { + return PersistentDataContainer.class; + } + + @Override + public Class getComplexType() { + return deprecated.getComplexType(); + } + + @Override + public PersistentDataContainer toPrimitive(Z complex, PersistentDataAdapterContext context) { + CustomItemTagContainer deprecated = this.deprecated.toPrimitive(complex, new DeprecatedItemAdapterContext(context)); + Validate.isInstanceOf(DeprecatedCustomTagContainer.class, deprecated, "Could not wrap deprecated API due to foreign CustomItemTagContainer implementation %s", deprecated.getClass().getSimpleName()); + + DeprecatedCustomTagContainer tagContainer = (DeprecatedCustomTagContainer) deprecated; + PersistentDataContainer wrapped = tagContainer.getWrapped(); + Validate.isInstanceOf(CraftPersistentDataContainer.class, wrapped, "Could not wrap deprecated API due to wrong deprecation wrapper %s", deprecated.getClass().getSimpleName()); + + CraftPersistentDataContainer craftTagContainer = (CraftPersistentDataContainer) wrapped; + return new CraftPersistentDataContainer(craftTagContainer.getRaw(), craftTagContainer.getDataTagTypeRegistry()); + } + + @Override + public Z fromPrimitive(PersistentDataContainer primitive, PersistentDataAdapterContext context) { + Validate.isInstanceOf(CraftPersistentDataContainer.class, primitive, "Could not wrap deprecated API due to foreign PersistentMetadataContainer implementation %s", primitive.getClass().getSimpleName()); + + return this.deprecated.fromPrimitive(new DeprecatedCustomTagContainer(primitive), new DeprecatedItemAdapterContext(context)); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedCustomTagContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedCustomTagContainer.java new file mode 100644 index 000000000..3ef217b08 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedCustomTagContainer.java @@ -0,0 +1,68 @@ +package org.bukkit.craftbukkit.inventory.tags; + +import java.util.Objects; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.meta.tags.CustomItemTagContainer; +import org.bukkit.inventory.meta.tags.ItemTagAdapterContext; +import org.bukkit.inventory.meta.tags.ItemTagType; +import org.bukkit.persistence.PersistentDataContainer; + +/** + * The {@link DeprecatedCustomTagContainer} is a simply wrapper implementation + * that wraps the new api to still be usable with the old api parts. + */ +@SuppressWarnings("unchecked") +public final class DeprecatedCustomTagContainer implements CustomItemTagContainer { + + private final PersistentDataContainer wrapped; + + public DeprecatedCustomTagContainer(PersistentDataContainer wrapped) { + this.wrapped = wrapped; + } + + @Override + public void setCustomTag(NamespacedKey key, ItemTagType type, Z value) { + if (Objects.equals(CustomItemTagContainer.class, type.getPrimitiveType())) { + wrapped.set(key, new DeprecatedContainerTagType<>((ItemTagType) type), value); + } else { + wrapped.set(key, new DeprecatedItemTagType<>(type), value); + } + } + + @Override + public boolean hasCustomTag(NamespacedKey key, ItemTagType type) { + if (Objects.equals(CustomItemTagContainer.class, type.getPrimitiveType())) { + return wrapped.has(key, new DeprecatedContainerTagType<>((ItemTagType) type)); + } else { + return wrapped.has(key, new DeprecatedItemTagType<>(type)); + } + } + + @Override + public Z getCustomTag(NamespacedKey key, ItemTagType type) { + if (Objects.equals(CustomItemTagContainer.class, type.getPrimitiveType())) { + return wrapped.get(key, new DeprecatedContainerTagType<>((ItemTagType) type)); + } else { + return wrapped.get(key, new DeprecatedItemTagType<>(type)); + } + } + + @Override + public void removeCustomTag(NamespacedKey key) { + wrapped.remove(key); + } + + @Override + public boolean isEmpty() { + return wrapped.isEmpty(); + } + + @Override + public ItemTagAdapterContext getAdapterContext() { + return new DeprecatedItemAdapterContext(this.wrapped.getAdapterContext()); + } + + public PersistentDataContainer getWrapped() { + return wrapped; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedItemAdapterContext.java b/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedItemAdapterContext.java new file mode 100644 index 000000000..e8bb75e9f --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedItemAdapterContext.java @@ -0,0 +1,24 @@ +package org.bukkit.craftbukkit.inventory.tags; + +import org.bukkit.inventory.meta.tags.CustomItemTagContainer; +import org.bukkit.inventory.meta.tags.ItemTagAdapterContext; +import org.bukkit.persistence.PersistentDataAdapterContext; + +public final class DeprecatedItemAdapterContext implements ItemTagAdapterContext { + + private final PersistentDataAdapterContext context; + + public DeprecatedItemAdapterContext(PersistentDataAdapterContext context) { + this.context = context; + } + + /** + * Creates a new and empty tag container instance. + * + * @return the fresh container instance + */ + @Override + public CustomItemTagContainer newTagContainer() { + return new DeprecatedCustomTagContainer(context.newPersistentDataContainer()); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedItemTagType.java b/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedItemTagType.java new file mode 100644 index 000000000..3e3d3804e --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/tags/DeprecatedItemTagType.java @@ -0,0 +1,34 @@ +package org.bukkit.craftbukkit.inventory.tags; + +import org.bukkit.inventory.meta.tags.ItemTagType; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +public final class DeprecatedItemTagType implements PersistentDataType { + + private final ItemTagType deprecated; + + public DeprecatedItemTagType(ItemTagType deprecated) { + this.deprecated = deprecated; + } + + @Override + public Class getPrimitiveType() { + return deprecated.getPrimitiveType(); + } + + @Override + public Class getComplexType() { + return deprecated.getComplexType(); + } + + @Override + public T toPrimitive(Z complex, PersistentDataAdapterContext context) { + return this.deprecated.toPrimitive(complex, new DeprecatedItemAdapterContext(context)); + } + + @Override + public Z fromPrimitive(T primitive, PersistentDataAdapterContext context) { + return this.deprecated.fromPrimitive(primitive, new DeprecatedItemAdapterContext(context)); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftInventoryCreator.java b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftInventoryCreator.java index d25928e09..ae280dd40 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftInventoryCreator.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftInventoryCreator.java @@ -25,9 +25,17 @@ public final class CraftInventoryCreator { converterMap.put(InventoryType.MERCHANT, DEFAULT_CONVERTER); converterMap.put(InventoryType.ENDER_CHEST, DEFAULT_CONVERTER); converterMap.put(InventoryType.ANVIL, DEFAULT_CONVERTER); - converterMap.put(InventoryType.BEACON, new CraftTileInventoryConverter.Beacon()); + converterMap.put(InventoryType.BEACON, DEFAULT_CONVERTER); converterMap.put(InventoryType.HOPPER, new CraftTileInventoryConverter.Hopper()); converterMap.put(InventoryType.SHULKER_BOX, DEFAULT_CONVERTER); + converterMap.put(InventoryType.BARREL, DEFAULT_CONVERTER); + converterMap.put(InventoryType.BLAST_FURNACE, new CraftTileInventoryConverter.BlastFurnace()); + converterMap.put(InventoryType.LECTERN, new CraftTileInventoryConverter.Lectern()); + converterMap.put(InventoryType.SMOKER, new CraftTileInventoryConverter.Smoker()); + converterMap.put(InventoryType.LOOM, DEFAULT_CONVERTER); + converterMap.put(InventoryType.CARTOGRAPHY, DEFAULT_CONVERTER); + converterMap.put(InventoryType.GRINDSTONE, DEFAULT_CONVERTER); + converterMap.put(InventoryType.STONECUTTER, DEFAULT_CONVERTER); } public Inventory createInventory(InventoryHolder holder, InventoryType type) { diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java index bb09139f8..f6fa0650f 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java @@ -1,17 +1,19 @@ package org.bukkit.craftbukkit.inventory.util; import net.minecraft.server.DimensionManager; -import net.minecraft.server.ITileInventory; +import net.minecraft.server.IInventory; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.TileEntityBlastFurnace; import net.minecraft.server.TileEntityBrewingStand; import net.minecraft.server.TileEntityDispenser; import net.minecraft.server.TileEntityDropper; import net.minecraft.server.TileEntityFurnace; +import net.minecraft.server.TileEntityFurnaceFurnace; import net.minecraft.server.TileEntityHopper; +import net.minecraft.server.TileEntityLectern; import net.minecraft.server.TileEntityLootable; +import net.minecraft.server.TileEntitySmoker; import org.bukkit.craftbukkit.inventory.CraftInventory; -import org.bukkit.craftbukkit.inventory.CraftInventoryBeacon; import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer; import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace; import org.bukkit.craftbukkit.util.CraftChatMessage; @@ -21,7 +23,7 @@ import org.bukkit.inventory.InventoryHolder; public abstract class CraftTileInventoryConverter implements CraftInventoryCreator.InventoryConverter { - public abstract ITileInventory getTileEntity(); + public abstract IInventory getTileEntity(); @Override public Inventory createInventory(InventoryHolder holder, InventoryType type) { @@ -30,7 +32,7 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat @Override public Inventory createInventory(InventoryHolder holder, InventoryType type, String title) { - ITileInventory te = getTileEntity(); + IInventory te = getTileEntity(); if (te instanceof TileEntityLootable) { ((TileEntityLootable) te).setCustomName(CraftChatMessage.fromStringOrNull(title)); } @@ -38,28 +40,28 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat return getInventory(te); } - public Inventory getInventory(ITileInventory tileEntity) { + public Inventory getInventory(IInventory tileEntity) { return new CraftInventory(tileEntity); } public static class Furnace extends CraftTileInventoryConverter { @Override - public ITileInventory getTileEntity() { - TileEntityFurnace furnace = new TileEntityFurnace(); + public IInventory getTileEntity() { + TileEntityFurnace furnace = new TileEntityFurnaceFurnace(); furnace.setWorld(MinecraftServer.getServer().getWorldServer(DimensionManager.OVERWORLD)); // TODO: customize this if required return furnace; } @Override public Inventory createInventory(InventoryHolder owner, InventoryType type, String title) { - ITileInventory tileEntity = getTileEntity(); + IInventory tileEntity = getTileEntity(); ((TileEntityFurnace) tileEntity).setCustomName(CraftChatMessage.fromStringOrNull(title)); return getInventory(tileEntity); } @Override - public Inventory getInventory(ITileInventory tileEntity) { + public Inventory getInventory(IInventory tileEntity) { return new CraftInventoryFurnace((TileEntityFurnace) tileEntity); } } @@ -67,14 +69,14 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat public static class BrewingStand extends CraftTileInventoryConverter { @Override - public ITileInventory getTileEntity() { + public IInventory getTileEntity() { return new TileEntityBrewingStand(); } @Override public Inventory createInventory(InventoryHolder holder, InventoryType type, String title) { // BrewingStand does not extend TileEntityLootable - ITileInventory tileEntity = getTileEntity(); + IInventory tileEntity = getTileEntity(); if (tileEntity instanceof TileEntityBrewingStand) { ((TileEntityBrewingStand) tileEntity).setCustomName(CraftChatMessage.fromStringOrNull(title)); } @@ -82,28 +84,15 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat } @Override - public Inventory getInventory(ITileInventory tileEntity) { + public Inventory getInventory(IInventory tileEntity) { return new CraftInventoryBrewer(tileEntity); } } - public static class Beacon extends CraftTileInventoryConverter { - - @Override - public ITileInventory getTileEntity() { - return new TileEntityBeacon(); - } - - @Override - public Inventory getInventory(ITileInventory tileInventory) { - return new CraftInventoryBeacon((TileEntityBeacon) tileInventory); - } - } - public static class Dispenser extends CraftTileInventoryConverter { @Override - public ITileInventory getTileEntity() { + public IInventory getTileEntity() { return new TileEntityDispenser(); } } @@ -111,7 +100,7 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat public static class Dropper extends CraftTileInventoryConverter { @Override - public ITileInventory getTileEntity() { + public IInventory getTileEntity() { return new TileEntityDropper(); } } @@ -119,8 +108,32 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat public static class Hopper extends CraftTileInventoryConverter { @Override - public ITileInventory getTileEntity() { + public IInventory getTileEntity() { return new TileEntityHopper(); } } + + public static class BlastFurnace extends CraftTileInventoryConverter { + + @Override + public IInventory getTileEntity() { + return new TileEntityBlastFurnace(); + } + } + + public static class Lectern extends CraftTileInventoryConverter { + + @Override + public IInventory getTileEntity() { + return new TileEntityLectern().inventory; + } + } + + public static class Smoker extends CraftTileInventoryConverter { + + @Override + public IInventory getTileEntity() { + return new TileEntitySmoker(); + } + } } diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java index 7372614c7..04b3ab0b4 100644 --- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java +++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java @@ -20,18 +20,22 @@ public class CraftMapCanvas implements MapCanvas { Arrays.fill(buffer, (byte) -1); } + @Override public CraftMapView getMapView() { return mapView; } + @Override public MapCursorCollection getCursors() { return cursors; } + @Override public void setCursors(MapCursorCollection cursors) { this.cursors = cursors; } + @Override public void setPixel(int x, int y, byte color) { if (x < 0 || y < 0 || x >= 128 || y >= 128) return; @@ -41,12 +45,14 @@ public class CraftMapCanvas implements MapCanvas { } } + @Override public byte getPixel(int x, int y) { if (x < 0 || y < 0 || x >= 128 || y >= 128) return 0; return buffer[y * 128 + x]; } + @Override public byte getBasePixel(int x, int y) { if (x < 0 || y < 0 || x >= 128 || y >= 128) return 0; @@ -61,6 +67,7 @@ public class CraftMapCanvas implements MapCanvas { return buffer; } + @Override public void drawImage(int x, int y, Image image) { byte[] bytes = MapPalette.imageToBytes(image); for (int x2 = 0; x2 < image.getWidth(null); ++x2) { @@ -70,6 +77,7 @@ public class CraftMapCanvas implements MapCanvas { } } + @Override public void drawText(int x, int y, MapFont font, String text) { int xStart = x; byte color = MapPalette.DARK_GRAY; diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java index e6c6a675d..93b39092c 100644 --- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java +++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java @@ -1,8 +1,7 @@ package org.bukkit.craftbukkit.map; -import net.minecraft.server.WorldMap; import net.minecraft.server.MapIcon; - +import net.minecraft.server.WorldMap; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.entity.Player; @@ -43,7 +42,7 @@ public class CraftMapRenderer extends MapRenderer { } MapIcon decoration = (MapIcon) worldMap.decorations.get(key); - cursors.addCursor(decoration.getX(), decoration.getY(), (byte) (decoration.getRotation() & 15), decoration.b().a(), true, CraftChatMessage.fromComponent(decoration.g())); + cursors.addCursor(decoration.getX(), decoration.getY(), (byte) (decoration.getRotation() & 15), decoration.getType().a(), true, CraftChatMessage.fromComponent(decoration.getName())); } } diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java index d52fcde17..f44ef67af 100644 --- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java +++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java @@ -6,12 +6,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; - import net.minecraft.server.DimensionManager; import net.minecraft.server.MinecraftServer; import net.minecraft.server.WorldMap; import net.minecraft.server.WorldServer; - import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.craftbukkit.CraftWorld; @@ -46,18 +44,22 @@ public final class CraftMapView implements MapView { } } + @Override public boolean isVirtual() { return renderers.size() > 0 && !(renderers.get(0) instanceof CraftMapRenderer); } + @Override public Scale getScale() { return Scale.valueOf(worldMap.scale); } + @Override public void setScale(Scale scale) { worldMap.scale = scale.getValue(); } + @Override public World getWorld() { DimensionManager dimension = worldMap.map; WorldServer world = MinecraftServer.getServer().getWorldServer(dimension); @@ -65,30 +67,37 @@ public final class CraftMapView implements MapView { return (world == null) ? null : world.getWorld(); } + @Override public void setWorld(World world) { - worldMap.map = ((CraftWorld) world).getHandle().dimension; + worldMap.map = ((CraftWorld) world).getHandle().getWorldProvider().getDimensionManager(); } + @Override public int getCenterX() { return worldMap.centerX; } + @Override public int getCenterZ() { return worldMap.centerZ; } + @Override public void setCenterX(int x) { worldMap.centerX = x; } + @Override public void setCenterZ(int z) { worldMap.centerZ = z; } + @Override public List getRenderers() { return new ArrayList(renderers); } + @Override public void addRenderer(MapRenderer renderer) { if (!renderers.contains(renderer)) { renderers.add(renderer); @@ -97,6 +106,7 @@ public final class CraftMapView implements MapView { } } + @Override public boolean removeRenderer(MapRenderer renderer) { if (renderers.contains(renderer)) { renderers.remove(renderer); @@ -166,6 +176,16 @@ public final class CraftMapView implements MapView { return render; } + @Override + public boolean isTrackingPosition() { + return worldMap.track; + } + + @Override + public void setTrackingPosition(boolean trackingPosition) { + worldMap.track = trackingPosition; + } + @Override public boolean isUnlimitedTracking() { return worldMap.unlimitedTracking; @@ -175,4 +195,14 @@ public final class CraftMapView implements MapView { public void setUnlimitedTracking(boolean unlimited) { worldMap.unlimitedTracking = unlimited; } + + @Override + public boolean isLocked() { + return worldMap.locked; + } + + @Override + public void setLocked(boolean locked) { + worldMap.locked = locked; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/metadata/BlockMetadataStore.java b/src/main/java/org/bukkit/craftbukkit/metadata/BlockMetadataStore.java index 6f7102f26..6441d0e04 100644 --- a/src/main/java/org/bukkit/craftbukkit/metadata/BlockMetadataStore.java +++ b/src/main/java/org/bukkit/craftbukkit/metadata/BlockMetadataStore.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.metadata; +import java.util.List; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.metadata.MetadataStore; @@ -7,8 +8,6 @@ import org.bukkit.metadata.MetadataStoreBase; import org.bukkit.metadata.MetadataValue; import org.bukkit.plugin.Plugin; -import java.util.List; - /** * A BlockMetadataStore stores metadata values for {@link Block} objects. */ diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataAdapterContext.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataAdapterContext.java new file mode 100644 index 000000000..6371f6836 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataAdapterContext.java @@ -0,0 +1,22 @@ +package org.bukkit.craftbukkit.persistence; + +import org.bukkit.persistence.PersistentDataAdapterContext; + +public final class CraftPersistentDataAdapterContext implements PersistentDataAdapterContext { + + private final CraftPersistentDataTypeRegistry registry; + + public CraftPersistentDataAdapterContext(CraftPersistentDataTypeRegistry registry) { + this.registry = registry; + } + + /** + * Creates a new and empty tag container instance + * + * @return the fresh container instance + */ + @Override + public CraftPersistentDataContainer newPersistentDataContainer() { + return new CraftPersistentDataContainer(this.registry); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java new file mode 100644 index 000000000..6c6540dd3 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java @@ -0,0 +1,142 @@ +package org.bukkit.craftbukkit.persistence; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import net.minecraft.server.NBTBase; +import net.minecraft.server.NBTTagCompound; +import org.apache.commons.lang.Validate; +import org.bukkit.NamespacedKey; +import org.bukkit.craftbukkit.util.CraftNBTTagConfigSerializer; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +public final class CraftPersistentDataContainer implements PersistentDataContainer { + + private final Map customDataTags = new HashMap<>(); + private final CraftPersistentDataTypeRegistry registry; + private final CraftPersistentDataAdapterContext adapterContext; + + public CraftPersistentDataContainer(Map customTags, CraftPersistentDataTypeRegistry registry) { + this(registry); + this.customDataTags.putAll(customTags); + } + + public CraftPersistentDataContainer(CraftPersistentDataTypeRegistry registry) { + this.registry = registry; + this.adapterContext = new CraftPersistentDataAdapterContext(this.registry); + } + + @Override + public void set(NamespacedKey key, PersistentDataType type, Z value) { + Validate.notNull(key, "The provided key for the custom value was null"); + Validate.notNull(type, "The provided type for the custom value was null"); + Validate.notNull(value, "The provided value for the custom value was null"); + + this.customDataTags.put(key.toString(), registry.wrap(type.getPrimitiveType(), type.toPrimitive(value, adapterContext))); + } + + @Override + public boolean has(NamespacedKey key, PersistentDataType type) { + Validate.notNull(key, "The provided key for the custom value was null"); + Validate.notNull(type, "The provided type for the custom value was null"); + + NBTBase value = this.customDataTags.get(key.toString()); + if (value == null) { + return false; + } + + return registry.isInstanceOf(type.getPrimitiveType(), value); + } + + @Override + public Z get(NamespacedKey key, PersistentDataType type) { + Validate.notNull(key, "The provided key for the custom value was null"); + Validate.notNull(type, "The provided type for the custom value was null"); + + NBTBase value = this.customDataTags.get(key.toString()); + if (value == null) { + return null; + } + + return type.fromPrimitive(registry.extract(type.getPrimitiveType(), value), adapterContext); + } + + @Override + public Z getOrDefault(NamespacedKey key, PersistentDataType type, Z defaultValue) { + Z z = get(key, type); + return z != null ? z : defaultValue; + } + + @Override + public void remove(NamespacedKey key) { + Validate.notNull(key, "The provided key for the custom value was null"); + + this.customDataTags.remove(key.toString()); + } + + @Override + public boolean isEmpty() { + return this.customDataTags.isEmpty(); + } + + @Override + public PersistentDataAdapterContext getAdapterContext() { + return this.adapterContext; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CraftPersistentDataContainer)) { + return false; + } + + Map myRawMap = getRaw(); + Map theirRawMap = ((CraftPersistentDataContainer) obj).getRaw(); + + return Objects.equals(myRawMap, theirRawMap); + } + + public NBTTagCompound toTagCompound() { + NBTTagCompound tag = new NBTTagCompound(); + for (Entry entry : this.customDataTags.entrySet()) { + tag.set(entry.getKey(), entry.getValue()); + } + return tag; + } + + public void put(String key, NBTBase base) { + this.customDataTags.put(key, base); + } + + public void putAll(Map map) { + this.customDataTags.putAll(map); + } + + public void putAll(NBTTagCompound compound) { + for (String key : compound.getKeys()) { + this.customDataTags.put(key, compound.get(key)); + } + } + + public Map getRaw() { + return this.customDataTags; + } + + public CraftPersistentDataTypeRegistry getDataTagTypeRegistry() { + return registry; + } + + @Override + public int hashCode() { + int hashCode = 3; + hashCode += this.customDataTags.hashCode(); // We will simply add the maps hashcode + return hashCode; + } + + public Map serialize() { + return (Map) CraftNBTTagConfigSerializer.serialize(toTagCompound()); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftCustomTagTypeRegistry.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataTypeRegistry.java similarity index 82% rename from src/main/java/org/bukkit/craftbukkit/inventory/CraftCustomTagTypeRegistry.java rename to src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataTypeRegistry.java index 47ff875b9..0bf63e459 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftCustomTagTypeRegistry.java +++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataTypeRegistry.java @@ -1,11 +1,11 @@ -package org.bukkit.craftbukkit.inventory; +package org.bukkit.craftbukkit.persistence; -import com.google.common.primitives.Primitives; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.function.Function; +import com.google.common.primitives.Primitives; import net.minecraft.server.NBTBase; import net.minecraft.server.NBTTagByte; import net.minecraft.server.NBTTagByteArray; @@ -19,17 +19,16 @@ import net.minecraft.server.NBTTagLongArray; import net.minecraft.server.NBTTagShort; import net.minecraft.server.NBTTagString; import org.apache.commons.lang3.Validate; -import org.bukkit.craftbukkit.inventory.tags.CraftCustomItemTagContainer; -import org.bukkit.inventory.meta.tags.CustomItemTagContainer; +import org.bukkit.persistence.PersistentDataContainer; /** * This class represents a registry that contains the used adapters for. */ -public final class CraftCustomTagTypeRegistry { +public final class CraftPersistentDataTypeRegistry { - private final Function CREATE_ADAPTER = this::createAdapter; + private final Function CREATE_ADAPTER = this::createAdapter; - private class CustomTagAdapter { + private class TagAdapter { private final Function builder; private final Function extractor; @@ -37,7 +36,7 @@ public final class CraftCustomTagTypeRegistry { private final Class primitiveType; private final Class nbtBaseType; - public CustomTagAdapter(Class primitiveType, Class nbtBaseType, Function builder, Function extractor) { + public TagAdapter(Class primitiveType, Class nbtBaseType, Function builder, Function extractor) { this.primitiveType = primitiveType; this.nbtBaseType = nbtBaseType; this.builder = builder; @@ -49,7 +48,9 @@ public final class CraftCustomTagTypeRegistry { * the expected primitive type. * * @param base the base to extract from + * * @return the value stored inside of the tag + * * @throws ClassCastException if the passed base is not an instanced of * the defined base type and therefore is not applicable to the * extractor function @@ -63,7 +64,9 @@ public final class CraftCustomTagTypeRegistry { * Builds a tag instance wrapping around the provided value object. * * @param value the value to store inside the created tag + * * @return the new tag instance + * * @throws ClassCastException if the passed value object is not of the * defined primitive type and therefore is not applicable to the builder * function @@ -77,6 +80,7 @@ public final class CraftCustomTagTypeRegistry { * Returns if the tag instance matches the adapters one. * * @param base the base to check + * * @return if the tag was an instance of the set type */ boolean isInstance(NBTBase base) { @@ -84,18 +88,20 @@ public final class CraftCustomTagTypeRegistry { } } - private final Map adapters = new HashMap<>(); + private final Map adapters = new HashMap<>(); /** * Creates a suitable adapter instance for the primitive class type * * @param type the type to create an adapter for * @param the generic type of that class + * * @return the created adapter instance + * * @throws IllegalArgumentException if no suitable tag type adapter for this * type was found */ - private CustomTagAdapter createAdapter(Class type) { + private TagAdapter createAdapter(Class type) { if (!Primitives.isWrapperType(type)) { type = Primitives.wrap(type); //Make sure we will always "switch" over the wrapper types } @@ -133,22 +139,22 @@ public final class CraftCustomTagTypeRegistry { Primitive Arrays */ if (Objects.equals(byte[].class, type)) { - return createAdapter(byte[].class, NBTTagByteArray.class, array -> new NBTTagByteArray(Arrays.copyOf(array, array.length)), n -> Arrays.copyOf(n.c(), n.size())); + return createAdapter(byte[].class, NBTTagByteArray.class, array -> new NBTTagByteArray(Arrays.copyOf(array, array.length)), n -> Arrays.copyOf(n.getBytes(), n.size())); } if (Objects.equals(int[].class, type)) { - return createAdapter(int[].class, NBTTagIntArray.class, array -> new NBTTagIntArray(Arrays.copyOf(array, array.length)), n -> Arrays.copyOf(n.d(), n.size())); + return createAdapter(int[].class, NBTTagIntArray.class, array -> new NBTTagIntArray(Arrays.copyOf(array, array.length)), n -> Arrays.copyOf(n.getInts(), n.size())); } if (Objects.equals(long[].class, type)) { - return createAdapter(long[].class, NBTTagLongArray.class, array -> new NBTTagLongArray(Arrays.copyOf(array, array.length)), n -> Arrays.copyOf(n.d(), n.size())); + return createAdapter(long[].class, NBTTagLongArray.class, array -> new NBTTagLongArray(Arrays.copyOf(array, array.length)), n -> Arrays.copyOf(n.getLongs(), n.size())); } /* - Note that this will map the interface CustomItemTagContainer directly to the CraftBukkit implementation - Passing any other instance of this form to the tag type registry will throw a ClassCastException as defined in CustomTagAdapter#build + Note that this will map the interface PersistentMetadataContainer directly to the CraftBukkit implementation + Passing any other instance of this form to the tag type registry will throw a ClassCastException as defined in TagAdapter#build */ - if (Objects.equals(CustomItemTagContainer.class, type)) { - return createAdapter(CraftCustomItemTagContainer.class, NBTTagCompound.class, CraftCustomItemTagContainer::toTagCompound, tag -> { - CraftCustomItemTagContainer container = new CraftCustomItemTagContainer(this); + if (Objects.equals(PersistentDataContainer.class, type)) { + return createAdapter(CraftPersistentDataContainer.class, NBTTagCompound.class, CraftPersistentDataContainer::toTagCompound, tag -> { + CraftPersistentDataContainer container = new CraftPersistentDataContainer(this); for (String key : tag.getKeys()) { container.put(key, tag.get(key)); } @@ -156,11 +162,11 @@ public final class CraftCustomTagTypeRegistry { }); } - throw new IllegalArgumentException("Could not find a valid CustomTagAdapter implementation for the requested type " + type.getSimpleName()); + throw new IllegalArgumentException("Could not find a valid TagAdapter implementation for the requested type " + type.getSimpleName()); } - private CustomTagAdapter createAdapter(Class primitiveType, Class nbtBaseType, Function builder, Function extractor) { - return new CustomTagAdapter<>(primitiveType, nbtBaseType, builder, extractor); + private TagAdapter createAdapter(Class primitiveType, Class nbtBaseType, Function builder, Function extractor) { + return new TagAdapter<>(primitiveType, nbtBaseType, builder, extractor); } /** @@ -169,7 +175,9 @@ public final class CraftCustomTagTypeRegistry { * @param type the type of the passed value * @param value the value to be stored in the tag * @param the generic type of the value + * * @return the created tag instance + * * @throws IllegalArgumentException if no suitable tag type adapter for this * type was found */ @@ -183,7 +191,9 @@ public final class CraftCustomTagTypeRegistry { * @param type the type of the primitive value * @param base the base instance to check * @param the generic type of the type + * * @return if the base stores values of the primitive type passed + * * @throws IllegalArgumentException if no suitable tag type adapter for this * type was found */ @@ -197,7 +207,9 @@ public final class CraftCustomTagTypeRegistry { * @param type the type of the value to extract * @param tag the tag to extract the value from * @param the generic type of the value stored inside the tag + * * @return the extracted value + * * @throws IllegalArgumentException if the passed base is not an instanced * of the defined base type and therefore is not applicable to the extractor * function @@ -207,7 +219,7 @@ public final class CraftCustomTagTypeRegistry { * type was found */ public T extract(Class type, NBTBase tag) throws ClassCastException, IllegalArgumentException { - CustomTagAdapter adapter = this.adapters.computeIfAbsent(type, CREATE_ADAPTER); + TagAdapter adapter = this.adapters.computeIfAbsent(type, CREATE_ADAPTER); Validate.isTrue(adapter.isInstance(tag), "`The found tag instance cannot store %s as it is a %s", type.getSimpleName(), tag.getClass().getSimpleName()); Object foundValue = adapter.extract(tag); diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java index 14b79c13a..87d680a87 100644 --- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java +++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java @@ -1,25 +1,23 @@ package org.bukkit.craftbukkit.potion; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Maps; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; - import net.minecraft.server.MobEffect; import net.minecraft.server.PotionRegistry; - -import org.bukkit.potion.PotionEffectType; -import org.bukkit.potion.PotionType; import org.bukkit.potion.PotionBrewer; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionType; public class CraftPotionBrewer implements PotionBrewer { private static final Map> cache = Maps.newHashMap(); + @Override public Collection getEffects(PotionType damage, boolean upgraded, boolean extended) { if (cache.containsKey(damage)) return cache.get(damage); diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java index 035e4fe82..082b0fdf9 100644 --- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java +++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.potion; import net.minecraft.server.MobEffectList; - import org.bukkit.Color; import org.bukkit.potion.PotionEffectType; @@ -15,7 +14,7 @@ public class CraftPotionEffectType extends PotionEffectType { @Override public double getDurationModifier() { - return handle.durationModifier; + return 1.0D; } public MobEffectList getHandle() { @@ -85,6 +84,10 @@ public class CraftPotionEffectType extends PotionEffectType { return "CONDUIT_POWER"; case 30: return "DOLPHINS_GRACE"; + case 31: + return "BAD_OMEN"; + case 32: + return "HERO_OF_THE_VILLAGE"; default: return "UNKNOWN_EFFECT_TYPE_" + getId(); } diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java index 2392b457f..c1e0863c4 100644 --- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java +++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java @@ -3,14 +3,12 @@ package org.bukkit.craftbukkit.potion; import com.google.common.base.Preconditions; import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableBiMap; - import net.minecraft.server.MobEffect; import net.minecraft.server.MobEffectList; - +import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionType; -import org.bukkit.potion.PotionData; public class CraftPotionUtil { diff --git a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java index ece177b82..834fc1783 100644 --- a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java +++ b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java @@ -1,12 +1,31 @@ package org.bukkit.craftbukkit.projectiles; import java.util.Random; - +import net.minecraft.server.BlockDispenser; +import net.minecraft.server.EntityArrow; +import net.minecraft.server.EntityEgg; +import net.minecraft.server.EntityEnderPearl; +import net.minecraft.server.EntityFireball; +import net.minecraft.server.EntityPotion; +import net.minecraft.server.EntityProjectile; +import net.minecraft.server.EntitySmallFireball; +import net.minecraft.server.EntitySnowball; +import net.minecraft.server.EntitySpectralArrow; +import net.minecraft.server.EntityThrownExpBottle; +import net.minecraft.server.EntityTippedArrow; +import net.minecraft.server.EntityTypes; +import net.minecraft.server.EnumDirection; +import net.minecraft.server.IPosition; +import net.minecraft.server.IProjectile; +import net.minecraft.server.MathHelper; +import net.minecraft.server.SourceBlock; +import net.minecraft.server.TileEntityDispenser; import org.apache.commons.lang.Validate; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.potion.CraftPotionUtil; +import org.bukkit.entity.AbstractArrow; import org.bukkit.entity.Arrow; import org.bukkit.entity.Egg; import org.bukkit.entity.EnderPearl; @@ -26,27 +45,6 @@ import org.bukkit.potion.PotionType; import org.bukkit.projectiles.BlockProjectileSource; import org.bukkit.util.Vector; -import net.minecraft.server.BlockDispenser; -import net.minecraft.server.EntityArrow; -import net.minecraft.server.EntityEgg; -import net.minecraft.server.EntityEnderPearl; -import net.minecraft.server.EntityFireball; -import net.minecraft.server.EntityLargeFireball; -import net.minecraft.server.EntityPotion; -import net.minecraft.server.EntityProjectile; -import net.minecraft.server.EntitySmallFireball; -import net.minecraft.server.EntitySnowball; -import net.minecraft.server.EntitySpectralArrow; -import net.minecraft.server.EntityThrownExpBottle; -import net.minecraft.server.EntityTippedArrow; -import net.minecraft.server.EntityWitherSkull; -import net.minecraft.server.EnumDirection; -import net.minecraft.server.IPosition; -import net.minecraft.server.IProjectile; -import net.minecraft.server.MathHelper; -import net.minecraft.server.SourceBlock; -import net.minecraft.server.TileEntityDispenser; - public class CraftBlockProjectileSource implements BlockProjectileSource { private final TileEntityDispenser dispenserBlock; @@ -56,7 +54,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { @Override public Block getBlock() { - return dispenserBlock.getWorld().getWorld().getBlockAt(dispenserBlock.getPosition()); // Akarin + return dispenserBlock.getWorld().getWorld().getBlockAt(dispenserBlock.getPosition().getX(), dispenserBlock.getPosition().getY(), dispenserBlock.getPosition().getZ()); } @Override @@ -71,7 +69,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { SourceBlock isourceblock = new SourceBlock(dispenserBlock.getWorld(), dispenserBlock.getPosition()); // Copied from DispenseBehaviorProjectile IPosition iposition = BlockDispenser.a(isourceblock); - EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); + EnumDirection enumdirection = (EnumDirection) isourceblock.getBlockData().get(BlockDispenser.FACING); net.minecraft.server.World world = dispenserBlock.getWorld(); net.minecraft.server.Entity launch = null; @@ -86,11 +84,13 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { launch = new EntityThrownExpBottle(world, iposition.getX(), iposition.getY(), iposition.getZ()); } else if (ThrownPotion.class.isAssignableFrom(projectile)) { if (LingeringPotion.class.isAssignableFrom(projectile)) { - launch = new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.LINGERING_POTION, 1))); + launch = new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ()); + ((EntityPotion) launch).setItem(CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.LINGERING_POTION, 1))); } else { - launch = new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.SPLASH_POTION, 1))); + launch = new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ()); + ((EntityPotion) launch).setItem(CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.SPLASH_POTION, 1))); } - } else if (Arrow.class.isAssignableFrom(projectile)) { + } else if (AbstractArrow.class.isAssignableFrom(projectile)) { if (TippedArrow.class.isAssignableFrom(projectile)) { launch = new EntityTippedArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); ((EntityTippedArrow) launch).setType(CraftPotionUtil.fromBukkit(new PotionData(PotionType.WATER, false, false))); @@ -113,7 +113,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { if (SmallFireball.class.isAssignableFrom(projectile)) { launch = new EntitySmallFireball(world, null, d0, d1, d2); } else if (WitherSkull.class.isAssignableFrom(projectile)) { - launch = new EntityWitherSkull(world); + launch = EntityTypes.WITHER_SKULL.a(world); launch.setPosition(d0, d1, d2); double d6 = (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); @@ -121,7 +121,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource { ((EntityFireball) launch).dirY = d4 / d6 * 0.1D; ((EntityFireball) launch).dirZ = d5 / d6 * 0.1D; } else { - launch = new EntityLargeFireball(world); + launch = EntityTypes.FIREBALL.a(world); launch.setPosition(d0, d1, d2); double d6 = (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java index 26ca44c5d..692aca048 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java @@ -4,7 +4,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.logging.Level; - import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitWorker; @@ -34,14 +33,17 @@ class CraftAsyncTask extends CraftTask { } workers.add( new BukkitWorker() { + @Override public Thread getThread() { return thread; } + @Override public int getTaskId() { return CraftAsyncTask.this.getTaskId(); } + @Override public Plugin getOwner() { return CraftAsyncTask.this.getOwner(); } @@ -96,6 +98,7 @@ class CraftAsyncTask extends CraftTask { return workers; } + @Override boolean cancel0() { synchronized (workers) { // Synchronizing here prevents race condition for a completing task diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java index bb990e511..1e20385fd 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java @@ -6,7 +6,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; - import org.bukkit.plugin.Plugin; class CraftFuture extends CraftTask implements Future { @@ -20,6 +19,7 @@ class CraftFuture extends CraftTask implements Future { this.callable = callable; } + @Override public synchronized boolean cancel(final boolean mayInterruptIfRunning) { if (getPeriod() != CraftTask.NO_REPEATING) { return false; @@ -28,11 +28,13 @@ class CraftFuture extends CraftTask implements Future { return true; } + @Override public boolean isDone() { final long period = this.getPeriod(); return period != CraftTask.NO_REPEATING && period != CraftTask.PROCESS_FOR_FUTURE; } + @Override public T get() throws CancellationException, InterruptedException, ExecutionException { try { return get(0, TimeUnit.MILLISECONDS); @@ -41,6 +43,7 @@ class CraftFuture extends CraftTask implements Future { } } + @Override public synchronized T get(long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { timeout = unit.toMillis(timeout); long period = this.getPeriod(); @@ -93,6 +96,7 @@ class CraftFuture extends CraftTask implements Future { } } + @Override synchronized boolean cancel0() { if (getPeriod() != CraftTask.NO_REPEATING) { return false; diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java index 5c4ec9e6c..5db848de1 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.scheduler; +import co.aikar.timings.MinecraftTimings; // Paper import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.util.ArrayList; import java.util.Comparator; @@ -15,8 +16,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.logging.Level; - -import co.aikar.timings.MinecraftTimings; // Paper +import com.destroystokyo.paper.ServerSchedulerReportingWrapper; import com.destroystokyo.paper.event.server.ServerExceptionEvent; import com.destroystokyo.paper.exception.ServerSchedulerException; import org.apache.commons.lang.Validate; @@ -64,6 +64,7 @@ public class CraftScheduler implements BukkitScheduler { */ final PriorityQueue pending = new PriorityQueue(10, // Paper new Comparator() { + @Override public int compare(final CraftTask o1, final CraftTask o2) { int value = Long.compare(o1.getNextRun(), o2.getNextRun()); @@ -253,6 +254,7 @@ public class CraftScheduler implements BukkitScheduler { } task = new CraftTask( new Runnable() { + @Override public void run() { if (!check(CraftScheduler.this.temp)) { check(CraftScheduler.this.pending); @@ -294,6 +296,7 @@ public class CraftScheduler implements BukkitScheduler { // Paper end final CraftTask task = new CraftTask( new Runnable() { + @Override public void run() { check(CraftScheduler.this.pending); check(CraftScheduler.this.temp); @@ -342,7 +345,7 @@ public class CraftScheduler implements BukkitScheduler { return false; } if (task.isSync()) { - return (task == currentTask); + return (task == currentTask); } final CraftAsyncTask asyncTask = (CraftAsyncTask) task; synchronized (asyncTask.getWorkers()) { @@ -479,10 +482,10 @@ public class CraftScheduler implements BukkitScheduler { runners.remove(task.getTaskId()); } } - MinecraftTimings.bukkitSchedulerFinishTimer.startTimingUnsafe(); + MinecraftTimings.bukkitSchedulerFinishTimer.startTiming(); pending.addAll(temp); temp.clear(); - MinecraftTimings.bukkitSchedulerFinishTimer.stopTimingUnsafe(); + MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming(); //debugHead = debugHead.getNextHead(currentTick); // Paper } @@ -521,7 +524,7 @@ public class CraftScheduler implements BukkitScheduler { } void parsePending() { // Paper - if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.startTimingUnsafe(); // Paper + if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.startTiming(); // Paper CraftTask head = this.head; CraftTask task = head.getNext(); CraftTask lastTask = head; @@ -540,7 +543,7 @@ public class CraftScheduler implements BukkitScheduler { task.setNext(null); } this.head = lastTask; - if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.stopTimingUnsafe(); // Paper + if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming(); // Paper } private boolean isReady(final int currentTick) { @@ -563,54 +566,54 @@ public class CraftScheduler implements BukkitScheduler { @Deprecated @Override public int scheduleSyncDelayedTask(Plugin plugin, BukkitRunnable task, long delay) { - return scheduleSyncDelayedTask(plugin, (Runnable) task, delay); + throw new UnsupportedOperationException("Use BukkitRunnable#runTaskLater(Plugin, long)"); } @Deprecated @Override public int scheduleSyncDelayedTask(Plugin plugin, BukkitRunnable task) { - return scheduleSyncDelayedTask(plugin, (Runnable) task); + throw new UnsupportedOperationException("Use BukkitRunnable#runTask(Plugin)"); } @Deprecated @Override public int scheduleSyncRepeatingTask(Plugin plugin, BukkitRunnable task, long delay, long period) { - return scheduleSyncRepeatingTask(plugin, (Runnable) task, delay, period); + throw new UnsupportedOperationException("Use BukkitRunnable#runTaskTimer(Plugin, long, long)"); } @Deprecated @Override public BukkitTask runTask(Plugin plugin, BukkitRunnable task) throws IllegalArgumentException { - return runTask(plugin, (Runnable) task); + throw new UnsupportedOperationException("Use BukkitRunnable#runTask(Plugin)"); } @Deprecated @Override public BukkitTask runTaskAsynchronously(Plugin plugin, BukkitRunnable task) throws IllegalArgumentException { - return runTaskAsynchronously(plugin, (Runnable) task); + throw new UnsupportedOperationException("Use BukkitRunnable#runTaskAsynchronously(Plugin)"); } @Deprecated @Override public BukkitTask runTaskLater(Plugin plugin, BukkitRunnable task, long delay) throws IllegalArgumentException { - return runTaskLater(plugin, (Runnable) task, delay); + throw new UnsupportedOperationException("Use BukkitRunnable#runTaskLater(Plugin, long)"); } @Deprecated @Override public BukkitTask runTaskLaterAsynchronously(Plugin plugin, BukkitRunnable task, long delay) throws IllegalArgumentException { - return runTaskLaterAsynchronously(plugin, (Runnable) task, delay); + throw new UnsupportedOperationException("Use BukkitRunnable#runTaskLaterAsynchronously(Plugin, long)"); } @Deprecated @Override public BukkitTask runTaskTimer(Plugin plugin, BukkitRunnable task, long delay, long period) throws IllegalArgumentException { - return runTaskTimer(plugin, (Runnable) task, delay, period); + throw new UnsupportedOperationException("Use BukkitRunnable#runTaskTimer(Plugin, long, long)"); } @Deprecated @Override public BukkitTask runTaskTimerAsynchronously(Plugin plugin, BukkitRunnable task, long delay, long period) throws IllegalArgumentException { - return runTaskTimerAsynchronously(plugin, (Runnable) task, delay, period); + throw new UnsupportedOperationException("Use BukkitRunnable#runTaskTimerAsynchronously(Plugin, long, long)"); } } diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java index 7dedd0222..7cc904851 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java @@ -1,12 +1,10 @@ package org.bukkit.craftbukkit.scoreboard; +import com.google.common.collect.ImmutableMap; import java.util.Map; - import net.minecraft.server.IScoreboardCriteria; import net.minecraft.server.ScoreboardObjective; -import com.google.common.collect.ImmutableMap; - final class CraftCriteria { static final Map DEFAULTS; static final CraftCriteria DUMMY; diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java index dcbbea38a..5eaea24d2 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.scoreboard; import net.minecraft.server.Scoreboard; import net.minecraft.server.ScoreboardObjective; - import org.apache.commons.lang.Validate; import org.bukkit.OfflinePlayer; import org.bukkit.craftbukkit.util.CraftChatMessage; @@ -25,18 +24,21 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective return objective; } + @Override public String getName() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return objective.getName(); } + @Override public String getDisplayName() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return CraftChatMessage.fromComponent(objective.getDisplayName()); } + @Override public void setDisplayName(String displayName) throws IllegalStateException, IllegalArgumentException { Validate.notNull(displayName, "Display name cannot be null"); Validate.isTrue(displayName.length() <= 128, "Display name '" + displayName + "' is longer than the limit of 128 characters"); @@ -45,18 +47,21 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective objective.setDisplayName(CraftChatMessage.fromString(displayName)[0]); // SPIGOT-4112: not nullable } + @Override public String getCriteria() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return criteria.bukkitName; } + @Override public boolean isModifiable() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return !criteria.criteria.isReadOnly(); } + @Override public void setDisplaySlot(DisplaySlot slot) throws IllegalStateException { CraftScoreboard scoreboard = checkState(); Scoreboard board = scoreboard.board; @@ -73,6 +78,7 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective } } + @Override public DisplaySlot getDisplaySlot() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); Scoreboard board = scoreboard.board; @@ -101,6 +107,7 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective return CraftScoreboardTranslations.toBukkitRender(this.objective.getRenderType()); } + @Override public Score getScore(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException { Validate.notNull(player, "Player cannot be null"); CraftScoreboard scoreboard = checkState(); @@ -108,6 +115,7 @@ final class CraftObjective extends CraftScoreboardComponent implements Objective return new CraftScore(this, player.getName()); } + @Override public Score getScore(String entry) throws IllegalArgumentException, IllegalStateException { Validate.notNull(entry, "Entry cannot be null"); Validate.isTrue(entry.length() <= 40, "Score '" + entry + "' is longer than the limit of 40 characters"); diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java index 134bdd819..41d22d223 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java @@ -1,11 +1,9 @@ package org.bukkit.craftbukkit.scoreboard; import java.util.Map; - import net.minecraft.server.Scoreboard; import net.minecraft.server.ScoreboardObjective; import net.minecraft.server.ScoreboardScore; - import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.scoreboard.Objective; @@ -26,22 +24,26 @@ final class CraftScore implements Score { this.entry = entry; } + @Override public OfflinePlayer getPlayer() { return Bukkit.getOfflinePlayer(entry); } + @Override public String getEntry() { return entry; } + @Override public Objective getObjective() { return objective; } + @Override public int getScore() throws IllegalStateException { Scoreboard board = objective.checkState().board; - if (board.containsPlayer(entry)) { // Lazy // Akarin + if (board.getPlayers().contains(entry)) { // Lazy Map scores = board.getPlayerObjectives(entry); ScoreboardScore score = scores.get(objective.getHandle()); if (score != null) { // Lazy @@ -52,6 +54,7 @@ final class CraftScore implements Score { return 0; // Lazy } + @Override public void setScore(int score) throws IllegalStateException { objective.checkState().board.getPlayerScoreForObjective(entry, objective.getHandle()).setScore(score); } @@ -60,9 +63,10 @@ final class CraftScore implements Score { public boolean isScoreSet() throws IllegalStateException { Scoreboard board = objective.checkState().board; - return board.containsPlayer(entry) && board.getPlayerObjectives(entry).containsKey(objective.getHandle()); // Akarin + return board.getPlayers().contains(entry) && board.getPlayerObjectives(entry).containsKey(objective.getHandle()); } + @Override public CraftScoreboard getScoreboard() { return objective.getScoreboard(); } diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java index 7320f339f..e3036fe23 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java @@ -1,24 +1,22 @@ package org.bukkit.craftbukkit.scoreboard; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import java.util.Collection; import net.minecraft.server.Scoreboard; import net.minecraft.server.ScoreboardObjective; import net.minecraft.server.ScoreboardTeam; - import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.RenderType; import org.bukkit.scoreboard.Score; import org.bukkit.scoreboard.Team; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import org.bukkit.craftbukkit.util.CraftChatMessage; - public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { final Scoreboard board; @@ -51,12 +49,14 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return new CraftObjective(this, objective); } + @Override public Objective getObjective(String name) throws IllegalArgumentException { Validate.notNull(name, "Name cannot be null"); ScoreboardObjective nms = board.getObjective(name); return nms == null ? null : new CraftObjective(this, nms); } + @Override public ImmutableSet getObjectivesByCriteria(String criteria) throws IllegalArgumentException { Validate.notNull(criteria, "Criteria cannot be null"); @@ -70,6 +70,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return objectives.build(); } + @Override public ImmutableSet getObjectives() { return ImmutableSet.copyOf(Iterables.transform((Collection) this.board.getObjectives(), new Function() { @@ -80,6 +81,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { })); } + @Override public Objective getObjective(DisplaySlot slot) throws IllegalArgumentException { Validate.notNull(slot, "Display slot cannot be null"); ScoreboardObjective objective = board.getObjectiveForSlot(CraftScoreboardTranslations.fromBukkitSlot(slot)); @@ -89,12 +91,14 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return new CraftObjective(this, objective); } + @Override public ImmutableSet getScores(OfflinePlayer player) throws IllegalArgumentException { Validate.notNull(player, "OfflinePlayer cannot be null"); return getScores(player.getName()); } + @Override public ImmutableSet getScores(String entry) throws IllegalArgumentException { Validate.notNull(entry, "Entry cannot be null"); @@ -105,12 +109,14 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return scores.build(); } + @Override public void resetScores(OfflinePlayer player) throws IllegalArgumentException { Validate.notNull(player, "OfflinePlayer cannot be null"); resetScores(player.getName()); } + @Override public void resetScores(String entry) throws IllegalArgumentException { Validate.notNull(entry, "Entry cannot be null"); @@ -119,6 +125,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { } } + @Override public Team getPlayerTeam(OfflinePlayer player) throws IllegalArgumentException { Validate.notNull(player, "OfflinePlayer cannot be null"); @@ -126,6 +133,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return team == null ? null : new CraftTeam(this, team); } + @Override public Team getEntryTeam(String entry) throws IllegalArgumentException { Validate.notNull(entry, "Entry cannot be null"); @@ -133,6 +141,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return team == null ? null : new CraftTeam(this, team); } + @Override public Team getTeam(String teamName) throws IllegalArgumentException { Validate.notNull(teamName, "Team name cannot be null"); @@ -140,6 +149,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return team == null ? null : new CraftTeam(this, team); } + @Override public ImmutableSet getTeams() { return ImmutableSet.copyOf(Iterables.transform((Collection) this.board.getTeams(), new Function() { @@ -150,6 +160,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { })); } + @Override public Team registerNewTeam(String name) throws IllegalArgumentException { Validate.notNull(name, "Team name cannot be null"); Validate.isTrue(name.length() <= 16, "Team name '" + name + "' is longer than the limit of 16 characters"); @@ -158,6 +169,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return new CraftTeam(this, board.createTeam(name)); } + @Override public ImmutableSet getPlayers() { ImmutableSet.Builder players = ImmutableSet.builder(); for (Object playerName : board.getPlayers()) { @@ -166,6 +178,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return players.build(); } + @Override public ImmutableSet getEntries() { ImmutableSet.Builder entries = ImmutableSet.builder(); for (Object entry : board.getPlayers()) { @@ -174,6 +187,7 @@ public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { return entries.build(); } + @Override public void clearSlot(DisplaySlot slot) throws IllegalArgumentException { Validate.notNull(slot, "Slot cannot be null"); board.setDisplaySlot(CraftScoreboardTranslations.fromBukkitSlot(slot), null); diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java index bc3c14871..ca2be3060 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java @@ -1,14 +1,11 @@ package org.bukkit.craftbukkit.scoreboard; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.function.Consumer; - import net.minecraft.server.EntityPlayer; import net.minecraft.server.IScoreboardCriteria; import net.minecraft.server.MinecraftServer; @@ -19,7 +16,6 @@ import net.minecraft.server.ScoreboardObjective; import net.minecraft.server.ScoreboardScore; import net.minecraft.server.ScoreboardServer; import net.minecraft.server.ScoreboardTeam; - import org.apache.commons.lang.Validate; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.util.WeakCollection; @@ -38,12 +34,14 @@ public final class CraftScoreboardManager implements ScoreboardManager { scoreboards.add(mainScoreboard); } + @Override public CraftScoreboard getMainScoreboard() { return mainScoreboard; } + @Override public CraftScoreboard getNewScoreboard() { - //org.spigotmc.AsyncCatcher.catchOp( "scoreboard creation"); // Spigot // Akarin + org.spigotmc.AsyncCatcher.catchOp("scoreboard creation"); // Spigot CraftScoreboard scoreboard = new CraftScoreboard(new ScoreboardServer(server)); scoreboards.add(scoreboard); return scoreboard; diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java index 207ffdd25..edd147fe6 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java @@ -1,13 +1,11 @@ package org.bukkit.craftbukkit.scoreboard; +import com.google.common.collect.ImmutableBiMap; import net.minecraft.server.IScoreboardCriteria; import net.minecraft.server.Scoreboard; - import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.RenderType; -import com.google.common.collect.ImmutableBiMap; - class CraftScoreboardTranslations { static final int MAX_DISPLAY_SLOT = 3; static ImmutableBiMap SLOTS = ImmutableBiMap.of( diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java index 4154b754e..bc92089ea 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java @@ -1,21 +1,18 @@ package org.bukkit.craftbukkit.scoreboard; +import com.google.common.collect.ImmutableSet; import java.util.Set; - +import net.minecraft.server.ScoreboardTeam; +import net.minecraft.server.ScoreboardTeamBase; import net.minecraft.server.ScoreboardTeamBase.EnumNameTagVisibility; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.scoreboard.NameTagVisibility; import org.bukkit.scoreboard.Team; -import com.google.common.collect.ImmutableSet; - -import net.minecraft.server.ScoreboardTeam; -import net.minecraft.server.ScoreboardTeamBase; -import org.bukkit.ChatColor; -import org.bukkit.craftbukkit.util.CraftChatMessage; - final class CraftTeam extends CraftScoreboardComponent implements Team { private final ScoreboardTeam team; @@ -24,18 +21,21 @@ final class CraftTeam extends CraftScoreboardComponent implements Team { this.team = team; } + @Override public String getName() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return team.getName(); } + @Override public String getDisplayName() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return CraftChatMessage.fromComponent(team.getDisplayName()); } + @Override public void setDisplayName(String displayName) throws IllegalStateException { Validate.notNull(displayName, "Display name cannot be null"); Validate.isTrue(displayName.length() <= 128, "Display name '" + displayName + "' is longer than the limit of 128 characters"); @@ -44,12 +44,14 @@ final class CraftTeam extends CraftScoreboardComponent implements Team { team.setDisplayName(CraftChatMessage.fromString(displayName)[0]); // SPIGOT-4112: not nullable } + @Override public String getPrefix() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return CraftChatMessage.fromComponent(team.getPrefix()); } + @Override public void setPrefix(String prefix) throws IllegalStateException, IllegalArgumentException { Validate.notNull(prefix, "Prefix cannot be null"); Validate.isTrue(prefix.length() <= 64, "Prefix '" + prefix + "' is longer than the limit of 64 characters"); @@ -58,12 +60,14 @@ final class CraftTeam extends CraftScoreboardComponent implements Team { team.setPrefix(CraftChatMessage.fromStringOrNull(prefix)); } + @Override public String getSuffix() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return CraftChatMessage.fromComponent(team.getSuffix()); } + @Override public void setSuffix(String suffix) throws IllegalStateException, IllegalArgumentException { Validate.notNull(suffix, "Suffix cannot be null"); Validate.isTrue(suffix.length() <= 64, "Suffix '" + suffix + "' is longer than the limit of 64 characters"); @@ -87,42 +91,49 @@ final class CraftTeam extends CraftScoreboardComponent implements Team { team.setColor(CraftChatMessage.getColor(color)); } + @Override public boolean allowFriendlyFire() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return team.allowFriendlyFire(); } + @Override public void setAllowFriendlyFire(boolean enabled) throws IllegalStateException { CraftScoreboard scoreboard = checkState(); team.setAllowFriendlyFire(enabled); } + @Override public boolean canSeeFriendlyInvisibles() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return team.canSeeFriendlyInvisibles(); } + @Override public void setCanSeeFriendlyInvisibles(boolean enabled) throws IllegalStateException { CraftScoreboard scoreboard = checkState(); team.setCanSeeFriendlyInvisibles(enabled); } + @Override public NameTagVisibility getNameTagVisibility() throws IllegalArgumentException { CraftScoreboard scoreboard = checkState(); return notchToBukkit(team.getNameTagVisibility()); } + @Override public void setNameTagVisibility(NameTagVisibility visibility) throws IllegalArgumentException { CraftScoreboard scoreboard = checkState(); team.setNameTagVisibility(bukkitToNotch(visibility)); } + @Override public Set getPlayers() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); @@ -144,17 +155,20 @@ final class CraftTeam extends CraftScoreboardComponent implements Team { return entries.build(); } + @Override public int getSize() throws IllegalStateException { CraftScoreboard scoreboard = checkState(); return team.getPlayerNameSet().size(); } + @Override public void addPlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException { Validate.notNull(player, "OfflinePlayer cannot be null"); addEntry(player.getName()); } + @Override public void addEntry(String entry) throws IllegalStateException, IllegalArgumentException { Validate.notNull(entry, "Entry cannot be null"); CraftScoreboard scoreboard = checkState(); @@ -162,11 +176,13 @@ final class CraftTeam extends CraftScoreboardComponent implements Team { scoreboard.board.addPlayerToTeam(entry, team); } + @Override public boolean removePlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException { Validate.notNull(player, "OfflinePlayer cannot be null"); return removeEntry(player.getName()); } + @Override public boolean removeEntry(String entry) throws IllegalStateException, IllegalArgumentException { Validate.notNull(entry, "Entry cannot be null"); CraftScoreboard scoreboard = checkState(); @@ -179,11 +195,13 @@ final class CraftTeam extends CraftScoreboardComponent implements Team { return true; } + @Override public boolean hasPlayer(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException { Validate.notNull(player, "OfflinePlayer cannot be null"); return hasEntry(player.getName()); } + @Override public boolean hasEntry(String entry) throws IllegalArgumentException, IllegalStateException { Validate.notNull("Entry cannot be null"); diff --git a/src/main/java/org/bukkit/craftbukkit/tag/CraftBlockTag.java b/src/main/java/org/bukkit/craftbukkit/tag/CraftBlockTag.java index cfd7b50b0..2fe308d91 100644 --- a/src/main/java/org/bukkit/craftbukkit/tag/CraftBlockTag.java +++ b/src/main/java/org/bukkit/craftbukkit/tag/CraftBlockTag.java @@ -22,6 +22,6 @@ public class CraftBlockTag extends CraftTag { @Override public Set getValues() { - return com.koloboke.collect.set.hash.HashObjSets.newImmutableSet(getHandle().a().stream().map((block) -> CraftMagicNumbers.getMaterial(block)).collect(Collectors.toSet())); // Akarin - koloboke + return Collections.unmodifiableSet(getHandle().a().stream().map((block) -> CraftMagicNumbers.getMaterial(block)).collect(Collectors.toSet())); } } diff --git a/src/main/java/org/bukkit/craftbukkit/tag/CraftItemTag.java b/src/main/java/org/bukkit/craftbukkit/tag/CraftItemTag.java index 160a21835..4a1a45257 100644 --- a/src/main/java/org/bukkit/craftbukkit/tag/CraftItemTag.java +++ b/src/main/java/org/bukkit/craftbukkit/tag/CraftItemTag.java @@ -22,6 +22,6 @@ public class CraftItemTag extends CraftTag { @Override public Set getValues() { - return com.koloboke.collect.set.hash.HashObjSets.newImmutableSet(getHandle().a().stream().map((item) -> CraftMagicNumbers.getMaterial(item)).collect(Collectors.toSet())); // Akarin - koloboke + return Collections.unmodifiableSet(getHandle().a().stream().map((item) -> CraftMagicNumbers.getMaterial(item)).collect(Collectors.toSet())); } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java b/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java deleted file mode 100644 index cf1258c55..000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java +++ /dev/null @@ -1,360 +0,0 @@ -package org.bukkit.craftbukkit.util; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; - -import org.apache.commons.lang.Validate; - -/** - * Executes tasks using a multi-stage process executor. Synchronous executions are via {@link AsynchronousExecutor#finishActive()} or the {@link AsynchronousExecutor#get(Object)} methods. - *
  • Stage 1 creates the object from a parameter, and is usually called asynchronously. - *
  • Stage 2 takes the parameter and object from stage 1 and does any synchronous processing to prepare it. - *
  • Stage 3 takes the parameter and object from stage 1, as well as a callback that was registered, and performs any synchronous calculations. - * - * @param

    The type of parameter you provide to make the object that will be created. It should implement {@link Object#hashCode()} and {@link Object#equals(Object)} if you want to get the value early. - * @param The type of object you provide. This is created in stage 1, and passed to stage 2, 3, and returned if get() is called. - * @param The type of callback you provide. You may register many of these to be passed to the provider in stage 3, one at a time. - * @param A type of exception you may throw and expect to be handled by the main thread - * @author Wesley Wolfe (c) 2012, 2014 - */ -public final class AsynchronousExecutor { - - public static interface CallBackProvider extends ThreadFactory { - - /** - * Normally an asynchronous call, but can be synchronous - * - * @param parameter parameter object provided - * @return the created object - */ - T callStage1(P parameter) throws E; - - /** - * Synchronous call - * - * @param parameter parameter object provided - * @param object the previously created object - */ - void callStage2(P parameter, T object) throws E; - - /** - * Synchronous call, called multiple times, once per registered callback - * - * @param parameter parameter object provided - * @param object the previously created object - * @param callback the current callback to execute - */ - void callStage3(P parameter, T object, C callback) throws E; - } - - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater STATE_FIELD = AtomicIntegerFieldUpdater.newUpdater(AsynchronousExecutor.Task.class, "state"); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static boolean set(AsynchronousExecutor.Task $this, int expected, int value) { - return STATE_FIELD.compareAndSet($this, expected, value); - } - - class Task implements Runnable { - static final int PENDING = 0x0; - static final int STAGE_1_ASYNC = PENDING + 1; - static final int STAGE_1_SYNC = STAGE_1_ASYNC + 1; - static final int STAGE_1_COMPLETE = STAGE_1_SYNC + 1; - static final int FINISHED = STAGE_1_COMPLETE + 1; - - volatile int state = PENDING; - final P parameter; - T object; - final List callbacks = new LinkedList(); - E t = null; - - Task(final P parameter) { - this.parameter = parameter; - } - - public void run() { - if (initAsync()) { - finished.add(this); - } - } - - boolean initAsync() { - if (set(this, PENDING, STAGE_1_ASYNC)) { - boolean ret = true; - - try { - init(); - } finally { - if (set(this, STAGE_1_ASYNC, STAGE_1_COMPLETE)) { - // No one is/will be waiting - } else { - // We know that the sync thread will be waiting - synchronized (this) { - if (state != STAGE_1_SYNC) { - // They beat us to the synchronized block - this.notifyAll(); - } else { - // We beat them to the synchronized block - } - state = STAGE_1_COMPLETE; // They're already synchronized, atomic locks are not needed - } - // We want to return false, because we know a synchronous task already handled the finish() - ret = false; // Don't return inside finally; VERY bad practice. - } - } - - return ret; - } else { - return false; - } - } - - void initSync() { - if (set(this, PENDING, STAGE_1_COMPLETE)) { - // If we succeed that variable switch, good as done - init(); - } else if (set(this, STAGE_1_ASYNC, STAGE_1_SYNC)) { - // Async thread is running, but this shouldn't be likely; we need to sync to wait on them because of it. - synchronized (this) { - if (set(this, STAGE_1_SYNC, PENDING)) { // They might NOT synchronized yet, atomic lock IS needed - // We are the first into the lock - while (state != STAGE_1_COMPLETE) { - try { - this.wait(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException("Unable to handle interruption on " + parameter, e); - } - } - } else { - // They beat us to the synchronized block - } - } - } else { - // Async thread is not pending, the more likely situation for a task not pending - } - } - - @SuppressWarnings("unchecked") - void init() { - try { - object = provider.callStage1(parameter); - } catch (final Throwable t) { - this.t = (E) t; - } - } - - @SuppressWarnings("unchecked") - T get() throws E { - initSync(); - if (callbacks.isEmpty()) { - // 'this' is a placeholder to prevent callbacks from being empty during finish call - // See get method below - callbacks.add((C) this); - } - finish(); - return object; - } - - void finish() throws E { - switch (state) { - default: - case PENDING: - case STAGE_1_ASYNC: - case STAGE_1_SYNC: - throw new IllegalStateException("Attempting to finish unprepared(" + state + ") task(" + parameter + ")"); - case STAGE_1_COMPLETE: - try { - if (t != null) { - throw t; - } - if (callbacks.isEmpty()) { - return; - } - - final CallBackProvider provider = AsynchronousExecutor.this.provider; - final P parameter = this.parameter; - final T object = this.object; - - provider.callStage2(parameter, object); - for (C callback : callbacks) { - if (callback == this) { - // 'this' is a placeholder to prevent callbacks from being empty on a get() call - // See get method above - continue; - } - provider.callStage3(parameter, object, callback); - } - } finally { - tasks.remove(parameter); - state = FINISHED; - } - case FINISHED: - } - } - - boolean drop() { - if (set(this, PENDING, FINISHED)) { - // If we succeed that variable switch, good as forgotten - tasks.remove(parameter); - return true; - } else { - // We need the async thread to finish normally to properly dispose of the task - return false; - } - } - } - - final CallBackProvider provider; - final Queue finished = new ConcurrentLinkedQueue(); - final Map tasks = new HashMap(); - final ThreadPoolExecutor pool; - - /** - * Uses a thread pool to pass executions to the provider. - * @see AsynchronousExecutor - */ - public AsynchronousExecutor(final CallBackProvider provider, final int coreSize) { - Validate.notNull(provider, "Provider cannot be null"); - this.provider = provider; - - // We have an unbound queue size so do not need a max thread size - pool = new ThreadPoolExecutor(coreSize, Integer.MAX_VALUE, 60l, TimeUnit.SECONDS, new LinkedBlockingQueue(), provider); - } - - /** - * Adds a callback to the parameter provided, adding parameter to the queue if needed. - *

    - * This should always be synchronous. - */ - public void add(P parameter, C callback) { - Task task = tasks.get(parameter); - if (task == null) { - tasks.put(parameter, task = new Task(parameter)); - pool.execute(task); - } - task.callbacks.add(callback); - } - - /** - * This removes a particular callback from the specified parameter. - *

    - * If no callbacks remain for a given parameter, then the {@link CallBackProvider CallBackProvider's} stages may be omitted from execution. - * Stage 3 will have no callbacks, stage 2 will be skipped unless a {@link #get(Object)} is used, and stage 1 will be avoided on a best-effort basis. - *

    - * Subsequent calls to {@link #getSkipQueue(Object)} will always work. - *

    - * Subsequent calls to {@link #get(Object)} might work. - *

    - * This should always be synchronous - * @return true if no further execution for the parameter is possible, such that, no exceptions will be thrown in {@link #finishActive()} for the parameter, and {@link #get(Object)} will throw an {@link IllegalStateException}, false otherwise - * @throws IllegalStateException if parameter is not in the queue anymore - * @throws IllegalStateException if the callback was not specified for given parameter - */ - public boolean drop(P parameter, C callback) throws IllegalStateException { - final Task task = tasks.get(parameter); - if (task == null) { - return true; - } - if (!task.callbacks.remove(callback)) { - throw new IllegalStateException("Unknown " + callback + " for " + parameter); - } - if (task.callbacks.isEmpty()) { - return task.drop(); - } - return false; - } - - /** - * This method attempts to skip the waiting period for said parameter. - *

    - * This should always be synchronous. - * @throws IllegalStateException if the parameter is not in the queue anymore, or sometimes if called from asynchronous thread - */ - public T get(P parameter) throws E, IllegalStateException { - final Task task = tasks.get(parameter); - if (task == null) { - throw new IllegalStateException("Unknown " + parameter); - } - return task.get(); - } - - /** - * Processes a parameter as if it was in the queue, without ever passing to another thread. - */ - public T getSkipQueue(P parameter) throws E { - return skipQueue(parameter); - } - - /** - * Processes a parameter as if it was in the queue, without ever passing to another thread. - */ - public T getSkipQueue(P parameter, C callback) throws E { - final T object = skipQueue(parameter); - provider.callStage3(parameter, object, callback); - return object; - } - - /** - * Processes a parameter as if it was in the queue, without ever passing to another thread. - */ - public T getSkipQueue(P parameter, C...callbacks) throws E { - final CallBackProvider provider = this.provider; - final T object = skipQueue(parameter); - for (C callback : callbacks) { - provider.callStage3(parameter, object, callback); - } - return object; - } - - /** - * Processes a parameter as if it was in the queue, without ever passing to another thread. - */ - public T getSkipQueue(P parameter, Iterable callbacks) throws E { - final CallBackProvider provider = this.provider; - final T object = skipQueue(parameter); - for (C callback : callbacks) { - provider.callStage3(parameter, object, callback); - } - return object; - } - - private T skipQueue(P parameter) throws E { - Task task = tasks.get(parameter); - if (task != null) { - return task.get(); - } - T object = provider.callStage1(parameter); - provider.callStage2(parameter, object); - return object; - } - - /** - * This is the 'heartbeat' that should be called synchronously to finish any pending tasks - */ - public void finishActive() throws E { - final Queue finished = this.finished; - while (!finished.isEmpty()) { - finished.poll().finish(); - } - } - - public void setActiveThreads(final int coreSize) { - pool.setCorePoolSize(coreSize); - } - - // Paper start - public boolean hasTask(P parameter) throws IllegalStateException { - return tasks.get(parameter) != null; - } - // Paper end -} diff --git a/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java b/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java index 165843ddf..f66f8b323 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java +++ b/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java @@ -3,11 +3,11 @@ package org.bukkit.craftbukkit.util; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; - +import java.util.Set; import net.minecraft.server.BlockPosition; +import net.minecraft.server.Fluid; import net.minecraft.server.IBlockData; import net.minecraft.server.World; - import org.bukkit.block.BlockState; import org.bukkit.craftbukkit.block.CraftBlockState; @@ -24,8 +24,25 @@ public class BlockStateListPopulator extends DummyGeneratorAccess { this.list = list; } + @Override + public IBlockData getType(BlockPosition bp) { + CraftBlockState state = list.get(bp); + return (state != null) ? state.getHandle() : world.getType(bp); + } + + @Override + public Fluid getFluid(BlockPosition bp) { + CraftBlockState state = list.get(bp); + return (state != null) ? state.getHandle().p() : world.getFluid(bp); + } + @Override public boolean setTypeAndData(BlockPosition position, IBlockData data, int flag) { + // Paper start + // When a LinkedHashMap entry is overwritten, it keeps its old position. Removing the entry here before adding + // a new one ensures that the nether portal blocks are placed last and are not destroyed by physics. + list.remove(position); + // Paper end CraftBlockState state = CraftBlockState.getBlockState(world, position, flag); state.setData(data); list.put(position, state); @@ -38,6 +55,10 @@ public class BlockStateListPopulator extends DummyGeneratorAccess { } } + public Set getBlocks() { + return list.keySet(); + } + public List getList() { return new ArrayList<>(list.values()); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java index b66323220..61f102355 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java @@ -258,6 +258,28 @@ public class Commodore if ( modern ) { + if ( owner.equals( "org/bukkit/Material" ) ) + { + switch ( name ) + { + case "CACTUS_GREEN": + name = "GREEN_DYE"; + break; + case "DANDELION_YELLOW": + name = "YELLOW_DYE"; + break; + case "ROSE_RED": + name = "RED_DYE"; + break; + case "SIGN": + name = "OAK_SIGN"; + break; + case "WALL_SIGN": + name = "OAK_WALL_SIGN"; + break; + } + } + super.visitFieldInsn( opcode, owner, name, desc ); return; } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java index d054405e4..e7a741724 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java @@ -1,21 +1,19 @@ package org.bukkit.craftbukkit.util; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; - import net.minecraft.server.ChatClickable; +import net.minecraft.server.ChatClickable.EnumClickAction; import net.minecraft.server.ChatComponentText; +import net.minecraft.server.ChatMessage; import net.minecraft.server.ChatModifier; import net.minecraft.server.EnumChatFormat; -import net.minecraft.server.ChatClickable.EnumClickAction; import net.minecraft.server.IChatBaseComponent; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; -import net.minecraft.server.ChatMessage; import org.bukkit.ChatColor; public final class CraftChatMessage { @@ -142,6 +140,10 @@ public final class CraftChatMessage { return (message == null || message.isEmpty()) ? null : new ChatComponentText(message); } + public static IChatBaseComponent wrapOrEmpty(String message) { + return (message == null) ? new ChatComponentText("") : new ChatComponentText(message); + } + public static IChatBaseComponent fromStringOrNull(String message) { return fromStringOrNull(message, false); } @@ -208,7 +210,7 @@ public final class CraftChatMessage { ChatModifier modifier = text.getChatModifier() != null ? text.getChatModifier() : new ChatModifier(); List extras = new ArrayList(); - List extrasOld = new ArrayList(text.a()); + List extrasOld = new ArrayList(text.getSiblings()); component = text = new ChatComponentText(""); int pos = 0; @@ -243,21 +245,21 @@ public final class CraftChatMessage { } } - List extras = component.a(); + List extras = component.getSiblings(); for (int i = 0; i < extras.size(); i++) { - IChatBaseComponent comp = (IChatBaseComponent) extras.get(i); - if (comp.getChatModifier() != null && comp.getChatModifier().h() == null) { + IChatBaseComponent comp = extras.get(i); + if (comp.getChatModifier() != null && comp.getChatModifier().getClickEvent() == null) { extras.set(i, fixComponent(comp, matcher)); } } if (component instanceof ChatMessage) { - Object[] subs = ((ChatMessage) component).l(); + Object[] subs = ((ChatMessage) component).getArgs(); for (int i = 0; i < subs.length; i++) { Object comp = subs[i]; if (comp instanceof IChatBaseComponent) { IChatBaseComponent c = (IChatBaseComponent) comp; - if (c.getChatModifier() != null && c.getChatModifier().h() == null) { + if (c.getChatModifier() != null && c.getChatModifier().getClickEvent() == null) { subs[i] = fixComponent(c, matcher); } } else if (comp instanceof String && matcher.reset((String)comp).find()) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftEvil.java b/src/main/java/org/bukkit/craftbukkit/util/CraftEvil.java index db77fbe71..1580db836 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftEvil.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftEvil.java @@ -22,6 +22,10 @@ public class CraftEvil { static { for (Material material : Material.values()) { + if (!material.isLegacy()) { + continue; + } + Preconditions.checkState(!byId.containsKey(material.getId()), "Duplicate material ID for", material); byId.put(material.getId(), material); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftLegacy.java b/src/main/java/org/bukkit/craftbukkit/util/CraftLegacy.java index c6aae8071..4539a4a77 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftLegacy.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftLegacy.java @@ -43,7 +43,7 @@ import org.bukkit.material.MaterialData; public class CraftLegacy { private static final Map SPAWN_EGGS = new HashMap<>(); - private static final Set whitelistedStates = new HashSet<>(Arrays.asList("explode", "check_decay", "decayable")); + private static final Set whitelistedStates = new HashSet<>(Arrays.asList("explode", "check_decay", "decayable", "facing")); private static final Map materialToItem = new HashMap<>(16384); private static final Map itemToMaterial = new HashMap<>(1024); private static final Map materialToData = new HashMap<>(4096); @@ -311,7 +311,7 @@ public class CraftLegacy { SPAWN_EGGS.put((byte) EntityType.PIG_ZOMBIE.getTypeId(), Material.ZOMBIE_PIGMAN_SPAWN_EGG); SPAWN_EGGS.put((byte) EntityType.ZOMBIE_VILLAGER.getTypeId(), Material.ZOMBIE_VILLAGER_SPAWN_EGG); - DispenserRegistry.c(); + DispenserRegistry.init(); for (Material material : Material.values()) { if (!material.isLegacy()) { @@ -324,11 +324,11 @@ public class CraftLegacy { MaterialData matData = new MaterialData(material, data); Dynamic blockTag = DataConverterFlattenData.b(material.getId() << 4 | data); // TODO: better skull conversion, chests - if (blockTag.getString("Name").contains("%%FILTER_ME%%")) { + if (blockTag.get("Name").asString("").contains("%%FILTER_ME%%")) { continue; } - String name = blockTag.getString("Name"); + String name = blockTag.get("Name").asString(""); // TODO: need to fix if (name.equals("minecraft:portal")) { name = "minecraft:nether_portal"; @@ -341,9 +341,9 @@ public class CraftLegacy { IBlockData blockData = block.getBlockData(); BlockStateList states = block.getStates(); - Optional propMap = blockTag.get("Properties"); + Optional propMap = blockTag.getElement("Properties"); if (propMap.isPresent()) { - NBTTagCompound properties = (NBTTagCompound) propMap.get().getValue(); + NBTTagCompound properties = propMap.get(); for (String dataKey : properties.getKeys()) { IBlockState state = states.a(dataKey); @@ -402,7 +402,7 @@ public class CraftLegacy { Dynamic converted = DataConverterRegistry.a().update(DataConverterTypes.ITEM_STACK, new Dynamic(DynamicOpsNBT.a, stack), -1, CraftMagicNumbers.INSTANCE.getDataVersion()); - String newId = converted.getString("id"); + String newId = converted.get("id").asString(""); // Recover spawn eggs with invalid data if (newId.equals("minecraft:spawn_egg")) { newId = "minecraft:pig_spawn_egg"; diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java index 72e83454f..921c16dff 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -1,29 +1,36 @@ package org.bukkit.craftbukkit.util; import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import com.google.common.io.Files; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.datafixers.Dynamic; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; - import net.minecraft.server.AdvancementDataWorld; import net.minecraft.server.Block; import net.minecraft.server.ChatDeserializer; +import net.minecraft.server.DataConverterRegistry; +import net.minecraft.server.DataConverterTypes; +import net.minecraft.server.DynamicOpsNBT; import net.minecraft.server.IBlockData; import net.minecraft.server.IRegistry; import net.minecraft.server.Item; import net.minecraft.server.MinecraftKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.MojangsonParser; +import net.minecraft.server.NBTBase; import net.minecraft.server.NBTTagCompound; - +import net.minecraft.server.SharedConstants; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -74,19 +81,22 @@ public final class CraftMagicNumbers implements UnsafeValues { private static final Map MATERIAL_BLOCK = new HashMap<>(); static { - for (Block block : (Iterable) IRegistry.BLOCK) { // Eclipse fail + for (Block block : IRegistry.BLOCK) { BLOCK_MATERIAL.put(block, Material.getMaterial(IRegistry.BLOCK.getKey(block).getKey().toUpperCase(Locale.ROOT))); } - for (Item item : (Iterable) IRegistry.ITEM) { // Eclipse fail + for (Item item : IRegistry.ITEM) { ITEM_MATERIAL.put(item, Material.getMaterial(IRegistry.ITEM.getKey(item).getKey().toUpperCase(Locale.ROOT))); } for (Material material : Material.values()) { MinecraftKey key = key(material); - // TODO: only register if block/item? - MATERIAL_ITEM.put(material, IRegistry.ITEM.get(key)); - MATERIAL_BLOCK.put(material, IRegistry.BLOCK.get(key)); + IRegistry.ITEM.getOptional(key).ifPresent((item) -> { + MATERIAL_ITEM.put(material, item); + }); + IRegistry.BLOCK.getOptional(key).ifPresent((block) -> { + MATERIAL_BLOCK.put(material, block); + }); } } @@ -144,6 +154,24 @@ public final class CraftMagicNumbers implements UnsafeValues { return CraftBlockData.fromData(getBlock(material, data)); } + @Override + public Material getMaterial(String material, int version) { + Preconditions.checkArgument(version <= this.getDataVersion(), "Newer version! Server downgrades are not supported!"); + + // Fastpath up to date materials + if (version == this.getDataVersion()) { + return Material.getMaterial(material); + } + + NBTTagCompound stack = new NBTTagCompound(); + stack.setString("id", "minecraft:" + material.toLowerCase(Locale.ROOT)); + + Dynamic converted = DataConverterRegistry.a().update(DataConverterTypes.ITEM_STACK, new Dynamic<>(DynamicOpsNBT.a, stack), version, this.getDataVersion()); + String newId = converted.get("id").asString(""); + + return Material.matchMaterial(newId); + } + /** * This string should be changed if the NMS mappings do. * @@ -160,12 +188,12 @@ public final class CraftMagicNumbers implements UnsafeValues { * @return string */ public String getMappingsVersion() { - return "7dd4b3ec31629620c41553e5c142e454"; + return "11ae498d9cf909730659b6357e7c2afa"; } @Override public int getDataVersion() { - return 1631; + return SharedConstants.a().getWorldVersion(); } @Override @@ -191,7 +219,7 @@ public final class CraftMagicNumbers implements UnsafeValues { net.minecraft.server.Advancement.SerializedAdvancement nms = (net.minecraft.server.Advancement.SerializedAdvancement) ChatDeserializer.a(AdvancementDataWorld.DESERIALIZER, advancement, net.minecraft.server.Advancement.SerializedAdvancement.class); if (nms != null) { - AdvancementDataWorld.REGISTRY.a(Maps.newHashMap(Collections.singletonMap(CraftNamespacedKey.toMinecraft(key), nms))); + MinecraftServer.getServer().getAdvancementData().REGISTRY.a(Maps.newHashMap(Collections.singletonMap(CraftNamespacedKey.toMinecraft(key), nms))); Advancement bukkit = Bukkit.getAdvancement(key); if (bukkit != null) { @@ -219,12 +247,29 @@ public final class CraftMagicNumbers implements UnsafeValues { return file.delete(); } + private static final List SUPPORTED_API = Arrays.asList("1.13", "1.14"); + @Override public void checkSupported(PluginDescriptionFile pdf) throws InvalidPluginException { + String minimumVersion = MinecraftServer.getServer().server.minimumAPI; + int minimumIndex = SUPPORTED_API.indexOf(minimumVersion); + if (pdf.getAPIVersion() != null) { - if (!pdf.getAPIVersion().equals("1.13")) { + int pluginIndex = SUPPORTED_API.indexOf(pdf.getAPIVersion()); + + if (pluginIndex == -1) { throw new InvalidPluginException("Unsupported API version " + pdf.getAPIVersion()); } + + if (pluginIndex < minimumIndex) { + throw new InvalidPluginException("Plugin API version " + pdf.getAPIVersion() + " is lower than the minimum allowed version. Please update or replace it."); + } + } else { + if (minimumIndex == -1) { + Bukkit.getLogger().log(Level.WARNING, "Plugin " + pdf.getFullName() + " does not specify an api-version."); + } else { + throw new InvalidPluginException("Plugin API version " + pdf.getAPIVersion() + " is lower than the minimum allowed version. Please update or replace it."); + } } } @@ -243,6 +288,18 @@ public final class CraftMagicNumbers implements UnsafeValues { return clazz; } + // Paper start + @Override + public String getTimingsServerName() { + return com.destroystokyo.paper.PaperConfig.timingsServerName; + } + + @Override + public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { + return new com.destroystokyo.paper.PaperVersionFetcher(); + } + // Paper end + /** * This helper class represents the different NBT Tags. *

    diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java b/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java index 8b7c29403..fd0b99b78 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftNBTTagConfigSerializer.java @@ -34,7 +34,7 @@ public class CraftNBTTagConfigSerializer { } else if (base instanceof NBTTagList) { List baseList = new ArrayList<>(); for (int i = 0; i < ((NBTList) base).size(); i++) { - baseList.add(serialize(((NBTList) base).get(i))); + baseList.add(serialize((NBTBase) ((NBTList) base).get(i))); } return baseList; diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java b/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java index f1f41262d..b308b1901 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java @@ -21,7 +21,7 @@ public final class CraftNamespacedKey { } public static NamespacedKey fromMinecraft(MinecraftKey minecraft) { - return new NamespacedKey(minecraft.b(), minecraft.getKey()); + return new NamespacedKey(minecraft.getNamespace(), minecraft.getKey()); } public static MinecraftKey toMinecraft(NamespacedKey key) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftRayTraceResult.java b/src/main/java/org/bukkit/craftbukkit/util/CraftRayTraceResult.java index 6ac556652..5c978a261 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftRayTraceResult.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftRayTraceResult.java @@ -1,5 +1,11 @@ package org.bukkit.craftbukkit.util; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.MovingObjectPosition; +import net.minecraft.server.MovingObjectPosition.EnumMovingObjectType; +import net.minecraft.server.MovingObjectPositionBlock; +import net.minecraft.server.MovingObjectPositionEntity; +import net.minecraft.server.Vec3D; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -7,35 +13,32 @@ import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.entity.Entity; import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; -import net.minecraft.server.BlockPosition; -import net.minecraft.server.MovingObjectPosition; -import net.minecraft.server.MovingObjectPosition.EnumMovingObjectType; -import net.minecraft.server.Vec3D; public class CraftRayTraceResult { private CraftRayTraceResult() {} public static RayTraceResult fromNMS(World world, MovingObjectPosition nmsHitResult) { - if (nmsHitResult == null || nmsHitResult.type == EnumMovingObjectType.MISS) return null; + if (nmsHitResult == null || nmsHitResult.getType() == EnumMovingObjectType.MISS) return null; - Vec3D nmsHitPos = nmsHitResult.pos; + Vec3D nmsHitPos = nmsHitResult.getPos(); Vector hitPosition = new Vector(nmsHitPos.x, nmsHitPos.y, nmsHitPos.z); BlockFace hitBlockFace = null; - if (nmsHitResult.direction != null) { - hitBlockFace = CraftBlock.notchToBlockFace(nmsHitResult.direction); - } - - if (nmsHitResult.entity != null) { - Entity hitEntity = nmsHitResult.entity.getBukkitEntity(); - return new RayTraceResult(hitPosition, hitEntity, hitBlockFace); + if (nmsHitResult.getType() == EnumMovingObjectType.ENTITY) { + Entity hitEntity = ((MovingObjectPositionEntity) nmsHitResult).getEntity().getBukkitEntity(); + return new RayTraceResult(hitPosition, hitEntity, null); } Block hitBlock = null; - BlockPosition nmsBlockPos = nmsHitResult.getBlockPosition(); + BlockPosition nmsBlockPos = null; + if (nmsHitResult.getType() == EnumMovingObjectType.BLOCK) { + MovingObjectPositionBlock blockHitResult = (MovingObjectPositionBlock) nmsHitResult; + hitBlockFace = CraftBlock.notchToBlockFace(blockHitResult.getDirection()); + nmsBlockPos = blockHitResult.getBlockPosition(); + } if (nmsBlockPos != null && world != null) { - hitBlock = world.getBlockAt(nmsBlockPos.getX(), nmsBlockPos.getY(), nmsBlockPos.getZ()); // Akarin + hitBlock = world.getBlockAt(nmsBlockPos.getX(), nmsBlockPos.getY(), nmsBlockPos.getZ()); } return new RayTraceResult(hitPosition, hitBlock, hitBlockFace); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftVector.java b/src/main/java/org/bukkit/craftbukkit/util/CraftVector.java new file mode 100644 index 000000000..d47432739 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftVector.java @@ -0,0 +1,15 @@ +package org.bukkit.craftbukkit.util; + +public final class CraftVector { + + private CraftVector() { + } + + public static org.bukkit.util.Vector toBukkit(net.minecraft.server.Vec3D nms) { + return new org.bukkit.util.Vector(nms.x, nms.y, nms.z); + } + + public static net.minecraft.server.Vec3D toNMS(org.bukkit.util.Vector bukkit) { + return new net.minecraft.server.Vec3D(bukkit.getX(), bukkit.getY(), bukkit.getZ()); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/util/DatFileFilter.java b/src/main/java/org/bukkit/craftbukkit/util/DatFileFilter.java index 712c44f14..66ff685d7 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DatFileFilter.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DatFileFilter.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.FilenameFilter; public class DatFileFilter implements FilenameFilter { + @Override public boolean accept(File dir, String name) { return name.endsWith(".dat"); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java index b1ecf5a53..5bae026dc 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java @@ -1,14 +1,16 @@ package org.bukkit.craftbukkit.util; +import java.util.List; import java.util.Random; import java.util.function.Predicate; +import net.minecraft.server.AxisAlignedBB; import net.minecraft.server.BiomeBase; import net.minecraft.server.Block; import net.minecraft.server.BlockPosition; +import net.minecraft.server.ChunkStatus; import net.minecraft.server.DifficultyDamageScaler; import net.minecraft.server.Entity; import net.minecraft.server.EntityHuman; -import net.minecraft.server.EnumDirection; import net.minecraft.server.EnumSkyBlock; import net.minecraft.server.Fluid; import net.minecraft.server.FluidType; @@ -17,19 +19,15 @@ import net.minecraft.server.HeightMap; import net.minecraft.server.IBlockData; import net.minecraft.server.IChunkAccess; import net.minecraft.server.IChunkProvider; -import net.minecraft.server.IDataManager; import net.minecraft.server.ParticleParam; -import net.minecraft.server.PersistentCollection; import net.minecraft.server.SoundCategory; import net.minecraft.server.SoundEffect; import net.minecraft.server.TickList; import net.minecraft.server.TileEntity; -import net.minecraft.server.VoxelShape; import net.minecraft.server.World; import net.minecraft.server.WorldBorder; import net.minecraft.server.WorldData; import net.minecraft.server.WorldProvider; -import org.bukkit.event.entity.CreatureSpawnEvent; public class DummyGeneratorAccess implements GeneratorAccess { @@ -53,11 +51,6 @@ public class DummyGeneratorAccess implements GeneratorAccess { throw new UnsupportedOperationException("Not supported yet."); } - @Override - public IChunkAccess getChunkAt(int i, int i1) { - throw new UnsupportedOperationException("Not supported yet."); - } - @Override public World getMinecraftWorld() { throw new UnsupportedOperationException("Not supported yet."); @@ -79,12 +72,7 @@ public class DummyGeneratorAccess implements GeneratorAccess { } @Override - public IDataManager getDataManager() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Random m() { + public Random getRandom() { throw new UnsupportedOperationException("Not supported yet."); } @@ -94,12 +82,7 @@ public class DummyGeneratorAccess implements GeneratorAccess { } @Override - public BlockPosition getSpawn() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void a(EntityHuman eh, BlockPosition bp, SoundEffect se, SoundCategory sc, float f, float f1) { + public void playSound(EntityHuman eh, BlockPosition bp, SoundEffect se, SoundCategory sc, float f, float f1) { throw new UnsupportedOperationException("Not supported yet."); } @@ -109,17 +92,22 @@ public class DummyGeneratorAccess implements GeneratorAccess { } @Override - public boolean isEmpty(BlockPosition bp) { + public void a(EntityHuman eh, int i, BlockPosition bp, int i1) { throw new UnsupportedOperationException("Not supported yet."); } @Override - public BiomeBase getBiome(BlockPosition bp) { + public List getEntities(Entity entity, AxisAlignedBB aabb, Predicate prdct) { throw new UnsupportedOperationException("Not supported yet."); } @Override - public int getBrightness(EnumSkyBlock esb, BlockPosition bp) { + public List a(Class type, AxisAlignedBB aabb, Predicate prdct) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public List getPlayers() { throw new UnsupportedOperationException("Not supported yet."); } @@ -129,12 +117,12 @@ public class DummyGeneratorAccess implements GeneratorAccess { } @Override - public boolean isChunkLoaded(int i, int i1, boolean bln) { + public IChunkAccess getChunkAt(int i, int i1, ChunkStatus cs, boolean bln) { throw new UnsupportedOperationException("Not supported yet."); } @Override - public boolean e(BlockPosition bp) { + public BlockPosition getHighestBlockYAt(HeightMap.Type type, BlockPosition bp) { throw new UnsupportedOperationException("Not supported yet."); } @@ -143,11 +131,6 @@ public class DummyGeneratorAccess implements GeneratorAccess { throw new UnsupportedOperationException("Not supported yet."); } - @Override - public EntityHuman a(double d, double d1, double d2, double d3, Predicate prdct) { - throw new UnsupportedOperationException("Not supported yet."); - } - @Override public int c() { throw new UnsupportedOperationException("Not supported yet."); @@ -158,16 +141,6 @@ public class DummyGeneratorAccess implements GeneratorAccess { throw new UnsupportedOperationException("Not supported yet."); } - @Override - public boolean a(Entity entity, VoxelShape vs) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int a(BlockPosition bp, EnumDirection ed) { - throw new UnsupportedOperationException("Not supported yet."); - } - @Override public boolean e() { throw new UnsupportedOperationException("Not supported yet."); @@ -179,7 +152,17 @@ public class DummyGeneratorAccess implements GeneratorAccess { } @Override - public WorldProvider o() { + public WorldProvider getWorldProvider() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public BiomeBase getBiome(BlockPosition bp) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public int getBrightness(EnumSkyBlock esb, BlockPosition bp) { throw new UnsupportedOperationException("Not supported yet."); } @@ -199,7 +182,7 @@ public class DummyGeneratorAccess implements GeneratorAccess { } @Override - public PersistentCollection h() { + public boolean a(BlockPosition bp, Predicate prdct) { throw new UnsupportedOperationException("Not supported yet."); } @@ -209,27 +192,30 @@ public class DummyGeneratorAccess implements GeneratorAccess { } @Override - public boolean addEntity(Entity entity) { + public boolean a(BlockPosition blockposition, boolean flag) { throw new UnsupportedOperationException("Not supported yet."); } @Override - public boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason reason) { + public boolean b(BlockPosition blockposition, boolean flag) { + throw new UnsupportedOperationException("Not supported yet."); + } + + // Paper start - if loaded util + @javax.annotation.Nullable + @Override + public IChunkAccess getChunkIfLoadedImmediately(int x, int z) { throw new UnsupportedOperationException("Not supported yet."); } @Override - public boolean setAir(BlockPosition blockposition) { + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { throw new UnsupportedOperationException("Not supported yet."); } @Override - public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean setAir(BlockPosition blockposition, boolean flag) { + public Fluid getFluidIfLoaded(BlockPosition blockposition) { throw new UnsupportedOperationException("Not supported yet."); } + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/util/ForwardLogHandler.java b/src/main/java/org/bukkit/craftbukkit/util/ForwardLogHandler.java index 74ce4b2ec..100b8566d 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/ForwardLogHandler.java +++ b/src/main/java/org/bukkit/craftbukkit/util/ForwardLogHandler.java @@ -1,13 +1,12 @@ package org.bukkit.craftbukkit.util; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.LogRecord; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class ForwardLogHandler extends ConsoleHandler { private Map cachedLoggers = new ConcurrentHashMap(); diff --git a/src/main/java/org/bukkit/craftbukkit/util/HashTreeSet.java b/src/main/java/org/bukkit/craftbukkit/util/HashTreeSet.java deleted file mode 100644 index cd864c404..000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/HashTreeSet.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.bukkit.craftbukkit.util; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.TreeSet; - -public class HashTreeSet implements Set { - - private Set hash = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet(); //Paper - Replace java.util.HashSet with ObjectOpenHashSet - private TreeSet tree = new TreeSet(); - - public HashTreeSet() { - - } - - @Override - public int size() { - return hash.size(); - } - - @Override - public boolean isEmpty() { - return hash.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return hash.contains(o); - } - - @Override - public Iterator iterator() { - return new Iterator() { - - private Iterator it = tree.iterator(); - private V last; - - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public V next() { - return last = it.next(); - } - - @Override - public void remove() { - if (last == null) { - throw new IllegalStateException(); - } - it.remove(); - hash.remove(last); - last = null; - } - }; - } - - @Override - public Object[] toArray() { - return hash.toArray(); - } - - @Override - public Object[] toArray(Object[] a) { - return hash.toArray(a); - } - - @Override - public boolean add(V e) { - hash.add(e); - return tree.add(e); - } - - @Override - public boolean remove(Object o) { - hash.remove(o); - return tree.remove(o); - } - - @Override - public boolean containsAll(Collection c) { - return hash.containsAll(c); - } - - @Override - public boolean addAll(Collection c) { - tree.addAll(c); - return hash.addAll(c); - } - - @Override - public boolean retainAll(Collection c) { - tree.retainAll(c); - return hash.retainAll(c); - } - - @Override - public boolean removeAll(Collection c) { - tree.removeAll(c); - return hash.removeAll(c); - } - - @Override - public void clear() { - hash.clear(); - tree.clear(); - } - - public V first() { - return tree.first(); - } - -} diff --git a/src/main/java/org/bukkit/craftbukkit/util/LazyHashSet.java b/src/main/java/org/bukkit/craftbukkit/util/LazyHashSet.java index 2ae000d4b..c407d783b 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LazyHashSet.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LazyHashSet.java @@ -7,54 +7,67 @@ import java.util.Set; public abstract class LazyHashSet implements Set { Set reference = null; + @Override public int size() { return getReference().size(); } + @Override public boolean isEmpty() { return getReference().isEmpty(); } + @Override public boolean contains(Object o) { return getReference().contains(o); } + @Override public Iterator iterator() { return getReference().iterator(); } + @Override public Object[] toArray() { return getReference().toArray(); } + @Override public T[] toArray(T[] a) { return getReference().toArray(a); } + @Override public boolean add(E o) { return getReference().add(o); } + @Override public boolean remove(Object o) { return getReference().remove(o); } + @Override public boolean containsAll(Collection c) { return getReference().containsAll(c); } + @Override public boolean addAll(Collection c) { return getReference().addAll(c); } + @Override public boolean retainAll(Collection c) { return getReference().retainAll(c); } + @Override public boolean removeAll(Collection c) { return getReference().removeAll(c); } + @Override public void clear() { getReference().clear(); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java b/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java index 457d19e9c..f847a9dd6 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java @@ -4,7 +4,6 @@ import java.util.HashSet; import java.util.List; import net.minecraft.server.EntityPlayer; import net.minecraft.server.MinecraftServer; - import org.bukkit.entity.Player; public class LazyPlayerSet extends LazyHashSet { diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHash.java b/src/main/java/org/bukkit/craftbukkit/util/LongHash.java deleted file mode 100644 index 691cafd03..000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/LongHash.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.bukkit.craftbukkit.util; - -public class LongHash { - public static long toLong(int msw, int lsw) { - return ((long) msw << 32) + lsw - Integer.MIN_VALUE; - } - - public static int msw(long l) { - return (int) (l >> 32); - } - - public static int lsw(long l) { - return (int) (l & 0xFFFFFFFF) + Integer.MIN_VALUE; - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java deleted file mode 100644 index a21357922..000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - Based on CompactHashSet Copyright 2011 Ontopia Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package org.bukkit.craftbukkit.util; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.ConcurrentModificationException; -import java.util.NoSuchElementException; - -public class LongHashSet { - private final static int INITIAL_SIZE = 3; - private final static double LOAD_FACTOR = 0.75; - - private final static long FREE = 0; - private final static long REMOVED = Long.MIN_VALUE; - - private int freeEntries; - private int elements; - private long[] values; - private int modCount; - - public LongHashSet() { - this(INITIAL_SIZE); - } - - public LongHashSet(int size) { - values = new long[(size==0 ? 1 : size)]; - elements = 0; - freeEntries = values.length; - modCount = 0; - } - - public Iterator iterator() { - return new Itr(); - } - - public int size() { - return elements; - } - - public boolean isEmpty() { - return elements == 0; - } - - public boolean contains(int msw, int lsw) { - return contains(LongHash.toLong(msw, lsw)); - } - - public boolean contains(long value) { - int hash = hash(value); - int index = (hash & 0x7FFFFFFF) % values.length; - int offset = 1; - - // search for the object (continue while !null and !this object) - while(values[index] != FREE && !(hash(values[index]) == hash && values[index] == value)) { - index = ((index + offset) & 0x7FFFFFFF) % values.length; - offset = offset * 2 + 1; - - if (offset == -1) { - offset = 2; - } - } - - return values[index] != FREE; - } - - public boolean add(int msw, int lsw) { - return add(LongHash.toLong(msw, lsw)); - } - - public boolean add(long value) { - int hash = hash(value); - int index = (hash & 0x7FFFFFFF) % values.length; - int offset = 1; - int deletedix = -1; - - // search for the object (continue while !null and !this object) - while(values[index] != FREE && !(hash(values[index]) == hash && values[index] == value)) { - // if there's a deleted object here we can put this object here, - // provided it's not in here somewhere else already - if (values[index] == REMOVED) { - deletedix = index; - } - - index = ((index + offset) & 0x7FFFFFFF) % values.length; - offset = offset * 2 + 1; - - if (offset == -1) { - offset = 2; - } - } - - if (values[index] == FREE) { - if (deletedix != -1) { // reusing a deleted cell - index = deletedix; - } else { - freeEntries--; - } - - modCount++; - elements++; - values[index] = value; - - if (1 - (freeEntries / (double) values.length) > LOAD_FACTOR) { - rehash(); - } - - return true; - } else { - return false; - } - } - - public void remove(int msw, int lsw) { - remove(LongHash.toLong(msw, lsw)); - } - - public boolean remove(long value) { - int hash = hash(value); - int index = (hash & 0x7FFFFFFF) % values.length; - int offset = 1; - - // search for the object (continue while !null and !this object) - while(values[index] != FREE && !(hash(values[index]) == hash && values[index] == value)) { - index = ((index + offset) & 0x7FFFFFFF) % values.length; - offset = offset * 2 + 1; - - if (offset == -1) { - offset = 2; - } - } - - if (values[index] != FREE) { - values[index] = REMOVED; - modCount++; - elements--; - return true; - } else { - return false; - } - } - - public void clear() { - elements = 0; - for (int ix = 0; ix < values.length; ix++) { - values[ix] = FREE; - } - - freeEntries = values.length; - modCount++; - } - - public long[] toArray() { - long[] result = new long[elements]; - long[] values = Arrays.copyOf(this.values, this.values.length); - int pos = 0; - - for (long value : values) { - if (value != FREE && value != REMOVED) { - result[pos++] = value; - } - } - - return result; - } - - public long popFirst() { - for (long value : values) { - if (value != FREE && value != REMOVED) { - remove(value); - return value; - } - } - - return 0; - } - - public long[] popAll() { - long[] ret = toArray(); - clear(); - return ret; - } - - // This method copied from Murmur3, written by Austin Appleby released under Public Domain - private int hash(long value) { - value ^= value >>> 33; - value *= 0xff51afd7ed558ccdL; - value ^= value >>> 33; - value *= 0xc4ceb9fe1a85ec53L; - value ^= value >>> 33; - return (int) value; - } - - private void rehash() { - int gargagecells = values.length - (elements + freeEntries); - if (gargagecells / (double) values.length > 0.05) { - rehash(values.length); - } else { - rehash(values.length * 2 + 1); - } - } - - private void rehash(int newCapacity) { - long[] newValues = new long[newCapacity]; - - for (long value : values) { - if (value == FREE || value == REMOVED) { - continue; - } - - int hash = hash(value); - int index = (hash & 0x7FFFFFFF) % newCapacity; - int offset = 1; - - // search for the object - while (newValues[index] != FREE) { - index = ((index + offset) & 0x7FFFFFFF) % newCapacity; - offset = offset * 2 + 1; - - if (offset == -1) { - offset = 2; - } - } - - newValues[index] = value; - } - - values = newValues; - freeEntries = values.length - elements; - } - - private class Itr implements Iterator { - private int index; - private int lastReturned = -1; - private int expectedModCount; - - public Itr() { - for (index = 0; index < values.length && (values[index] == FREE || values[index] == REMOVED); index++) { - // This is just to drive the index forward to the first valid entry - } - expectedModCount = modCount; - } - - public boolean hasNext() { - return index != values.length; - } - - public Long next() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - - int length = values.length; - if (index >= length) { - lastReturned = -2; - throw new NoSuchElementException(); - } - - lastReturned = index; - for (index += 1; index < length && (values[index] == FREE || values[index] == REMOVED); index++) { - // This is just to drive the index forward to the next valid entry - } - - if (values[lastReturned] == FREE) { - return FREE; - } else { - return values[lastReturned]; - } - } - - public void remove() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - - if (lastReturned == -1 || lastReturned == -2) { - throw new IllegalStateException(); - } - - if (values[lastReturned] != FREE && values[lastReturned] != REMOVED) { - values[lastReturned] = REMOVED; - elements--; - modCount++; - expectedModCount = modCount; - } - } - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java deleted file mode 100644 index 0cd430a3a..000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java +++ /dev/null @@ -1,422 +0,0 @@ -package org.bukkit.craftbukkit.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.AbstractCollection; -import java.util.AbstractSet; -import java.util.Arrays; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; - -@SuppressWarnings("unchecked") -public class LongObjectHashMap implements Cloneable, Serializable { - static final long serialVersionUID = 2841537710170573815L; - - private static final long EMPTY_KEY = Long.MIN_VALUE; - private static final int BUCKET_SIZE = 4096; - - private transient long[][] keys; - private transient V[][] values; - private transient int modCount; - private transient int size; - - public LongObjectHashMap() { - initialize(); - } - - public LongObjectHashMap(Map map) { - this(); - putAll(map); - } - - public int size() { - return size; - } - - public boolean isEmpty() { - return size == 0; - } - - public boolean containsKey(long key) { - return get(key) != null; - } - - public boolean containsValue(V value) { - for (V val : values()) { - if (val == value || val.equals(value)) { - return true; - } - } - - return false; - } - - public V get(long key) { - int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); - long[] inner = keys[index]; - if (inner == null) return null; - - for (int i = 0; i < inner.length; i++) { - long innerKey = inner[i]; - if (innerKey == EMPTY_KEY) { - return null; - } else if (innerKey == key) { - return values[index][i]; - } - } - - return null; - } - - public V put(long key, V value) { - int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); - long[] innerKeys = keys[index]; - V[] innerValues = values[index]; - modCount++; - - if (innerKeys == null) { - // need to make a new chain - keys[index] = innerKeys = new long[8]; - Arrays.fill(innerKeys, EMPTY_KEY); - values[index] = innerValues = (V[]) new Object[8]; - innerKeys[0] = key; - innerValues[0] = value; - size++; - } else { - int i; - for (i = 0; i < innerKeys.length; i++) { - // found an empty spot in the chain to put this - if (innerKeys[i] == EMPTY_KEY) { - size++; - innerKeys[i] = key; - innerValues[i] = value; - return null; - } - - // found an existing entry in the chain with this key, replace it - if (innerKeys[i] == key) { - V oldValue = innerValues[i]; - innerKeys[i] = key; - innerValues[i] = value; - return oldValue; - } - } - - // chain is full, resize it and add our new entry - keys[index] = innerKeys = Arrays.copyOf(innerKeys, i << 1); - Arrays.fill(innerKeys, i, innerKeys.length, EMPTY_KEY); - values[index] = innerValues = Arrays.copyOf(innerValues, i << 1); - innerKeys[i] = key; - innerValues[i] = value; - size++; - } - - return null; - } - - public V remove(long key) { - int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); - long[] inner = keys[index]; - if (inner == null) { - return null; - } - - for (int i = 0; i < inner.length; i++) { - // hit the end of the chain, didn't find this entry - if (inner[i] == EMPTY_KEY) { - break; - } - - if (inner[i] == key) { - V value = values[index][i]; - - for (i++; i < inner.length; i++) { - if (inner[i] == EMPTY_KEY) { - break; - } - - inner[i - 1] = inner[i]; - values[index][i - 1] = values[index][i]; - } - - inner[i - 1] = EMPTY_KEY; - values[index][i - 1] = null; - size--; - modCount++; - return value; - } - } - - return null; - } - - public void putAll(Map map) { - for (Map.Entry entry : map.entrySet()) { - put((Long) entry.getKey(), (V) entry.getValue()); - } - } - - public void clear() { - if (size == 0) { - return; - } - - modCount++; - size = 0; - Arrays.fill(keys, null); - Arrays.fill(values, null); - } - - public Set keySet() { - return new KeySet(); - } - - public Collection values() { - return new ValueCollection(); - } - - /** - * Returns a Set of Entry objects for the HashMap. This is not how the internal - * implementation is laid out so this constructs the entire Set when called. For - * this reason it should be avoided if at all possible. - * - * @return Set of Entry objects - * @deprecated - */ - @Deprecated - public Set> entrySet() { - HashSet> set = new HashSet>(); - for (long key : keySet()) { - set.add(new Entry(key, get(key))); - } - - return set; - } - - public Object clone() throws CloneNotSupportedException { - LongObjectHashMap clone = (LongObjectHashMap) super.clone(); - // Make sure we clear any existing information from the clone - clone.clear(); - // Make sure the clone is properly setup for new entries - clone.initialize(); - - // Iterate through the data normally to do a safe clone - for (long key : keySet()) { - final V value = get(key); - clone.put(key, value); - } - - return clone; - } - - private void initialize() { - keys = new long[BUCKET_SIZE][]; - values = (V[][]) new Object[BUCKET_SIZE][]; - } - - private long keyIndex(long key) { - key ^= key >>> 33; - key *= 0xff51afd7ed558ccdL; - key ^= key >>> 33; - key *= 0xc4ceb9fe1a85ec53L; - key ^= key >>> 33; - return key; - } - - private void writeObject(ObjectOutputStream outputStream) throws IOException { - outputStream.defaultWriteObject(); - - for (long key : keySet()) { - V value = get(key); - outputStream.writeLong(key); - outputStream.writeObject(value); - } - - outputStream.writeLong(EMPTY_KEY); - outputStream.writeObject(null); - } - - private void readObject(ObjectInputStream inputStream) throws ClassNotFoundException, IOException { - inputStream.defaultReadObject(); - initialize(); - - while (true) { - long key = inputStream.readLong(); - V value = (V) inputStream.readObject(); - if (key == EMPTY_KEY && value == null) { - break; - } - - put(key, value); - } - } - - - private class ValueIterator implements Iterator { - private int count; - private int index; - private int innerIndex; - private int expectedModCount; - private long lastReturned = EMPTY_KEY; - - long prevKey = EMPTY_KEY; - V prevValue; - - ValueIterator() { - expectedModCount = LongObjectHashMap.this.modCount; - } - - public boolean hasNext() { - return count < LongObjectHashMap.this.size; - } - - public void remove() { - if (LongObjectHashMap.this.modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - - if (lastReturned == EMPTY_KEY) { - throw new IllegalStateException(); - } - - count--; - LongObjectHashMap.this.remove(lastReturned); - lastReturned = EMPTY_KEY; - expectedModCount = LongObjectHashMap.this.modCount; - } - - public V next() { - if (LongObjectHashMap.this.modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - - if (!hasNext()) { - throw new NoSuchElementException(); - } - - long[][] keys = LongObjectHashMap.this.keys; - count++; - - if (prevKey != EMPTY_KEY) { - innerIndex++; - } - - for (; index < keys.length; index++) { - if (keys[index] != null) { - for (; innerIndex < keys[index].length; innerIndex++) { - long key = keys[index][innerIndex]; - V value = values[index][innerIndex]; - if (key == EMPTY_KEY) { - break; - } - - lastReturned = key; - prevKey = key; - prevValue = value; - return prevValue; - } - innerIndex = 0; - } - } - - throw new NoSuchElementException(); - } - } - - private class KeyIterator implements Iterator { - final ValueIterator iterator; - - public KeyIterator() { - iterator = new ValueIterator(); - } - - public void remove() { - iterator.remove(); - } - - public boolean hasNext() { - return iterator.hasNext(); - } - - public Long next() { - iterator.next(); - return iterator.prevKey; - } - } - - - private class KeySet extends AbstractSet { - public void clear() { - LongObjectHashMap.this.clear(); - } - - public int size() { - return LongObjectHashMap.this.size(); - } - - public boolean contains(Object key) { - return key instanceof Long && LongObjectHashMap.this.containsKey((Long) key); - - } - - public boolean remove(Object key) { - return LongObjectHashMap.this.remove((Long) key) != null; - } - - public Iterator iterator() { - return new KeyIterator(); - } - } - - - private class ValueCollection extends AbstractCollection { - public void clear() { - LongObjectHashMap.this.clear(); - } - - public int size() { - return LongObjectHashMap.this.size(); - } - - public boolean contains(Object value) { - return LongObjectHashMap.this.containsValue((V) value); - } - - public Iterator iterator() { - return new ValueIterator(); - } - } - - - private class Entry implements Map.Entry { - private final Long key; - private V value; - - Entry(long k, V v) { - key = k; - value = v; - } - - public Long getKey() { - return key; - } - - public V getValue() { - return value; - } - - public V setValue(V v) { - V old = value; - value = v; - put(key, v); - return old; - } - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/util/MojangNameLookup.java b/src/main/java/org/bukkit/craftbukkit/util/MojangNameLookup.java deleted file mode 100644 index 93a8f0bd7..000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/MojangNameLookup.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.bukkit.craftbukkit.util; - -import com.google.common.base.Charsets; -import com.google.gson.Gson; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.UUID; -import org.apache.commons.io.IOUtils; - -public class MojangNameLookup { - private static final Logger logger = LogManager.getFormatterLogger(MojangNameLookup.class); - - public static String lookupName(UUID id) { - if (id == null) { - return null; - } - - InputStream inputStream = null; - try { - URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + id.toString().replace("-", "")); - URLConnection connection = url.openConnection(); - connection.setConnectTimeout(15000); - connection.setReadTimeout(15000); - connection.setUseCaches(false); - inputStream = connection.getInputStream(); - String result = IOUtils.toString(inputStream, Charsets.UTF_8); - Gson gson = new Gson(); - Response response = gson.fromJson(result, Response.class); - if (response == null || response.name == null) { - logger.warn("Failed to lookup name from UUID"); - return null; - } - - if (response.cause != null && response.cause.length() > 0) { - logger.warn("Failed to lookup name from UUID: %s", response.errorMessage); - return null; - } - - return response.name; - } catch (MalformedURLException ex) { - logger.warn("Malformed URL in UUID lookup"); - return null; - } catch (IOException ex) { - IOUtils.closeQuietly(inputStream); - } finally { - IOUtils.closeQuietly(inputStream); - } - - return null; - } - - private class Response { - String errorMessage; - String cause; - String name; - } -} diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java index bbb5a84f3..449e99d1b 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java +++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java @@ -1,6 +1,5 @@ package org.bukkit.craftbukkit.util; -import net.minecraft.server.ExceptionWorldConflict; import net.minecraft.server.MinecraftServer; public class ServerShutdownThread extends Thread { @@ -15,9 +14,7 @@ public class ServerShutdownThread extends Thread { try { org.spigotmc.AsyncCatcher.enabled = false; // Spigot org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper - server.stop(); - } catch (ExceptionWorldConflict ex) { - ex.printStackTrace(); + server.close(); } finally { try { net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender diff --git a/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java b/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java deleted file mode 100644 index 2dbfef963..000000000 --- a/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.bukkit.craftbukkit.util; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.text.SimpleDateFormat; -import java.util.logging.Formatter; -import java.util.logging.LogRecord; -import joptsimple.OptionException; -import joptsimple.OptionSet; -import net.minecraft.server.MinecraftServer; - -public class ShortConsoleLogFormatter extends Formatter { - private final SimpleDateFormat date; - - public ShortConsoleLogFormatter(MinecraftServer server) { - OptionSet options = server.options; - SimpleDateFormat date = null; - - if (options.has("date-format")) { - try { - Object object = options.valueOf("date-format"); - - if ((object != null) && (object instanceof SimpleDateFormat)) { - date = (SimpleDateFormat) object; - } - } catch (OptionException ex) { - System.err.println("Given date format is not valid. Falling back to default."); - } - } else if (options.has("nojline")) { - date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - } - - if (date == null) { - date = new SimpleDateFormat("HH:mm:ss"); - } - - this.date = date; - } - - @Override - public String format(LogRecord record) { - StringBuilder builder = new StringBuilder(); - Throwable ex = record.getThrown(); - - builder.append(date.format(record.getMillis())); - builder.append(" ["); - builder.append(record.getLevel().getLocalizedName().toUpperCase()); - builder.append("] "); - builder.append(formatMessage(record)); - builder.append('\n'); - - if (ex != null) { - StringWriter writer = new StringWriter(); - ex.printStackTrace(new PrintWriter(writer)); - builder.append(writer); - } - - return builder.toString(); - } - -} diff --git a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java index 08d105603..1aec70a1f 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java +++ b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java @@ -43,6 +43,7 @@ public class UnsafeList extends AbstractList implements List, RandomAcc this(32); } + @Override public E get(int index) { rangeCheck(index); @@ -53,6 +54,7 @@ public class UnsafeList extends AbstractList implements List, RandomAcc return (E) data[index]; } + @Override public E set(int index, E element) { rangeCheck(index); @@ -61,12 +63,14 @@ public class UnsafeList extends AbstractList implements List, RandomAcc return old; } + @Override public boolean add(E element) { growIfNeeded(); data[size++] = element; return true; } + @Override public void add(int index, E element) { growIfNeeded(); System.arraycopy(data, index, data, index + 1, size - index); @@ -74,6 +78,7 @@ public class UnsafeList extends AbstractList implements List, RandomAcc size++; } + @Override public E remove(int index) { rangeCheck(index); @@ -87,6 +92,7 @@ public class UnsafeList extends AbstractList implements List, RandomAcc return old; } + @Override public boolean remove(Object o) { int index = indexOf(o); if (index >= 0) { @@ -97,6 +103,7 @@ public class UnsafeList extends AbstractList implements List, RandomAcc return false; } + @Override public int indexOf(Object o) { for (int i = 0; i < size; i++) { if (o == data[i] || o.equals(data[i])) { @@ -107,10 +114,12 @@ public class UnsafeList extends AbstractList implements List, RandomAcc return -1; } + @Override public boolean contains(Object o) { return indexOf(o) >= 0; } + @Override public void clear() { // Create new array to reset memory usage to initial capacity size = 0; @@ -134,14 +143,17 @@ public class UnsafeList extends AbstractList implements List, RandomAcc } } + @Override public int size() { return size; } + @Override public boolean isEmpty() { return size == 0; } + @Override public Object clone() throws CloneNotSupportedException { UnsafeList copy = (UnsafeList) super.clone(); copy.data = Arrays.copyOf(data, size); @@ -154,6 +166,7 @@ public class UnsafeList extends AbstractList implements List, RandomAcc return copy; } + @Override public Iterator iterator() { // Try to find an iterator that isn't in use for (Iterator iter : iterPool) { @@ -233,11 +246,13 @@ public class UnsafeList extends AbstractList implements List, RandomAcc valid = true; } + @Override public boolean hasNext() { valid = index != size; return valid; } + @Override public E next() { if (modCount != expectedModCount) { throw new ConcurrentModificationException(); @@ -256,6 +271,7 @@ public class UnsafeList extends AbstractList implements List, RandomAcc return (E) data[lastRet = i]; } + @Override public void remove() { if (lastRet < 0) { throw new IllegalStateException(); diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java index bc508c72a..674096cab 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java @@ -11,7 +11,7 @@ public final class Versioning { public static String getBukkitVersion() { String result = "Unknown-Version"; - InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.destroystokyo.paper/akarin-api/pom.properties"); // Akarin + InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/com.destroystokyo.paper/paper-api/pom.properties"); Properties properties = new Properties(); if (stream != null) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/Waitable.java b/src/main/java/org/bukkit/craftbukkit/util/Waitable.java index 5cd115434..a7ec02287 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/Waitable.java +++ b/src/main/java/org/bukkit/craftbukkit/util/Waitable.java @@ -13,6 +13,7 @@ public abstract class Waitable implements Runnable { T value = null; Status status = Status.WAITING; + @Override public final void run() { synchronized (this) { if (status != Status.WAITING) { diff --git a/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java index 7e7363f52..166f4ee08 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java +++ b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java @@ -5,7 +5,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; - import org.apache.commons.lang.Validate; public final class WeakCollection implements Collection { @@ -16,11 +15,13 @@ public final class WeakCollection implements Collection { collection = new ArrayList>(); } + @Override public boolean add(T value) { Validate.notNull(value, "Cannot add null value"); return collection.add(new WeakReference(value)); } + @Override public boolean addAll(Collection collection) { Collection> values = this.collection; boolean ret = false; @@ -31,10 +32,12 @@ public final class WeakCollection implements Collection { return ret; } + @Override public void clear() { collection.clear(); } + @Override public boolean contains(Object object) { if (object == null) { return false; @@ -47,19 +50,23 @@ public final class WeakCollection implements Collection { return false; } + @Override public boolean containsAll(Collection collection) { return toCollection().containsAll(collection); } + @Override public boolean isEmpty() { return !iterator().hasNext(); } + @Override public Iterator iterator() { return new Iterator() { Iterator> it = collection.iterator(); Object value = NO_VALUE; + @Override public boolean hasNext() { Object value = this.value; if (value != null && value != NO_VALUE) { @@ -82,6 +89,7 @@ public final class WeakCollection implements Collection { return false; } + @Override public T next() throws NoSuchElementException { if (!hasNext()) { throw new NoSuchElementException("No more elements"); @@ -93,6 +101,7 @@ public final class WeakCollection implements Collection { return value; } + @Override public void remove() throws IllegalStateException { if (value != NO_VALUE) { throw new IllegalStateException("No last element"); @@ -104,6 +113,7 @@ public final class WeakCollection implements Collection { }; } + @Override public boolean remove(Object object) { if (object == null) { return false; @@ -119,6 +129,7 @@ public final class WeakCollection implements Collection { return false; } + @Override public boolean removeAll(Collection collection) { Iterator it = this.iterator(); boolean ret = false; @@ -131,6 +142,7 @@ public final class WeakCollection implements Collection { return ret; } + @Override public boolean retainAll(Collection collection) { Iterator it = this.iterator(); boolean ret = false; @@ -143,6 +155,7 @@ public final class WeakCollection implements Collection { return ret; } + @Override public int size() { int s = 0; for (T value : this) { @@ -151,10 +164,12 @@ public final class WeakCollection implements Collection { return s; } + @Override public Object[] toArray() { return this.toArray(new Object[0]); } + @Override public T[] toArray(T[] array) { return toCollection().toArray(array); } diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java index 3a10eb639..d5f4ece06 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java +++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java @@ -32,6 +32,8 @@ public final class CommandPermissions { DefaultPermissions.registerPermission(PREFIX + "selector", "Allows the use of selectors", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(PREFIX + "trigger", "Allows the use of the trigger command", PermissionDefault.TRUE, commands); + DefaultPermissions.registerPermission("minecraft.admin.command_feedback", "Receive command broadcasts when sendCommandFeedback is true", PermissionDefault.OP, commands); + commands.recalculatePermissibles(); return commands; } diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java index 69fe84213..574aee621 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java +++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.util.permissions; import org.bukkit.permissions.Permission; -import org.bukkit.permissions.PermissionDefault; import org.bukkit.util.permissions.DefaultPermissions; public final class CraftDefaultPermissions { @@ -13,9 +12,9 @@ public final class CraftDefaultPermissions { Permission parent = DefaultPermissions.registerPermission(ROOT, "Gives the user the ability to use all vanilla utilities and commands"); CommandPermissions.registerPermissions(parent); // Spigot start - DefaultPermissions.registerPermission(ROOT + ".nbt.place", "Gives the user the ability to place restricted blocks with NBT in creative", PermissionDefault.OP, parent); - DefaultPermissions.registerPermission(ROOT + ".nbt.copy", "Gives the user the ability to copy NBT in creative", PermissionDefault.TRUE, parent); - DefaultPermissions.registerPermission(ROOT + ".debugstick", "Gives the user the ability to use the debug stick creative", PermissionDefault.OP, parent); + DefaultPermissions.registerPermission(ROOT + ".nbt.place", "Gives the user the ability to place restricted blocks with NBT in creative", org.bukkit.permissions.PermissionDefault.OP, parent); + DefaultPermissions.registerPermission(ROOT + ".nbt.copy", "Gives the user the ability to copy NBT in creative", org.bukkit.permissions.PermissionDefault.TRUE, parent); + DefaultPermissions.registerPermission(ROOT + ".debugstick", "Gives the user the ability to use the debug stick creative", org.bukkit.permissions.PermissionDefault.OP, parent); // Spigot end parent.recalculatePermissibles(); } diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java index 89d40a6a6..92601c581 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -1,9 +1,7 @@ package org.spigotmc; +import java.util.Collection; import java.util.List; -import java.util.Set; - -import co.aikar.timings.MinecraftTimings; import net.minecraft.server.AxisAlignedBB; import net.minecraft.server.Chunk; import net.minecraft.server.Entity; @@ -15,38 +13,41 @@ import net.minecraft.server.EntityCreature; import net.minecraft.server.EntityCreeper; import net.minecraft.server.EntityEnderCrystal; import net.minecraft.server.EntityEnderDragon; -import net.minecraft.server.EntityFallingBlock; +import net.minecraft.server.EntityFallingBlock; // Paper import net.minecraft.server.EntityFireball; import net.minecraft.server.EntityFireworks; -import net.minecraft.server.EntityFish; import net.minecraft.server.EntityHuman; -import net.minecraft.server.EntityInsentient; +import net.minecraft.server.EntityLightning; import net.minecraft.server.EntityLiving; -import net.minecraft.server.EntityLlama; import net.minecraft.server.EntityMonster; import net.minecraft.server.EntityProjectile; +import net.minecraft.server.EntityRaider; import net.minecraft.server.EntitySheep; +import net.minecraft.server.EntitySlice; import net.minecraft.server.EntitySlime; import net.minecraft.server.EntityTNTPrimed; import net.minecraft.server.EntityThrownTrident; import net.minecraft.server.EntityVillager; -import net.minecraft.server.EntityWaterAnimal; -import net.minecraft.server.EntityWeather; import net.minecraft.server.EntityWither; -import net.minecraft.server.MCUtil; import net.minecraft.server.MathHelper; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.NavigationGuardian; import net.minecraft.server.World; +import co.aikar.timings.MinecraftTimings; public class ActivationRange { + public enum ActivationType + { + MONSTER, + ANIMAL, + RAIDER, + MISC; + + AxisAlignedBB boundingBox = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 ); + } + static AxisAlignedBB maxBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 ); - static AxisAlignedBB miscBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 ); - static AxisAlignedBB animalBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 ); - static AxisAlignedBB waterBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 ); // Paper - static AxisAlignedBB monsterBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 ); /** * Initializes an entities type on construction to specify what group this @@ -55,18 +56,20 @@ public class ActivationRange * @param entity * @return group id */ - public static byte initializeEntityActivationType(Entity entity) + public static ActivationType initializeEntityActivationType(Entity entity) { - if (entity instanceof EntityWaterAnimal) { return 4; } // Paper - if ( entity instanceof EntityMonster || entity instanceof EntitySlime ) + if ( entity instanceof EntityRaider ) { - return 1; // Monster + return ActivationType.RAIDER; + } else if ( entity instanceof EntityMonster || entity instanceof EntitySlime ) + { + return ActivationType.MONSTER; } else if ( entity instanceof EntityCreature || entity instanceof EntityAmbient ) { - return 2; // Animal + return ActivationType.ANIMAL; } else { - return 3; // Misc + return ActivationType.MISC; } } @@ -79,17 +82,17 @@ public class ActivationRange */ public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config) { - if ( ( entity.activationType == 3 && config.miscActivationRange == 0 ) - || ( entity.activationType == 2 && config.animalActivationRange == 0 ) - || ( entity.activationType == 1 && config.monsterActivationRange == 0 ) - || ( entity.activationType == 4 && config.waterActivationRange == 0 ) // Paper + if ( ( entity.activationType == ActivationType.MISC && config.miscActivationRange == 0 ) + || ( entity.activationType == ActivationType.RAIDER && config.raiderActivationRange == 0 ) + || ( entity.activationType == ActivationType.ANIMAL && config.animalActivationRange == 0 ) + || ( entity.activationType == ActivationType.MONSTER && config.monsterActivationRange == 0 ) || entity instanceof EntityHuman || entity instanceof EntityProjectile || entity instanceof EntityEnderDragon || entity instanceof EntityComplexPart || entity instanceof EntityWither || entity instanceof EntityFireball - || entity instanceof EntityWeather + || entity instanceof EntityLightning || entity instanceof EntityTNTPrimed || entity instanceof EntityFallingBlock // Paper - Always tick falling blocks || entity instanceof EntityEnderCrystal @@ -110,26 +113,26 @@ public class ActivationRange */ public static void activateEntities(World world) { - MinecraftTimings.entityActivationCheckTimer.startTimingUnsafe(); + MinecraftTimings.entityActivationCheckTimer.startTiming(); final int miscActivationRange = world.spigotConfig.miscActivationRange; + final int raiderActivationRange = world.spigotConfig.raiderActivationRange; final int animalActivationRange = world.spigotConfig.animalActivationRange; final int monsterActivationRange = world.spigotConfig.monsterActivationRange; - final int waterActivationRange = world.spigotConfig.waterActivationRange; // Paper int maxRange = Math.max( monsterActivationRange, animalActivationRange ); + maxRange = Math.max( maxRange, raiderActivationRange ); maxRange = Math.max( maxRange, miscActivationRange ); - //maxRange = Math.min( ( world.spigotConfig.viewDistance << 4 ) - 8, maxRange ); Paper - Use player view distance API below instead + maxRange = Math.min( ( world.spigotConfig.viewDistance << 4 ) - 8, maxRange ); - Chunk chunk; // Paper - for ( EntityHuman player : world.players ) + for ( EntityHuman player : world.getPlayers() ) { - int playerMaxRange = maxRange = Math.min( ( player.getViewDistance() << 4 ) - 8, maxRange ); // Paper - Use player view distance API + player.activatedTick = MinecraftServer.currentTick; - maxBB = player.getBoundingBox().grow( playerMaxRange, 256, playerMaxRange ); // Paper - Use player view distance API - miscBB = player.getBoundingBox().grow( miscActivationRange, 256, miscActivationRange ); - animalBB = player.getBoundingBox().grow( animalActivationRange, 256, animalActivationRange ); - waterBB = player.getBoundingBox().grow( waterActivationRange, 256, waterActivationRange ); // Paper - monsterBB = player.getBoundingBox().grow( monsterActivationRange, 256, monsterActivationRange ); + maxBB = player.getBoundingBox().grow( maxRange, 256, maxRange ); + ActivationType.MISC.boundingBox = player.getBoundingBox().grow( miscActivationRange, 256, miscActivationRange ); + ActivationType.RAIDER.boundingBox = player.getBoundingBox().grow( raiderActivationRange, 256, raiderActivationRange ); + ActivationType.ANIMAL.boundingBox = player.getBoundingBox().grow( animalActivationRange, 256, animalActivationRange ); + ActivationType.MONSTER.boundingBox = player.getBoundingBox().grow( monsterActivationRange, 256, monsterActivationRange ); int i = MathHelper.floor( maxBB.minX / 16.0D ); int j = MathHelper.floor( maxBB.maxX / 16.0D ); @@ -140,14 +143,15 @@ public class ActivationRange { for ( int j1 = k; j1 <= l; ++j1 ) { - if ( (chunk = world.getChunkIfLoaded(i1, j1 )) != null ) // Paper + Chunk chunk = (Chunk) world.getChunkIfLoadedImmediately( i1, j1 ); + if ( chunk != null ) { - activateChunkEntities( chunk ); // Paper + activateChunkEntities( chunk ); } } } } - MinecraftTimings.entityActivationCheckTimer.stopTimingUnsafe(); + MinecraftTimings.entityActivationCheckTimer.stopTiming(); } /** @@ -159,7 +163,7 @@ public class ActivationRange { for ( List slice : chunk.entitySlices ) { - for ( Entity entity : slice ) + for ( Entity entity : (Collection) slice ) { if ( MinecraftServer.currentTick > entity.activatedTick ) { @@ -168,34 +172,9 @@ public class ActivationRange entity.activatedTick = MinecraftServer.currentTick; continue; } - switch ( entity.activationType ) + if ( entity.activationType.boundingBox.c( entity.getBoundingBox() ) ) { - case 1: - if ( monsterBB.c( entity.getBoundingBox() ) ) - { - entity.activatedTick = MinecraftServer.currentTick; - } - break; - case 2: - if ( animalBB.c( entity.getBoundingBox() ) ) - { - entity.activatedTick = MinecraftServer.currentTick; - } - break; - // Paper start - case 4: - if ( waterBB.c( entity.getBoundingBox() ) ) - { - entity.activatedTick = MinecraftServer.currentTick; - } - break; - // Paper end - case 3: - default: - if ( miscBB.c( entity.getBoundingBox() ) ) - { - entity.activatedTick = MinecraftServer.currentTick; - } + entity.activatedTick = MinecraftServer.currentTick; } } } @@ -211,17 +190,11 @@ public class ActivationRange */ public static boolean checkEntityImmunities(Entity entity) { - // Paper start - optimize Water cases - if (entity instanceof EntityFish) { - return false; - } - if (entity.inWater && (!(entity instanceof EntityInsentient) || !(((EntityInsentient) entity).getNavigation() instanceof NavigationGuardian))) { + // quick checks. + if ( entity.inWater || entity.fireTicks > 0 ) + { return true; } - if (entity.fireTicks > 0) { - return true; - } - // Paper end if ( !( entity instanceof EntityArrow ) ) { if ( !entity.onGround || !entity.passengers.isEmpty() || entity.isPassenger() ) @@ -236,29 +209,18 @@ public class ActivationRange if ( entity instanceof EntityLiving ) { EntityLiving living = (EntityLiving) entity; - if ( living.lastDamageByPlayerTime > 0 || living.hurtTicks > 0 || living.effects.size() > 0 ) // Paper + if ( /*TODO: Missed mapping? living.attackTicks > 0 || */ living.hurtTicks > 0 || living.effects.size() > 0 ) { return true; } - if ( entity instanceof EntityCreature ) - { - // Paper start - EntityCreature creature = (EntityCreature) entity; - if (creature.getGoalTarget() != null || creature.getMovingTarget() != null) { - return true; - } - // Paper end - } - if ( entity instanceof EntityVillager && ( (EntityVillager) entity ).isInLove() ) + if ( entity instanceof EntityCreature && ( (EntityCreature) entity ).getGoalTarget() != null ) { return true; } - // Paper start - if ( entity instanceof EntityLlama && ( (EntityLlama ) entity ).inCaravan() ) + if ( entity instanceof EntityVillager && ( (EntityVillager) entity ).canBreed() ) { return true; } - // Paper end if ( entity instanceof EntityAnimal ) { EntityAnimal animal = (EntityAnimal) entity; @@ -305,29 +267,12 @@ public class ActivationRange entity.activatedTick = MinecraftServer.currentTick + 20; } isActive = true; - // Paper start - } else if (entity instanceof EntityInsentient && ((EntityInsentient) entity).targetSelector.hasTasks()) { - isActive = true; } - // Paper end // Add a little performance juice to active entities. Skip 1/4 if not immune. - } else if ( !entity.defaultActivationState && entity.ticksLived % 4 == 0 && !(entity instanceof EntityInsentient && ((EntityInsentient) entity).targetSelector.hasTasks()) && !checkEntityImmunities( entity ) ) // Paper - add targetSelector.hasTasks + } else if ( !entity.defaultActivationState && entity.ticksLived % 4 == 0 && !checkEntityImmunities( entity ) ) { isActive = false; } - //int x = MathHelper.floor( entity.locX ); // Paper - //int z = MathHelper.floor( entity.locZ ); // Paper - // Make sure not on edge of unloaded chunk - Chunk chunk = entity.getChunkAtLocation(); // Paper - if ( isActive && !( chunk != null && chunk.areNeighborsLoaded( 1 ) ) ) - { - isActive = false; - } - // Paper start - Skip ticking in chunks scheduled for unload - else if (entity.world.paperConfig.skipEntityTickingInChunksScheduledForUnload && (chunk == null || chunk.scheduledForUnload != null)) { - isActive = false; - } - // Paper end return isActive; } } diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java index 8b220cc5f..9f7d2ef93 100644 --- a/src/main/java/org/spigotmc/AsyncCatcher.java +++ b/src/main/java/org/spigotmc/AsyncCatcher.java @@ -1,6 +1,5 @@ package org.spigotmc; -import co.aikar.timings.ThreadAssertion; import net.minecraft.server.MinecraftServer; public class AsyncCatcher @@ -11,7 +10,7 @@ public class AsyncCatcher public static void catchOp(String reason) { - if ( enabled && !ThreadAssertion.is() && Thread.currentThread() != MinecraftServer.getServer().primaryThread ) + if ( enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread ) { throw new IllegalStateException( "Asynchronous " + reason + "!" ); } diff --git a/src/main/java/org/spigotmc/Metrics.java b/src/main/java/org/spigotmc/Metrics.java index e7d5e8ab6..05d2d3d52 100644 --- a/src/main/java/org/spigotmc/Metrics.java +++ b/src/main/java/org/spigotmc/Metrics.java @@ -70,7 +70,7 @@ public class Metrics { /** * The current revision number */ - private final static int REVISION = 6; + private static final int REVISION = 6; /** * The base url of the metrics domain */ @@ -580,7 +580,7 @@ public class Metrics { /** * Interface used to collect custom data for a plugin */ - public static abstract class Plotter { + public abstract static class Plotter { /** * The plot's name diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java index 0c6f70396..aefea3a9a 100644 --- a/src/main/java/org/spigotmc/RestartCommand.java +++ b/src/main/java/org/spigotmc/RestartCommand.java @@ -42,29 +42,24 @@ public class RestartCommand extends Command private static void restart(final String restartScript) { - // Akarin start - if (io.akarin.server.core.AkarinGlobalConfig.noResponseDoGC) { - System.out.println("Attempting to garbage collect, this may takes a few seconds"); - System.runFinalization(); - System.gc(); - } - // Akarin end AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper try { // Paper - extract method and cleanup - boolean isRestarting = addShutdownHook(restartScript); - if (isRestarting) { - System.out.println("Attempting to restart with " + SpigotConfig.restartScript); - } else { + boolean isRestarting = addShutdownHook( restartScript ); + if ( isRestarting ) + { + System.out.println( "Attempting to restart with " + SpigotConfig.restartScript ); + } else + { System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." ); } - // Stop the watchdog WatchdogThread.doStop(); - shutdownServer(isRestarting); + shutdownServer( isRestarting ); + // Paper end } catch ( Exception ex ) { ex.printStackTrace(); @@ -74,7 +69,7 @@ public class RestartCommand extends Command // Paper start - sync copied from above with minor changes, async added private static void shutdownServer(boolean isRestarting) { - if (MinecraftServer.getServer().isMainThread()) + if ( MinecraftServer.getServer().isMainThread() ) { // Kick all players for ( EntityPlayer p : com.google.common.collect.ImmutableList.copyOf( MinecraftServer.getServer().getPlayerList().players ) ) @@ -94,25 +89,23 @@ public class RestartCommand extends Command // Actually shutdown try { - MinecraftServer.getServer().stop(); + MinecraftServer.getServer().close(); // calls stop() } catch ( Throwable t ) { } // Actually stop the JVM - System.exit(0); + System.exit( 0 ); } else { // Mark the server to shutdown at the end of the tick - MinecraftServer.getServer().safeShutdown(isRestarting); - - + MinecraftServer.getServer().safeShutdown( false, isRestarting ); // wait 10 seconds to see if we're actually going to try shutdown try { - Thread.sleep(10000); + Thread.sleep( 10000 ); } catch (InterruptedException ignored) { @@ -127,9 +120,11 @@ public class RestartCommand extends Command System.exit( 0 ); } } + // Paper end // Paper - Split from moved code - private static void closeSocket() { + private static void closeSocket() + { // Close the socket so we can rebind with the new process MinecraftServer.getServer().getServerConnection().b(); @@ -143,33 +138,42 @@ public class RestartCommand extends Command } // Paper end - // Paper - copied from above and modified to return if the hook registered - private static boolean addShutdownHook(final String restartScript) { - + // Paper start - copied from above and modified to return if the hook registered + private static boolean addShutdownHook(String restartScript) + { String[] split = restartScript.split( " " ); if ( split.length > 0 && new File( split[0] ).isFile() ) { - Thread shutdownHook = new Thread() { + Thread shutdownHook = new Thread() + { @Override - public void run() { - try { - String os = System.getProperty("os.name").toLowerCase(java.util.Locale.ENGLISH); - if (os.contains("win")) { - Runtime.getRuntime().exec("cmd /c start " + restartScript); - } else { + public void run() + { + try + { + String os = System.getProperty( "os.name" ).toLowerCase(java.util.Locale.ENGLISH); + if ( os.contains( "win" ) ) + { + Runtime.getRuntime().exec( "cmd /c start " + restartScript ); + } else + { Runtime.getRuntime().exec( "sh " + restartScript ); } - } catch (Exception e) { + } catch ( Exception e ) + { e.printStackTrace(); } } }; - shutdownHook.setDaemon(true); - Runtime.getRuntime().addShutdownHook(shutdownHook); + shutdownHook.setDaemon( true ); + Runtime.getRuntime().addShutdownHook( shutdownHook ); return true; - } else { + } else + { return false; } } + // Paper end + } diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java index fb09fb097..359a0c8af 100644 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java @@ -71,8 +71,8 @@ public class SpigotConfig commands = new HashMap(); commands.put( "spigot", new SpigotCommand( "spigot" ) ); - version = getInt( "config-version", 11 ); - set( "config-version", 11 ); + version = getInt( "config-version", 12 ); + set( "config-version", 12 ); readConfig( SpigotConfig.class, null ); } @@ -245,11 +245,6 @@ public class SpigotConfig Bukkit.getLogger().log( Level.INFO, "Using {0} threads for Netty based IO", count ); } - public static boolean lateBind; - private static void lateBind() { - lateBind = getBoolean( "settings.late-bind", false ); - } - public static boolean disableStatSaving; public static Map forcedStats = new HashMap<>(); private static void stats() @@ -290,7 +285,7 @@ public class SpigotConfig public static int playerSample; private static void playerSample() { - playerSample = Math.max(getInt( "settings.sample-count", 12 ), 0); // Paper - Avoid negative counts + playerSample = Math.max( getInt( "settings.sample-count", 12 ), 0 ); // Paper - Avoid negative counts Bukkit.getLogger().log( Level.INFO, "Server Ping Player Sample Count: {0}", playerSample ); // Paper - Use logger } @@ -357,7 +352,7 @@ public class SpigotConfig private static void attributeMaxes() { maxHealth = getDouble( "settings.attribute.maxHealth.max", maxHealth ); - ( (AttributeRanged) GenericAttributes.maxHealth ).maximum = maxHealth; + ( (AttributeRanged) GenericAttributes.MAX_HEALTH ).maximum = maxHealth; movementSpeed = getDouble( "settings.attribute.movementSpeed.max", movementSpeed ); ( (AttributeRanged) GenericAttributes.MOVEMENT_SPEED ).maximum = movementSpeed; attackDamage = getDouble( "settings.attribute.attackDamage.max", attackDamage ); diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java index 809ce1d6a..4feea10de 100644 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java @@ -39,36 +39,47 @@ public class SpigotWorldConfig config.set( "world-settings.default." + path, val ); } - public boolean getBoolean(String path, boolean def) + public boolean getBoolean(String path, boolean def) // Paper - private -> public { config.addDefault( "world-settings.default." + path, def ); return config.getBoolean( "world-settings." + worldName + "." + path, config.getBoolean( "world-settings.default." + path ) ); } - public double getDouble(String path, double def) + public double getDouble(String path, double def) // Paper - private -> public { config.addDefault( "world-settings.default." + path, def ); return config.getDouble( "world-settings." + worldName + "." + path, config.getDouble( "world-settings.default." + path ) ); } - public int getInt(String path, int def) + public int getInt(String path) // Paper - private -> public + { + return config.getInt( "world-settings." + worldName + "." + path ); + } + + public int getInt(String path, int def) // Paper - private -> public { config.addDefault( "world-settings.default." + path, def ); return config.getInt( "world-settings." + worldName + "." + path, config.getInt( "world-settings.default." + path ) ); } - public List getList(String path, T def) + public List getList(String path, T def) // Paper - private -> public { config.addDefault( "world-settings.default." + path, def ); return (List) config.getList( "world-settings." + worldName + "." + path, config.getList( "world-settings.default." + path ) ); } - public String getString(String path, String def) + public String getString(String path, String def) // Paper - private -> public { config.addDefault( "world-settings.default." + path, def ); return config.getString( "world-settings." + worldName + "." + path, config.getString( "world-settings.default." + path ) ); } + private Object get(String path, Object def) + { + config.addDefault( "world-settings.default." + path, def ); + return config.get( "world-settings." + worldName + "." + path, config.get( "world-settings.default." + path ) ); + } + // Crop growth rates public int cactusModifier; public int caneModifier; @@ -83,6 +94,9 @@ public class SpigotWorldConfig public int wartModifier; public int vineModifier; public int cocoaModifier; + public int bambooModifier; + public int sweetBerryModifier; + public int kelpModifier; private int getAndValidateGrowth(String crop) { int modifier = getInt( "growth." + crop.toLowerCase(java.util.Locale.ENGLISH) + "-modifier", 100 ); @@ -110,6 +124,9 @@ public class SpigotWorldConfig wartModifier = getAndValidateGrowth( "NetherWart" ); vineModifier = getAndValidateGrowth( "Vine" ); cocoaModifier = getAndValidateGrowth( "Cocoa" ); + bambooModifier = getAndValidateGrowth( "Bamboo" ); + sweetBerryModifier = getAndValidateGrowth( "SweetBerry" ); + kelpModifier = getAndValidateGrowth( "Kelp" ); } public double itemMerge; @@ -129,7 +146,19 @@ public class SpigotWorldConfig public int viewDistance; private void viewDistance() { - viewDistance = getInt( "view-distance", Bukkit.getViewDistance() ); + if ( SpigotConfig.version < 12 ) + { + set( "view-distance", null ); + } + + Object viewDistanceObject = get( "view-distance", "default" ); + viewDistance = ( viewDistanceObject ) instanceof Number ? ( (Number) viewDistanceObject ).intValue() : -1; + if ( viewDistance <= 0 ) + { + viewDistance = Bukkit.getViewDistance(); + } + + viewDistance = Math.max( Math.min( viewDistance, 32 ), 3 ); log( "View Distance: " + viewDistance ); } @@ -149,17 +178,17 @@ public class SpigotWorldConfig public int animalActivationRange = 32; public int monsterActivationRange = 32; + public int raiderActivationRange = 48; public int miscActivationRange = 16; - public int waterActivationRange = 16; // Paper public boolean tickInactiveVillagers = true; private void activationRange() { animalActivationRange = getInt( "entity-activation-range.animals", animalActivationRange ); monsterActivationRange = getInt( "entity-activation-range.monsters", monsterActivationRange ); + raiderActivationRange = getInt( "entity-activation-range.raiders", raiderActivationRange ); miscActivationRange = getInt( "entity-activation-range.misc", miscActivationRange ); - waterActivationRange = getInt( "entity-activation-range.water", waterActivationRange ); // Paper tickInactiveVillagers = getBoolean( "entity-activation-range.tick-inactive-villagers", tickInactiveVillagers ); - log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Mi " + miscActivationRange + " / Tiv " + tickInactiveVillagers ); + log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Ra " + raiderActivationRange + " / Mi " + miscActivationRange + " / Tiv " + tickInactiveVillagers ); } public int playerTrackingRange = 48; @@ -193,13 +222,6 @@ public class SpigotWorldConfig log( "Hopper Transfer: " + hopperTransfer + " Hopper Check: " + hopperCheck + " Hopper Amount: " + hopperAmount ); } - public boolean randomLightUpdates; - private void lightUpdates() - { - randomLightUpdates = getBoolean( "random-light-updates", false ); - log( "Random Lighting Updates: " + randomLightUpdates ); - } - public int arrowDespawnRate; private void arrowDespawnRate() { @@ -247,6 +269,7 @@ public class SpigotWorldConfig public int swampSeed; public int monumentSeed; public int oceanSeed; + public int outpostSeed; public int shipwreckSeed; public int slimeSeed; private void initWorldGenSeeds() @@ -259,6 +282,7 @@ public class SpigotWorldConfig monumentSeed = getInt( "seed-monument", 10387313 ); shipwreckSeed = getInt( "seed-shipwreck", 165745295 ); oceanSeed = getInt( "seed-ocean", 14357621 ); + outpostSeed = getInt( "seed-outpost", 165745296 ); slimeSeed = getInt( "seed-slime", 987234911 ); log( "Custom Map Seeds: Village: " + villageSeed + " Desert: " + desertSeed + " Igloo: " + iglooSeed + " Jungle: " + jungleSeed + " Swamp: " + swampSeed + " Monument: " + monumentSeed + "Ocean: " + oceanSeed + " Shipwreck: " + shipwreckSeed + " Slime: " + slimeSeed ); } diff --git a/src/main/java/org/spigotmc/SupplierUtils.java b/src/main/java/org/spigotmc/SupplierUtils.java deleted file mode 100644 index f63ce98bf..000000000 --- a/src/main/java/org/spigotmc/SupplierUtils.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.spigotmc; - -import java.util.function.Supplier; -import javax.annotation.Nullable; - -/** - * Utilities for creating and working with {@code Supplier} instances. - */ -public class SupplierUtils { - - /** - * Repeatedly supplies the first value from a given sequence; the value is - * obtained only when required. - */ - public static class LazyHeadSupplier implements Supplier { - - private @Nullable Supplier completion; - private @Nullable V value; - - public LazyHeadSupplier(Supplier completion) { - this.completion = completion; - } - - public synchronized @Nullable V get() { - if (this.completion != null) { - this.value = this.completion.get(); - this.completion = null; - } - - return this.value; - } - } - - /** - * Repeatedly supplies the given value. - */ - public static class ValueSupplier implements Supplier { - - private final @Nullable V value; - - public ValueSupplier(@Nullable V value) { - this.value = value; - } - - public @Nullable V get() { - return this.value; - } - } - - /** - * Creates a new {@code Supplier} that supplies the given {@code Supplier}'s - * first value. - * - * @param doLazily {@code false}, if {@code completion.get()} should be - * called immediately, or {@code true}, if {@code completion.get()} should - * be called only when the value is first needed. - */ - public static Supplier createUnivaluedSupplier(Supplier completion, boolean doLazily) { - return doLazily ? new LazyHeadSupplier(completion) : new ValueSupplier(completion.get()); - } - - /** - * Returns {@code supplier.get()}, if {@code supplier} is non-{@code null} - * (or {@code null}, otherwise). - */ - public static @Nullable V getIfExists(@Nullable Supplier supplier) { - return supplier != null ? supplier.get() : null; - } -} diff --git a/src/main/java/org/spigotmc/TrackingRange.java b/src/main/java/org/spigotmc/TrackingRange.java index 4bf4d2ac6..6f8e6c1d0 100644 --- a/src/main/java/org/spigotmc/TrackingRange.java +++ b/src/main/java/org/spigotmc/TrackingRange.java @@ -25,7 +25,7 @@ public class TrackingRange if ( entity instanceof EntityPlayer ) { return config.playerTrackingRange; - } else if ( entity.activationType == 1 ) + } else if ( entity.activationType == ActivationRange.ActivationType.MONSTER || entity.activationType == ActivationRange.ActivationType.RAIDER ) { return config.monsterTrackingRange; } else if ( entity instanceof EntityGhast ) @@ -37,13 +37,13 @@ public class TrackingRange { return config.monsterActivationRange; } - } else if ( entity.activationType == 2 ) + } else if ( entity.activationType == ActivationRange.ActivationType.ANIMAL ) { return config.animalTrackingRange; } else if ( entity instanceof EntityItemFrame || entity instanceof EntityPainting || entity instanceof EntityItem || entity instanceof EntityExperienceOrb ) { return config.miscTrackingRange; - } else + } else { return config.otherTrackingRange; } diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java index 9c2066441..6ca0ebfde 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java @@ -6,6 +6,7 @@ import java.lang.management.ThreadInfo; import java.util.logging.Level; import java.util.logging.Logger; import com.destroystokyo.paper.PaperConfig; +import com.destroystokyo.paper.io.chunk.ChunkTaskManager; // Paper import net.minecraft.server.MinecraftServer; import org.bukkit.Bukkit; @@ -24,7 +25,7 @@ public class WatchdogThread extends Thread private WatchdogThread(long timeoutTime, boolean restart) { - super( "Akarin Watchdog Thread" ); // Akarin + super( "Paper Watchdog Thread" ); this.timeoutTime = timeoutTime; this.restart = restart; earlyWarningEvery = Math.min(PaperConfig.watchdogPrintEarlyWarningEvery, timeoutTime); // Paper @@ -75,14 +76,15 @@ public class WatchdogThread extends Thread if (isLongTimeout) { // Paper end log.log( Level.SEVERE, "------------------------------" ); - log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Akarin bug." ); // Paper // Akarin + log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" ); - log.log( Level.SEVERE, "\t *Especially* if it looks like HTTP or disk operations are occurring" ); // Akarin - MYSQL -> disk + log.log( Level.SEVERE, "\t *Especially* if it looks like HTTP or MySQL operations are occurring" ); log.log( Level.SEVERE, "If you see a world save or edit, then it means you did far more than your server can handle at once" ); log.log( Level.SEVERE, "\t If this is the case, consider increasing timeout-time in spigot.yml but note that this will replace the crash with LARGE lag spikes" ); - log.log( Level.SEVERE, "If you are unsure or still think this is a Akarin bug, please report this to https://github.com/Akarin-project/Akarin/issues" ); // Akarin + log.log( Level.SEVERE, "If you are unsure or still think this is a Paper bug, please report this to https://github.com/PaperMC/Paper/issues" ); log.log( Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports" ); log.log( Level.SEVERE, "Paper version: " + Bukkit.getServer().getVersion() ); + ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper // if ( net.minecraft.server.World.lastPhysicsProblem != null ) { @@ -105,14 +107,15 @@ public class WatchdogThread extends Thread // Paper end } else { - log.log(Level.WARNING, "--- DO NOT REPORT THIS TO AKARIN - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---"); // Akarin - use WARNING level - log.log(Level.WARNING, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump"); // Akarin - use WARNING level + log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---"); + log.log(Level.SEVERE, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump"); } // Paper end - Different message for short timeout - log.log( Level.WARNING, "------------------------------" ); // Akarin - use WARNING level - log.log( Level.WARNING, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Akarin - use WARNING level - dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().primaryThread.getId(), Integer.MAX_VALUE ), log ); - log.log( Level.WARNING, "------------------------------" ); // Akarin - use WARNING level + log.log( Level.SEVERE, "------------------------------" ); + log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper + log.log( Level.SEVERE, "The server is waiting on these chunks: " + ChunkTaskManager.getChunkWaitInfo() ); // Paper - async chunk debug + dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); + log.log( Level.SEVERE, "------------------------------" ); // // Paper start - Only print full dump on long timeouts if ( isLongTimeout ) @@ -124,11 +127,11 @@ public class WatchdogThread extends Thread dumpThread( thread, log ); } } else { - log.log(Level.WARNING, "--- DO NOT REPORT THIS TO AKARIN - THIS IS NOT A BUG OR A CRASH ---"); // Akarin - use WARNING level + log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---"); } - log.log( isLongTimeout ? Level.SEVERE : Level.WARNING, "------------------------------" ); // Akarin - use WARNING level + log.log( Level.SEVERE, "------------------------------" ); if ( isLongTimeout ) {